main
1package rfb
2
3import (
4 "encoding/hex"
5 "testing"
6)
7
8func TestReverseBits(t *testing.T) {
9 tests := []struct {
10 input byte
11 want byte
12 }{
13 {0x00, 0x00},
14 {0xFF, 0xFF},
15 {0x01, 0x80},
16 {0x80, 0x01},
17 {0x0F, 0xF0},
18 {0xF0, 0x0F},
19 {0xAA, 0x55}, // 10101010 -> 01010101
20 {0x55, 0xAA}, // 01010101 -> 10101010
21 }
22
23 for _, tt := range tests {
24 got := reverseBits(tt.input)
25 if got != tt.want {
26 t.Errorf("reverseBits(%02x) = %02x, want %02x", tt.input, got, tt.want)
27 }
28 }
29}
30
31func TestVNCAuthEncrypt(t *testing.T) {
32 // Known test vectors for VNC authentication
33 // Challenge is 16 random bytes from server
34 // Password is converted to 8-byte key with reversed bits
35 // Then DES-ECB encrypt the challenge
36
37 // Test with empty password (all zeros key)
38 challenge := make([]byte, 16)
39 for i := range challenge {
40 challenge[i] = byte(i)
41 }
42
43 response := vncAuthEncrypt(challenge, "")
44 if len(response) != 16 {
45 t.Errorf("response length = %d, want 16", len(response))
46 }
47
48 // Test with a known password
49 // The response should be deterministic
50 response1 := vncAuthEncrypt(challenge, "password")
51 response2 := vncAuthEncrypt(challenge, "password")
52
53 if hex.EncodeToString(response1) != hex.EncodeToString(response2) {
54 t.Error("vncAuthEncrypt should be deterministic")
55 }
56
57 // Different passwords should produce different responses
58 response3 := vncAuthEncrypt(challenge, "different")
59 if hex.EncodeToString(response1) == hex.EncodeToString(response3) {
60 t.Error("different passwords should produce different responses")
61 }
62}
63
64func TestParseServerInit(t *testing.T) {
65 // Build a valid ServerInit message
66 // width(2) + height(2) + pixel_format(16) + name_len(4) + name
67 data := make([]byte, 24+4) // minimum + "test"
68 data[0] = 0x07 // width high byte
69 data[1] = 0x80 // width low byte (1920)
70 data[2] = 0x04 // height high byte
71 data[3] = 0x38 // height low byte (1080)
72 // pixel format at data[4:20]
73 data[4] = 32 // bits per pixel
74 data[5] = 24 // depth
75 data[6] = 0 // big endian (false)
76 data[7] = 1 // true colour
77 data[8] = 0 // red max high
78 data[9] = 255 // red max low
79 // ... rest of pixel format
80 data[20] = 0 // name len high bytes
81 data[21] = 0
82 data[22] = 0
83 data[23] = 4 // name len = 4
84 data[24] = 't'
85 data[25] = 'e'
86 data[26] = 's'
87 data[27] = 't'
88
89 session, err := ParseServerInit(data)
90 if err != nil {
91 t.Fatalf("ParseServerInit() error = %v", err)
92 }
93
94 if session.Width != 1920 {
95 t.Errorf("Width = %d, want 1920", session.Width)
96 }
97 if session.Height != 1080 {
98 t.Errorf("Height = %d, want 1080", session.Height)
99 }
100 if session.Name != "test" {
101 t.Errorf("Name = %q, want %q", session.Name, "test")
102 }
103 if session.PixelFormat.BitsPerPixel != 32 {
104 t.Errorf("BitsPerPixel = %d, want 32", session.PixelFormat.BitsPerPixel)
105 }
106}
107
108func TestParseServerInitTooShort(t *testing.T) {
109 data := make([]byte, 10) // too short
110 _, err := ParseServerInit(data)
111 if err == nil {
112 t.Error("ParseServerInit() should fail with short data")
113 }
114}