mirror of
https://github.com/amitbet/vncproxy.git
synced 2025-09-23 10:28:54 +00:00
created proxy and listeners to connect recorder and server-client cross writing
This commit is contained in:
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"vncproxy/common"
|
||||
)
|
||||
|
||||
@@ -24,7 +25,7 @@ func (*SetPixelFormat) Type() common.ClientMessageType {
|
||||
return common.SetPixelFormatMsgType
|
||||
}
|
||||
|
||||
func (msg *SetPixelFormat) Write(c common.Conn) error {
|
||||
func (msg *SetPixelFormat) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -33,16 +34,16 @@ func (msg *SetPixelFormat) Write(c common.Conn) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pf := c.PixelFormat()
|
||||
//pf := c.CurrentPixelFormat()
|
||||
// Invalidate the color map.
|
||||
if pf.TrueColor {
|
||||
c.SetColorMap(&common.ColorMap{})
|
||||
}
|
||||
// if pf.TrueColor {
|
||||
// c.SetColorMap(&common.ColorMap{})
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SetPixelFormat) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*SetPixelFormat) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := SetPixelFormat{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
return nil, err
|
||||
@@ -61,7 +62,7 @@ func (*SetEncodings) Type() common.ClientMessageType {
|
||||
return common.SetEncodingsMsgType
|
||||
}
|
||||
|
||||
func (*SetEncodings) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*SetEncodings) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := SetEncodings{}
|
||||
var pad [1]byte
|
||||
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
||||
@@ -78,11 +79,11 @@ func (*SetEncodings) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
}
|
||||
msg.Encodings = append(msg.Encodings, enc)
|
||||
}
|
||||
c.SetEncodings(msg.Encodings)
|
||||
c.(common.ServerConn).SetEncodings(msg.Encodings)
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (msg *SetEncodings) Write(c common.Conn) error {
|
||||
func (msg *SetEncodings) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -117,7 +118,7 @@ func (*FramebufferUpdateRequest) Type() common.ClientMessageType {
|
||||
return common.FramebufferUpdateRequestMsgType
|
||||
}
|
||||
|
||||
func (*FramebufferUpdateRequest) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*FramebufferUpdateRequest) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := FramebufferUpdateRequest{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
return nil, err
|
||||
@@ -125,7 +126,7 @@ func (*FramebufferUpdateRequest) Read(c common.Conn) (common.ClientMessage, erro
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (msg *FramebufferUpdateRequest) Write(c common.Conn) error {
|
||||
func (msg *FramebufferUpdateRequest) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -146,7 +147,7 @@ func (*KeyEvent) Type() common.ClientMessageType {
|
||||
return common.KeyEventMsgType
|
||||
}
|
||||
|
||||
func (*KeyEvent) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*KeyEvent) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := KeyEvent{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
return nil, err
|
||||
@@ -154,7 +155,7 @@ func (*KeyEvent) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (msg *KeyEvent) Write(c common.Conn) error {
|
||||
func (msg *KeyEvent) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -174,7 +175,7 @@ func (*PointerEvent) Type() common.ClientMessageType {
|
||||
return common.PointerEventMsgType
|
||||
}
|
||||
|
||||
func (*PointerEvent) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*PointerEvent) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := PointerEvent{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
return nil, err
|
||||
@@ -182,7 +183,7 @@ func (*PointerEvent) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (msg *PointerEvent) Write(c common.Conn) error {
|
||||
func (msg *PointerEvent) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -203,7 +204,7 @@ func (*ClientCutText) Type() common.ClientMessageType {
|
||||
return common.ClientCutTextMsgType
|
||||
}
|
||||
|
||||
func (*ClientCutText) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
func (*ClientCutText) Read(c io.Reader) (common.ClientMessage, error) {
|
||||
msg := ClientCutText{}
|
||||
var pad [3]byte
|
||||
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
||||
@@ -221,7 +222,7 @@ func (*ClientCutText) Read(c common.Conn) (common.ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (msg *ClientCutText) Write(c common.Conn) error {
|
||||
func (msg *ClientCutText) Write(c io.Writer) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
Binary file not shown.
@@ -130,7 +130,7 @@ func ServerServerInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
||||
srvInit := &common.ServerInit{
|
||||
FBWidth: c.Width(),
|
||||
FBHeight: c.Height(),
|
||||
PixelFormat: *c.PixelFormat(),
|
||||
PixelFormat: *c.CurrentPixelFormat(),
|
||||
NameLength: uint32(len(cfg.DesktopName)),
|
||||
NameText: []byte(cfg.DesktopName),
|
||||
}
|
||||
|
@@ -1,335 +1,335 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/des"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"log"
|
||||
"vncproxy/common"
|
||||
)
|
||||
|
||||
type SecurityType uint8
|
||||
|
||||
const (
|
||||
SecTypeUnknown = SecurityType(0)
|
||||
SecTypeNone = SecurityType(1)
|
||||
SecTypeVNC = SecurityType(2)
|
||||
SecTypeVeNCrypt = SecurityType(19)
|
||||
)
|
||||
|
||||
type SecuritySubType uint32
|
||||
|
||||
const (
|
||||
SecSubTypeUnknown = SecuritySubType(0)
|
||||
)
|
||||
|
||||
const (
|
||||
SecSubTypeVeNCrypt01Unknown = SecuritySubType(0)
|
||||
SecSubTypeVeNCrypt01Plain = SecuritySubType(19)
|
||||
SecSubTypeVeNCrypt01TLSNone = SecuritySubType(20)
|
||||
SecSubTypeVeNCrypt01TLSVNC = SecuritySubType(21)
|
||||
SecSubTypeVeNCrypt01TLSPlain = SecuritySubType(22)
|
||||
SecSubTypeVeNCrypt01X509None = SecuritySubType(23)
|
||||
SecSubTypeVeNCrypt01X509VNC = SecuritySubType(24)
|
||||
SecSubTypeVeNCrypt01X509Plain = SecuritySubType(25)
|
||||
)
|
||||
|
||||
const (
|
||||
SecSubTypeVeNCrypt02Unknown = SecuritySubType(0)
|
||||
SecSubTypeVeNCrypt02Plain = SecuritySubType(256)
|
||||
SecSubTypeVeNCrypt02TLSNone = SecuritySubType(257)
|
||||
SecSubTypeVeNCrypt02TLSVNC = SecuritySubType(258)
|
||||
SecSubTypeVeNCrypt02TLSPlain = SecuritySubType(259)
|
||||
SecSubTypeVeNCrypt02X509None = SecuritySubType(260)
|
||||
SecSubTypeVeNCrypt02X509VNC = SecuritySubType(261)
|
||||
SecSubTypeVeNCrypt02X509Plain = SecuritySubType(262)
|
||||
)
|
||||
|
||||
type SecurityHandler interface {
|
||||
Type() SecurityType
|
||||
SubType() SecuritySubType
|
||||
Auth(common.Conn) error
|
||||
}
|
||||
|
||||
// type ClientAuthNone struct{}
|
||||
|
||||
// func (*ClientAuthNone) Type() SecurityType {
|
||||
// return SecTypeNone
|
||||
// }
|
||||
|
||||
// func (*ClientAuthNone) SubType() SecuritySubType {
|
||||
// return SecSubTypeUnknown
|
||||
// }
|
||||
|
||||
// func (*ClientAuthNone) Auth(conn common.Conn) error {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// ServerAuthNone is the "none" authentication. See 7.2.1.
|
||||
type ServerAuthNone struct{}
|
||||
|
||||
func (*ServerAuthNone) Type() SecurityType {
|
||||
return SecTypeNone
|
||||
}
|
||||
|
||||
func (*ServerAuthNone) Auth(c common.Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*ServerAuthNone) SubType() SecuritySubType {
|
||||
return SecSubTypeUnknown
|
||||
}
|
||||
|
||||
// func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
|
||||
// return SecTypeVeNCrypt
|
||||
// }
|
||||
|
||||
// func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
||||
// return SecSubTypeVeNCrypt02Plain
|
||||
// }
|
||||
|
||||
// // ClientAuthVeNCryptPlain see https://www.berrange.com/~dan/vencrypt.txt
|
||||
// type ClientAuthVeNCrypt02Plain struct {
|
||||
// Username []byte
|
||||
// Password []byte
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVeNCrypt02Plain) Auth(c common.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.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
|
||||
// }
|
||||
|
||||
// username := make([]byte, uLength)
|
||||
// password := make([]byte, pLength)
|
||||
// if err := binary.Read(c, binary.BigEndian, &username); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// if err := binary.Read(c, binary.BigEndian, &password); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
|
||||
// return fmt.Errorf("invalid username/password")
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
||||
type ServerAuthVNC struct {
|
||||
pass string
|
||||
}
|
||||
|
||||
func (*ServerAuthVNC) Type() SecurityType {
|
||||
return SecTypeVNC
|
||||
}
|
||||
|
||||
func (*ServerAuthVNC) SubType() SecuritySubType {
|
||||
return SecSubTypeUnknown
|
||||
}
|
||||
|
||||
const AUTH_FAIL = "Authentication Failure"
|
||||
|
||||
func (auth *ServerAuthVNC) Auth(c common.Conn) error {
|
||||
buf := make([]byte, 8+len([]byte(AUTH_FAIL)))
|
||||
rand.Read(buf[:16]) // Random 16 bytes in buf
|
||||
sndsz, err := c.Write(buf[:16])
|
||||
if err != nil {
|
||||
log.Printf("Error sending challenge to client: %s\n", err.Error())
|
||||
return errors.New("Error sending challenge to client:" + err.Error())
|
||||
}
|
||||
if sndsz != 16 {
|
||||
log.Printf("The full 16 byte challenge was not sent!\n")
|
||||
return errors.New("The full 16 byte challenge was not sent")
|
||||
}
|
||||
//c.Flush()
|
||||
buf2 := make([]byte, 16)
|
||||
_, err = c.Read(buf2)
|
||||
if err != nil {
|
||||
log.Printf("The authentication result was not read: %s\n", err.Error())
|
||||
return errors.New("The authentication result was not read" + err.Error())
|
||||
}
|
||||
AuthText := auth.pass
|
||||
bk, err := des.NewCipher([]byte(fixDesKey(AuthText)))
|
||||
if err != nil {
|
||||
log.Printf("Error generating authentication cipher: %s\n", err.Error())
|
||||
return errors.New("Error generating authentication cipher")
|
||||
}
|
||||
buf3 := make([]byte, 16)
|
||||
bk.Encrypt(buf3, buf) //Encrypt first 8 bytes
|
||||
bk.Encrypt(buf3[8:], buf[8:]) // Encrypt second 8 bytes
|
||||
if bytes.Compare(buf2, buf3) != 0 { // If the result does not decrypt correctly to what we sent then a problem
|
||||
SetUint32(buf, 0, 1)
|
||||
SetUint32(buf, 4, uint32(len([]byte(AUTH_FAIL))))
|
||||
copy(buf[8:], []byte(AUTH_FAIL))
|
||||
c.Write(buf)
|
||||
//c.Flush()
|
||||
return errors.New("Authentication failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUint32 set 4 bytes at pos in buf to the val (in big endian format)
|
||||
// A test is done to ensure there are 4 bytes available at pos in the buffer
|
||||
func SetUint32(buf []byte, pos int, val uint32) {
|
||||
if pos+4 > len(buf) {
|
||||
return
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
buf[3-i+pos] = byte(val)
|
||||
val >>= 8
|
||||
}
|
||||
}
|
||||
|
||||
// fixDesKeyByte is used to mirror a byte's bits
|
||||
// This is not clearly indicated by the document, but is in actual fact used
|
||||
func fixDesKeyByte(val byte) byte {
|
||||
var newval byte = 0
|
||||
for i := 0; i < 8; i++ {
|
||||
newval <<= 1
|
||||
newval += (val & 1)
|
||||
val >>= 1
|
||||
}
|
||||
return newval
|
||||
}
|
||||
|
||||
// fixDesKey will make sure that exactly 8 bytes is used either by truncating or padding with nulls
|
||||
// The bytes are then bit mirrored and returned
|
||||
func fixDesKey(key string) []byte {
|
||||
tmp := []byte(key)
|
||||
buf := make([]byte, 8)
|
||||
if len(tmp) <= 8 {
|
||||
copy(buf, tmp)
|
||||
} else {
|
||||
copy(buf, tmp[:8])
|
||||
}
|
||||
for i := 0; i < 8; i++ {
|
||||
buf[i] = fixDesKeyByte(buf[i])
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// // ClientAuthVNC is the standard password authentication. See 7.2.2.
|
||||
// type ClientAuthVNC struct {
|
||||
// Challenge [16]byte
|
||||
// Password []byte
|
||||
// }
|
||||
|
||||
// func (*ClientAuthVNC) Type() SecurityType {
|
||||
// return SecTypeVNC
|
||||
// }
|
||||
// func (*ClientAuthVNC) SubType() SecuritySubType {
|
||||
// return SecSubTypeUnknown
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVNC) Auth(c common.Conn) error {
|
||||
// if len(auth.Password) == 0 {
|
||||
// return fmt.Errorf("Security Handshake failed; no password provided for VNCAuth.")
|
||||
// }
|
||||
|
||||
// if err := binary.Read(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// auth.encode()
|
||||
|
||||
// // Send the encrypted challenge back to server
|
||||
// if err := binary.Write(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return c.Flush()
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVNC) encode() error {
|
||||
// // Copy password string to 8 byte 0-padded slice
|
||||
// key := make([]byte, 8)
|
||||
// copy(key, auth.Password)
|
||||
|
||||
// // Each byte of the password needs to be reversed. This is a
|
||||
// // non RFC-documented behaviour of VNC clients and servers
|
||||
// for i := range key {
|
||||
// key[i] = (key[i]&0x55)<<1 | (key[i]&0xAA)>>1 // Swap adjacent bits
|
||||
// key[i] = (key[i]&0x33)<<2 | (key[i]&0xCC)>>2 // Swap adjacent pairs
|
||||
// key[i] = (key[i]&0x0F)<<4 | (key[i]&0xF0)>>4 // Swap the 2 halves
|
||||
// }
|
||||
|
||||
// // Encrypt challenge with key.
|
||||
// cipher, err := des.NewCipher(key)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// for i := 0; i < len(auth.Challenge); i += cipher.BlockSize() {
|
||||
// cipher.Encrypt(auth.Challenge[i:i+cipher.BlockSize()], auth.Challenge[i:i+cipher.BlockSize()])
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/des"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"log"
|
||||
"vncproxy/common"
|
||||
)
|
||||
|
||||
type SecurityType uint8
|
||||
|
||||
const (
|
||||
SecTypeUnknown = SecurityType(0)
|
||||
SecTypeNone = SecurityType(1)
|
||||
SecTypeVNC = SecurityType(2)
|
||||
SecTypeVeNCrypt = SecurityType(19)
|
||||
)
|
||||
|
||||
type SecuritySubType uint32
|
||||
|
||||
const (
|
||||
SecSubTypeUnknown = SecuritySubType(0)
|
||||
)
|
||||
|
||||
const (
|
||||
SecSubTypeVeNCrypt01Unknown = SecuritySubType(0)
|
||||
SecSubTypeVeNCrypt01Plain = SecuritySubType(19)
|
||||
SecSubTypeVeNCrypt01TLSNone = SecuritySubType(20)
|
||||
SecSubTypeVeNCrypt01TLSVNC = SecuritySubType(21)
|
||||
SecSubTypeVeNCrypt01TLSPlain = SecuritySubType(22)
|
||||
SecSubTypeVeNCrypt01X509None = SecuritySubType(23)
|
||||
SecSubTypeVeNCrypt01X509VNC = SecuritySubType(24)
|
||||
SecSubTypeVeNCrypt01X509Plain = SecuritySubType(25)
|
||||
)
|
||||
|
||||
const (
|
||||
SecSubTypeVeNCrypt02Unknown = SecuritySubType(0)
|
||||
SecSubTypeVeNCrypt02Plain = SecuritySubType(256)
|
||||
SecSubTypeVeNCrypt02TLSNone = SecuritySubType(257)
|
||||
SecSubTypeVeNCrypt02TLSVNC = SecuritySubType(258)
|
||||
SecSubTypeVeNCrypt02TLSPlain = SecuritySubType(259)
|
||||
SecSubTypeVeNCrypt02X509None = SecuritySubType(260)
|
||||
SecSubTypeVeNCrypt02X509VNC = SecuritySubType(261)
|
||||
SecSubTypeVeNCrypt02X509Plain = SecuritySubType(262)
|
||||
)
|
||||
|
||||
type SecurityHandler interface {
|
||||
Type() SecurityType
|
||||
SubType() SecuritySubType
|
||||
Auth(common.ServerConn) error
|
||||
}
|
||||
|
||||
// type ClientAuthNone struct{}
|
||||
|
||||
// func (*ClientAuthNone) Type() SecurityType {
|
||||
// return SecTypeNone
|
||||
// }
|
||||
|
||||
// func (*ClientAuthNone) SubType() SecuritySubType {
|
||||
// return SecSubTypeUnknown
|
||||
// }
|
||||
|
||||
// func (*ClientAuthNone) Auth(conn common.ServerConn) error {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// ServerAuthNone is the "none" authentication. See 7.2.1.
|
||||
type ServerAuthNone struct{}
|
||||
|
||||
func (*ServerAuthNone) Type() SecurityType {
|
||||
return SecTypeNone
|
||||
}
|
||||
|
||||
func (*ServerAuthNone) Auth(c common.ServerConn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*ServerAuthNone) SubType() SecuritySubType {
|
||||
return SecSubTypeUnknown
|
||||
}
|
||||
|
||||
// func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
|
||||
// return SecTypeVeNCrypt
|
||||
// }
|
||||
|
||||
// func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
||||
// return SecSubTypeVeNCrypt02Plain
|
||||
// }
|
||||
|
||||
// // ClientAuthVeNCryptPlain see https://www.berrange.com/~dan/vencrypt.txt
|
||||
// type ClientAuthVeNCrypt02Plain struct {
|
||||
// Username []byte
|
||||
// Password []byte
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVeNCrypt02Plain) Auth(c common.ServerConn) 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.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
|
||||
// }
|
||||
|
||||
// username := make([]byte, uLength)
|
||||
// password := make([]byte, pLength)
|
||||
// if err := binary.Read(c, binary.BigEndian, &username); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// if err := binary.Read(c, binary.BigEndian, &password); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
|
||||
// return fmt.Errorf("invalid username/password")
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
||||
type ServerAuthVNC struct {
|
||||
Pass string
|
||||
}
|
||||
|
||||
func (*ServerAuthVNC) Type() SecurityType {
|
||||
return SecTypeVNC
|
||||
}
|
||||
|
||||
func (*ServerAuthVNC) SubType() SecuritySubType {
|
||||
return SecSubTypeUnknown
|
||||
}
|
||||
|
||||
const AUTH_FAIL = "Authentication Failure"
|
||||
|
||||
func (auth *ServerAuthVNC) Auth(c common.ServerConn) error {
|
||||
buf := make([]byte, 8+len([]byte(AUTH_FAIL)))
|
||||
rand.Read(buf[:16]) // Random 16 bytes in buf
|
||||
sndsz, err := c.Write(buf[:16])
|
||||
if err != nil {
|
||||
log.Printf("Error sending challenge to client: %s\n", err.Error())
|
||||
return errors.New("Error sending challenge to client:" + err.Error())
|
||||
}
|
||||
if sndsz != 16 {
|
||||
log.Printf("The full 16 byte challenge was not sent!\n")
|
||||
return errors.New("The full 16 byte challenge was not sent")
|
||||
}
|
||||
//c.Flush()
|
||||
buf2 := make([]byte, 16)
|
||||
_, err = c.Read(buf2)
|
||||
if err != nil {
|
||||
log.Printf("The authentication result was not read: %s\n", err.Error())
|
||||
return errors.New("The authentication result was not read" + err.Error())
|
||||
}
|
||||
AuthText := auth.Pass
|
||||
bk, err := des.NewCipher([]byte(fixDesKey(AuthText)))
|
||||
if err != nil {
|
||||
log.Printf("Error generating authentication cipher: %s\n", err.Error())
|
||||
return errors.New("Error generating authentication cipher")
|
||||
}
|
||||
buf3 := make([]byte, 16)
|
||||
bk.Encrypt(buf3, buf) //Encrypt first 8 bytes
|
||||
bk.Encrypt(buf3[8:], buf[8:]) // Encrypt second 8 bytes
|
||||
if bytes.Compare(buf2, buf3) != 0 { // If the result does not decrypt correctly to what we sent then a problem
|
||||
SetUint32(buf, 0, 1)
|
||||
SetUint32(buf, 4, uint32(len([]byte(AUTH_FAIL))))
|
||||
copy(buf[8:], []byte(AUTH_FAIL))
|
||||
c.Write(buf)
|
||||
//c.Flush()
|
||||
return errors.New("Authentication failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUint32 set 4 bytes at pos in buf to the val (in big endian format)
|
||||
// A test is done to ensure there are 4 bytes available at pos in the buffer
|
||||
func SetUint32(buf []byte, pos int, val uint32) {
|
||||
if pos+4 > len(buf) {
|
||||
return
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
buf[3-i+pos] = byte(val)
|
||||
val >>= 8
|
||||
}
|
||||
}
|
||||
|
||||
// fixDesKeyByte is used to mirror a byte's bits
|
||||
// This is not clearly indicated by the document, but is in actual fact used
|
||||
func fixDesKeyByte(val byte) byte {
|
||||
var newval byte = 0
|
||||
for i := 0; i < 8; i++ {
|
||||
newval <<= 1
|
||||
newval += (val & 1)
|
||||
val >>= 1
|
||||
}
|
||||
return newval
|
||||
}
|
||||
|
||||
// fixDesKey will make sure that exactly 8 bytes is used either by truncating or padding with nulls
|
||||
// The bytes are then bit mirrored and returned
|
||||
func fixDesKey(key string) []byte {
|
||||
tmp := []byte(key)
|
||||
buf := make([]byte, 8)
|
||||
if len(tmp) <= 8 {
|
||||
copy(buf, tmp)
|
||||
} else {
|
||||
copy(buf, tmp[:8])
|
||||
}
|
||||
for i := 0; i < 8; i++ {
|
||||
buf[i] = fixDesKeyByte(buf[i])
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// // ClientAuthVNC is the standard password authentication. See 7.2.2.
|
||||
// type ClientAuthVNC struct {
|
||||
// Challenge [16]byte
|
||||
// Password []byte
|
||||
// }
|
||||
|
||||
// func (*ClientAuthVNC) Type() SecurityType {
|
||||
// return SecTypeVNC
|
||||
// }
|
||||
// func (*ClientAuthVNC) SubType() SecuritySubType {
|
||||
// return SecSubTypeUnknown
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVNC) Auth(c common.ServerConn) error {
|
||||
// if len(auth.Password) == 0 {
|
||||
// return fmt.Errorf("Security Handshake failed; no password provided for VNCAuth.")
|
||||
// }
|
||||
|
||||
// if err := binary.Read(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// auth.encode()
|
||||
|
||||
// // Send the encrypted challenge back to server
|
||||
// if err := binary.Write(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return c.Flush()
|
||||
// }
|
||||
|
||||
// func (auth *ClientAuthVNC) encode() error {
|
||||
// // Copy password string to 8 byte 0-padded slice
|
||||
// key := make([]byte, 8)
|
||||
// copy(key, auth.Password)
|
||||
|
||||
// // Each byte of the password needs to be reversed. This is a
|
||||
// // non RFC-documented behaviour of VNC clients and servers
|
||||
// for i := range key {
|
||||
// key[i] = (key[i]&0x55)<<1 | (key[i]&0xAA)>>1 // Swap adjacent bits
|
||||
// key[i] = (key[i]&0x33)<<2 | (key[i]&0xCC)>>2 // Swap adjacent pairs
|
||||
// key[i] = (key[i]&0x0F)<<4 | (key[i]&0xF0)>>4 // Swap the 2 halves
|
||||
// }
|
||||
|
||||
// // Encrypt challenge with key.
|
||||
// cipher, err := des.NewCipher(key)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// for i := 0; i < len(auth.Challenge); i += cipher.BlockSize() {
|
||||
// cipher.Encrypt(auth.Challenge[i:i+cipher.BlockSize()], auth.Challenge[i:i+cipher.BlockSize()])
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"vncproxy/common"
|
||||
@@ -37,6 +39,11 @@ type ServerConn struct {
|
||||
// SetPixelFormat method.
|
||||
pixelFormat *common.PixelFormat
|
||||
|
||||
// a consumer for the parsed messages, to allow for recording and proxy
|
||||
Listener common.SegmentConsumer
|
||||
|
||||
SessionId string
|
||||
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
@@ -44,6 +51,28 @@ type ServerConn struct {
|
||||
// return c.br.UnreadByte()
|
||||
// }
|
||||
|
||||
func NewServerConn(c io.ReadWriter, 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),
|
||||
//bw: bufio.NewWriter(c),
|
||||
cfg: cfg,
|
||||
quit: make(chan struct{}),
|
||||
encodings: cfg.Encodings,
|
||||
pixelFormat: cfg.PixelFormat,
|
||||
fbWidth: cfg.Width,
|
||||
fbHeight: cfg.Height,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ServerConn) Conn() io.ReadWriter {
|
||||
return c.c
|
||||
}
|
||||
@@ -72,7 +101,7 @@ func (c *ServerConn) SetProtoVersion(pv string) {
|
||||
// }
|
||||
|
||||
func (c *ServerConn) Close() error {
|
||||
return c.c.(io.ReadWriteCloser).Close()
|
||||
return c.c.(io.ReadWriteCloser).Close()
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,7 +133,7 @@ func (c *ServerConn) SetColorMap(cm *common.ColorMap) {
|
||||
func (c *ServerConn) DesktopName() string {
|
||||
return c.desktopName
|
||||
}
|
||||
func (c *ServerConn) PixelFormat() *common.PixelFormat {
|
||||
func (c *ServerConn) CurrentPixelFormat() *common.PixelFormat {
|
||||
return c.pixelFormat
|
||||
}
|
||||
func (c *ServerConn) SetDesktopName(name string) {
|
||||
@@ -134,3 +163,71 @@ func (c *ServerConn) SetWidth(w uint16) {
|
||||
func (c *ServerConn) SetHeight(h uint16) {
|
||||
c.fbHeight = h
|
||||
}
|
||||
|
||||
func (c *ServerConn) handle() error {
|
||||
//var err error
|
||||
//var wg sync.WaitGroup
|
||||
|
||||
//defer c.Close()
|
||||
|
||||
//create a map of all message types
|
||||
clientMessages := make(map[common.ClientMessageType]common.ClientMessage)
|
||||
for _, m := range c.cfg.ClientMessages {
|
||||
clientMessages[m.Type()] = m
|
||||
}
|
||||
//wg.Add(2)
|
||||
|
||||
// server
|
||||
go func() error {
|
||||
//defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case msg := <-c.cfg.ServerMessageCh:
|
||||
fmt.Printf("%v", msg)
|
||||
// if err = msg.Write(c); err != nil {
|
||||
// return err
|
||||
// }
|
||||
case <-c.quit:
|
||||
c.Close()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// client
|
||||
//go func() error {
|
||||
//defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-c.quit:
|
||||
return nil
|
||||
default:
|
||||
var messageType common.ClientMessageType
|
||||
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
return err
|
||||
}
|
||||
msg, ok := clientMessages[messageType]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported message-type: %v", messageType)
|
||||
|
||||
}
|
||||
parsedMsg, err := msg.Read(c)
|
||||
seg := &common.RfbSegment{
|
||||
SegmentType: common.SegmentFullyParsedClientMessage,
|
||||
Message: parsedMsg,
|
||||
}
|
||||
c.Listener.Consume(seg)
|
||||
if err != nil {
|
||||
fmt.Printf("srv err %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
fmt.Printf("message:%s, %v\n", parsedMsg.Type(), parsedMsg)
|
||||
//c.cfg.ClientMessageCh <- parsedMsg
|
||||
}
|
||||
}
|
||||
//}()
|
||||
|
||||
//wg.Wait()
|
||||
//return nil
|
||||
}
|
||||
|
122
server/server.go
122
server/server.go
@@ -1,8 +1,6 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -19,9 +17,7 @@ var DefaultClientMessages = []common.ClientMessage{
|
||||
&ClientCutText{},
|
||||
}
|
||||
|
||||
|
||||
|
||||
//var _ Conn = (*ServerConn)(nil)
|
||||
//var _ ServerConn = (*ServerConn)(nil)
|
||||
|
||||
// ServerMessage represents a Client-to-Server RFB message type.
|
||||
// type ServerMessageType uint8
|
||||
@@ -55,60 +51,43 @@ type ServerConfig struct {
|
||||
SecurityHandlers []SecurityHandler
|
||||
//ClientInitHandler ServerHandler
|
||||
//ServerInitHandler ServerHandler
|
||||
Encodings []common.Encoding
|
||||
PixelFormat *common.PixelFormat
|
||||
ColorMap *common.ColorMap
|
||||
ClientMessageCh chan common.ClientMessage
|
||||
Encodings []common.Encoding
|
||||
PixelFormat *common.PixelFormat
|
||||
ColorMap *common.ColorMap
|
||||
//ClientMessageCh chan common.ClientMessage
|
||||
ServerMessageCh chan common.ServerMessage
|
||||
ClientMessages []common.ClientMessage
|
||||
DesktopName []byte
|
||||
Height uint16
|
||||
Width uint16
|
||||
|
||||
//handler to allow for registering for messages, this can't be a channel
|
||||
//because of the websockets handler function which will kill the connection on exit if conn.handle() is run on another thread
|
||||
NewConnHandler ServerHandler
|
||||
}
|
||||
|
||||
func newServerConn(c io.ReadWriter, 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),
|
||||
//bw: bufio.NewWriter(c),
|
||||
cfg: cfg,
|
||||
quit: make(chan struct{}),
|
||||
encodings: cfg.Encodings,
|
||||
pixelFormat: cfg.PixelFormat,
|
||||
fbWidth: cfg.Width,
|
||||
fbHeight: cfg.Height,
|
||||
}, nil
|
||||
}
|
||||
func wsHandlerFunc(ws io.ReadWriter, cfg *ServerConfig) {
|
||||
func wsHandlerFunc(ws io.ReadWriter, cfg *ServerConfig, sessionId string) {
|
||||
// header := ws.Request().Header
|
||||
// url := ws.Request().URL
|
||||
// //stam := header.Get("Origin")
|
||||
// fmt.Printf("header: %v\nurl: %v\n", header, url)
|
||||
// io.Copy(ws, ws)
|
||||
|
||||
err := attachNewServerConn(ws, cfg)
|
||||
err := attachNewServerConn(ws, cfg, sessionId)
|
||||
if err != nil {
|
||||
log.Fatalf("Error attaching new connection. %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func WsServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||
func WsServe(url string, cfg *ServerConfig) error {
|
||||
//server := WsServer1{cfg}
|
||||
server := WsServer{cfg}
|
||||
server.Listen(url, WsHandler(wsHandlerFunc))
|
||||
return nil
|
||||
}
|
||||
|
||||
func TcpServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||
ln, err := net.Listen("tcp", ":5903")
|
||||
func TcpServe(url string, cfg *ServerConfig) error {
|
||||
ln, err := net.Listen("tcp", url)
|
||||
if err != nil {
|
||||
log.Fatalf("Error listen. %v", err)
|
||||
}
|
||||
@@ -117,7 +96,7 @@ func TcpServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go attachNewServerConn(c, cfg)
|
||||
go attachNewServerConn(c, cfg, "tcpDummySession")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
@@ -125,9 +104,9 @@ func TcpServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig) error {
|
||||
func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig, sessionId string) error {
|
||||
|
||||
conn, err := newServerConn(c, cfg)
|
||||
conn, err := NewServerConn(c, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -152,72 +131,11 @@ func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig) error {
|
||||
conn.Close()
|
||||
return err
|
||||
}
|
||||
conn.SessionId = sessionId
|
||||
cfg.NewConnHandler(cfg, conn)
|
||||
|
||||
//go
|
||||
//go here will kill ws connections
|
||||
conn.handle()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ServerConn) handle() error {
|
||||
//var err error
|
||||
//var wg sync.WaitGroup
|
||||
|
||||
//defer c.Close()
|
||||
|
||||
//create a map of all message types
|
||||
clientMessages := make(map[common.ClientMessageType]common.ClientMessage)
|
||||
for _, m := range c.cfg.ClientMessages {
|
||||
clientMessages[m.Type()] = m
|
||||
}
|
||||
//wg.Add(2)
|
||||
|
||||
// server
|
||||
// go func() error {
|
||||
// defer wg.Done()
|
||||
// for {
|
||||
// select {
|
||||
// case msg := <-c.cfg.ServerMessageCh:
|
||||
// fmt.Printf("%v", msg)
|
||||
// // if err = msg.Write(c); err != nil {
|
||||
// // return err
|
||||
// // }
|
||||
// case <-c.quit:
|
||||
// c.Close()
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
// }()
|
||||
|
||||
// client
|
||||
//go func() error {
|
||||
//defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-c.quit:
|
||||
return nil
|
||||
default:
|
||||
var messageType common.ClientMessageType
|
||||
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
return err
|
||||
}
|
||||
msg, ok := clientMessages[messageType]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported message-type: %v", messageType)
|
||||
|
||||
}
|
||||
parsedMsg, err := msg.Read(c)
|
||||
if err != nil {
|
||||
fmt.Printf("srv err %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
fmt.Printf("message:%s, %v\n", parsedMsg.Type(), parsedMsg)
|
||||
//c.cfg.ClientMessageCh <- parsedMsg
|
||||
}
|
||||
}
|
||||
//}()
|
||||
|
||||
//wg.Wait()
|
||||
//return nil
|
||||
}
|
||||
|
@@ -1,16 +1,20 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"testing"
|
||||
"vncproxy/common"
|
||||
"vncproxy/encodings"
|
||||
)
|
||||
|
||||
func newServerConnHandler(cfg *ServerConfig, conn *ServerConn) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
|
||||
chServer := make(chan common.ClientMessage)
|
||||
//chServer := make(chan common.ClientMessage)
|
||||
chClient := make(chan common.ServerMessage)
|
||||
|
||||
cfg := &ServerConfig{
|
||||
@@ -18,16 +22,17 @@ func TestServer(t *testing.T) {
|
||||
SecurityHandlers: []SecurityHandler{&ServerAuthVNC{"Ch_#!T@8"}},
|
||||
Encodings: []common.Encoding{&encodings.RawEncoding{}, &encodings.TightEncoding{}, &encodings.CopyRectEncoding{}},
|
||||
PixelFormat: common.NewPixelFormat(32),
|
||||
ClientMessageCh: chServer,
|
||||
ServerMessageCh: chClient,
|
||||
ClientMessages: DefaultClientMessages,
|
||||
DesktopName: []byte("workDesk"),
|
||||
Height: uint16(768),
|
||||
Width: uint16(1024),
|
||||
//ClientMessageCh: chServer,
|
||||
ServerMessageCh: chClient,
|
||||
ClientMessages: DefaultClientMessages,
|
||||
DesktopName: []byte("workDesk"),
|
||||
Height: uint16(768),
|
||||
Width: uint16(1024),
|
||||
NewConnHandler: newServerConnHandler,
|
||||
}
|
||||
url := "http://localhost:8091/"
|
||||
go WsServe(url, context.Background(), cfg)
|
||||
go TcpServe(":5903", context.Background(), cfg)
|
||||
go WsServe(url, cfg)
|
||||
go TcpServe(":5903", cfg)
|
||||
// Process messages coming in on the ClientMessage channel.
|
||||
for {
|
||||
msg := <-chClient
|
||||
|
@@ -13,7 +13,15 @@ type WsServer struct {
|
||||
cfg *ServerConfig
|
||||
}
|
||||
|
||||
type WsHandler func(io.ReadWriter, *ServerConfig)
|
||||
type WsHandler func(io.ReadWriter, *ServerConfig, string)
|
||||
|
||||
// func checkOrigin(config *websocket.Config, req *http.Request) (err error) {
|
||||
// config.Origin, err = websocket.Origin(config, req)
|
||||
// if err == nil && config.Origin == nil {
|
||||
// return fmt.Errorf("null origin")
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
// This example demonstrates a trivial echo server.
|
||||
func (wsServer *WsServer) Listen(urlStr string, handlerFunc WsHandler) {
|
||||
@@ -26,15 +34,28 @@ func (wsServer *WsServer) Listen(urlStr string, handlerFunc WsHandler) {
|
||||
fmt.Println("error while parsing url: ", err)
|
||||
}
|
||||
|
||||
http.Handle(url.Path, websocket.Handler(func(ws *websocket.Conn) {
|
||||
// header := ws.Request().Header
|
||||
// url := ws.Request().URL
|
||||
// //stam := header.Get("Origin")
|
||||
// fmt.Printf("header: %v\nurl: %v\n", header, url)
|
||||
// io.Copy(ws, ws)
|
||||
ws.PayloadType = websocket.BinaryFrame
|
||||
handlerFunc(ws, wsServer.cfg)
|
||||
}))
|
||||
// http.HandleFunc(url.Path,
|
||||
// func(w http.ResponseWriter, req *http.Request) {
|
||||
// sessionId := req.URL.Query().Get("sessionId")
|
||||
// s := websocket.Server{Handshake: checkOrigin, Handler: websocket.Handler(
|
||||
// func(ws *websocket.ServerConn) {
|
||||
// ws.PayloadType = websocket.BinaryFrame
|
||||
// handlerFunc(ws, wsServer.cfg, sessionId)
|
||||
// })}
|
||||
// s.ServeHTTP(w, req)
|
||||
// })
|
||||
|
||||
http.Handle(url.Path, websocket.Handler(
|
||||
func(ws *websocket.Conn) {
|
||||
path := ws.Request().URL.Path
|
||||
var sessionId string
|
||||
if path != "" {
|
||||
sessionId = path[1:]
|
||||
}
|
||||
|
||||
ws.PayloadType = websocket.BinaryFrame
|
||||
handlerFunc(ws, wsServer.cfg, sessionId)
|
||||
}))
|
||||
|
||||
err = http.ListenAndServe(url.Host, nil)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user