From 29d4b276e6fb39b1a143c44986932d9cf523931f Mon Sep 17 00:00:00 2001
From: Bolke de Bruin <bolke@xs4all.nl>
Date: Wed, 29 Jul 2020 18:55:47 +0200
Subject: [PATCH] Add tunnelauth tests

---
 protocol/client.go       | 34 ++++++++++++++++++++++++++++++
 protocol/handler_test.go | 45 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

diff --git a/protocol/client.go b/protocol/client.go
index 73aadf3..f6665fb 100644
--- a/protocol/client.go
+++ b/protocol/client.go
@@ -112,5 +112,39 @@ func (c *ClientConfig) tunnelResponse(data []byte) (tunnelId uint32, caps uint32
 		err = fmt.Errorf("tunnel error %d", errorCode)
 	}
 
+	return
+}
+
+func (c *ClientConfig) tunnelAuthRequest(name string) []byte {
+	utf16name := EncodeUTF16(name)
+	size := uint16(len(utf16name))
+
+	buf := new(bytes.Buffer)
+	binary.Write(buf, binary.LittleEndian, size)
+	buf.Write(utf16name)
+
+	return createPacket(PKT_TYPE_TUNNEL_AUTH, buf.Bytes())
+}
+
+func (c *ClientConfig) tunnelAuthResponse(data []byte) (flags uint32, timeout uint32, err error) {
+	var errorCode uint32
+	var fields uint16
+
+	r := bytes.NewReader(data)
+	binary.Read(r, binary.LittleEndian, &errorCode)
+	binary.Read(r, binary.LittleEndian, &fields)
+	r.Seek(2, io.SeekCurrent)
+
+	if (fields & HTTP_TUNNEL_AUTH_RESPONSE_FIELD_REDIR_FLAGS) == HTTP_TUNNEL_AUTH_RESPONSE_FIELD_REDIR_FLAGS {
+		binary.Read(r, binary.LittleEndian, &flags)
+	}
+	if (fields & HTTP_TUNNEL_AUTH_RESPONSE_FIELD_IDLE_TIMEOUT) == HTTP_TUNNEL_AUTH_RESPONSE_FIELD_IDLE_TIMEOUT {
+		binary.Read(r, binary.LittleEndian, &timeout)
+	}
+
+	if errorCode > 0 {
+		return 0, 0, fmt.Errorf("tunnel auth error %d", errorCode)
+	}
+
 	return
 }
\ No newline at end of file
diff --git a/protocol/handler_test.go b/protocol/handler_test.go
index 18308cb..bfbbf7c 100644
--- a/protocol/handler_test.go
+++ b/protocol/handler_test.go
@@ -12,6 +12,8 @@ const (
 	HandshakeResponseLen = HeaderLen + 10
 	TunnelCreateRequestLen = HeaderLen + 8 // + dynamic
 	TunnelCreateResponseLen = HeaderLen + 18
+	TunnelAuthLen = HeaderLen + 2 // + dynamic
+	TunnelAuthResponseLen = HeaderLen + 16
 )
 
 func verifyPacketHeader(data []byte , expPt uint16, expSize uint32) (uint16, uint32, []byte, error) {
@@ -113,4 +115,47 @@ func TestTunnelCreation(t *testing.T) {
 	if !((caps & HTTP_CAPABILITY_IDLE_TIMEOUT) == HTTP_CAPABILITY_IDLE_TIMEOUT) {
 		t.Fatalf("tunnelResponse failed got caps %d, expected %d", caps, caps | HTTP_CAPABILITY_IDLE_TIMEOUT)
 	}
+}
+
+func TestTunnelAuth(t *testing.T) {
+	client := ClientConfig{}
+	s := &SessionInfo{}
+	hc := &HandlerConf{
+		TokenAuth: true,
+		IdleTimeout: 10,
+		RedirectFlags: RedirectFlags{
+			Clipboard: true,
+		},
+	}
+	h := NewHandler(s, hc)
+	name := "test_name"
+
+	data := client.tunnelAuthRequest(name)
+	_, _, pkt, err := verifyPacketHeader(data, PKT_TYPE_TUNNEL_AUTH, uint32(TunnelAuthLen + len(name) * 2))
+	if err != nil {
+		t.Fatalf("verifyHeader failed: %s", err)
+	}
+
+	n := h.readTunnelAuthRequest(pkt)
+	if n != name {
+		t.Fatalf("readTunnelAuthRequest failed got name %s, expected %s", n, name)
+	}
+
+	data = h.createTunnelAuthResponse()
+	_, _, pkt, err = verifyPacketHeader(data, PKT_TYPE_TUNNEL_AUTH_RESPONSE, TunnelAuthResponseLen)
+	if err != nil {
+		t.Fatalf("verifyHeader failed: %s", err)
+	}
+	flags, timeout, err := client.tunnelAuthResponse(pkt)
+	if err != nil {
+		t.Fatalf("tunnel auth error %s", err)
+	}
+	if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD) == HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD {
+		t.Fatalf("tunnelAuthResponse failed got flags %d, expected %d",
+			flags, flags | HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
+	}
+	if int(timeout) != hc.IdleTimeout {
+		t.Fatalf("tunnelAuthResponse failed got timeout %d, expected %d",
+			timeout, hc.IdleTimeout)
+	}
 }
\ No newline at end of file
-- 
GitLab