add aten ikvm support

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Василий Толстов 2017-06-29 00:09:31 +03:00
parent a0f8168a6c
commit 43703cb18d
8 changed files with 151 additions and 77 deletions

View File

@ -22,7 +22,7 @@ var (
&DefaultClientSecurityHandler{}, &DefaultClientSecurityHandler{},
&DefaultClientClientInitHandler{}, &DefaultClientClientInitHandler{},
&DefaultClientServerInitHandler{}, &DefaultClientServerInitHandler{},
// &DefaultClientMessageHandler{}, &DefaultClientMessageHandler{},
} }
) )
@ -39,9 +39,7 @@ func Connect(ctx context.Context, c net.Conn, cfg *ClientConfig) (*ClientConn, e
} }
for _, h := range cfg.Handlers { for _, h := range cfg.Handlers {
fmt.Printf("%#+v\n", h)
if err := h.Handle(conn); err != nil { if err := h.Handle(conn); err != nil {
fmt.Printf("rrr %v\n", err)
conn.Close() conn.Close()
cfg.ErrorCh <- err cfg.ErrorCh <- err
return nil, err return nil, err
@ -57,6 +55,10 @@ func (c *ClientConn) Config() interface{} {
return c.cfg return c.cfg
} }
func (c *ClientConn) Wait() {
<-c.quit
}
func (c *ClientConn) Conn() net.Conn { func (c *ClientConn) Conn() net.Conn {
return c.c return c.c
} }
@ -80,6 +82,10 @@ func (c *ClientConn) Flush() error {
} }
func (c *ClientConn) Close() error { func (c *ClientConn) Close() error {
if c.quit != nil {
close(c.quit)
c.quit = nil
}
return c.c.Close() return c.c.Close()
} }
@ -163,13 +169,11 @@ type ClientConn struct {
pixelFormat *PixelFormat pixelFormat *PixelFormat
quitCh chan struct{} quitCh chan struct{}
quit chan struct{}
errorCh chan error errorCh chan error
} }
func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) { func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
if cfg.ServerMessages == nil {
return nil, fmt.Errorf("ServerMessages cannel is nil")
}
if len(cfg.Encodings) == 0 { if len(cfg.Encodings) == 0 {
return nil, fmt.Errorf("client can't handle encodings") return nil, fmt.Errorf("client can't handle encodings")
} }
@ -182,6 +186,7 @@ func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
quitCh: cfg.QuitCh, quitCh: cfg.QuitCh,
errorCh: cfg.ErrorCh, errorCh: cfg.ErrorCh,
pixelFormat: cfg.PixelFormat, pixelFormat: cfg.PixelFormat,
quit: make(chan struct{}),
}, nil }, nil
} }
@ -471,14 +476,12 @@ func (*DefaultClientMessageHandler) Handle(c Conn) error {
cfg.ErrorCh <- err cfg.ErrorCh <- err
return return
} }
msg, ok := serverMessages[messageType] msg, ok := serverMessages[messageType]
if !ok { if !ok {
err = fmt.Errorf("unknown message-type: %v", messageType) err = fmt.Errorf("unknown message-type: %v", messageType)
cfg.ErrorCh <- err cfg.ErrorCh <- err
return return
} }
parsedMsg, err := msg.Read(c) parsedMsg, err := msg.Read(c)
if err != nil { if err != nil {
cfg.ErrorCh <- err cfg.ErrorCh <- err
@ -511,4 +514,5 @@ type ClientConfig struct {
ServerMessages []ServerMessage ServerMessages []ServerMessage
QuitCh chan struct{} QuitCh chan struct{}
ErrorCh chan error ErrorCh chan error
quit chan struct{}
} }

View File

@ -23,5 +23,6 @@ type Conn interface {
DesktopName() []byte DesktopName() []byte
SetDesktopName([]byte) SetDesktopName([]byte)
Flush() error Flush() error
Wait()
SetProtoVersion(string) SetProtoVersion(string)
} }

View File

@ -91,7 +91,6 @@ func (*DefaultServerVersionHandler) Handle(c Conn) error {
if err := binary.Read(c, binary.BigEndian, &version); err != nil { if err := binary.Read(c, binary.BigEndian, &version); err != nil {
return err return err
} }
major, minor, err := ParseProtoVersion(version[:]) major, minor, err := ParseProtoVersion(version[:])
if err != nil { if err != nil {
return err return err
@ -259,20 +258,50 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error {
c.SetHeight(srvInit.FBHeight) c.SetHeight(srvInit.FBHeight)
c.SetPixelFormat(&srvInit.PixelFormat) c.SetPixelFormat(&srvInit.PixelFormat)
fmt.Printf("%s\n", srvInit)
if c.Protocol() == "aten" { if c.Protocol() == "aten" {
fmt.Printf("$$$$$$\n") ikvm := struct {
var pad [28]byte _ [8]byte
/* 12 IKVMVideoEnable uint8
8 byte unknown IKVMKMEnable uint8
1 byte IKVMVideoEnable IKVMKickEnable uint8
1 byte IKVMKMEnable VUSBEnable uint8
1 byte IKVMKickEnable }{}
1 byte VUSBEnable if err := binary.Read(c, binary.BigEndian, &ikvm); err != nil {
*/
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
return err return err
} }
fmt.Printf("rrrr\n") caps := struct {
ServerMessagesNum uint16
ClientMessagesNum uint16
EncodingsNum uint16
_ [2]byte
}{}
if err := binary.Read(c, binary.BigEndian, &caps); err != nil {
return err
}
caps.ServerMessagesNum = uint16(1)
var item [16]byte
for i := uint16(0); i < caps.ServerMessagesNum; i++ {
if err := binary.Read(c, binary.BigEndian, &item); err != nil {
return err
}
fmt.Printf("server message cap %s\n", item)
}
/*
for i := uint16(0); i < caps.ClientMessagesNum; i++ {
if err := binary.Read(c, binary.BigEndian, &item); err != nil {
return err
}
fmt.Printf("client message cap %s\n", item)
}
for i := uint16(0); i < caps.EncodingsNum; i++ {
if err := binary.Read(c, binary.BigEndian, &item); err != nil {
return err
}
fmt.Printf("encoding cap %s\n", item)
}
*/
} }
return nil return nil
} }
@ -295,7 +324,6 @@ func (*DefaultServerServerInitHandler) Handle(c Conn) error {
if err := binary.Write(c, binary.BigEndian, []byte(c.DesktopName())); err != nil { if err := binary.Write(c, binary.BigEndian, []byte(c.DesktopName())); err != nil {
return err return err
} }
return c.Flush() return c.Flush()
} }

View File

@ -134,7 +134,7 @@ func (pf *PixelFormat) Unmarshal(data []byte) error {
// String implements the fmt.Stringer interface. // String implements the fmt.Stringer interface.
func (pf *PixelFormat) String() string { func (pf *PixelFormat) String() string {
return fmt.Sprintf("{ bpp: %d depth: %d big-endian: %s true-color: %s red-max: %d green-max: %d blue-max: %d red-shift: %d green-shift: %d blue-shift: %d }", return fmt.Sprintf("{ bpp: %d depth: %d big-endian: %d true-color: %d red-max: %d green-max: %d blue-max: %d red-shift: %d green-shift: %d blue-shift: %d }",
pf.BPP, pf.Depth, pf.BigEndian, pf.TrueColor, pf.RedMax, pf.GreenMax, pf.BlueMax, pf.RedShift, pf.GreenShift, pf.BlueShift) pf.BPP, pf.Depth, pf.BigEndian, pf.TrueColor, pf.RedMax, pf.GreenMax, pf.BlueMax, pf.RedShift, pf.GreenShift, pf.BlueShift)
} }

View File

@ -1,6 +1,7 @@
package vnc package vnc
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
) )
@ -30,29 +31,68 @@ func charCodeAt(s string, n int) rune {
func (auth *ClientAuthATEN) Auth(c Conn) error { func (auth *ClientAuthATEN) Auth(c Conn) error {
var definedAuthLen = 24 var definedAuthLen = 24
if len(auth.Username) > definedAuthLen || len(auth.Password) > definedAuthLen {
return fmt.Errorf("username/password is too long, allowed 0-23")
}
nt, err := readTightTunnels(c) nt, err := readTightTunnels(c)
if err != nil { if err != nil {
return err return err
} }
if (nt&0xffff0ff0)>>0 == 0xaff90fb0 { /*
fmt.Printf("tunnels %d\n", nt)
for i := uint32(0); i < nt; i++ {
code, vendor, signature, err := readTightCaps(c)
if err != nil {
return err
}
fmt.Printf("code %d vendor %s signature %s\n", code, vendor, signature)
}
*/
if ((nt&0xffff0ff0)>>0 == 0xaff90fb0) || (nt <= 0 || nt > 0x1000000) {
c.SetProtoVersion("aten") c.SetProtoVersion("aten")
var skip [20]byte var skip [20]byte
binary.Read(c, binary.BigEndian, &skip) binary.Read(c, binary.BigEndian, &skip)
fmt.Printf("skip %s\n", skip) fmt.Printf("skip %v\n", skip)
}
username := make([]byte, definedAuthLen)
password := make([]byte, definedAuthLen)
copy(username, auth.Username)
copy(password, auth.Password)
challenge := bytes.Join([][]byte{username, password}, []byte(""))
if err := binary.Write(c, binary.BigEndian, challenge); err != nil {
return err
}
if err := c.Flush(); err != nil {
return err
} }
/* /*
if len(auth.Username) > 24 || len(auth.Password) > 24 {
return fmt.Errorf("username/password > 24") sendUsername := make([]byte, definedAuthLen)
for i := 0; i < definedAuthLen; i++ {
if i < len(auth.Username) {
sendUsername[i] = byte(charCodeAt(string(auth.Username), i))
} else {
sendUsername[i] = 0
}
} }
username := make([]byte, 24-len(auth.Username)+1) sendPassword := make([]byte, definedAuthLen)
password := make([]byte, 24-len(auth.Password)+1)
copy(username, auth.Username) for i := 0; i < definedAuthLen; i++ {
copy(password, auth.Password) if i < len(auth.Password) {
username = append(username, []byte("\x00")...) sendPassword[i] = byte(charCodeAt(string(auth.Password), i))
password = append(password, []byte("\x00")...) } else {
challenge := bytes.Join([][]byte{username, password}, []byte(":")) sendPassword[i] = 0
if err := binary.Write(c, binary.BigEndian, challenge); err != nil { }
}
if err := binary.Write(c, binary.BigEndian, sendUsername); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, sendPassword); err != nil {
return err return err
} }
@ -60,36 +100,6 @@ func (auth *ClientAuthATEN) Auth(c Conn) error {
return err return err
} }
*/ */
sendUsername := make([]byte, definedAuthLen)
for i := 0; i < definedAuthLen; i++ {
if i < len(auth.Username) {
sendUsername[i] = byte(charCodeAt(string(auth.Username), i))
} else {
sendUsername[i] = 0
}
}
sendPassword := make([]byte, definedAuthLen)
for i := 0; i < definedAuthLen; i++ {
if i < len(auth.Password) {
sendPassword[i] = byte(charCodeAt(string(auth.Password), i))
} else {
sendPassword[i] = 0
}
}
if err := binary.Write(c, binary.BigEndian, sendUsername); err != nil {
return err
}
if err := binary.Write(c, binary.BigEndian, sendPassword); err != nil {
return err
}
if err := c.Flush(); err != nil {
return err
}
//var pp [10]byte //var pp [10]byte
//binary.Read(c, binary.BigEndian, &pp) //binary.Read(c, binary.BigEndian, &pp)
//fmt.Printf("ddd %v\n", pp) //fmt.Printf("ddd %v\n", pp)

View File

@ -9,3 +9,19 @@ func readTightTunnels(c Conn) (uint32, error) {
} }
return n, nil return n, nil
} }
func readTightCaps(c Conn) (int32, []byte, []byte, error) {
var code int32
var vendor [4]byte
var signature [8]byte
if err := binary.Read(c, binary.BigEndian, &code); err != nil {
return 0, nil, nil, err
}
if err := binary.Read(c, binary.BigEndian, &vendor); err != nil {
return 0, nil, nil, err
}
if err := binary.Read(c, binary.BigEndian, &signature); err != nil {
return 0, nil, nil, err
}
return code, vendor[:], signature[:], nil
}

View File

@ -83,7 +83,6 @@ func (auth *ClientAuthVNC) Auth(c Conn) error {
if err != nil { if err != nil {
return err return err
} }
fmt.Printf("rrrr\n")
// Send the encrypted challenge back to server // Send the encrypted challenge back to server
if err := binary.Write(c, binary.BigEndian, encrypted); err != nil { if err := binary.Write(c, binary.BigEndian, encrypted); err != nil {
return err return err

View File

@ -25,6 +25,10 @@ type ServerInit struct {
NameText []byte NameText []byte
} }
func (srvInit *ServerInit) String() string {
return fmt.Sprintf("Width: %d, Height: %d, PixelFormat: %s, Name: %s", srvInit.FBWidth, srvInit.FBHeight, &srvInit.PixelFormat, srvInit.NameText)
}
var _ Conn = (*ServerConn)(nil) var _ Conn = (*ServerConn)(nil)
func (c *ServerConn) Config() interface{} { func (c *ServerConn) Config() interface{} {
@ -35,6 +39,10 @@ func (c *ServerConn) Conn() net.Conn {
return c.c return c.c
} }
func (c *ServerConn) Wait() {
<-c.quit
}
func (c *ServerConn) SetEncodings(encs []EncodingType) error { func (c *ServerConn) SetEncodings(encs []EncodingType) error {
encodings := make(map[EncodingType]Encoding) encodings := make(map[EncodingType]Encoding)
for _, enc := range c.cfg.Encodings { for _, enc := range c.cfg.Encodings {
@ -57,6 +65,10 @@ func (c *ServerConn) Flush() error {
} }
func (c *ServerConn) Close() error { func (c *ServerConn) Close() error {
if c.quit != nil {
close(c.quit)
c.quit = nil
}
return c.c.Close() return c.c.Close()
} }
@ -202,6 +214,8 @@ type ServerConn struct {
// be modified. If you wish to set a new pixel format, use the // be modified. If you wish to set a new pixel format, use the
// SetPixelFormat method. // SetPixelFormat method.
pixelFormat *PixelFormat pixelFormat *PixelFormat
quit chan struct{}
} }
type ServerHandler interface { type ServerHandler interface {
@ -234,14 +248,6 @@ type ServerConfig struct {
} }
func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) { func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
if cfg.ClientMessageCh == nil {
return nil, fmt.Errorf("ClientMessageCh nil")
}
if len(cfg.ClientMessages) == 0 {
return nil, fmt.Errorf("ClientMessage 0")
}
return &ServerConn{ return &ServerConn{
c: c, c: c,
br: bufio.NewReader(c), br: bufio.NewReader(c),
@ -252,6 +258,7 @@ func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
pixelFormat: cfg.PixelFormat, pixelFormat: cfg.PixelFormat,
fbWidth: cfg.Width, fbWidth: cfg.Width,
fbHeight: cfg.Height, fbHeight: cfg.Height,
quit: make(chan struct{}),
}, nil }, nil
} }
@ -274,7 +281,7 @@ func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
for _, h := range cfg.Handlers { for _, h := range cfg.Handlers {
if err := h.Handle(conn); err != nil { if err := h.Handle(conn); err != nil {
conn.Close() conn.Close()
continue break
} }
} }
} }
@ -306,7 +313,10 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error {
case msg := <-cfg.ServerMessageCh: case msg := <-cfg.ServerMessageCh:
if err = msg.Write(c); err != nil { if err = msg.Write(c); err != nil {
cfg.errorCh <- err cfg.errorCh <- err
close(quit) if quit != nil {
close(quit)
quit = nil
}
return return
} }
} }
@ -324,7 +334,10 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error {
var messageType ClientMessageType var messageType ClientMessageType
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil { if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
cfg.errorCh <- err cfg.errorCh <- err
close(quit) if quit != nil {
close(quit)
quit = nil
}
return return
} }
msg, ok := clientMessages[messageType] msg, ok := clientMessages[messageType]
@ -336,7 +349,10 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error {
parsedMsg, err := msg.Read(c) parsedMsg, err := msg.Read(c)
if err != nil { if err != nil {
cfg.errorCh <- err cfg.errorCh <- err
close(quit) if quit != nil {
close(quit)
quit = nil
}
return return
} }
cfg.ClientMessageCh <- parsedMsg cfg.ClientMessageCh <- parsedMsg