complete tight png

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Василий Толстов 2017-06-18 19:42:41 +03:00
parent 49c704bc67
commit 1413d28267
9 changed files with 513 additions and 120 deletions

View File

@ -4,6 +4,11 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"image"
"image/color"
"image/draw"
"image/png"
"io"
) )
// EncodingType represents a known VNC encoding type. // EncodingType represents a known VNC encoding type.
@ -12,26 +17,72 @@ type EncodingType int32
//go:generate stringer -type=EncodingType //go:generate stringer -type=EncodingType
const ( const (
EncRaw EncodingType = 0 EncRaw EncodingType = 0
EncCopyRect EncodingType = 1 EncCopyRect EncodingType = 1
EncRRE EncodingType = 2 EncRRE EncodingType = 2
EncCoRRE EncodingType = 4 EncCoRRE EncodingType = 4
EncHextile EncodingType = 5 EncHextile EncodingType = 5
EncZlib EncodingType = 6 EncZlib EncodingType = 6
EncTight EncodingType = 7 EncTight EncodingType = 7
EncZlibHex EncodingType = 8 EncZlibHex EncodingType = 8
EncUltra1 EncodingType = 9 EncUltra1 EncodingType = 9
EncUltra2 EncodingType = 10 EncUltra2 EncodingType = 10
EncJPEG EncodingType = 21 EncJPEG EncodingType = 21
EncJRLE EncodingType = 22 EncJRLE EncodingType = 22
//EncRichCursor EncodingType = 0xFFFFFF11 EncTRLE EncodingType = 15
//EncPointerPos EncodingType = 0xFFFFFF18 EncZRLE EncodingType = 16
//EncLastRec EncodingType = 0xFFFFFF20 EncJPEGQualityLevelPseudo10 EncodingType = -23
EncTRLE EncodingType = 15 EncJPEGQualityLevelPseudo9 EncodingType = -24
EncZRLE EncodingType = 16 EncJPEGQualityLevelPseudo8 EncodingType = -25
EncColorPseudo EncodingType = -239 EncJPEGQualityLevelPseudo7 EncodingType = -26
EncDesktopSizePseudo EncodingType = -223 EncJPEGQualityLevelPseudo6 EncodingType = -27
EncClientRedirect EncodingType = -311 EncJPEGQualityLevelPseudo5 EncodingType = -28
EncJPEGQualityLevelPseudo4 EncodingType = -29
EncJPEGQualityLevelPseudo3 EncodingType = -30
EncJPEGQualityLevelPseudo2 EncodingType = -31
EncJPEGQualityLevelPseudo1 EncodingType = -32
EncColorPseudo EncodingType = -239
EncDesktopSizePseudo EncodingType = -223
EncLastRectPseudo EncodingType = -224
EncCompressionLevel10 EncodingType = -247
EncCompressionLevel9 EncodingType = -248
EncCompressionLevel8 EncodingType = -249
EncCompressionLevel7 EncodingType = -250
EncCompressionLevel6 EncodingType = -251
EncCompressionLevel5 EncodingType = -252
EncCompressionLevel4 EncodingType = -253
EncCompressionLevel3 EncodingType = -254
EncCompressionLevel2 EncodingType = -255
EncCompressionLevel1 EncodingType = -256
EncQEMUPointerMotionChangePseudo EncodingType = -257
EncQEMUExtendedKeyEventPseudo EncodingType = -258
EncTightPng EncodingType = -260
EncExtendedDesktopSizePseudo EncodingType = -308
EncXvpPseudo EncodingType = -309
EncFencePseudo EncodingType = -312
EncContinuousUpdatesPseudo EncodingType = -313
EncClientRedirect EncodingType = -311
)
//go:generate stringer -type=TightCompression
type TightCompression uint8
const (
TightCompressionBasic TightCompression = 0
TightCompressionFill TightCompression = 8
TightCompressionJPEG TightCompression = 9
TightCompressionPNG TightCompression = 10
)
//go:generate stringer -type=TightFilter
type TightFilter uint8
const (
TightFilterCopy TightFilter = 0
TightFilterPalette TightFilter = 1
TightFilterGradient TightFilter = 2
) )
type Encoding interface { type Encoding interface {
@ -40,10 +91,230 @@ type Encoding interface {
Write(Conn, *Rectangle) error Write(Conn, *Rectangle) error
} }
type CopyRectEncoding struct {
SX, SY uint16
}
func (CopyRectEncoding) Type() EncodingType { return EncCopyRect }
func (enc *CopyRectEncoding) Read(c Conn, rect *Rectangle) error {
if err := binary.Read(c, binary.BigEndian, &enc.SX); err != nil {
return err
}
if err := binary.Read(c, binary.BigEndian, &enc.SY); err != nil {
return err
}
return nil
}
func (enc *CopyRectEncoding) Write(c Conn, rect *Rectangle) error {
if err := binary.Write(c, binary.BigEndian, enc.SX); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, enc.SY); err != nil {
return err
}
return nil
}
type RawEncoding struct { type RawEncoding struct {
Colors []Color Colors []Color
} }
type TightEncoding struct{}
func (*TightEncoding) Type() EncodingType { return EncTight }
func (enc *TightEncoding) Write(c Conn, rect *Rectangle) error {
return nil
}
func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
return nil
}
type TightCC struct {
Compression TightCompression
Filter TightFilter
}
func readTightCC(c Conn) (*TightCC, error) {
var ccb uint8 // compression control byte
if err := binary.Read(c, binary.BigEndian, &ccb); err != nil {
return nil, err
}
cmp := TightCompression(ccb >> 4)
switch cmp {
case TightCompressionBasic:
return &TightCC{TightCompressionBasic, TightFilterCopy}, nil
case TightCompressionFill:
return &TightCC{TightCompressionFill, TightFilterCopy}, nil
case TightCompressionPNG:
return &TightCC{TightCompressionPNG, TightFilterCopy}, nil
}
return nil, fmt.Errorf("unknown tight compression %d", cmp)
}
func setBit(n uint8, pos uint8) uint8 {
n |= (1 << pos)
return n
}
func clrBit(n uint8, pos uint8) uint8 {
n = n &^ (1 << pos)
return n
}
func hasBit(n uint8, pos uint8) bool {
v := n & (1 << pos)
return (v > 0)
}
func getBit(n uint8, pos uint8) uint8 {
n = n & (1 << pos)
return n
}
func writeTightCC(c Conn, tcc *TightCC) error {
var ccb uint8 // compression control byte
switch tcc.Compression {
case TightCompressionFill:
ccb = setBit(ccb, 7)
case TightCompressionJPEG:
ccb = setBit(ccb, 7)
ccb = setBit(ccb, 4)
case TightCompressionPNG:
ccb = setBit(ccb, 7)
ccb = setBit(ccb, 5)
}
return binary.Write(c, binary.BigEndian, ccb)
}
func (enc *TightPngEncoding) Write(c Conn, rect *Rectangle) error {
if err := writeTightCC(c, enc.TightCC); err != nil {
return err
}
cmp := enc.TightCC.Compression
switch cmp {
case TightCompressionPNG:
buf := bytes.NewBuffer(nil)
if err := png.Encode(buf, enc.Image); err != nil {
return err
}
if err := writeTightLength(c, buf.Len()); err != nil {
return err
}
if _, err := io.Copy(c, buf); err != nil {
return err
}
case TightCompressionFill:
var tpx TightPixel
r, g, b, _ := enc.Image.At(0, 0).RGBA()
tpx.R = uint8(r)
tpx.G = uint8(g)
tpx.B = uint8(b)
if err := binary.Write(c, binary.BigEndian, tpx); err != nil {
return err
}
default:
return fmt.Errorf("unknown tight compression %d", cmp)
}
return nil
}
type TightPixel struct {
R uint8
G uint8
B uint8
}
type TightPngEncoding struct {
TightCC *TightCC
Image image.Image
}
func (*TightPngEncoding) Type() EncodingType { return EncTightPng }
func (enc *TightPngEncoding) Read(c Conn, rect *Rectangle) error {
tcc, err := readTightCC(c)
if err != nil {
return err
}
enc.TightCC = tcc
cmp := enc.TightCC.Compression
switch cmp {
case TightCompressionPNG:
buf := bytes.NewBuffer(nil)
l, err := readTightLength(c)
if err != nil {
return err
}
_, err = io.CopyN(buf, c, int64(l))
if err != nil {
return err
}
enc.Image, err = png.Decode(buf)
if err != nil {
return err
}
case TightCompressionFill:
var tpx TightPixel
if err := binary.Read(c, binary.BigEndian, &tpx); err != nil {
return err
}
enc.Image = image.NewRGBA(image.Rect(0, 0, 1, 1))
enc.Image.(draw.Image).Set(0, 0, color.RGBA{R: tpx.R, G: tpx.G, B: tpx.B, A: 1})
default:
return fmt.Errorf("unknown compression %d", cmp)
}
return nil
}
func writeTightLength(c Conn, l int) error {
var buf []uint8
buf = append(buf, uint8(l&0x7F))
if l > 0x7F {
buf[0] |= 0x80
buf = append(buf, uint8((l>>7)&0x7F))
if l > 0x3FFF {
buf[1] |= 0x80
buf = append(buf, uint8((l>>14)&0xFF))
}
}
return binary.Write(c, binary.BigEndian, buf)
}
func readTightLength(c Conn) (int, error) {
var length int
var err error
var b uint8
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
return 0, err
}
length = int(b) & 0x7F
if (b & 0x80) == 0 {
return length, nil
}
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
return 0, err
}
length |= (int(b) & 0x7F) << 7
if (b & 0x80) == 0 {
return length, nil
}
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
return 0, err
}
length |= (int(b) & 0xFF) << 14
return length, nil
}
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error { func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
defer buf.Reset() defer buf.Reset()
@ -58,16 +329,7 @@ func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil { if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
return err return err
} }
/*
if _, err := buf.Write(bytes); err != nil {
return err
}
*/
} }
fmt.Printf("w %d\n", n)
//return binary.Write(c, binary.BigEndian, buf.Bytes())
fmt.Printf("w %v\n", buf.Bytes())
_, err := c.Write(buf.Bytes()) _, err := c.Write(buf.Bytes())
return err return err
} }
@ -80,13 +342,11 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
bytesPerPixel := int(pf.BPP / 8) bytesPerPixel := int(pf.BPP / 8)
n := rect.Area() * bytesPerPixel n := rect.Area() * bytesPerPixel
data := make([]byte, n) data := make([]byte, n)
fmt.Printf("r %d\n", n)
if err := binary.Read(c, binary.BigEndian, &data); err != nil { if err := binary.Read(c, binary.BigEndian, &data); err != nil {
return err return err
} }
buf.Write(data) buf.Write(data)
defer buf.Reset() defer buf.Reset()
fmt.Printf("r %v\n", buf.Bytes())
colors := make([]Color, rect.Area()) colors := make([]Color, rect.Area())
for y := uint16(0); y < rect.Height; y++ { for y := uint16(0); y < rect.Height; y++ {
for x := uint16(0); x < rect.Width; x++ { for x := uint16(0); x < rect.Width; x++ {
@ -105,7 +365,8 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
func (*RawEncoding) Type() EncodingType { return EncRaw } func (*RawEncoding) Type() EncodingType { return EncRaw }
// DesktopSizePseudoEncoding represents a desktop size message from the server. // DesktopSizePseudoEncoding represents a desktop size message from the server.
type DesktopSizePseudoEncoding struct{} type DesktopSizePseudoEncoding struct {
}
func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo } func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo }
@ -113,7 +374,6 @@ func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePse
func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error { func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error {
c.SetWidth(rect.Width) c.SetWidth(rect.Width)
c.SetHeight(rect.Height) c.SetHeight(rect.Height)
return nil return nil
} }

View File

@ -4,46 +4,59 @@ package vnc
import "fmt" import "fmt"
const ( const _EncodingType_name = "EncContinuousUpdatesPseudoEncFencePseudoEncClientRedirectEncXvpPseudoEncExtendedDesktopSizePseudoEncTightPngEncQEMUExtendedKeyEventPseudoEncQEMUPointerMotionChangePseudoEncCompressionLevel1EncCompressionLevel2EncCompressionLevel3EncCompressionLevel4EncCompressionLevel5EncCompressionLevel6EncCompressionLevel7EncCompressionLevel8EncCompressionLevel9EncCompressionLevel10EncColorPseudoEncLastRectPseudoEncDesktopSizePseudoEncJPEGQualityLevelPseudo1EncJPEGQualityLevelPseudo2EncJPEGQualityLevelPseudo3EncJPEGQualityLevelPseudo4EncJPEGQualityLevelPseudo5EncJPEGQualityLevelPseudo6EncJPEGQualityLevelPseudo7EncJPEGQualityLevelPseudo8EncJPEGQualityLevelPseudo9EncJPEGQualityLevelPseudo10EncRawEncCopyRectEncRREEncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2EncTRLEEncZRLEEncJPEGEncJRLE"
_EncodingType_name_0 = "EncClientRedirect"
_EncodingType_name_1 = "EncColorPseudo"
_EncodingType_name_2 = "EncDesktopSizePseudo"
_EncodingType_name_3 = "EncRawEncCopyRectEncRRE"
_EncodingType_name_4 = "EncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2"
_EncodingType_name_5 = "EncTRLEEncZRLE"
_EncodingType_name_6 = "EncJPEGEncJRLE"
)
var ( var _EncodingType_map = map[EncodingType]string{
_EncodingType_index_0 = [...]uint8{0, 17} -313: _EncodingType_name[0:26],
_EncodingType_index_1 = [...]uint8{0, 14} -312: _EncodingType_name[26:40],
_EncodingType_index_2 = [...]uint8{0, 20} -311: _EncodingType_name[40:57],
_EncodingType_index_3 = [...]uint8{0, 6, 17, 23} -309: _EncodingType_name[57:69],
_EncodingType_index_4 = [...]uint8{0, 8, 18, 25, 33, 43, 52, 61} -308: _EncodingType_name[69:97],
_EncodingType_index_5 = [...]uint8{0, 7, 14} -260: _EncodingType_name[97:108],
_EncodingType_index_6 = [...]uint8{0, 7, 14} -258: _EncodingType_name[108:137],
) -257: _EncodingType_name[137:169],
-256: _EncodingType_name[169:189],
-255: _EncodingType_name[189:209],
-254: _EncodingType_name[209:229],
-253: _EncodingType_name[229:249],
-252: _EncodingType_name[249:269],
-251: _EncodingType_name[269:289],
-250: _EncodingType_name[289:309],
-249: _EncodingType_name[309:329],
-248: _EncodingType_name[329:349],
-247: _EncodingType_name[349:370],
-239: _EncodingType_name[370:384],
-224: _EncodingType_name[384:401],
-223: _EncodingType_name[401:421],
-32: _EncodingType_name[421:447],
-31: _EncodingType_name[447:473],
-30: _EncodingType_name[473:499],
-29: _EncodingType_name[499:525],
-28: _EncodingType_name[525:551],
-27: _EncodingType_name[551:577],
-26: _EncodingType_name[577:603],
-25: _EncodingType_name[603:629],
-24: _EncodingType_name[629:655],
-23: _EncodingType_name[655:682],
0: _EncodingType_name[682:688],
1: _EncodingType_name[688:699],
2: _EncodingType_name[699:705],
4: _EncodingType_name[705:713],
5: _EncodingType_name[713:723],
6: _EncodingType_name[723:730],
7: _EncodingType_name[730:738],
8: _EncodingType_name[738:748],
9: _EncodingType_name[748:757],
10: _EncodingType_name[757:766],
15: _EncodingType_name[766:773],
16: _EncodingType_name[773:780],
21: _EncodingType_name[780:787],
22: _EncodingType_name[787:794],
}
func (i EncodingType) String() string { func (i EncodingType) String() string {
switch { if str, ok := _EncodingType_map[i]; ok {
case i == -311: return str
return _EncodingType_name_0
case i == -239:
return _EncodingType_name_1
case i == -223:
return _EncodingType_name_2
case 0 <= i && i <= 2:
return _EncodingType_name_3[_EncodingType_index_3[i]:_EncodingType_index_3[i+1]]
case 4 <= i && i <= 10:
i -= 4
return _EncodingType_name_4[_EncodingType_index_4[i]:_EncodingType_index_4[i+1]]
case 15 <= i && i <= 16:
i -= 15
return _EncodingType_name_5[_EncodingType_index_5[i]:_EncodingType_index_5[i+1]]
case 21 <= i && i <= 22:
i -= 21
return _EncodingType_name_6[_EncodingType_index_6[i]:_EncodingType_index_6[i+1]]
default:
return fmt.Sprintf("EncodingType(%d)", i)
} }
return fmt.Sprintf("EncodingType(%d)", i)
} }

View File

@ -18,19 +18,26 @@ func main() {
schServer := make(chan vnc.ServerMessage) schServer := make(chan vnc.ServerMessage)
scfg := &vnc.ServerConfig{ scfg := &vnc.ServerConfig{
Width: 800, Width: 800,
Height: 600, Height: 600,
VersionHandler: vnc.ServerVersionHandler, VersionHandler: vnc.ServerVersionHandler,
SecurityHandler: vnc.ServerSecurityHandler, SecurityHandler: vnc.ServerSecurityHandler,
SecurityHandlers: []vnc.SecurityHandler{&vnc.ClientAuthNone{}}, SecurityHandlers: []vnc.SecurityHandler{
&vnc.ClientAuthVeNCrypt02Plain{Username: []byte("test"), Password: []byte("test")},
&vnc.ClientAuthNone{},
},
ClientInitHandler: vnc.ServerClientInitHandler, ClientInitHandler: vnc.ServerClientInitHandler,
ServerInitHandler: vnc.ServerServerInitHandler, ServerInitHandler: vnc.ServerServerInitHandler,
Encodings: []vnc.Encoding{&vnc.RawEncoding{}}, Encodings: []vnc.Encoding{
PixelFormat: vnc.PixelFormat32bit, &vnc.TightPngEncoding{},
ClientMessageCh: schClient, &vnc.CopyRectEncoding{},
ServerMessageCh: schServer, &vnc.RawEncoding{},
ClientMessages: vnc.DefaultClientMessages, },
DesktopName: []byte("vnc proxy"), PixelFormat: vnc.PixelFormat32bit,
ClientMessageCh: schClient,
ServerMessageCh: schServer,
ClientMessages: vnc.DefaultClientMessages,
DesktopName: []byte("vnc proxy"),
} }
c, err := net.Dial("tcp", "127.0.0.1:5995") c, err := net.Dial("tcp", "127.0.0.1:5995")
if err != nil { if err != nil {
@ -57,9 +64,9 @@ func main() {
log.Fatalf("Error dial. %v", err) log.Fatalf("Error dial. %v", err)
} }
scfg.Width = cc.Width() // scfg.Width = cc.Width()
scfg.Height = cc.Height() // scfg.Height = cc.Height()
scfg.PixelFormat = cc.PixelFormat() // scfg.PixelFormat = cc.PixelFormat()
go vnc.Serve(context.Background(), ln, scfg) go vnc.Serve(context.Background(), ln, scfg)
defer cc.Close() defer cc.Close()
@ -75,28 +82,28 @@ func main() {
case msg := <-schClient: case msg := <-schClient:
switch msg.Type() { switch msg.Type() {
case vnc.SetEncodingsMsgType: case vnc.SetEncodingsMsgType:
msg0 := &vnc.SetPixelFormat{ var encTypes []vnc.EncodingType
PF: *vnc.PixelFormat32bit, for _, enc := range scfg.Encodings {
encTypes = append(encTypes, enc.Type())
}
msg0 := &vnc.SetEncodings{
Encodings: encTypes,
} }
cchClient <- msg0 cchClient <- msg0
encRaw := &vnc.RawEncoding{}
msg1 := &vnc.SetEncodings{
Encodings: []vnc.EncodingType{encRaw.Type()},
}
cchClient <- msg1
/* /*
msg2 := &vnc.FramebufferUpdateRequest{ if scfg.Width != cc.Width() || scfg.Height != cc.Height() {
Inc: 0, msg1 := &vnc.FramebufferUpdate{
X: 0, Rects: []*vnc.Rectangle{&vnc.Rectangle{
Y: 0, Width: cc.Width(),
Width: cc.Width(), Height: cc.Height(),
Height: cc.Height(), EncType: vnc.EncDesktopSizePseudo,
Enc: &vnc.DesktopSizePseudoEncoding{},
},
},
}
schServer <- msg1
} }
cchClient <- msg2
*/ */
case vnc.SetPixelFormatMsgType:
cchClient <- msg
default: default:
cchClient <- msg cchClient <- msg
} }

View File

@ -198,6 +198,9 @@ func ServerSecurityHandler(cfg *ServerConfig, c Conn) error {
if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil { if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil {
return err return err
} }
if err := c.Flush(); err != nil {
return err
}
return authErr return authErr
} }

View File

@ -115,7 +115,6 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
// Marshal implements the Marshaler interface. // Marshal implements the Marshaler interface.
func (r *Rectangle) Write(c Conn) error { func (r *Rectangle) Write(c Conn) error {
var err error var err error
fmt.Printf("w rect %#+v\n", r)
if err = binary.Write(c, binary.BigEndian, r.X); err != nil { if err = binary.Write(c, binary.BigEndian, r.X); err != nil {
return err return err
} }
@ -157,10 +156,17 @@ func (r *Rectangle) Read(c Conn) error {
return err return err
} }
switch r.EncType { switch r.EncType {
case EncCopyRect:
r.Enc = &CopyRectEncoding{}
case EncTight:
r.Enc = &TightEncoding{}
case EncTightPng:
r.Enc = &TightPngEncoding{}
case EncRaw: case EncRaw:
r.Enc = &RawEncoding{} r.Enc = &RawEncoding{}
default:
return fmt.Errorf("unsupported encoding %s", r.EncType)
} }
fmt.Printf("r rect %#+v\n", r)
return r.Enc.Read(c, r) return r.Enc.Read(c, r)
} }

View File

@ -1,6 +1,7 @@
package vnc package vnc
import ( import (
"bytes"
"crypto/des" "crypto/des"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
@ -74,6 +75,10 @@ func (*ServerAuthNone) Auth(c Conn) error {
return nil return nil
} }
func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
return SecTypeVeNCrypt
}
func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType { func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
return SecSubTypeVeNCrypt02Plain return SecSubTypeVeNCrypt02Plain
} }
@ -85,27 +90,91 @@ type ClientAuthVeNCrypt02Plain struct {
} }
func (auth *ClientAuthVeNCrypt02Plain) Auth(c Conn) error { func (auth *ClientAuthVeNCrypt02Plain) Auth(c Conn) error {
if err := binary.Write(c, binary.BigEndian, []uint8{0, 2}); err != nil {
return err
}
if err := c.Flush(); err != nil {
return err
}
var (
major, minor uint8
)
if err := binary.Read(c, binary.BigEndian, &major); err != nil {
return err
}
if err := binary.Read(c, binary.BigEndian, &minor); err != nil {
return err
}
res := uint8(1)
if major == 0 && minor == 2 {
res = uint8(0)
}
if err := binary.Write(c, binary.BigEndian, res); err != nil {
return err
}
c.Flush()
if err := binary.Write(c, binary.BigEndian, uint8(1)); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, auth.SubType()); err != nil {
return err
}
if err := c.Flush(); err != nil {
return err
}
var secType SecuritySubType
if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
return err
}
if secType != auth.SubType() {
binary.Write(c, binary.BigEndian, uint8(1))
c.Flush()
return fmt.Errorf("invalid sectype")
}
if len(auth.Password) == 0 || len(auth.Username) == 0 { if len(auth.Password) == 0 || len(auth.Username) == 0 {
return fmt.Errorf("Security Handshake failed; no username and/or password provided for VeNCryptAuth.") return fmt.Errorf("Security Handshake failed; no username and/or password provided for VeNCryptAuth.")
} }
/*
if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Username))); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Username))); err != nil { if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Password))); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, auth.Username); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil {
return err
}
*/
var (
uLength, pLength uint32
)
if err := binary.Read(c, binary.BigEndian, &uLength); err != nil {
return err
}
if err := binary.Read(c, binary.BigEndian, &pLength); err != nil {
return err return err
} }
if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Password))); err != nil { username := make([]byte, uLength)
password := make([]byte, pLength)
if err := binary.Read(c, binary.BigEndian, &username); err != nil {
return err return err
} }
if err := binary.Write(c, binary.BigEndian, auth.Username); err != nil { if err := binary.Read(c, binary.BigEndian, &password); err != nil {
return err return err
} }
if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil { return fmt.Errorf("invalid username/password")
return err
} }
return nil
return c.Flush()
} }
// ServerAuthVNC is the standard password authentication. See 7.2.2. // ServerAuthVNC is the standard password authentication. See 7.2.2.

View File

@ -156,7 +156,6 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil { if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
return nil, err return nil, err
} }
fmt.Printf("%#+v\n", msg)
for i := uint16(0); i < msg.NumRect; i++ { for i := uint16(0); i < msg.NumRect; i++ {
rect := &Rectangle{} rect := &Rectangle{}
if err := rect.Read(c); err != nil { if err := rect.Read(c); err != nil {
@ -164,15 +163,10 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
} }
msg.Rects = append(msg.Rects, rect) msg.Rects = append(msg.Rects, rect)
} }
fmt.Printf("r fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects)
if msg.NumRect != uint16(len(msg.Rects)) {
panic("rects not equal")
}
return &msg, nil return &msg, nil
} }
func (msg *FramebufferUpdate) Write(c Conn) error { func (msg *FramebufferUpdate) Write(c Conn) error {
fmt.Printf("w fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects)
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
return err return err
} }
@ -341,14 +335,12 @@ func (c *ServerConn) Handle() error {
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil { if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
return err return err
} }
fmt.Printf("srv r %s\n", messageType)
msg, ok := clientMessages[messageType] msg, ok := clientMessages[messageType]
if !ok { if !ok {
return fmt.Errorf("unsupported message-type: %v", messageType) return fmt.Errorf("unsupported message-type: %v", messageType)
} }
parsedMsg, err := msg.Read(c) parsedMsg, err := msg.Read(c)
fmt.Printf("srv r %#+v\n", parsedMsg)
if err != nil { if err != nil {
fmt.Printf("srv err %s\n", err.Error()) fmt.Printf("srv err %s\n", err.Error())
return err return err

View File

@ -0,0 +1,27 @@
// Code generated by "stringer -type=TightCompression"; DO NOT EDIT.
package vnc
import "fmt"
const (
_TightCompression_name_0 = "TightCompressionBasic"
_TightCompression_name_1 = "TightCompressionFillTightCompressionJPEGTightCompressionPNG"
)
var (
_TightCompression_index_0 = [...]uint8{0, 21}
_TightCompression_index_1 = [...]uint8{0, 20, 40, 59}
)
func (i TightCompression) String() string {
switch {
case i == 0:
return _TightCompression_name_0
case 8 <= i && i <= 10:
i -= 8
return _TightCompression_name_1[_TightCompression_index_1[i]:_TightCompression_index_1[i+1]]
default:
return fmt.Sprintf("TightCompression(%d)", i)
}
}

16
tightfilter_string.go Normal file
View File

@ -0,0 +1,16 @@
// Code generated by "stringer -type=TightFilter"; DO NOT EDIT.
package vnc
import "fmt"
const _TightFilter_name = "TightFilterCopyTightFilterPaletteTightFilterGradient"
var _TightFilter_index = [...]uint8{0, 15, 33, 52}
func (i TightFilter) String() string {
if i >= TightFilter(len(_TightFilter_index)-1) {
return fmt.Sprintf("TightFilter(%d)", i)
}
return _TightFilter_name[_TightFilter_index[i]:_TightFilter_index[i+1]]
}