Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 0259517

Browse files
committed
Added VNC standard DES authentication
1 parent 03f3462 commit 0259517

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

client_auth_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ func TestClientAuthNone_Impl(t *testing.T) {
99
t.Fatal("ClientAuthNone doesn't implement ClientAuth")
1010
}
1111
}
12+
13+
func TestClientAuthVNC_Impl(t *testing.T) {
14+
var raw interface{}
15+
raw = new(ClientAuthVNC)
16+
if _, ok := raw.(ClientAuth); !ok {
17+
t.Fatal("ClientAuthVNC doesn't implement ClientAuth")
18+
}
19+
}

client_auth_vnc.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package vnc
2+
3+
import (
4+
"crypto/des"
5+
"encoding/binary"
6+
"net"
7+
)
8+
9+
// ClientAuthVNC is the standard password authentication
10+
type ClientAuthVNC struct {
11+
Password string
12+
}
13+
14+
func (*ClientAuthVNC) SecurityType() uint8 {
15+
return 2
16+
}
17+
18+
func (auth *ClientAuthVNC) Handshake(conn net.Conn) error {
19+
// Read challenge block
20+
var challenge [16]byte
21+
if err := binary.Read(conn, binary.BigEndian, &challenge); err != nil {
22+
return err
23+
}
24+
25+
// Copy password string to 8 byte 0-padded slice
26+
key := make([]byte, 8)
27+
copy(key, auth.Password)
28+
29+
// Each byte of the password needs to be reversed. This is a
30+
// non RFC-documented behaviour of VNC clients and servers
31+
for i := range key {
32+
key[i] = (key[i]&0x55)<<1 | (key[i]&0xAA)>>1 // Swap adjacent bits
33+
key[i] = (key[i]&0x33)<<2 | (key[i]&0xCC)>>2 // Swap adjacent pairs
34+
key[i] = (key[i]&0x0F)<<4 | (key[i]&0xF0)>>4 // Swap the 2 halves
35+
}
36+
37+
cipher, err := des.NewCipher(key)
38+
if err != nil {
39+
return err
40+
}
41+
42+
// Encrypt the challenge low 8 bytes then high 8 bytes
43+
challengeLow := challenge[0:8]
44+
challengeHigh := challenge[8:16]
45+
cipher.Encrypt(challengeLow, challengeLow)
46+
cipher.Encrypt(challengeHigh, challengeHigh)
47+
48+
// Send the encrypted challenge back to server
49+
err = binary.Write(conn, binary.BigEndian, challenge)
50+
if err != nil {
51+
return err
52+
}
53+
54+
return nil
55+
}

0 commit comments

Comments
 (0)