mirror of
https://github.com/amitbet/vncproxy.git
synced 2025-07-06 18:59:01 +00:00
Added server for web sockets, plus some refactoring
This commit is contained in:
parent
66c322c164
commit
076d8bb4cf
@ -5,6 +5,7 @@
|
|||||||
<root url="file://$PROJECT_DIR$/../gopkg.in" />
|
<root url="file://$PROJECT_DIR$/../gopkg.in" />
|
||||||
<root url="file://$PROJECT_DIR$/../vncproxy1" />
|
<root url="file://$PROJECT_DIR$/../vncproxy1" />
|
||||||
<root url="file://$PROJECT_DIR$/../GoProjExample" />
|
<root url="file://$PROJECT_DIR$/../GoProjExample" />
|
||||||
|
<root url="file://$PROJECT_DIR$/../govmomi-fork" />
|
||||||
<root url="file://$PROJECT_DIR$/../srf.opb" />
|
<root url="file://$PROJECT_DIR$/../srf.opb" />
|
||||||
<root url="file://$PROJECT_DIR$/../vshpere-cli" />
|
<root url="file://$PROJECT_DIR$/../vshpere-cli" />
|
||||||
<root url="file://$PROJECT_DIR$/../sourcegraph.com" />
|
<root url="file://$PROJECT_DIR$/../sourcegraph.com" />
|
||||||
@ -26,6 +27,7 @@
|
|||||||
<root url="file://$PROJECT_DIR$/../gopkg.in" />
|
<root url="file://$PROJECT_DIR$/../gopkg.in" />
|
||||||
<root url="file://$PROJECT_DIR$/../vncproxy1" />
|
<root url="file://$PROJECT_DIR$/../vncproxy1" />
|
||||||
<root url="file://$PROJECT_DIR$/../GoProjExample" />
|
<root url="file://$PROJECT_DIR$/../GoProjExample" />
|
||||||
|
<root url="file://$PROJECT_DIR$/../govmomi-fork" />
|
||||||
<root url="file://$PROJECT_DIR$/../srf.opb" />
|
<root url="file://$PROJECT_DIR$/../srf.opb" />
|
||||||
<root url="file://$PROJECT_DIR$/../vshpere-cli" />
|
<root url="file://$PROJECT_DIR$/../vshpere-cli" />
|
||||||
<root url="file://$PROJECT_DIR$/../sourcegraph.com" />
|
<root url="file://$PROJECT_DIR$/../sourcegraph.com" />
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -8,7 +8,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"unicode"
|
"unicode"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
"vncproxy/listeners"
|
"vncproxy/tee-listeners"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ServerMessage implements a message sent from the server to the client.
|
// A ServerMessage implements a message sent from the server to the client.
|
@ -1,114 +1,114 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"crypto/des"
|
"crypto/des"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// ClientAuthNone is the "none" authentication. See 7.2.1
|
// ClientAuthNone is the "none" authentication. See 7.2.1
|
||||||
type ClientAuthNone byte
|
type ClientAuthNone byte
|
||||||
|
|
||||||
func (*ClientAuthNone) SecurityType() uint8 {
|
func (*ClientAuthNone) SecurityType() uint8 {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ClientAuthNone) Handshake(net.Conn) error {
|
func (*ClientAuthNone) Handshake(net.Conn) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordAuth is VNC authentication, 7.2.2
|
// PasswordAuth is VNC authentication, 7.2.2
|
||||||
type PasswordAuth struct {
|
type PasswordAuth struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordAuth) SecurityType() uint8 {
|
func (p *PasswordAuth) SecurityType() uint8 {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordAuth) Handshake(c net.Conn) error {
|
func (p *PasswordAuth) Handshake(c net.Conn) error {
|
||||||
randomValue := make([]uint8, 16)
|
randomValue := make([]uint8, 16)
|
||||||
if err := binary.Read(c, binary.BigEndian, &randomValue); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &randomValue); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
crypted, err := p.encrypt(p.Password, randomValue)
|
crypted, err := p.encrypt(p.Password, randomValue)
|
||||||
|
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(c, binary.BigEndian, &crypted); err != nil {
|
if err := binary.Write(c, binary.BigEndian, &crypted); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordAuth) reverseBits(b byte) byte {
|
func (p *PasswordAuth) reverseBits(b byte) byte {
|
||||||
var reverse = [256]int{
|
var reverse = [256]int{
|
||||||
0, 128, 64, 192, 32, 160, 96, 224,
|
0, 128, 64, 192, 32, 160, 96, 224,
|
||||||
16, 144, 80, 208, 48, 176, 112, 240,
|
16, 144, 80, 208, 48, 176, 112, 240,
|
||||||
8, 136, 72, 200, 40, 168, 104, 232,
|
8, 136, 72, 200, 40, 168, 104, 232,
|
||||||
24, 152, 88, 216, 56, 184, 120, 248,
|
24, 152, 88, 216, 56, 184, 120, 248,
|
||||||
4, 132, 68, 196, 36, 164, 100, 228,
|
4, 132, 68, 196, 36, 164, 100, 228,
|
||||||
20, 148, 84, 212, 52, 180, 116, 244,
|
20, 148, 84, 212, 52, 180, 116, 244,
|
||||||
12, 140, 76, 204, 44, 172, 108, 236,
|
12, 140, 76, 204, 44, 172, 108, 236,
|
||||||
28, 156, 92, 220, 60, 188, 124, 252,
|
28, 156, 92, 220, 60, 188, 124, 252,
|
||||||
2, 130, 66, 194, 34, 162, 98, 226,
|
2, 130, 66, 194, 34, 162, 98, 226,
|
||||||
18, 146, 82, 210, 50, 178, 114, 242,
|
18, 146, 82, 210, 50, 178, 114, 242,
|
||||||
10, 138, 74, 202, 42, 170, 106, 234,
|
10, 138, 74, 202, 42, 170, 106, 234,
|
||||||
26, 154, 90, 218, 58, 186, 122, 250,
|
26, 154, 90, 218, 58, 186, 122, 250,
|
||||||
6, 134, 70, 198, 38, 166, 102, 230,
|
6, 134, 70, 198, 38, 166, 102, 230,
|
||||||
22, 150, 86, 214, 54, 182, 118, 246,
|
22, 150, 86, 214, 54, 182, 118, 246,
|
||||||
14, 142, 78, 206, 46, 174, 110, 238,
|
14, 142, 78, 206, 46, 174, 110, 238,
|
||||||
30, 158, 94, 222, 62, 190, 126, 254,
|
30, 158, 94, 222, 62, 190, 126, 254,
|
||||||
1, 129, 65, 193, 33, 161, 97, 225,
|
1, 129, 65, 193, 33, 161, 97, 225,
|
||||||
17, 145, 81, 209, 49, 177, 113, 241,
|
17, 145, 81, 209, 49, 177, 113, 241,
|
||||||
9, 137, 73, 201, 41, 169, 105, 233,
|
9, 137, 73, 201, 41, 169, 105, 233,
|
||||||
25, 153, 89, 217, 57, 185, 121, 249,
|
25, 153, 89, 217, 57, 185, 121, 249,
|
||||||
5, 133, 69, 197, 37, 165, 101, 229,
|
5, 133, 69, 197, 37, 165, 101, 229,
|
||||||
21, 149, 85, 213, 53, 181, 117, 245,
|
21, 149, 85, 213, 53, 181, 117, 245,
|
||||||
13, 141, 77, 205, 45, 173, 109, 237,
|
13, 141, 77, 205, 45, 173, 109, 237,
|
||||||
29, 157, 93, 221, 61, 189, 125, 253,
|
29, 157, 93, 221, 61, 189, 125, 253,
|
||||||
3, 131, 67, 195, 35, 163, 99, 227,
|
3, 131, 67, 195, 35, 163, 99, 227,
|
||||||
19, 147, 83, 211, 51, 179, 115, 243,
|
19, 147, 83, 211, 51, 179, 115, 243,
|
||||||
11, 139, 75, 203, 43, 171, 107, 235,
|
11, 139, 75, 203, 43, 171, 107, 235,
|
||||||
27, 155, 91, 219, 59, 187, 123, 251,
|
27, 155, 91, 219, 59, 187, 123, 251,
|
||||||
7, 135, 71, 199, 39, 167, 103, 231,
|
7, 135, 71, 199, 39, 167, 103, 231,
|
||||||
23, 151, 87, 215, 55, 183, 119, 247,
|
23, 151, 87, 215, 55, 183, 119, 247,
|
||||||
15, 143, 79, 207, 47, 175, 111, 239,
|
15, 143, 79, 207, 47, 175, 111, 239,
|
||||||
31, 159, 95, 223, 63, 191, 127, 255,
|
31, 159, 95, 223, 63, 191, 127, 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
return byte(reverse[int(b)])
|
return byte(reverse[int(b)])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordAuth) encrypt(key string, bytes []byte) ([]byte, error) {
|
func (p *PasswordAuth) encrypt(key string, bytes []byte) ([]byte, error) {
|
||||||
keyBytes := []byte{0,0,0,0,0,0,0,0}
|
keyBytes := []byte{0,0,0,0,0,0,0,0}
|
||||||
|
|
||||||
if len(key) > 8 {
|
if len(key) > 8 {
|
||||||
key = key[:8]
|
key = key[:8]
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(key); i++ {
|
for i := 0; i < len(key); i++ {
|
||||||
keyBytes[i] = p.reverseBits(key[i])
|
keyBytes[i] = p.reverseBits(key[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := des.NewCipher(keyBytes)
|
block, err := des.NewCipher(keyBytes)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result1 := make([]byte, 8)
|
result1 := make([]byte, 8)
|
||||||
block.Encrypt(result1, bytes)
|
block.Encrypt(result1, bytes)
|
||||||
result2 := make([]byte, 8)
|
result2 := make([]byte, 8)
|
||||||
block.Encrypt(result2, bytes[8:])
|
block.Encrypt(result2, bytes[8:])
|
||||||
|
|
||||||
crypted := append(result1, result2...)
|
crypted := append(result1, result2...)
|
||||||
|
|
||||||
return crypted, nil
|
return crypted, nil
|
||||||
}
|
}
|
@ -1,169 +1,169 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
"bytes"
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeNetConnection struct {
|
type fakeNetConnection struct {
|
||||||
DataToSend []byte
|
DataToSend []byte
|
||||||
Test *testing.T
|
Test *testing.T
|
||||||
ExpectData []byte
|
ExpectData []byte
|
||||||
Finished bool
|
Finished bool
|
||||||
Matched bool
|
Matched bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc fakeNetConnection) Read(b []byte) (n int, err error) {
|
func (fc fakeNetConnection) Read(b []byte) (n int, err error) {
|
||||||
for i := 0; i < 16; i++ {
|
for i := 0; i < 16; i++ {
|
||||||
b[i] = fc.DataToSend[i]
|
b[i] = fc.DataToSend[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
fc.Finished = false
|
fc.Finished = false
|
||||||
|
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *fakeNetConnection) Write(b []byte) (n int, err error) {
|
func (fc *fakeNetConnection) Write(b []byte) (n int, err error) {
|
||||||
fc.Matched = bytes.Equal(b, fc.ExpectData)
|
fc.Matched = bytes.Equal(b, fc.ExpectData)
|
||||||
fc.Finished = true
|
fc.Finished = true
|
||||||
|
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *fakeNetConnection) Close() error { return nil; }
|
func (fc *fakeNetConnection) Close() error { return nil; }
|
||||||
func (fc *fakeNetConnection) LocalAddr() net.Addr { return nil; }
|
func (fc *fakeNetConnection) LocalAddr() net.Addr { return nil; }
|
||||||
func (fc *fakeNetConnection) RemoteAddr() net.Addr { return nil; }
|
func (fc *fakeNetConnection) RemoteAddr() net.Addr { return nil; }
|
||||||
func (fc *fakeNetConnection) SetDeadline(t time.Time) error { return nil; }
|
func (fc *fakeNetConnection) SetDeadline(t time.Time) error { return nil; }
|
||||||
func (fc *fakeNetConnection) SetReadDeadline(t time.Time) error { return nil; }
|
func (fc *fakeNetConnection) SetReadDeadline(t time.Time) error { return nil; }
|
||||||
func (fc *fakeNetConnection) SetWriteDeadline(t time.Time) error { return nil; }
|
func (fc *fakeNetConnection) SetWriteDeadline(t time.Time) error { return nil; }
|
||||||
|
|
||||||
func TestClientAuthNone_Impl(t *testing.T) {
|
func TestClientAuthNone_Impl(t *testing.T) {
|
||||||
var raw interface{}
|
var raw interface{}
|
||||||
raw = new(ClientAuthNone)
|
raw = new(ClientAuthNone)
|
||||||
if _, ok := raw.(ClientAuth); !ok {
|
if _, ok := raw.(ClientAuth); !ok {
|
||||||
t.Fatal("ClientAuthNone doesn't implement ClientAuth")
|
t.Fatal("ClientAuthNone doesn't implement ClientAuth")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientAuthPasswordSuccess_Impl(t *testing.T) {
|
func TestClientAuthPasswordSuccess_Impl(t *testing.T) {
|
||||||
// Values ripped using WireShark
|
// Values ripped using WireShark
|
||||||
randomValue := []byte{
|
randomValue := []byte{
|
||||||
0xa4,
|
0xa4,
|
||||||
0x51,
|
0x51,
|
||||||
0x3f,
|
0x3f,
|
||||||
0xa5,
|
0xa5,
|
||||||
0x1f,
|
0x1f,
|
||||||
0x87,
|
0x87,
|
||||||
0x06,
|
0x06,
|
||||||
0x10,
|
0x10,
|
||||||
0xa4,
|
0xa4,
|
||||||
0x5f,
|
0x5f,
|
||||||
0xae,
|
0xae,
|
||||||
0xbf,
|
0xbf,
|
||||||
0x4d,
|
0x4d,
|
||||||
0xac,
|
0xac,
|
||||||
0x12,
|
0x12,
|
||||||
0x22,
|
0x22,
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedResponse := []byte{
|
expectedResponse := []byte{
|
||||||
0x71,
|
0x71,
|
||||||
0xe4,
|
0xe4,
|
||||||
0x41,
|
0x41,
|
||||||
0x30,
|
0x30,
|
||||||
0x43,
|
0x43,
|
||||||
0x65,
|
0x65,
|
||||||
0x4e,
|
0x4e,
|
||||||
0x39,
|
0x39,
|
||||||
0xda,
|
0xda,
|
||||||
0x6d,
|
0x6d,
|
||||||
0x49,
|
0x49,
|
||||||
0x93,
|
0x93,
|
||||||
0x43,
|
0x43,
|
||||||
0xf6,
|
0xf6,
|
||||||
0x5e,
|
0x5e,
|
||||||
0x29,
|
0x29,
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := PasswordAuth{Password: "Ch_#!T@8"}
|
raw := PasswordAuth{Password: "Ch_#!T@8"}
|
||||||
|
|
||||||
// Only about 12 hours into Go at the moment...
|
// Only about 12 hours into Go at the moment...
|
||||||
// if _, ok := raw.(ClientAuth); !ok {
|
// if _, ok := raw.(ClientAuth); !ok {
|
||||||
// t.Fatal("PasswordAuth doesn't implement ClientAuth")
|
// t.Fatal("PasswordAuth doesn't implement ClientAuth")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
conn := &fakeNetConnection{DataToSend: randomValue, ExpectData: expectedResponse, Test: t}
|
conn := &fakeNetConnection{DataToSend: randomValue, ExpectData: expectedResponse, Test: t}
|
||||||
err := raw.Handshake(conn)
|
err := raw.Handshake(conn)
|
||||||
|
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !conn.Matched {
|
if !conn.Matched {
|
||||||
t.Fatal("PasswordAuth didn't pass the right response back to the wire")
|
t.Fatal("PasswordAuth didn't pass the right response back to the wire")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !conn.Finished {
|
if !conn.Finished {
|
||||||
t.Fatal("PasswordAuth didn't complete properly")
|
t.Fatal("PasswordAuth didn't complete properly")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientAuthPasswordReject_Impl(t *testing.T) {
|
func TestClientAuthPasswordReject_Impl(t *testing.T) {
|
||||||
// Values ripped using WireShark
|
// Values ripped using WireShark
|
||||||
randomValue := []byte{
|
randomValue := []byte{
|
||||||
0xa4,
|
0xa4,
|
||||||
0x51,
|
0x51,
|
||||||
0x3f,
|
0x3f,
|
||||||
0xa5,
|
0xa5,
|
||||||
0x1f,
|
0x1f,
|
||||||
0x87,
|
0x87,
|
||||||
0x06,
|
0x06,
|
||||||
0x10,
|
0x10,
|
||||||
0xa4,
|
0xa4,
|
||||||
0x5f,
|
0x5f,
|
||||||
0xae,
|
0xae,
|
||||||
0xbf,
|
0xbf,
|
||||||
0x4d,
|
0x4d,
|
||||||
0xac,
|
0xac,
|
||||||
0x12,
|
0x12,
|
||||||
0x22,
|
0x22,
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedResponse := []byte{
|
expectedResponse := []byte{
|
||||||
0x71,
|
0x71,
|
||||||
0xe4,
|
0xe4,
|
||||||
0x41,
|
0x41,
|
||||||
0x30,
|
0x30,
|
||||||
0x43,
|
0x43,
|
||||||
0x65,
|
0x65,
|
||||||
0x4e,
|
0x4e,
|
||||||
0x39,
|
0x39,
|
||||||
0xda,
|
0xda,
|
||||||
0x6d,
|
0x6d,
|
||||||
0x49,
|
0x49,
|
||||||
0x93,
|
0x93,
|
||||||
0x43,
|
0x43,
|
||||||
0xf6,
|
0xf6,
|
||||||
0x5e,
|
0x5e,
|
||||||
0x29,
|
0x29,
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := PasswordAuth{Password: "Ch_#!T@"}
|
raw := PasswordAuth{Password: "Ch_#!T@"}
|
||||||
|
|
||||||
conn := &fakeNetConnection{DataToSend: randomValue, ExpectData: expectedResponse, Test: t}
|
conn := &fakeNetConnection{DataToSend: randomValue, ExpectData: expectedResponse, Test: t}
|
||||||
err := raw.Handshake(conn)
|
err := raw.Handshake(conn)
|
||||||
|
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if conn.Matched {
|
if conn.Matched {
|
||||||
t.Fatal("PasswordAuth didn't pass the right response back to the wire")
|
t.Fatal("PasswordAuth didn't pass the right response back to the wire")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !conn.Finished {
|
if !conn.Finished {
|
||||||
t.Fatal("PasswordAuth didn't complete properly")
|
t.Fatal("PasswordAuth didn't complete properly")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,95 +1,95 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newMockServer(t *testing.T, version string) string {
|
func newMockServer(t *testing.T, version string) string {
|
||||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error listening: %s", err)
|
t.Fatalf("error listening: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer ln.Close()
|
defer ln.Close()
|
||||||
c, err := ln.Accept()
|
c, err := ln.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error accepting conn: %s", err)
|
t.Fatalf("error accepting conn: %s", err)
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
_, err = c.Write([]byte(fmt.Sprintf("RFB %s\n", version)))
|
_, err = c.Write([]byte(fmt.Sprintf("RFB %s\n", version)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("failed writing version")
|
t.Fatal("failed writing version")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return ln.Addr().String()
|
return ln.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_LowMajorVersion(t *testing.T) {
|
func TestClient_LowMajorVersion(t *testing.T) {
|
||||||
nc, err := net.Dial("tcp", newMockServer(t, "002.009"))
|
nc, err := net.Dial("tcp", newMockServer(t, "002.009"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error connecting to mock server: %s", err)
|
t.Fatalf("error connecting to mock server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = Client(nc, &ClientConfig{})
|
_, err = Client(nc, &ClientConfig{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("error expected")
|
t.Fatal("error expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Error() != "unsupported major version, less than 3: 2" {
|
if err.Error() != "unsupported major version, less than 3: 2" {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_LowMinorVersion(t *testing.T) {
|
func TestClient_LowMinorVersion(t *testing.T) {
|
||||||
nc, err := net.Dial("tcp", newMockServer(t, "003.007"))
|
nc, err := net.Dial("tcp", newMockServer(t, "003.007"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error connecting to mock server: %s", err)
|
t.Fatalf("error connecting to mock server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = Client(nc, &ClientConfig{})
|
_, err = Client(nc, &ClientConfig{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("error expected")
|
t.Fatal("error expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Error() != "unsupported minor version, less than 8: 7" {
|
if err.Error() != "unsupported minor version, less than 8: 7" {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseProtocolVersion(t *testing.T) {
|
func TestParseProtocolVersion(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
proto []byte
|
proto []byte
|
||||||
major, minor uint
|
major, minor uint
|
||||||
isErr bool
|
isErr bool
|
||||||
}{
|
}{
|
||||||
// Valid ProtocolVersion messages.
|
// Valid ProtocolVersion messages.
|
||||||
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 48, 48, 56, 10}, 3, 8, false}, // RFB 003.008\n
|
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 48, 48, 56, 10}, 3, 8, false}, // RFB 003.008\n
|
||||||
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 56, 56, 57, 10}, 3, 889, false}, // RFB 003.889\n -- OS X 10.10.3
|
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 56, 56, 57, 10}, 3, 889, false}, // RFB 003.889\n -- OS X 10.10.3
|
||||||
{[]byte{82, 70, 66, 32, 48, 48, 48, 46, 48, 48, 48, 10}, 0, 0, false}, // RFB 000.0000\n
|
{[]byte{82, 70, 66, 32, 48, 48, 48, 46, 48, 48, 48, 10}, 0, 0, false}, // RFB 000.0000\n
|
||||||
// Invalid messages.
|
// Invalid messages.
|
||||||
{[]byte{82, 70, 66, 32, 51, 46, 56, 10}, 0, 0, true}, // RFB 3.8\n -- too short; not zero padded
|
{[]byte{82, 70, 66, 32, 51, 46, 56, 10}, 0, 0, true}, // RFB 3.8\n -- too short; not zero padded
|
||||||
{[]byte{82, 70, 66, 10}, 0, 0, true}, // RFB\n -- too short
|
{[]byte{82, 70, 66, 10}, 0, 0, true}, // RFB\n -- too short
|
||||||
{[]byte{}, 0, 0, true}, // (empty) -- too short
|
{[]byte{}, 0, 0, true}, // (empty) -- too short
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
major, minor, err := parseProtocolVersion(tt.proto)
|
major, minor, err := parseProtocolVersion(tt.proto)
|
||||||
if err != nil && !tt.isErr {
|
if err != nil && !tt.isErr {
|
||||||
t.Fatalf("parseProtocolVersion(%v) unexpected error %v", tt.proto, err)
|
t.Fatalf("parseProtocolVersion(%v) unexpected error %v", tt.proto, err)
|
||||||
}
|
}
|
||||||
if err == nil && tt.isErr {
|
if err == nil && tt.isErr {
|
||||||
t.Fatalf("parseProtocolVersion(%v) expected error", tt.proto)
|
t.Fatalf("parseProtocolVersion(%v) expected error", tt.proto)
|
||||||
}
|
}
|
||||||
if major != tt.major {
|
if major != tt.major {
|
||||||
t.Errorf("parseProtocolVersion(%v) major = %v, want %v", tt.proto, major, tt.major)
|
t.Errorf("parseProtocolVersion(%v) major = %v, want %v", tt.proto, major, tt.major)
|
||||||
}
|
}
|
||||||
if major != tt.major {
|
if major != tt.major {
|
||||||
t.Errorf("parseProtocolVersion(%v) minor = %v, want %v", tt.proto, minor, tt.minor)
|
t.Errorf("parseProtocolVersion(%v) minor = %v, want %v", tt.proto, minor, tt.minor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
// Color represents a single color in a color map.
|
// Color represents a single color in a color map.
|
||||||
type Color struct {
|
type Color struct {
|
||||||
R, G, B uint16
|
R, G, B uint16
|
||||||
}
|
}
|
BIN
client/debug.test
Normal file
BIN
client/debug.test
Normal file
Binary file not shown.
@ -1,136 +1,136 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func readPixelFormat(r io.Reader, result *common.PixelFormat) error {
|
func readPixelFormat(r io.Reader, result *common.PixelFormat) error {
|
||||||
var rawPixelFormat [16]byte
|
var rawPixelFormat [16]byte
|
||||||
if _, err := io.ReadFull(r, rawPixelFormat[:]); err != nil {
|
if _, err := io.ReadFull(r, rawPixelFormat[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var pfBoolByte uint8
|
var pfBoolByte uint8
|
||||||
brPF := bytes.NewReader(rawPixelFormat[:])
|
brPF := bytes.NewReader(rawPixelFormat[:])
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.BPP); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.BPP); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.Depth); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.Depth); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pfBoolByte != 0 {
|
if pfBoolByte != 0 {
|
||||||
// Big endian is true
|
// Big endian is true
|
||||||
result.BigEndian = true
|
result.BigEndian = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pfBoolByte != 0 {
|
if pfBoolByte != 0 {
|
||||||
// True Color is true. So we also have to read all the color max & shifts.
|
// True Color is true. So we also have to read all the color max & shifts.
|
||||||
result.TrueColor = true
|
result.TrueColor = true
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.RedMax); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.RedMax); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.GreenMax); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.GreenMax); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.BlueMax); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.BlueMax); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.RedShift); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.RedShift); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.GreenShift); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.GreenShift); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Read(brPF, binary.BigEndian, &result.BlueShift); err != nil {
|
if err := binary.Read(brPF, binary.BigEndian, &result.BlueShift); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writePixelFormat(format *common.PixelFormat) ([]byte, error) {
|
func writePixelFormat(format *common.PixelFormat) ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
// Byte 1
|
// Byte 1
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.BPP); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.BPP); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Byte 2
|
// Byte 2
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.Depth); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.Depth); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var boolByte byte
|
var boolByte byte
|
||||||
if format.BigEndian {
|
if format.BigEndian {
|
||||||
boolByte = 1
|
boolByte = 1
|
||||||
} else {
|
} else {
|
||||||
boolByte = 0
|
boolByte = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Byte 3 (BigEndian)
|
// Byte 3 (BigEndian)
|
||||||
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if format.TrueColor {
|
if format.TrueColor {
|
||||||
boolByte = 1
|
boolByte = 1
|
||||||
} else {
|
} else {
|
||||||
boolByte = 0
|
boolByte = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Byte 4 (TrueColor)
|
// Byte 4 (TrueColor)
|
||||||
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have true color enabled then we have to fill in the rest of the
|
// If we have true color enabled then we have to fill in the rest of the
|
||||||
// structure with the color values.
|
// structure with the color values.
|
||||||
if format.TrueColor {
|
if format.TrueColor {
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.RedMax); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.RedMax); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.GreenMax); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.GreenMax); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.BlueMax); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.BlueMax); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.RedShift); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.RedShift); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.GreenShift); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.GreenShift); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(&buf, binary.BigEndian, format.BlueShift); err != nil {
|
if err := binary.Write(&buf, binary.BigEndian, format.BlueShift); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.Bytes()[0:16], nil
|
return buf.Bytes()[0:16], nil
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
// ButtonMask represents a mask of pointer presses/releases.
|
// ButtonMask represents a mask of pointer presses/releases.
|
||||||
type ButtonMask uint8
|
type ButtonMask uint8
|
||||||
|
|
||||||
// All available button mask components.
|
// All available button mask components.
|
||||||
const (
|
const (
|
||||||
ButtonLeft ButtonMask = 1 << iota
|
ButtonLeft ButtonMask = 1 << iota
|
||||||
ButtonMiddle
|
ButtonMiddle
|
||||||
ButtonRight
|
ButtonRight
|
||||||
Button4
|
Button4
|
||||||
Button5
|
Button5
|
||||||
Button6
|
Button6
|
||||||
Button7
|
Button7
|
||||||
Button8
|
Button8
|
||||||
)
|
)
|
@ -1,4 +1,4 @@
|
|||||||
package vnc
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
@ -1,9 +1,6 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import "io"
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ClientMessageType uint8
|
type ClientMessageType uint8
|
||||||
|
|
||||||
@ -31,8 +28,8 @@ type Color struct {
|
|||||||
type ColorMap [256]Color
|
type ColorMap [256]Color
|
||||||
|
|
||||||
type Conn interface {
|
type Conn interface {
|
||||||
io.ReadWriteCloser
|
io.ReadWriter
|
||||||
Conn() net.Conn
|
Conn() io.ReadWriter
|
||||||
Protocol() string
|
Protocol() string
|
||||||
PixelFormat() *PixelFormat
|
PixelFormat() *PixelFormat
|
||||||
SetPixelFormat(*PixelFormat) error
|
SetPixelFormat(*PixelFormat) error
|
||||||
@ -46,7 +43,7 @@ type Conn interface {
|
|||||||
SetHeight(uint16)
|
SetHeight(uint16)
|
||||||
DesktopName() string
|
DesktopName() string
|
||||||
SetDesktopName(string)
|
SetDesktopName(string)
|
||||||
Flush() error
|
//Flush() error
|
||||||
SetProtoVersion(string)
|
SetProtoVersion(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
main.go
10
main.go
@ -6,7 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
"vncproxy/encodings"
|
"vncproxy/encodings"
|
||||||
"vncproxy/vnc"
|
"vncproxy/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -17,12 +17,12 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error connecting to vnc server: %s", err)
|
fmt.Printf("error connecting to vnc server: %s", err)
|
||||||
}
|
}
|
||||||
var noauth vnc.ClientAuthNone
|
var noauth client.ClientAuthNone
|
||||||
authArr := []vnc.ClientAuth{&vnc.PasswordAuth{Password: "Ch_#!T@8"}, &noauth}
|
authArr := []client.ClientAuth{&client.PasswordAuth{Password: "Ch_#!T@8"}, &noauth}
|
||||||
|
|
||||||
vncSrvMessagesChan := make(chan common.ServerMessage)
|
vncSrvMessagesChan := make(chan common.ServerMessage)
|
||||||
clientConn, err := vnc.Client(nc,
|
clientConn, err := client.Client(nc,
|
||||||
&vnc.ClientConfig{
|
&client.ClientConfig{
|
||||||
Auth: authArr,
|
Auth: authArr,
|
||||||
ServerMessageCh: vncSrvMessagesChan,
|
ServerMessageCh: vncSrvMessagesChan,
|
||||||
Exclusive: true,
|
Exclusive: true,
|
||||||
|
@ -39,7 +39,7 @@ func (msg *SetPixelFormat) Write(c common.Conn) error {
|
|||||||
c.SetColorMap(&common.ColorMap{})
|
c.SetColorMap(&common.ColorMap{})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SetPixelFormat) Read(c common.Conn) (common.ClientMessage, error) {
|
func (*SetPixelFormat) Read(c common.Conn) (common.ClientMessage, error) {
|
||||||
@ -103,7 +103,7 @@ func (msg *SetEncodings) Write(c common.Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FramebufferUpdateRequest holds the wire format message.
|
// FramebufferUpdateRequest holds the wire format message.
|
||||||
@ -132,7 +132,7 @@ func (msg *FramebufferUpdateRequest) Write(c common.Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyEvent holds the wire format message.
|
// KeyEvent holds the wire format message.
|
||||||
@ -161,7 +161,7 @@ func (msg *KeyEvent) Write(c common.Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PointerEventMessage holds the wire format message.
|
// PointerEventMessage holds the wire format message.
|
||||||
@ -189,7 +189,7 @@ func (msg *PointerEvent) Write(c common.Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
if err := binary.Write(c, binary.BigEndian, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientCutText holds the wire format message, sans the text field.
|
// ClientCutText holds the wire format message, sans the text field.
|
||||||
@ -243,5 +243,5 @@ func (msg *ClientCutText) Write(c common.Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -7,20 +7,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// // ClientMessage is the interface
|
|
||||||
// type ClientMessage interface {
|
|
||||||
// Type() ClientMessageType
|
|
||||||
// Read(Conn) (ClientMessage, error)
|
|
||||||
// Write(Conn) error
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // ServerMessage is the interface
|
|
||||||
// type ServerMessage interface {
|
|
||||||
// Type() ServerMessageType
|
|
||||||
// Read(Conn) (ServerMessage, error)
|
|
||||||
// Write(Conn) error
|
|
||||||
// }
|
|
||||||
|
|
||||||
const ProtoVersionLength = 12
|
const ProtoVersionLength = 12
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -47,45 +33,14 @@ func ParseProtoVersion(pv []byte) (uint, uint, error) {
|
|||||||
return major, minor, nil
|
return major, minor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ClientVersionHandler(cfg *ClientConfig, c ServerConn) error {
|
|
||||||
// var version [ProtoVersionLength]byte
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &version); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// major, minor, err := ParseProtoVersion(version[:])
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pv := ProtoVersionUnknown
|
|
||||||
// if major == 3 {
|
|
||||||
// if minor >= 8 {
|
|
||||||
// pv = ProtoVersion38
|
|
||||||
// } else if minor >= 3 {
|
|
||||||
// pv = ProtoVersion38
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if pv == ProtoVersionUnknown {
|
|
||||||
// return fmt.Errorf("ProtocolVersion handshake failed; unsupported version '%v'", string(version[:]))
|
|
||||||
// }
|
|
||||||
// c.SetProtoVersion(string(version[:]))
|
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, []byte(pv)); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return c.Flush()
|
|
||||||
// }
|
|
||||||
|
|
||||||
func ServerVersionHandler(cfg *ServerConfig, c *ServerConn) error {
|
func ServerVersionHandler(cfg *ServerConfig, c *ServerConn) error {
|
||||||
var version [ProtoVersionLength]byte
|
var version [ProtoVersionLength]byte
|
||||||
if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil {
|
if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if err := binary.Read(c, binary.BigEndian, &version); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &version); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -111,58 +66,6 @@ func ServerVersionHandler(cfg *ServerConfig, c *ServerConn) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ClientSecurityHandler(cfg *ClientConfig, c Conn) error {
|
|
||||||
// var numSecurityTypes uint8
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &numSecurityTypes); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// secTypes := make([]SecurityType, numSecurityTypes)
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &secTypes); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var secType SecurityHandler
|
|
||||||
// for _, st := range cfg.SecurityHandlers {
|
|
||||||
// for _, sc := range secTypes {
|
|
||||||
// if st.Type() == sc {
|
|
||||||
// secType = st
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, cfg.SecurityHandlers[0].Type()); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := c.Flush(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// err := secType.Auth(c)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var authCode uint32
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &authCode); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if authCode == 1 {
|
|
||||||
// var reasonLength uint32
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &reasonLength); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// reasonText := make([]byte, reasonLength)
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &reasonText); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return fmt.Errorf("%s", reasonText)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func ServerSecurityHandler(cfg *ServerConfig, c *ServerConn) error {
|
func ServerSecurityHandler(cfg *ServerConfig, c *ServerConn) error {
|
||||||
if err := binary.Write(c, binary.BigEndian, uint8(len(cfg.SecurityHandlers))); err != nil {
|
if err := binary.Write(c, binary.BigEndian, uint8(len(cfg.SecurityHandlers))); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -174,9 +77,9 @@ func ServerSecurityHandler(cfg *ServerConfig, c *ServerConn) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
var secType SecurityType
|
var secType SecurityType
|
||||||
if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
|
||||||
@ -202,9 +105,9 @@ func ServerSecurityHandler(cfg *ServerConfig, c *ServerConn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, authCode); err != nil {
|
if err := binary.Write(c, binary.BigEndian, authCode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
if authErr != nil {
|
if authErr != nil {
|
||||||
if err := binary.Write(c, binary.BigEndian, len(authErr.Error())); err != nil {
|
if err := binary.Write(c, binary.BigEndian, len(authErr.Error())); err != nil {
|
||||||
@ -213,44 +116,15 @@ func ServerSecurityHandler(cfg *ServerConfig, c *ServerConn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil {
|
if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
return authErr
|
return authErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ClientServerInitHandler(cfg *ClientConfig, c *ServerConn) error {
|
|
||||||
// srvInit := &ServerInit{}
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &srvInit.FBWidth); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &srvInit.FBHeight); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &srvInit.PixelFormat); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &srvInit.NameLength); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// nameText := make([]byte, srvInit.NameLength)
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, nameText); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// srvInit.NameText = nameText
|
|
||||||
// c.SetDesktopName(string(srvInit.NameText))
|
|
||||||
// c.SetWidth(srvInit.FBWidth)
|
|
||||||
// c.SetHeight(srvInit.FBHeight)
|
|
||||||
// c.SetPixelFormat(&srvInit.PixelFormat)
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func ServerServerInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
func ServerServerInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
||||||
srvInit := &ServerInit{
|
srvInit := &ServerInit{
|
||||||
FBWidth: c.Width(),
|
FBWidth: c.Width(),
|
||||||
@ -293,7 +167,7 @@ func ServerServerInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
|||||||
//}
|
//}
|
||||||
//tightInit.WriteTo(c)
|
//tightInit.WriteTo(c)
|
||||||
|
|
||||||
return c.Flush()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -465,19 +339,6 @@ func (t *TightCapability) ReadFrom(r io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ClientClientInitHandler(cfg *ClientConfig, c *ServerConn) error {
|
|
||||||
// var shared uint8
|
|
||||||
// if cfg.Exclusive {
|
|
||||||
// shared = 0
|
|
||||||
// } else {
|
|
||||||
// shared = 1
|
|
||||||
// }
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, shared); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return c.Flush()
|
|
||||||
// }
|
|
||||||
|
|
||||||
func ServerClientInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
func ServerClientInitHandler(cfg *ServerConfig, c *ServerConn) error {
|
||||||
var shared uint8
|
var shared uint8
|
||||||
if err := binary.Read(c, binary.BigEndian, &shared); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &shared); err != nil {
|
||||||
|
@ -1,333 +1,335 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/des"
|
"crypto/des"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecurityType uint8
|
type SecurityType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SecTypeUnknown = SecurityType(0)
|
SecTypeUnknown = SecurityType(0)
|
||||||
SecTypeNone = SecurityType(1)
|
SecTypeNone = SecurityType(1)
|
||||||
SecTypeVNC = SecurityType(2)
|
SecTypeVNC = SecurityType(2)
|
||||||
SecTypeVeNCrypt = SecurityType(19)
|
SecTypeVeNCrypt = SecurityType(19)
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecuritySubType uint32
|
type SecuritySubType uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SecSubTypeUnknown = SecuritySubType(0)
|
SecSubTypeUnknown = SecuritySubType(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SecSubTypeVeNCrypt01Unknown = SecuritySubType(0)
|
SecSubTypeVeNCrypt01Unknown = SecuritySubType(0)
|
||||||
SecSubTypeVeNCrypt01Plain = SecuritySubType(19)
|
SecSubTypeVeNCrypt01Plain = SecuritySubType(19)
|
||||||
SecSubTypeVeNCrypt01TLSNone = SecuritySubType(20)
|
SecSubTypeVeNCrypt01TLSNone = SecuritySubType(20)
|
||||||
SecSubTypeVeNCrypt01TLSVNC = SecuritySubType(21)
|
SecSubTypeVeNCrypt01TLSVNC = SecuritySubType(21)
|
||||||
SecSubTypeVeNCrypt01TLSPlain = SecuritySubType(22)
|
SecSubTypeVeNCrypt01TLSPlain = SecuritySubType(22)
|
||||||
SecSubTypeVeNCrypt01X509None = SecuritySubType(23)
|
SecSubTypeVeNCrypt01X509None = SecuritySubType(23)
|
||||||
SecSubTypeVeNCrypt01X509VNC = SecuritySubType(24)
|
SecSubTypeVeNCrypt01X509VNC = SecuritySubType(24)
|
||||||
SecSubTypeVeNCrypt01X509Plain = SecuritySubType(25)
|
SecSubTypeVeNCrypt01X509Plain = SecuritySubType(25)
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SecSubTypeVeNCrypt02Unknown = SecuritySubType(0)
|
SecSubTypeVeNCrypt02Unknown = SecuritySubType(0)
|
||||||
SecSubTypeVeNCrypt02Plain = SecuritySubType(256)
|
SecSubTypeVeNCrypt02Plain = SecuritySubType(256)
|
||||||
SecSubTypeVeNCrypt02TLSNone = SecuritySubType(257)
|
SecSubTypeVeNCrypt02TLSNone = SecuritySubType(257)
|
||||||
SecSubTypeVeNCrypt02TLSVNC = SecuritySubType(258)
|
SecSubTypeVeNCrypt02TLSVNC = SecuritySubType(258)
|
||||||
SecSubTypeVeNCrypt02TLSPlain = SecuritySubType(259)
|
SecSubTypeVeNCrypt02TLSPlain = SecuritySubType(259)
|
||||||
SecSubTypeVeNCrypt02X509None = SecuritySubType(260)
|
SecSubTypeVeNCrypt02X509None = SecuritySubType(260)
|
||||||
SecSubTypeVeNCrypt02X509VNC = SecuritySubType(261)
|
SecSubTypeVeNCrypt02X509VNC = SecuritySubType(261)
|
||||||
SecSubTypeVeNCrypt02X509Plain = SecuritySubType(262)
|
SecSubTypeVeNCrypt02X509Plain = SecuritySubType(262)
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecurityHandler interface {
|
type SecurityHandler interface {
|
||||||
Type() SecurityType
|
Type() SecurityType
|
||||||
SubType() SecuritySubType
|
SubType() SecuritySubType
|
||||||
Auth(common.Conn) error
|
Auth(common.Conn) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// type ClientAuthNone struct{}
|
// type ClientAuthNone struct{}
|
||||||
|
|
||||||
// func (*ClientAuthNone) Type() SecurityType {
|
// func (*ClientAuthNone) Type() SecurityType {
|
||||||
// return SecTypeNone
|
// return SecTypeNone
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (*ClientAuthNone) SubType() SecuritySubType {
|
// func (*ClientAuthNone) SubType() SecuritySubType {
|
||||||
// return SecSubTypeUnknown
|
// return SecSubTypeUnknown
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (*ClientAuthNone) Auth(conn common.Conn) error {
|
// func (*ClientAuthNone) Auth(conn common.Conn) error {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// ServerAuthNone is the "none" authentication. See 7.2.1.
|
// ServerAuthNone is the "none" authentication. See 7.2.1.
|
||||||
type ServerAuthNone struct{}
|
type ServerAuthNone struct{}
|
||||||
|
|
||||||
func (*ServerAuthNone) Type() SecurityType {
|
func (*ServerAuthNone) Type() SecurityType {
|
||||||
return SecTypeNone
|
return SecTypeNone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ServerAuthNone) Auth(c common.Conn) error {
|
func (*ServerAuthNone) Auth(c common.Conn) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ServerAuthNone) SubType() SecuritySubType {
|
func (*ServerAuthNone) SubType() SecuritySubType {
|
||||||
return SecSubTypeUnknown
|
return SecSubTypeUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
|
// func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
|
||||||
// return SecTypeVeNCrypt
|
// return SecTypeVeNCrypt
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
// func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
||||||
// return SecSubTypeVeNCrypt02Plain
|
// return SecSubTypeVeNCrypt02Plain
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // ClientAuthVeNCryptPlain see https://www.berrange.com/~dan/vencrypt.txt
|
// // ClientAuthVeNCryptPlain see https://www.berrange.com/~dan/vencrypt.txt
|
||||||
// type ClientAuthVeNCrypt02Plain struct {
|
// type ClientAuthVeNCrypt02Plain struct {
|
||||||
// Username []byte
|
// Username []byte
|
||||||
// Password []byte
|
// Password []byte
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (auth *ClientAuthVeNCrypt02Plain) Auth(c common.Conn) error {
|
// func (auth *ClientAuthVeNCrypt02Plain) Auth(c common.Conn) error {
|
||||||
// if err := binary.Write(c, binary.BigEndian, []uint8{0, 2}); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, []uint8{0, 2}); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// var (
|
// var (
|
||||||
// major, minor uint8
|
// major, minor uint8
|
||||||
// )
|
// )
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &major); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &major); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if err := binary.Read(c, binary.BigEndian, &minor); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &minor); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// res := uint8(1)
|
// res := uint8(1)
|
||||||
// if major == 0 && minor == 2 {
|
// if major == 0 && minor == 2 {
|
||||||
// res = uint8(0)
|
// res = uint8(0)
|
||||||
// }
|
// }
|
||||||
// if err := binary.Write(c, binary.BigEndian, res); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, res); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// c.Flush()
|
// c.Flush()
|
||||||
// if err := binary.Write(c, binary.BigEndian, uint8(1)); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, uint8(1)); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if err := binary.Write(c, binary.BigEndian, auth.SubType()); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, auth.SubType()); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if err := c.Flush(); err != nil {
|
// if err := c.Flush(); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// var secType SecuritySubType
|
// var secType SecuritySubType
|
||||||
// if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if secType != auth.SubType() {
|
// if secType != auth.SubType() {
|
||||||
// binary.Write(c, binary.BigEndian, uint8(1))
|
// binary.Write(c, binary.BigEndian, uint8(1))
|
||||||
// c.Flush()
|
// c.Flush()
|
||||||
// return fmt.Errorf("invalid sectype")
|
// return fmt.Errorf("invalid sectype")
|
||||||
// }
|
// }
|
||||||
// if len(auth.Password) == 0 || len(auth.Username) == 0 {
|
// if len(auth.Password) == 0 || len(auth.Username) == 0 {
|
||||||
// return fmt.Errorf("Security Handshake failed; no username and/or password provided for VeNCryptAuth.")
|
// 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 {
|
// if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Username))); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Password))); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Password))); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, auth.Username); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, auth.Username); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil {
|
// if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// */
|
// */
|
||||||
// var (
|
// var (
|
||||||
// uLength, pLength uint32
|
// uLength, pLength uint32
|
||||||
// )
|
// )
|
||||||
// if err := binary.Read(c, binary.BigEndian, &uLength); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &uLength); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if err := binary.Read(c, binary.BigEndian, &pLength); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &pLength); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// username := make([]byte, uLength)
|
// username := make([]byte, uLength)
|
||||||
// password := make([]byte, pLength)
|
// password := make([]byte, pLength)
|
||||||
// if err := binary.Read(c, binary.BigEndian, &username); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &username); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &password); err != nil {
|
// if err := binary.Read(c, binary.BigEndian, &password); err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
// if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
|
// if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
|
||||||
// return fmt.Errorf("invalid username/password")
|
// return fmt.Errorf("invalid username/password")
|
||||||
// }
|
// }
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
||||||
type ServerAuthVNC struct{}
|
type ServerAuthVNC struct {
|
||||||
|
pass string
|
||||||
func (*ServerAuthVNC) Type() SecurityType {
|
}
|
||||||
return SecTypeVNC
|
|
||||||
}
|
func (*ServerAuthVNC) Type() SecurityType {
|
||||||
|
return SecTypeVNC
|
||||||
func (*ServerAuthVNC) SubType() SecuritySubType {
|
}
|
||||||
return SecSubTypeUnknown
|
|
||||||
}
|
func (*ServerAuthVNC) SubType() SecuritySubType {
|
||||||
|
return SecSubTypeUnknown
|
||||||
const AUTH_FAIL = "Authentication Failure"
|
}
|
||||||
|
|
||||||
func (auth *ServerAuthVNC) Auth(c common.Conn) error {
|
const AUTH_FAIL = "Authentication Failure"
|
||||||
buf := make([]byte, 8+len([]byte(AUTH_FAIL)))
|
|
||||||
rand.Read(buf[:16]) // Random 16 bytes in buf
|
func (auth *ServerAuthVNC) Auth(c common.Conn) error {
|
||||||
sndsz, err := c.Write(buf[:16])
|
buf := make([]byte, 8+len([]byte(AUTH_FAIL)))
|
||||||
if err != nil {
|
rand.Read(buf[:16]) // Random 16 bytes in buf
|
||||||
log.Printf("Error sending challenge to client: %s\n", err.Error())
|
sndsz, err := c.Write(buf[:16])
|
||||||
return errors.New("Error sending challenge to client:" + err.Error())
|
if err != nil {
|
||||||
}
|
log.Printf("Error sending challenge to client: %s\n", err.Error())
|
||||||
if sndsz != 16 {
|
return errors.New("Error sending challenge to client:" + err.Error())
|
||||||
log.Printf("The full 16 byte challenge was not sent!\n")
|
}
|
||||||
return errors.New("The full 16 byte challenge was not sent")
|
if sndsz != 16 {
|
||||||
}
|
log.Printf("The full 16 byte challenge was not sent!\n")
|
||||||
c.Flush()
|
return errors.New("The full 16 byte challenge was not sent")
|
||||||
buf2 := make([]byte, 16)
|
}
|
||||||
_, err = c.Read(buf2)
|
//c.Flush()
|
||||||
if err != nil {
|
buf2 := make([]byte, 16)
|
||||||
log.Printf("The authentication result was not read: %s\n", err.Error())
|
_, err = c.Read(buf2)
|
||||||
return errors.New("The authentication result was not read" + err.Error())
|
if err != nil {
|
||||||
}
|
log.Printf("The authentication result was not read: %s\n", err.Error())
|
||||||
AuthText := "1234"
|
return errors.New("The authentication result was not read" + err.Error())
|
||||||
bk, err := des.NewCipher([]byte(fixDesKey(AuthText)))
|
}
|
||||||
if err != nil {
|
AuthText := auth.pass
|
||||||
log.Printf("Error generating authentication cipher: %s\n", err.Error())
|
bk, err := des.NewCipher([]byte(fixDesKey(AuthText)))
|
||||||
return errors.New("Error generating authentication cipher")
|
if err != nil {
|
||||||
}
|
log.Printf("Error generating authentication cipher: %s\n", err.Error())
|
||||||
buf3 := make([]byte, 16)
|
return errors.New("Error generating authentication cipher")
|
||||||
bk.Encrypt(buf3, buf) //Encrypt first 8 bytes
|
}
|
||||||
bk.Encrypt(buf3[8:], buf[8:]) // Encrypt second 8 bytes
|
buf3 := make([]byte, 16)
|
||||||
if bytes.Compare(buf2, buf3) != 0 { // If the result does not decrypt correctly to what we sent then a problem
|
bk.Encrypt(buf3, buf) //Encrypt first 8 bytes
|
||||||
SetUint32(buf, 0, 1)
|
bk.Encrypt(buf3[8:], buf[8:]) // Encrypt second 8 bytes
|
||||||
SetUint32(buf, 4, uint32(len([]byte(AUTH_FAIL))))
|
if bytes.Compare(buf2, buf3) != 0 { // If the result does not decrypt correctly to what we sent then a problem
|
||||||
copy(buf[8:], []byte(AUTH_FAIL))
|
SetUint32(buf, 0, 1)
|
||||||
c.Write(buf)
|
SetUint32(buf, 4, uint32(len([]byte(AUTH_FAIL))))
|
||||||
c.Flush()
|
copy(buf[8:], []byte(AUTH_FAIL))
|
||||||
return errors.New("Authentication failed")
|
c.Write(buf)
|
||||||
}
|
//c.Flush()
|
||||||
return nil
|
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) {
|
// SetUint32 set 4 bytes at pos in buf to the val (in big endian format)
|
||||||
if pos+4 > len(buf) {
|
// A test is done to ensure there are 4 bytes available at pos in the buffer
|
||||||
return
|
func SetUint32(buf []byte, pos int, val uint32) {
|
||||||
}
|
if pos+4 > len(buf) {
|
||||||
for i := 0; i < 4; i++ {
|
return
|
||||||
buf[3-i+pos] = byte(val)
|
}
|
||||||
val >>= 8
|
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 {
|
// fixDesKeyByte is used to mirror a byte's bits
|
||||||
var newval byte = 0
|
// This is not clearly indicated by the document, but is in actual fact used
|
||||||
for i := 0; i < 8; i++ {
|
func fixDesKeyByte(val byte) byte {
|
||||||
newval <<= 1
|
var newval byte = 0
|
||||||
newval += (val & 1)
|
for i := 0; i < 8; i++ {
|
||||||
val >>= 1
|
newval <<= 1
|
||||||
}
|
newval += (val & 1)
|
||||||
return newval
|
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 {
|
// fixDesKey will make sure that exactly 8 bytes is used either by truncating or padding with nulls
|
||||||
tmp := []byte(key)
|
// The bytes are then bit mirrored and returned
|
||||||
buf := make([]byte, 8)
|
func fixDesKey(key string) []byte {
|
||||||
if len(tmp) <= 8 {
|
tmp := []byte(key)
|
||||||
copy(buf, tmp)
|
buf := make([]byte, 8)
|
||||||
} else {
|
if len(tmp) <= 8 {
|
||||||
copy(buf, tmp[:8])
|
copy(buf, tmp)
|
||||||
}
|
} else {
|
||||||
for i := 0; i < 8; i++ {
|
copy(buf, tmp[:8])
|
||||||
buf[i] = fixDesKeyByte(buf[i])
|
}
|
||||||
}
|
for i := 0; i < 8; i++ {
|
||||||
return buf
|
buf[i] = fixDesKeyByte(buf[i])
|
||||||
}
|
}
|
||||||
|
return buf
|
||||||
// // ClientAuthVNC is the standard password authentication. See 7.2.2.
|
}
|
||||||
// type ClientAuthVNC struct {
|
|
||||||
// Challenge [16]byte
|
// // ClientAuthVNC is the standard password authentication. See 7.2.2.
|
||||||
// Password []byte
|
// type ClientAuthVNC struct {
|
||||||
// }
|
// Challenge [16]byte
|
||||||
|
// Password []byte
|
||||||
// func (*ClientAuthVNC) Type() SecurityType {
|
// }
|
||||||
// return SecTypeVNC
|
|
||||||
// }
|
// func (*ClientAuthVNC) Type() SecurityType {
|
||||||
// func (*ClientAuthVNC) SubType() SecuritySubType {
|
// return SecTypeVNC
|
||||||
// return SecSubTypeUnknown
|
// }
|
||||||
// }
|
// 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.")
|
// 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
|
|
||||||
// }
|
// if err := binary.Read(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||||
|
// return err
|
||||||
// auth.encode()
|
// }
|
||||||
|
|
||||||
// // Send the encrypted challenge back to server
|
// auth.encode()
|
||||||
// if err := binary.Write(c, binary.BigEndian, auth.Challenge); err != nil {
|
|
||||||
// return err
|
// // Send the encrypted challenge back to server
|
||||||
// }
|
// if err := binary.Write(c, binary.BigEndian, auth.Challenge); err != nil {
|
||||||
|
// return err
|
||||||
// return c.Flush()
|
// }
|
||||||
// }
|
|
||||||
|
// return c.Flush()
|
||||||
// func (auth *ClientAuthVNC) encode() error {
|
// }
|
||||||
// // Copy password string to 8 byte 0-padded slice
|
|
||||||
// key := make([]byte, 8)
|
// func (auth *ClientAuthVNC) encode() error {
|
||||||
// copy(key, auth.Password)
|
// // Copy password string to 8 byte 0-padded slice
|
||||||
|
// key := make([]byte, 8)
|
||||||
// // Each byte of the password needs to be reversed. This is a
|
// copy(key, auth.Password)
|
||||||
// // non RFC-documented behaviour of VNC clients and servers
|
|
||||||
// for i := range key {
|
// // Each byte of the password needs to be reversed. This is a
|
||||||
// key[i] = (key[i]&0x55)<<1 | (key[i]&0xAA)>>1 // Swap adjacent bits
|
// // non RFC-documented behaviour of VNC clients and servers
|
||||||
// key[i] = (key[i]&0x33)<<2 | (key[i]&0xCC)>>2 // Swap adjacent pairs
|
// for i := range key {
|
||||||
// key[i] = (key[i]&0x0F)<<4 | (key[i]&0xF0)>>4 // Swap the 2 halves
|
// 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 {
|
// // Encrypt challenge with key.
|
||||||
// return err
|
// cipher, err := des.NewCipher(key)
|
||||||
// }
|
// if err != nil {
|
||||||
// for i := 0; i < len(auth.Challenge); i += cipher.BlockSize() {
|
// return err
|
||||||
// cipher.Encrypt(auth.Challenge[i:i+cipher.BlockSize()], auth.Challenge[i:i+cipher.BlockSize()])
|
// }
|
||||||
// }
|
// 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
|
// }
|
||||||
// }
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"io"
|
||||||
"net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerConn struct {
|
type ServerConn struct {
|
||||||
c net.Conn
|
c io.ReadWriter
|
||||||
cfg *ServerConfig
|
cfg *ServerConfig
|
||||||
br *bufio.Reader
|
//br *bufio.Reader
|
||||||
bw *bufio.Writer
|
//bw *bufio.Writer
|
||||||
protocol string
|
protocol string
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
// If the pixel format uses a color map, then this is the color
|
// If the pixel format uses a color map, then this is the color
|
||||||
@ -41,11 +40,11 @@ type ServerConn struct {
|
|||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerConn) UnreadByte() error {
|
// func (c *ServerConn) UnreadByte() error {
|
||||||
return c.br.UnreadByte()
|
// return c.br.UnreadByte()
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *ServerConn) Conn() net.Conn {
|
func (c *ServerConn) Conn() io.ReadWriter {
|
||||||
return c.c
|
return c.c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,14 +65,14 @@ func (c *ServerConn) SetProtoVersion(pv string) {
|
|||||||
c.protocol = pv
|
c.protocol = pv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerConn) Flush() error {
|
// func (c *ServerConn) Flush() error {
|
||||||
// c.m.Lock()
|
// // c.m.Lock()
|
||||||
// defer c.m.Unlock()
|
// // defer c.m.Unlock()
|
||||||
return c.bw.Flush()
|
// return c.bw.Flush()
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *ServerConn) Close() error {
|
func (c *ServerConn) Close() error {
|
||||||
return c.c.Close()
|
return c.c.(io.ReadWriteCloser).Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -86,13 +85,13 @@ func (c *ServerConn) Output() chan *ClientMessage {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
func (c *ServerConn) Read(buf []byte) (int, error) {
|
func (c *ServerConn) Read(buf []byte) (int, error) {
|
||||||
return c.br.Read(buf)
|
return c.c.Read(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerConn) Write(buf []byte) (int, error) {
|
func (c *ServerConn) Write(buf []byte) (int, error) {
|
||||||
// c.m.Lock()
|
// c.m.Lock()
|
||||||
// defer c.m.Unlock()
|
// defer c.m.Unlock()
|
||||||
return c.bw.Write(buf)
|
return c.c.Write(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerConn) ColorMap() *common.ColorMap {
|
func (c *ServerConn) ColorMap() *common.ColorMap {
|
||||||
|
380
server/server.go
380
server/server.go
@ -1,12 +1,12 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ type ServerConfig struct {
|
|||||||
Width uint16
|
Width uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
|
func newServerConn(c io.ReadWriter, cfg *ServerConfig) (*ServerConn, error) {
|
||||||
if cfg.ClientMessageCh == nil {
|
if cfg.ClientMessageCh == nil {
|
||||||
return nil, fmt.Errorf("ClientMessageCh nil")
|
return nil, fmt.Errorf("ClientMessageCh nil")
|
||||||
}
|
}
|
||||||
@ -81,9 +81,9 @@ func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &ServerConn{
|
return &ServerConn{
|
||||||
c: c,
|
c: c,
|
||||||
br: bufio.NewReader(c),
|
//br: bufio.NewReader(c),
|
||||||
bw: bufio.NewWriter(c),
|
//bw: bufio.NewWriter(c),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
encodings: cfg.Encodings,
|
encodings: cfg.Encodings,
|
||||||
@ -92,275 +92,137 @@ func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
|
|||||||
fbHeight: cfg.Height,
|
fbHeight: cfg.Height,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
func wsHandlerFunc(ws io.ReadWriter, cfg *ServerConfig) {
|
||||||
|
// 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)
|
||||||
|
|
||||||
func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
|
err := attachNewServerConn(ws, cfg)
|
||||||
for {
|
if err != nil {
|
||||||
|
log.Fatalf("Error attaching new connection. %v", err)
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := NewServerConn(c, cfg)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ServerVersionHandler(cfg, conn); err != nil {
|
|
||||||
conn.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ServerSecurityHandler(cfg, conn); err != nil {
|
|
||||||
conn.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ServerClientInitHandler(cfg, conn); err != nil {
|
|
||||||
conn.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ServerServerInitHandler(cfg, conn); err != nil {
|
|
||||||
conn.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go conn.Handle()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerConn) Handle() error {
|
func WsServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||||
//var err error
|
//server := WsServer1{cfg}
|
||||||
var wg sync.WaitGroup
|
server := WsServer{cfg}
|
||||||
|
server.Listen(url, WsHandler(wsHandlerFunc))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
defer c.Close()
|
func TcpServe(url string, ctx context.Context, cfg *ServerConfig) error {
|
||||||
|
ln, err := net.Listen("tcp", ":5903")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error listen. %v", err)
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
c, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go attachNewServerConn(c, cfg)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig) error {
|
||||||
|
|
||||||
|
conn, err := newServerConn(c, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ServerVersionHandler(cfg, conn); err != nil {
|
||||||
|
fmt.Errorf("err: %v\n", err)
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ServerSecurityHandler(cfg, conn); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ServerClientInitHandler(cfg, conn); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ServerServerInitHandler(cfg, conn); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//go
|
||||||
|
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
|
//create a map of all message types
|
||||||
clientMessages := make(map[common.ClientMessageType]common.ClientMessage)
|
clientMessages := make(map[common.ClientMessageType]common.ClientMessage)
|
||||||
for _, m := range c.cfg.ClientMessages {
|
for _, m := range c.cfg.ClientMessages {
|
||||||
clientMessages[m.Type()] = m
|
clientMessages[m.Type()] = m
|
||||||
}
|
}
|
||||||
wg.Add(2)
|
//wg.Add(2)
|
||||||
|
|
||||||
// server
|
// server
|
||||||
go func() error {
|
// go func() error {
|
||||||
defer wg.Done()
|
// defer wg.Done()
|
||||||
for {
|
// for {
|
||||||
select {
|
// select {
|
||||||
case msg := <-c.cfg.ServerMessageCh:
|
// case msg := <-c.cfg.ServerMessageCh:
|
||||||
fmt.Printf("%v", msg)
|
// fmt.Printf("%v", msg)
|
||||||
// if err = msg.Write(c); err != nil {
|
// // if err = msg.Write(c); err != nil {
|
||||||
// return err
|
// // return err
|
||||||
// }
|
// // }
|
||||||
case <-c.quit:
|
// case <-c.quit:
|
||||||
return nil
|
// c.Close()
|
||||||
}
|
// return nil
|
||||||
}
|
// }
|
||||||
}()
|
// }
|
||||||
|
// }()
|
||||||
|
|
||||||
// client
|
// client
|
||||||
go func() error {
|
//go func() error {
|
||||||
defer wg.Done()
|
//defer wg.Done()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-c.quit:
|
case <-c.quit:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
var messageType common.ClientMessageType
|
var messageType common.ClientMessageType
|
||||||
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
||||||
return err
|
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
|
|
||||||
}
|
}
|
||||||
|
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()
|
//wg.Wait()
|
||||||
return nil
|
//return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// type ServerCutText struct {
|
|
||||||
// _ [1]byte
|
|
||||||
// Length uint32
|
|
||||||
// Text []byte
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*ServerCutText) Type() ServerMessageType {
|
|
||||||
// return ServerCutTextMsgType
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*ServerCutText) Read(c common.Conn) (common.ServerMessage, error) {
|
|
||||||
// msg := ServerCutText{}
|
|
||||||
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &msg.Length); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// msg.Text = make([]byte, msg.Length)
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &msg.Text); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return &msg, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (msg *ServerCutText) Write(c common.Conn) error {
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if msg.Length < uint32(len(msg.Text)) {
|
|
||||||
// msg.Length = uint32(len(msg.Text))
|
|
||||||
// }
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.Length); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.Text); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type Bell struct{}
|
|
||||||
|
|
||||||
// func (*Bell) Type() ServerMessageType {
|
|
||||||
// return BellMsgType
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*Bell) Read(c common.Conn) (common.ServerMessage, error) {
|
|
||||||
// return &Bell{}, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (msg *Bell) Write(c common.Conn) error {
|
|
||||||
// return binary.Write(c, binary.BigEndian, msg.Type())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type SetColorMapEntries struct {
|
|
||||||
// _ [1]byte
|
|
||||||
// FirstColor uint16
|
|
||||||
// ColorsNum uint16
|
|
||||||
// Colors []common.Color
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*SetColorMapEntries) Type() ServerMessageType {
|
|
||||||
// return SetColorMapEntriesMsgType
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*SetColorMapEntries) Read(c common.Conn) (common.ServerMessage, error) {
|
|
||||||
// msg := SetColorMapEntries{}
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &msg.FirstColor); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &msg.ColorsNum); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// msg.Colors = make([]common.Color, msg.ColorsNum)
|
|
||||||
// colorMap := c.ColorMap()
|
|
||||||
|
|
||||||
// for i := uint16(0); i < msg.ColorsNum; i++ {
|
|
||||||
// color := &msg.Colors[i]
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &color); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// colorMap[msg.FirstColor+i] = *color
|
|
||||||
// }
|
|
||||||
// c.SetColorMap(colorMap)
|
|
||||||
// return &msg, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (msg *SetColorMapEntries) Write(c common.Conn) error {
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, &pad); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.FirstColor); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if msg.ColorsNum < uint16(len(msg.Colors)) {
|
|
||||||
// msg.ColorsNum = uint16(len(msg.Colors))
|
|
||||||
// }
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.ColorsNum); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for i := 0; i < len(msg.Colors); i++ {
|
|
||||||
// color := msg.Colors[i]
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, color); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (*FramebufferUpdate) Read(cliInfo common.IClientConn, c *common.RfbReadHelper) (common.ServerMessage, error) {
|
|
||||||
// msg := FramebufferUpdate{}
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// for i := uint16(0); i < msg.NumRect; i++ {
|
|
||||||
// rect := &common.Rectangle{}
|
|
||||||
// if err := rect.Read(c); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// msg.Rects = append(msg.Rects, rect)
|
|
||||||
// }
|
|
||||||
// return &msg, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (msg *FramebufferUpdate) Write(c common.Conn) error {
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// var pad [1]byte
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if err := binary.Write(c, binary.BigEndian, msg.NumRect); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// for _, rect := range msg.Rects {
|
|
||||||
// if err := rect.Write(c); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return c.Flush()
|
|
||||||
// }
|
|
||||||
|
@ -3,24 +3,19 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
|
||||||
"testing"
|
"testing"
|
||||||
"vncproxy/common"
|
"vncproxy/common"
|
||||||
"vncproxy/encodings"
|
"vncproxy/encodings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestServer(t *testing.T) {
|
func TestServer(t *testing.T) {
|
||||||
ln, err := net.Listen("tcp", ":5903")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error listen. %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
chServer := make(chan common.ClientMessage)
|
chServer := make(chan common.ClientMessage)
|
||||||
chClient := make(chan common.ServerMessage)
|
chClient := make(chan common.ServerMessage)
|
||||||
|
|
||||||
cfg := &ServerConfig{
|
cfg := &ServerConfig{
|
||||||
//SecurityHandlers: []SecurityHandler{&ServerAuthNone{}, &ServerAuthVNC{}},
|
//SecurityHandlers: []SecurityHandler{&ServerAuthNone{}, &ServerAuthVNC{}},
|
||||||
SecurityHandlers: []SecurityHandler{&ServerAuthVNC{}},
|
SecurityHandlers: []SecurityHandler{&ServerAuthVNC{"Ch_#!T@8"}},
|
||||||
Encodings: []common.Encoding{&encodings.RawEncoding{}, &encodings.TightEncoding{}, &encodings.CopyRectEncoding{}},
|
Encodings: []common.Encoding{&encodings.RawEncoding{}, &encodings.TightEncoding{}, &encodings.CopyRectEncoding{}},
|
||||||
PixelFormat: common.NewPixelFormat(32),
|
PixelFormat: common.NewPixelFormat(32),
|
||||||
ClientMessageCh: chServer,
|
ClientMessageCh: chServer,
|
||||||
@ -29,10 +24,10 @@ func TestServer(t *testing.T) {
|
|||||||
DesktopName: []byte("workDesk"),
|
DesktopName: []byte("workDesk"),
|
||||||
Height: uint16(768),
|
Height: uint16(768),
|
||||||
Width: uint16(1024),
|
Width: uint16(1024),
|
||||||
|
|
||||||
}
|
}
|
||||||
go Serve(context.Background(), ln, cfg)
|
url := "http://localhost:8091/"
|
||||||
|
go WsServe(url, context.Background(), cfg)
|
||||||
|
go TcpServe(":5903", context.Background(), cfg)
|
||||||
// Process messages coming in on the ClientMessage channel.
|
// Process messages coming in on the ClientMessage channel.
|
||||||
for {
|
for {
|
||||||
msg := <-chClient
|
msg := <-chClient
|
||||||
|
43
server/ws-server-go.go
Normal file
43
server/ws-server-go.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"golang.org/x/net/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WsServer struct {
|
||||||
|
cfg *ServerConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsHandler func(io.ReadWriter, *ServerConfig)
|
||||||
|
|
||||||
|
// This example demonstrates a trivial echo server.
|
||||||
|
func (wsServer *WsServer) Listen(urlStr string, handlerFunc WsHandler) {
|
||||||
|
//http.Handle("/", websocket.Handler(EchoHandler))
|
||||||
|
if urlStr == "" {
|
||||||
|
urlStr = "/"
|
||||||
|
}
|
||||||
|
url, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
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)
|
||||||
|
}))
|
||||||
|
|
||||||
|
err = http.ListenAndServe(url.Host, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic("ListenAndServe: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
104
server/ws-server-gorilla.go
Normal file
104
server/ws-server-gorilla.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WsServer1 struct {
|
||||||
|
cfg *ServerConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsHandler1 func(io.ReadWriter, *ServerConfig)
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
|
return true
|
||||||
|
}}
|
||||||
|
|
||||||
|
type WsConnection struct {
|
||||||
|
Reader WsReader
|
||||||
|
Writer WsWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWsConnection(c *websocket.Conn) *WsConnection {
|
||||||
|
return &WsConnection{
|
||||||
|
WsReader{},
|
||||||
|
WsWriter{c},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsWriter struct {
|
||||||
|
conn *websocket.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsReader struct {
|
||||||
|
Buff bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wr WsReader) Read(p []byte) (n int, err error) {
|
||||||
|
return wr.Buff.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wr WsWriter) Write(p []byte) (int, error) {
|
||||||
|
err := wr.conn.WriteMessage(websocket.BinaryMessage, p)
|
||||||
|
return len(p), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleConnection(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Print("got connection:", r.URL)
|
||||||
|
c, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Print("upgrade:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
myConn := NewWsConnection(c)
|
||||||
|
|
||||||
|
for {
|
||||||
|
mt, message, err := c.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("read:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if mt == websocket.BinaryMessage {
|
||||||
|
myConn.Reader.Buff.Write(message)
|
||||||
|
}
|
||||||
|
log.Printf("recv: %s", message)
|
||||||
|
// err = c.WriteMessage(mt, message)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Println("write:", err)
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This example demonstrates a trivial echo server.
|
||||||
|
func (wsServer *WsServer1) Listen(urlStr string, handlerFunc WsHandler) {
|
||||||
|
//http.Handle("/", websocket.Handler(EchoHandler))
|
||||||
|
if urlStr == "" {
|
||||||
|
urlStr = "/"
|
||||||
|
}
|
||||||
|
url, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error while parsing url: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc(url.Path, handleConnection)
|
||||||
|
|
||||||
|
err = http.ListenAndServe(url.Host, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic("ListenAndServe: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
33
server/ws_test.go
Normal file
33
server/ws_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// "io"
|
||||||
|
// "net/http"
|
||||||
|
// "testing"
|
||||||
|
|
||||||
|
// "golang.org/x/net/websocket"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func TestWsServer(t *testing.T) {
|
||||||
|
// server := WsServer{}
|
||||||
|
// server.Listen(":8090")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Echo the data received on the WebSocket.
|
||||||
|
// func EchoHandler(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)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // This example demonstrates a trivial echo server.
|
||||||
|
// func TestGoWsServer(t *testing.T) {
|
||||||
|
// http.Handle("/", websocket.Handler(EchoHandler))
|
||||||
|
// err := http.ListenAndServe(":11111", nil)
|
||||||
|
// if err != nil {
|
||||||
|
// panic("ListenAndServe: " + err.Error())
|
||||||
|
// }
|
||||||
|
// }
|
10
vncproxy.iml
Normal file
10
vncproxy.iml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="GOPATH <vncproxy>" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
Loading…
Reference in New Issue
Block a user