complete tight png
Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
parent
49c704bc67
commit
1413d28267
326
encoding.go
326
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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
10
image.go
10
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)
|
||||
}
|
||||
|
||||
|
85
security.go
85
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.
|
||||
|
@ -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
|
||||
|
27
tightcompression_string.go
Normal file
27
tightcompression_string.go
Normal 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
16
tightfilter_string.go
Normal 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]]
|
||||
}
|
Loading…
Reference in New Issue
Block a user