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

View File

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

View File

@ -91,7 +91,6 @@ func (*DefaultServerVersionHandler) Handle(c Conn) error {
if err := binary.Read(c, binary.BigEndian, &version); err != nil {
return err
}
major, minor, err := ParseProtoVersion(version[:])
if err != nil {
return err
@ -259,20 +258,50 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error {
c.SetHeight(srvInit.FBHeight)
c.SetPixelFormat(&srvInit.PixelFormat)
fmt.Printf("%s\n", srvInit)
if c.Protocol() == "aten" {
fmt.Printf("$$$$$$\n")
var pad [28]byte
/* 12
8 byte unknown
1 byte IKVMVideoEnable
1 byte IKVMKMEnable
1 byte IKVMKickEnable
1 byte VUSBEnable
*/
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
ikvm := struct {
_ [8]byte
IKVMVideoEnable uint8
IKVMKMEnable uint8
IKVMKickEnable uint8
VUSBEnable uint8
}{}
if err := binary.Read(c, binary.BigEndian, &ikvm); err != nil {
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
}
@ -295,7 +324,6 @@ func (*DefaultServerServerInitHandler) Handle(c Conn) error {
if err := binary.Write(c, binary.BigEndian, []byte(c.DesktopName())); err != nil {
return err
}
return c.Flush()
}

View File

@ -134,7 +134,7 @@ func (pf *PixelFormat) Unmarshal(data []byte) error {
// String implements the fmt.Stringer interface.
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)
}

View File

@ -1,6 +1,7 @@
package vnc
import (
"bytes"
"encoding/binary"
"fmt"
)
@ -30,29 +31,68 @@ func charCodeAt(s string, n int) rune {
func (auth *ClientAuthATEN) Auth(c Conn) error {
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)
if err != nil {
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")
var skip [20]byte
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)
password := make([]byte, 24-len(auth.Password)+1)
copy(username, auth.Username)
copy(password, auth.Password)
username = append(username, []byte("\x00")...)
password = append(password, []byte("\x00")...)
challenge := bytes.Join([][]byte{username, password}, []byte(":"))
if err := binary.Write(c, binary.BigEndian, challenge); err != nil {
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
}
@ -60,36 +100,6 @@ func (auth *ClientAuthATEN) Auth(c Conn) error {
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
//binary.Read(c, binary.BigEndian, &pp)
//fmt.Printf("ddd %v\n", pp)

View File

@ -9,3 +9,19 @@ func readTightTunnels(c Conn) (uint32, error) {
}
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 {
return err
}
fmt.Printf("rrrr\n")
// Send the encrypted challenge back to server
if err := binary.Write(c, binary.BigEndian, encrypted); err != nil {
return err

View File

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