1package stun
2
3import (
4	"net"
5	"testing"
6)
7
8func TestRFC5769(t *testing.T) {
9	// Test Vectors for Session Traversal Utilities for NAT (STUN)
10	// see https://tools.ietf.org/html/rfc5769
11	t.Run("Request", func(t *testing.T) {
12		m := &Message{
13			Raw: []byte("\x00\x01\x00\x58" +
14				"\x21\x12\xa4\x42" +
15				"\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" +
16				"\x80\x22\x00\x10" +
17				"STUN test client" +
18				"\x00\x24\x00\x04" +
19				"\x6e\x00\x01\xff" +
20				"\x80\x29\x00\x08" +
21				"\x93\x2f\xf9\xb1\x51\x26\x3b\x36" +
22				"\x00\x06\x00\x09" +
23				"\x65\x76\x74\x6a\x3a\x68\x36\x76\x59\x20\x20\x20" +
24				"\x00\x08\x00\x14" +
25				"\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" +
26				"\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" +
27				"\x80\x28\x00\x04" +
28				"\xe5\x7a\x3b\xcf",
29			),
30		}
31		if err := m.Decode(); err != nil {
32			t.Error(err)
33		}
34		software := new(Software)
35		if err := software.GetFrom(m); err != nil {
36			t.Error(err)
37		}
38		if software.String() != "STUN test client" {
39			t.Error("bad software: ", software)
40		}
41		if err := Fingerprint.Check(m); err != nil {
42			t.Error("check failed: ", err)
43		}
44		t.Run("Long-Term credentials", func(t *testing.T) {
45			m := &Message{
46				Raw: []byte("\x00\x01\x00\x60" +
47					"\x21\x12\xa4\x42" +
48					"\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" +
49					"\x00\x06\x00\x12" +
50					"\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" +
51					"\xe3\x82\xaf\xe3\x82\xb9\x00\x00" +
52					"\x00\x15\x00\x1c" +
53					"\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" +
54					"\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" +
55					"\x36\x34\x73\x41" +
56					"\x00\x14\x00\x0b" +
57					"\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" +
58					"\x00\x08\x00\x14" +
59					"\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" +
60					"\x2e\x85\xc9\xa2\x8c\xa8\x96\x66",
61				),
62			}
63			if err := m.Decode(); err != nil {
64				t.Error(err)
65			}
66			u := new(Username)
67			if err := u.GetFrom(m); err != nil {
68				t.Error(err)
69			}
70			expectedUsername := "\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9"
71			if u.String() != expectedUsername {
72				t.Errorf("username: %q (got) != %q (exp)", u, expectedUsername)
73			}
74			n := new(Nonce)
75			if err := n.GetFrom(m); err != nil {
76				t.Error(err)
77			}
78			if n.String() != "f//499k954d6OL34oL9FSTvy64sA" {
79				t.Error("bad nonce")
80			}
81			r := new(Realm)
82			if err := r.GetFrom(m); err != nil {
83				t.Error(err)
84			}
85			if r.String() != "example.org" {
86				t.Error("bad realm")
87			}
88			// checking HMAC
89			i := NewLongTermIntegrity(
90				"\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9",
91				"example.org",
92				"TheMatrIX",
93			)
94			if err := i.Check(m); err != nil {
95				t.Error(err)
96			}
97		})
98	})
99	t.Run("Response", func(t *testing.T) {
100		t.Run("IPv4", func(t *testing.T) {
101			m := &Message{
102				Raw: []byte("\x01\x01\x00\x3c" +
103					"\x21\x12\xa4\x42" +
104					"\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" +
105					"\x80\x22\x00\x0b" +
106					"\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" +
107					"\x00\x20\x00\x08" +
108					"\x00\x01\xa1\x47\xe1\x12\xa6\x43" +
109					"\x00\x08\x00\x14" +
110					"\x2b\x91\xf5\x99\xfd\x9e\x90\xc3\x8c\x74\x89\xf9" +
111					"\x2a\xf9\xba\x53\xf0\x6b\xe7\xd7" +
112					"\x80\x28\x00\x04" +
113					"\xc0\x7d\x4c\x96",
114				),
115			}
116			if err := m.Decode(); err != nil {
117				t.Error(err)
118			}
119			software := new(Software)
120			if err := software.GetFrom(m); err != nil {
121				t.Error(err)
122			}
123			if software.String() != "test vector" {
124				t.Error("bad software: ", software)
125			}
126			if err := Fingerprint.Check(m); err != nil {
127				t.Error("Check failed: ", err)
128			}
129			addr := new(XORMappedAddress)
130			if err := addr.GetFrom(m); err != nil {
131				t.Error(err)
132			}
133			if !addr.IP.Equal(net.ParseIP("192.0.2.1")) {
134				t.Error("bad IP")
135			}
136			if addr.Port != 32853 {
137				t.Error("bad Port")
138			}
139			if err := Fingerprint.Check(m); err != nil {
140				t.Error("check failed: ", err)
141			}
142		})
143		t.Run("IPv6", func(t *testing.T) {
144			m := &Message{
145				Raw: []byte("\x01\x01\x00\x48" +
146					"\x21\x12\xa4\x42" +
147					"\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" +
148					"\x80\x22\x00\x0b" +
149					"\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" +
150					"\x00\x20\x00\x14" +
151					"\x00\x02\xa1\x47" +
152					"\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" +
153					"\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" +
154					"\x00\x08\x00\x14" +
155					"\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" +
156					"\x82\x92\xc2\x75\xbf\xe3\xed\x41" +
157					"\x80\x28\x00\x04" +
158					"\xc8\xfb\x0b\x4c",
159				),
160			}
161			if err := m.Decode(); err != nil {
162				t.Error(err)
163			}
164			software := new(Software)
165			if err := software.GetFrom(m); err != nil {
166				t.Error(err)
167			}
168			if software.String() != "test vector" {
169				t.Error("bad software: ", software)
170			}
171			if err := Fingerprint.Check(m); err != nil {
172				t.Error("Check failed: ", err)
173			}
174			addr := new(XORMappedAddress)
175			if err := addr.GetFrom(m); err != nil {
176				t.Error(err)
177			}
178			if !addr.IP.Equal(net.ParseIP("2001:db8:1234:5678:11:2233:4455:6677")) {
179				t.Error("bad IP")
180			}
181			if addr.Port != 32853 {
182				t.Error("bad Port")
183			}
184			if err := Fingerprint.Check(m); err != nil {
185				t.Error("check failed: ", err)
186			}
187		})
188	})
189}
190