From 1413d282670f1b7c99dd85f0a896a2f4d9e9fdcd Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Sun, 18 Jun 2017 19:42:41 +0300 Subject: [PATCH] complete tight png Signed-off-by: Vasiliy Tolstov --- encoding.go | 326 +++++++++++++++++++++++++++++++++---- encodingtype_string.go | 89 +++++----- example/proxy/main.go | 69 ++++---- handlers.go | 3 + image.go | 10 +- security.go | 85 +++++++++- server.go | 8 - tightcompression_string.go | 27 +++ tightfilter_string.go | 16 ++ 9 files changed, 513 insertions(+), 120 deletions(-) create mode 100644 tightcompression_string.go create mode 100644 tightfilter_string.go diff --git a/encoding.go b/encoding.go index 9df8d3c..e5b70b2 100644 --- a/encoding.go +++ b/encoding.go @@ -4,6 +4,11 @@ import ( "bytes" "encoding/binary" "fmt" + "image" + "image/color" + "image/draw" + "image/png" + "io" ) // EncodingType represents a known VNC encoding type. @@ -12,26 +17,72 @@ type EncodingType int32 //go:generate stringer -type=EncodingType const ( - EncRaw EncodingType = 0 - EncCopyRect EncodingType = 1 - EncRRE EncodingType = 2 - EncCoRRE EncodingType = 4 - EncHextile EncodingType = 5 - EncZlib EncodingType = 6 - EncTight EncodingType = 7 - EncZlibHex EncodingType = 8 - EncUltra1 EncodingType = 9 - EncUltra2 EncodingType = 10 - EncJPEG EncodingType = 21 - EncJRLE EncodingType = 22 - //EncRichCursor EncodingType = 0xFFFFFF11 - //EncPointerPos EncodingType = 0xFFFFFF18 - //EncLastRec EncodingType = 0xFFFFFF20 - EncTRLE EncodingType = 15 - EncZRLE EncodingType = 16 - EncColorPseudo EncodingType = -239 - EncDesktopSizePseudo EncodingType = -223 - EncClientRedirect EncodingType = -311 + EncRaw EncodingType = 0 + EncCopyRect EncodingType = 1 + EncRRE EncodingType = 2 + EncCoRRE EncodingType = 4 + EncHextile EncodingType = 5 + EncZlib EncodingType = 6 + EncTight EncodingType = 7 + EncZlibHex EncodingType = 8 + EncUltra1 EncodingType = 9 + EncUltra2 EncodingType = 10 + EncJPEG EncodingType = 21 + EncJRLE EncodingType = 22 + EncTRLE EncodingType = 15 + EncZRLE EncodingType = 16 + EncJPEGQualityLevelPseudo10 EncodingType = -23 + EncJPEGQualityLevelPseudo9 EncodingType = -24 + EncJPEGQualityLevelPseudo8 EncodingType = -25 + EncJPEGQualityLevelPseudo7 EncodingType = -26 + EncJPEGQualityLevelPseudo6 EncodingType = -27 + 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 { @@ -40,10 +91,230 @@ type Encoding interface { 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 { 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 { buf := bytes.NewBuffer(nil) 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 { 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()) return err } @@ -80,13 +342,11 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error { bytesPerPixel := int(pf.BPP / 8) n := rect.Area() * bytesPerPixel data := make([]byte, n) - fmt.Printf("r %d\n", n) if err := binary.Read(c, binary.BigEndian, &data); err != nil { return err } buf.Write(data) defer buf.Reset() - fmt.Printf("r %v\n", buf.Bytes()) colors := make([]Color, rect.Area()) for y := uint16(0); y < rect.Height; y++ { 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 } // DesktopSizePseudoEncoding represents a desktop size message from the server. -type DesktopSizePseudoEncoding struct{} +type DesktopSizePseudoEncoding struct { +} func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo } @@ -113,7 +374,6 @@ func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePse func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error { c.SetWidth(rect.Width) c.SetHeight(rect.Height) - return nil } diff --git a/encodingtype_string.go b/encodingtype_string.go index ac99e3e..723779b 100644 --- a/encodingtype_string.go +++ b/encodingtype_string.go @@ -4,46 +4,59 @@ package vnc import "fmt" -const ( - _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" -) +const _EncodingType_name = "EncContinuousUpdatesPseudoEncFencePseudoEncClientRedirectEncXvpPseudoEncExtendedDesktopSizePseudoEncTightPngEncQEMUExtendedKeyEventPseudoEncQEMUPointerMotionChangePseudoEncCompressionLevel1EncCompressionLevel2EncCompressionLevel3EncCompressionLevel4EncCompressionLevel5EncCompressionLevel6EncCompressionLevel7EncCompressionLevel8EncCompressionLevel9EncCompressionLevel10EncColorPseudoEncLastRectPseudoEncDesktopSizePseudoEncJPEGQualityLevelPseudo1EncJPEGQualityLevelPseudo2EncJPEGQualityLevelPseudo3EncJPEGQualityLevelPseudo4EncJPEGQualityLevelPseudo5EncJPEGQualityLevelPseudo6EncJPEGQualityLevelPseudo7EncJPEGQualityLevelPseudo8EncJPEGQualityLevelPseudo9EncJPEGQualityLevelPseudo10EncRawEncCopyRectEncRREEncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2EncTRLEEncZRLEEncJPEGEncJRLE" -var ( - _EncodingType_index_0 = [...]uint8{0, 17} - _EncodingType_index_1 = [...]uint8{0, 14} - _EncodingType_index_2 = [...]uint8{0, 20} - _EncodingType_index_3 = [...]uint8{0, 6, 17, 23} - _EncodingType_index_4 = [...]uint8{0, 8, 18, 25, 33, 43, 52, 61} - _EncodingType_index_5 = [...]uint8{0, 7, 14} - _EncodingType_index_6 = [...]uint8{0, 7, 14} -) +var _EncodingType_map = map[EncodingType]string{ + -313: _EncodingType_name[0:26], + -312: _EncodingType_name[26:40], + -311: _EncodingType_name[40:57], + -309: _EncodingType_name[57:69], + -308: _EncodingType_name[69:97], + -260: _EncodingType_name[97:108], + -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 { - switch { - case i == -311: - 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) + if str, ok := _EncodingType_map[i]; ok { + return str } + return fmt.Sprintf("EncodingType(%d)", i) } diff --git a/example/proxy/main.go b/example/proxy/main.go index 12ee014..8fc24e6 100644 --- a/example/proxy/main.go +++ b/example/proxy/main.go @@ -18,19 +18,26 @@ func main() { schServer := make(chan vnc.ServerMessage) scfg := &vnc.ServerConfig{ - Width: 800, - Height: 600, - VersionHandler: vnc.ServerVersionHandler, - SecurityHandler: vnc.ServerSecurityHandler, - SecurityHandlers: []vnc.SecurityHandler{&vnc.ClientAuthNone{}}, + Width: 800, + Height: 600, + VersionHandler: vnc.ServerVersionHandler, + SecurityHandler: vnc.ServerSecurityHandler, + SecurityHandlers: []vnc.SecurityHandler{ + &vnc.ClientAuthVeNCrypt02Plain{Username: []byte("test"), Password: []byte("test")}, + &vnc.ClientAuthNone{}, + }, ClientInitHandler: vnc.ServerClientInitHandler, ServerInitHandler: vnc.ServerServerInitHandler, - Encodings: []vnc.Encoding{&vnc.RawEncoding{}}, - PixelFormat: vnc.PixelFormat32bit, - ClientMessageCh: schClient, - ServerMessageCh: schServer, - ClientMessages: vnc.DefaultClientMessages, - DesktopName: []byte("vnc proxy"), + Encodings: []vnc.Encoding{ + &vnc.TightPngEncoding{}, + &vnc.CopyRectEncoding{}, + &vnc.RawEncoding{}, + }, + PixelFormat: vnc.PixelFormat32bit, + ClientMessageCh: schClient, + ServerMessageCh: schServer, + ClientMessages: vnc.DefaultClientMessages, + DesktopName: []byte("vnc proxy"), } c, err := net.Dial("tcp", "127.0.0.1:5995") if err != nil { @@ -57,9 +64,9 @@ func main() { log.Fatalf("Error dial. %v", err) } - scfg.Width = cc.Width() - scfg.Height = cc.Height() - scfg.PixelFormat = cc.PixelFormat() + // scfg.Width = cc.Width() + // scfg.Height = cc.Height() + // scfg.PixelFormat = cc.PixelFormat() go vnc.Serve(context.Background(), ln, scfg) defer cc.Close() @@ -75,28 +82,28 @@ func main() { case msg := <-schClient: switch msg.Type() { case vnc.SetEncodingsMsgType: - msg0 := &vnc.SetPixelFormat{ - PF: *vnc.PixelFormat32bit, + var encTypes []vnc.EncodingType + for _, enc := range scfg.Encodings { + encTypes = append(encTypes, enc.Type()) + } + msg0 := &vnc.SetEncodings{ + Encodings: encTypes, } cchClient <- msg0 - - encRaw := &vnc.RawEncoding{} - msg1 := &vnc.SetEncodings{ - Encodings: []vnc.EncodingType{encRaw.Type()}, - } - cchClient <- msg1 /* - msg2 := &vnc.FramebufferUpdateRequest{ - Inc: 0, - X: 0, - Y: 0, - Width: cc.Width(), - Height: cc.Height(), + if scfg.Width != cc.Width() || scfg.Height != cc.Height() { + msg1 := &vnc.FramebufferUpdate{ + Rects: []*vnc.Rectangle{&vnc.Rectangle{ + Width: cc.Width(), + Height: cc.Height(), + EncType: vnc.EncDesktopSizePseudo, + Enc: &vnc.DesktopSizePseudoEncoding{}, + }, + }, + } + schServer <- msg1 } - cchClient <- msg2 */ - case vnc.SetPixelFormatMsgType: - cchClient <- msg default: cchClient <- msg } diff --git a/handlers.go b/handlers.go index 8c6a58f..8fa703f 100644 --- a/handlers.go +++ b/handlers.go @@ -198,6 +198,9 @@ func ServerSecurityHandler(cfg *ServerConfig, c Conn) error { if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil { return err } + if err := c.Flush(); err != nil { + return err + } return authErr } diff --git a/image.go b/image.go index f40dac3..c795a8b 100644 --- a/image.go +++ b/image.go @@ -115,7 +115,6 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 { // Marshal implements the Marshaler interface. func (r *Rectangle) Write(c Conn) error { var err error - fmt.Printf("w rect %#+v\n", r) if err = binary.Write(c, binary.BigEndian, r.X); err != nil { return err } @@ -157,10 +156,17 @@ func (r *Rectangle) Read(c Conn) error { return err } switch r.EncType { + case EncCopyRect: + r.Enc = &CopyRectEncoding{} + case EncTight: + r.Enc = &TightEncoding{} + case EncTightPng: + r.Enc = &TightPngEncoding{} case EncRaw: 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) } diff --git a/security.go b/security.go index 009af9e..fa8357b 100644 --- a/security.go +++ b/security.go @@ -1,6 +1,7 @@ package vnc import ( + "bytes" "crypto/des" "encoding/binary" "fmt" @@ -74,6 +75,10 @@ func (*ServerAuthNone) Auth(c Conn) error { return nil } +func (*ClientAuthVeNCrypt02Plain) Type() SecurityType { + return SecTypeVeNCrypt +} + func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType { return SecSubTypeVeNCrypt02Plain } @@ -85,27 +90,91 @@ type ClientAuthVeNCrypt02Plain struct { } 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 { 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 } - 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 } - if err := binary.Write(c, binary.BigEndian, auth.Username); err != nil { + if err := binary.Read(c, binary.BigEndian, &password); err != nil { return err } - - if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil { - return err + if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) { + return fmt.Errorf("invalid username/password") } - - return c.Flush() + return nil } // ServerAuthVNC is the standard password authentication. See 7.2.2. diff --git a/server.go b/server.go index 5f868e9..a21849c 100644 --- a/server.go +++ b/server.go @@ -156,7 +156,6 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) { if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil { return nil, err } - fmt.Printf("%#+v\n", msg) for i := uint16(0); i < msg.NumRect; i++ { rect := &Rectangle{} if err := rect.Read(c); err != nil { @@ -164,15 +163,10 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) { } 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 } 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 { return err } @@ -341,14 +335,12 @@ func (c *ServerConn) Handle() error { if err := binary.Read(c, binary.BigEndian, &messageType); err != nil { return err } - fmt.Printf("srv r %s\n", messageType) msg, ok := clientMessages[messageType] if !ok { return fmt.Errorf("unsupported message-type: %v", messageType) } parsedMsg, err := msg.Read(c) - fmt.Printf("srv r %#+v\n", parsedMsg) if err != nil { fmt.Printf("srv err %s\n", err.Error()) return err diff --git a/tightcompression_string.go b/tightcompression_string.go new file mode 100644 index 0000000..b0a1457 --- /dev/null +++ b/tightcompression_string.go @@ -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) + } +} diff --git a/tightfilter_string.go b/tightfilter_string.go new file mode 100644 index 0000000..c87ebea --- /dev/null +++ b/tightfilter_string.go @@ -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]] +}