Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #include "core/or/or.h"
7 : #include "lib/buf/buffers.h"
8 : #include "app/config/config.h"
9 : #include "core/mainloop/connection.h"
10 : #include "core/proto/proto_socks.h"
11 : #include "test/test.h"
12 : #include "test/log_test_helpers.h"
13 : #include "core/or/socks_request_st.h"
14 : #include "lib/net/socks5_status.h"
15 :
16 : typedef struct socks_test_data_t {
17 : socks_request_t *req;
18 : buf_t *buf;
19 : } socks_test_data_t;
20 :
21 : static void *
22 16 : socks_test_setup(const struct testcase_t *testcase)
23 : {
24 16 : socks_test_data_t *data = tor_malloc(sizeof(socks_test_data_t));
25 16 : (void)testcase;
26 16 : data->buf = buf_new_with_capacity(256);
27 16 : data->req = socks_request_new();
28 16 : config_register_addressmaps(get_options());
29 16 : return data;
30 : }
31 : static int
32 16 : socks_test_cleanup(const struct testcase_t *testcase, void *ptr)
33 : {
34 16 : socks_test_data_t *data = ptr;
35 16 : (void)testcase;
36 16 : buf_free(data->buf);
37 16 : socks_request_free(data->req);
38 16 : tor_free(data);
39 16 : return 1;
40 : }
41 :
42 : static const struct testcase_setup_t socks_setup = {
43 : socks_test_setup, socks_test_cleanup
44 : };
45 :
46 : #define SOCKS_TEST_INIT() \
47 : socks_test_data_t *testdata = ptr; \
48 : buf_t *buf = testdata->buf; \
49 : socks_request_t *socks = testdata->req;
50 : #define ADD_DATA(buf, s) \
51 : buf_add(buf, s, sizeof(s)-1)
52 :
53 : static void
54 17 : socks_request_clear(socks_request_t *socks)
55 : {
56 17 : tor_free(socks->username);
57 17 : tor_free(socks->password);
58 17 : memset(socks, 0, sizeof(socks_request_t));
59 : }
60 :
61 : /** Perform unsupported SOCKS 4 commands */
62 : static void
63 1 : test_socks_4_unsupported_commands(void *ptr)
64 : {
65 1 : SOCKS_TEST_INIT();
66 :
67 : /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
68 1 : ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
69 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
70 : get_options()->SafeSocks),
71 : OP_EQ, -1);
72 1 : tt_int_op(4,OP_EQ, socks->socks_version);
73 1 : tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
74 :
75 1 : done:
76 1 : ;
77 1 : }
78 :
79 : /** Perform supported SOCKS 4 commands */
80 : static void
81 1 : test_socks_4_supported_commands(void *ptr)
82 : {
83 1 : SOCKS_TEST_INIT();
84 :
85 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
86 :
87 : /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.3:4370 */
88 1 : ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
89 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
90 : get_options()->SafeSocks),
91 : OP_EQ, 1);
92 1 : tt_int_op(4,OP_EQ, socks->socks_version);
93 1 : tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
94 1 : tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
95 1 : tt_str_op("2.2.2.3",OP_EQ, socks->address);
96 1 : tt_int_op(4370,OP_EQ, socks->port);
97 1 : tt_assert(socks->got_auth == 0);
98 1 : tt_assert(! socks->username);
99 :
100 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
101 1 : socks_request_clear(socks);
102 :
103 : /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.4:4369 with userid*/
104 1 : ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
105 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
106 : OP_EQ, 1);
107 1 : tt_int_op(4,OP_EQ, socks->socks_version);
108 1 : tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
109 1 : tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
110 1 : tt_str_op("2.2.2.4",OP_EQ, socks->address);
111 1 : tt_int_op(4370,OP_EQ, socks->port);
112 1 : tt_assert(socks->got_auth == 1);
113 1 : tt_assert(socks->username);
114 1 : tt_int_op(2,OP_EQ, socks->usernamelen);
115 1 : tt_mem_op("me",OP_EQ, socks->username, 2);
116 :
117 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
118 1 : socks_request_clear(socks);
119 :
120 : /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
121 1 : ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
122 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1,
123 : get_options()->SafeSocks),
124 : OP_EQ, 1);
125 1 : tt_int_op(4,OP_EQ, socks->socks_version);
126 1 : tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
127 1 : tt_str_op("torproject.org",OP_EQ, socks->address);
128 :
129 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
130 :
131 1 : done:
132 1 : ;
133 1 : }
134 :
135 : static void
136 1 : test_socks_4_bad_arguments(void *ptr)
137 : {
138 1 : SOCKS_TEST_INIT();
139 1 : setup_capture_of_logs(LOG_DEBUG);
140 :
141 : /* Try with 0 IPv4 address */
142 1 : ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x00\x00");
143 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
144 : get_options()->SafeSocks),
145 : OP_EQ, -1);
146 1 : buf_clear(buf);
147 1 : expect_log_msg_containing("Port or DestIP is zero.");
148 1 : mock_clean_saved_logs();
149 :
150 : /* Try with 0 port */
151 1 : ADD_DATA(buf, "\x04\x01\x00\x00\x01\x02\x03\x04\x00");
152 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
153 : get_options()->SafeSocks),
154 : OP_EQ, -1);
155 1 : buf_clear(buf);
156 1 : expect_log_msg_containing("Port or DestIP is zero.");
157 1 : mock_clean_saved_logs();
158 :
159 : /* Try with 2000-byte username (!) */
160 1 : ADD_DATA(buf, "\x04\x01\x00\x50\x01\x02\x03\x04");
161 1 : int i;
162 202 : for (i = 0; i < 200; ++i) {
163 200 : ADD_DATA(buf, "1234567890");
164 : }
165 1 : ADD_DATA(buf, "\x00");
166 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
167 : OP_EQ, -1);
168 1 : buf_clear(buf);
169 1 : expect_log_msg_containing("socks4: parsing failed - invalid request.");
170 1 : mock_clean_saved_logs();
171 :
172 : /* Try with 2000-byte hostname */
173 1 : ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
174 202 : for (i = 0; i < 200; ++i) {
175 200 : ADD_DATA(buf, "1234567890");
176 : }
177 1 : ADD_DATA(buf, "\x00");
178 : {
179 1 : const char *p;
180 1 : size_t s;
181 1 : buf_pullup(buf, 9999, &p, &s);
182 : }
183 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
184 : OP_EQ, -1);
185 1 : buf_clear(buf);
186 1 : expect_log_msg_containing("Destaddr too long. Rejecting.");
187 1 : mock_clean_saved_logs();
188 :
189 : /* Try with 2000-byte hostname, not terminated. */
190 1 : ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
191 202 : for (i = 0; i < 200; ++i) {
192 200 : ADD_DATA(buf, "1234567890");
193 : }
194 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
195 : OP_EQ, -1);
196 1 : buf_clear(buf);
197 1 : expect_log_msg_containing("parsing failed - invalid request.");
198 1 : mock_clean_saved_logs();
199 :
200 : /* Socks4, bogus hostname */
201 1 : ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00" "---\x00" );
202 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
203 1 : buf_clear(buf);
204 1 : expect_log_msg_containing("Your application (using socks4 to port 80) "
205 1 : "gave Tor a malformed hostname: ");
206 1 : mock_clean_saved_logs();
207 :
208 1 : done:
209 1 : teardown_capture_of_logs();
210 1 : }
211 :
212 : /** Perform unsupported SOCKS 5 commands */
213 : static void
214 1 : test_socks_5_unsupported_commands(void *ptr)
215 : {
216 1 : SOCKS_TEST_INIT();
217 :
218 : /* SOCKS 5 Send unsupported BIND [02] command */
219 1 : ADD_DATA(buf, "\x05\x02\x00\x01");
220 :
221 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
222 : get_options()->SafeSocks),OP_EQ, 0);
223 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
224 1 : tt_int_op(5,OP_EQ, socks->socks_version);
225 1 : tt_int_op(2,OP_EQ, socks->replylen);
226 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
227 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
228 1 : ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
229 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
230 : get_options()->SafeSocks),OP_EQ, -1);
231 :
232 1 : tt_int_op(5,OP_EQ,socks->socks_version);
233 1 : tt_int_op(10,OP_EQ,socks->replylen);
234 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
235 1 : tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
236 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
237 :
238 1 : buf_clear(buf);
239 1 : socks_request_clear(socks);
240 :
241 : /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
242 1 : ADD_DATA(buf, "\x05\x02\x00\x01");
243 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
244 : get_options()->SafeSocks),OP_EQ, 0);
245 1 : tt_int_op(5,OP_EQ, socks->socks_version);
246 1 : tt_int_op(2,OP_EQ, socks->replylen);
247 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
248 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
249 1 : ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
250 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
251 : get_options()->SafeSocks),OP_EQ, -1);
252 :
253 1 : tt_int_op(5,OP_EQ,socks->socks_version);
254 1 : tt_int_op(10,OP_EQ,socks->replylen);
255 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
256 1 : tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
257 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
258 :
259 1 : done:
260 1 : ;
261 1 : }
262 :
263 : /** Perform supported SOCKS 5 commands */
264 : static void
265 1 : test_socks_5_supported_commands(void *ptr)
266 : {
267 1 : SOCKS_TEST_INIT();
268 :
269 : /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
270 1 : ADD_DATA(buf, "\x05\x01\x00");
271 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
272 : get_options()->SafeSocks),OP_EQ, 0);
273 1 : tt_int_op(5,OP_EQ, socks->socks_version);
274 1 : tt_int_op(2,OP_EQ, socks->replylen);
275 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
276 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
277 :
278 1 : ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
279 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
280 : get_options()->SafeSocks),OP_EQ, 1);
281 1 : tt_str_op("2.2.2.2",OP_EQ, socks->address);
282 1 : tt_int_op(4369,OP_EQ, socks->port);
283 :
284 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
285 1 : socks_request_clear(socks);
286 :
287 : /* SOCKS 5 Send CONNECT [01] to one of the ipv6 addresses for
288 : torproject.org:80 */
289 1 : ADD_DATA(buf, "\x05\x01\x00");
290 1 : ADD_DATA(buf, "\x05\x01\x00\x04"
291 : "\x20\x02\x41\xb8\x02\x02\x0d\xeb\x02\x13\x21\xff\xfe\x20\x14\x26"
292 : "\x00\x50");
293 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
294 : get_options()->SafeSocks),OP_EQ, 1);
295 1 : tt_int_op(5,OP_EQ, socks->socks_version);
296 1 : tt_int_op(2,OP_EQ, socks->replylen);
297 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
298 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
299 1 : tt_str_op("[2002:41b8:202:deb:213:21ff:fe20:1426]",OP_EQ, socks->address);
300 1 : tt_int_op(80,OP_EQ, socks->port);
301 :
302 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
303 1 : socks_request_clear(socks);
304 :
305 : /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
306 1 : ADD_DATA(buf, "\x05\x01\x00");
307 1 : ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
308 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1,
309 : get_options()->SafeSocks),OP_EQ, 1);
310 :
311 1 : tt_int_op(5,OP_EQ, socks->socks_version);
312 1 : tt_int_op(2,OP_EQ, socks->replylen);
313 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
314 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
315 1 : tt_str_op("torproject.org",OP_EQ, socks->address);
316 1 : tt_int_op(4369,OP_EQ, socks->port);
317 :
318 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
319 1 : socks_request_clear(socks);
320 :
321 : /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
322 1 : ADD_DATA(buf, "\x05\x01\x00");
323 1 : ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
324 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
325 : get_options()->SafeSocks),
326 : OP_EQ, 1);
327 1 : tt_int_op(5,OP_EQ, socks->socks_version);
328 1 : tt_int_op(2,OP_EQ, socks->replylen);
329 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
330 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
331 1 : tt_str_op("torproject.org",OP_EQ, socks->address);
332 :
333 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
334 1 : socks_request_clear(socks);
335 :
336 : /* SOCKS 5 Should NOT reject RESOLVE [F0] request for IPv4 address
337 : * string if SafeSocks is enabled. */
338 :
339 1 : ADD_DATA(buf, "\x05\x01\x00");
340 1 : ADD_DATA(buf, "\x05\xF0\x00\x03\x07");
341 1 : ADD_DATA(buf, "8.8.8.8");
342 1 : ADD_DATA(buf, "\x11\x11");
343 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
344 : OP_EQ, 1);
345 :
346 1 : tt_str_op("8.8.8.8", OP_EQ, socks->address);
347 1 : tt_int_op(4369, OP_EQ, socks->port);
348 :
349 1 : tt_int_op(0, OP_EQ, buf_datalen(buf));
350 :
351 1 : socks_request_clear(socks);
352 :
353 : /* SOCKS 5 should NOT reject RESOLVE [F0] request for IPv6 address
354 : * string if SafeSocks is enabled. */
355 :
356 1 : ADD_DATA(buf, "\x05\x01\x00");
357 1 : ADD_DATA(buf, "\x05\xF0\x00\x03\x29");
358 1 : ADD_DATA(buf, "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
359 1 : ADD_DATA(buf, "\x01\x02");
360 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
361 : OP_EQ, 1);
362 :
363 1 : tt_str_op("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", OP_EQ,
364 : socks->address);
365 1 : tt_int_op(258, OP_EQ, socks->port);
366 :
367 1 : tt_int_op(0, OP_EQ, buf_datalen(buf));
368 :
369 1 : socks_request_clear(socks);
370 :
371 : /* Also allow bracket-less form. */
372 :
373 1 : ADD_DATA(buf, "\x05\x01\x00");
374 1 : ADD_DATA(buf, "\x05\xF0\x00\x03\x27");
375 1 : ADD_DATA(buf, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
376 1 : ADD_DATA(buf, "\x01\x02");
377 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
378 : OP_EQ, 1);
379 :
380 1 : tt_str_op("2001:0db8:85a3:0000:0000:8a2e:0370:7334", OP_EQ,
381 : socks->address);
382 1 : tt_int_op(258, OP_EQ, socks->port);
383 :
384 1 : tt_int_op(0, OP_EQ, buf_datalen(buf));
385 :
386 1 : socks_request_clear(socks);
387 :
388 : /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
389 1 : ADD_DATA(buf, "\x05\x01\x00");
390 1 : ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
391 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
392 : get_options()->SafeSocks),
393 : OP_EQ, 1);
394 1 : tt_int_op(5,OP_EQ, socks->socks_version);
395 1 : tt_int_op(2,OP_EQ, socks->replylen);
396 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
397 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
398 1 : tt_str_op("2.2.2.5",OP_EQ, socks->address);
399 :
400 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
401 :
402 1 : socks_request_clear(socks);
403 :
404 : /* SOCKS 5 Send RESOLVE_PTR [F1] for an IPv6 address */
405 1 : ADD_DATA(buf, "\x05\x01\x00");
406 1 : ADD_DATA(buf, "\x05\xF1\x00\x04"
407 : "\x20\x01\x0d\xb8\x85\xa3\x00\x00\x00\x00\x8a\x2e\x03\x70\x73\x34"
408 : "\x12\x34");
409 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
410 : get_options()->SafeSocks),
411 : OP_EQ, 1);
412 1 : tt_int_op(5,OP_EQ, socks->socks_version);
413 1 : tt_int_op(2,OP_EQ, socks->replylen);
414 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
415 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
416 1 : tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ, socks->address);
417 :
418 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
419 :
420 1 : socks_request_clear(socks);
421 :
422 : /* SOCKS 5 Send RESOLVE_PTR [F1] for a an IPv6 address written as a
423 : * string with brackets */
424 1 : ADD_DATA(buf, "\x05\x01\x00");
425 1 : ADD_DATA(buf, "\x05\xF1\x00\x03\x1e");
426 1 : ADD_DATA(buf, "[2001:db8:85a3::8a2e:370:7334]");
427 1 : ADD_DATA(buf, "\x12\x34");
428 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
429 : get_options()->SafeSocks),
430 : OP_EQ, 1);
431 1 : tt_int_op(5,OP_EQ, socks->socks_version);
432 1 : tt_int_op(2,OP_EQ, socks->replylen);
433 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
434 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
435 1 : tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ, socks->address);
436 :
437 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
438 :
439 1 : done:
440 1 : ;
441 1 : }
442 :
443 : /** Perform SOCKS 5 authentication */
444 : static void
445 1 : test_socks_5_no_authenticate(void *ptr)
446 : {
447 1 : SOCKS_TEST_INIT();
448 :
449 : /*SOCKS 5 No Authentication */
450 1 : ADD_DATA(buf,"\x05\x01\x00");
451 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
452 : get_options()->TestSocks,
453 : get_options()->SafeSocks));
454 1 : tt_int_op(2,OP_EQ, socks->replylen);
455 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
456 1 : tt_int_op(SOCKS_NO_AUTH,OP_EQ, socks->reply[1]);
457 :
458 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
459 :
460 : /*SOCKS 5 Send username/password anyway - pretend to be broken */
461 1 : ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01");
462 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
463 : get_options()->TestSocks,
464 : get_options()->SafeSocks));
465 1 : tt_int_op(5,OP_EQ, socks->socks_version);
466 1 : tt_int_op(2,OP_EQ, socks->replylen);
467 1 : tt_int_op(1,OP_EQ, socks->reply[0]);
468 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
469 :
470 1 : tt_int_op(2,OP_EQ, socks->usernamelen);
471 1 : tt_int_op(2,OP_EQ, socks->passwordlen);
472 :
473 1 : tt_mem_op("\x01\x01",OP_EQ, socks->username, 2);
474 1 : tt_mem_op("\x01\x01",OP_EQ, socks->password, 2);
475 :
476 1 : done:
477 1 : ;
478 1 : }
479 :
480 : /** Perform SOCKS 5 authentication */
481 : static void
482 1 : test_socks_5_authenticate(void *ptr)
483 : {
484 1 : SOCKS_TEST_INIT();
485 :
486 : /* SOCKS 5 Negotiate username/password authentication */
487 1 : ADD_DATA(buf, "\x05\x01\x02");
488 :
489 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
490 : get_options()->TestSocks,
491 : get_options()->SafeSocks));
492 1 : tt_int_op(2,OP_EQ, socks->replylen);
493 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
494 1 : tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
495 1 : tt_int_op(5,OP_EQ, socks->socks_version);
496 :
497 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
498 :
499 : /* SOCKS 5 Send username/password */
500 1 : ADD_DATA(buf, "\x01\x02me\x08mypasswd");
501 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
502 : get_options()->TestSocks,
503 : get_options()->SafeSocks));
504 1 : tt_int_op(5,OP_EQ, socks->socks_version);
505 1 : tt_int_op(2,OP_EQ, socks->replylen);
506 1 : tt_int_op(1,OP_EQ, socks->reply[0]);
507 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
508 :
509 1 : tt_int_op(2,OP_EQ, socks->usernamelen);
510 1 : tt_int_op(8,OP_EQ, socks->passwordlen);
511 :
512 1 : tt_mem_op("me",OP_EQ, socks->username, 2);
513 1 : tt_mem_op("mypasswd",OP_EQ, socks->password, 8);
514 :
515 1 : done:
516 1 : ;
517 1 : }
518 :
519 : /** Perform SOCKS 5 authentication with empty username/password fields.
520 : * Technically this violates RfC 1929, but some client software will send
521 : * this kind of message to Tor.
522 : * */
523 : static void
524 1 : test_socks_5_authenticate_empty_user_pass(void *ptr)
525 : {
526 1 : SOCKS_TEST_INIT();
527 :
528 : /* SOCKS 5 Negotiate username/password authentication */
529 1 : ADD_DATA(buf, "\x05\x01\x02");
530 :
531 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
532 : get_options()->TestSocks,
533 : get_options()->SafeSocks));
534 1 : tt_int_op(2,OP_EQ, socks->replylen);
535 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
536 1 : tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
537 1 : tt_int_op(5,OP_EQ, socks->socks_version);
538 :
539 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
540 :
541 : /* SOCKS 5 Send username/password auth message with empty user/pass fields */
542 1 : ADD_DATA(buf, "\x01\x00\x00");
543 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
544 : get_options()->TestSocks,
545 : get_options()->SafeSocks));
546 1 : tt_int_op(5,OP_EQ, socks->socks_version);
547 1 : tt_int_op(2,OP_EQ, socks->replylen);
548 1 : tt_int_op(1,OP_EQ, socks->reply[0]);
549 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
550 :
551 1 : tt_int_op(0,OP_EQ, socks->usernamelen);
552 1 : tt_int_op(0,OP_EQ, socks->passwordlen);
553 :
554 1 : done:
555 1 : ;
556 1 : }
557 : /** Perform SOCKS 5 authentication and send data all in one go */
558 : static void
559 1 : test_socks_5_authenticate_with_data(void *ptr)
560 : {
561 1 : SOCKS_TEST_INIT();
562 :
563 : /* SOCKS 5 Negotiate username/password authentication */
564 1 : ADD_DATA(buf, "\x05\x01\x02");
565 :
566 1 : tt_assert(!fetch_from_buf_socks(buf, socks,
567 : get_options()->TestSocks,
568 : get_options()->SafeSocks));
569 1 : tt_int_op(2,OP_EQ, socks->replylen);
570 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
571 1 : tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
572 1 : tt_int_op(5,OP_EQ, socks->socks_version);
573 :
574 1 : tt_int_op(0,OP_EQ, buf_datalen(buf));
575 :
576 : /* SOCKS 5 Send username/password */
577 : /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
578 1 : ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
579 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
580 : get_options()->SafeSocks),
581 : OP_EQ, 1);
582 1 : tt_int_op(5,OP_EQ, socks->socks_version);
583 1 : tt_int_op(2,OP_EQ, socks->replylen);
584 1 : tt_int_op(1,OP_EQ, socks->reply[0]);
585 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
586 :
587 1 : tt_str_op("2.2.2.2",OP_EQ, socks->address);
588 1 : tt_int_op(4369,OP_EQ, socks->port);
589 :
590 1 : tt_int_op(2,OP_EQ, socks->usernamelen);
591 1 : tt_int_op(3,OP_EQ, socks->passwordlen);
592 1 : tt_mem_op("me",OP_EQ, socks->username, 2);
593 1 : tt_mem_op("you",OP_EQ, socks->password, 3);
594 :
595 1 : done:
596 1 : ;
597 1 : }
598 :
599 : /** Try to negotiate an unsupported authentication type */
600 : static void
601 1 : test_socks_5_auth_unsupported_type(void *ptr)
602 : {
603 1 : SOCKS_TEST_INIT();
604 :
605 : /* None of these authentication types are recognized. */
606 1 : ADD_DATA(buf, "\x05\x03\x99\x21\x10");
607 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
608 : get_options()->SafeSocks),
609 : OP_EQ, -1);
610 1 : tt_int_op(0,OP_EQ, socks->socks_version);
611 1 : tt_int_op(2,OP_EQ, socks->replylen);
612 1 : tt_int_op(5,OP_EQ, socks->reply[0]);
613 1 : tt_int_op(0xff,OP_EQ, socks->reply[1]);
614 :
615 1 : done:
616 1 : ;
617 1 : }
618 :
619 : /** Try to negotiate an unsupported version of username/password auth. */
620 : static void
621 1 : test_socks_5_auth_unsupported_version(void *ptr)
622 : {
623 1 : SOCKS_TEST_INIT();
624 :
625 : /* Negotiate username/password */
626 1 : ADD_DATA(buf, "\x05\x01\x02");
627 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
628 : get_options()->SafeSocks),
629 : OP_EQ, 0);
630 1 : tt_int_op(0,OP_EQ, buf_datalen(buf)); /* buf should be drained */
631 : /* Now, suggest an unrecognized username/password version */
632 1 : ADD_DATA(buf, "\x02\x05" "hello" "\x05" "world");
633 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
634 : get_options()->SafeSocks),
635 : OP_EQ, -1);
636 :
637 1 : done:
638 1 : ;
639 1 : }
640 :
641 : /** Perform SOCKS 5 authentication before method negotiated */
642 : static void
643 1 : test_socks_5_auth_before_negotiation(void *ptr)
644 : {
645 1 : SOCKS_TEST_INIT();
646 :
647 : /* SOCKS 5 Send username/password */
648 1 : ADD_DATA(buf, "\x01\x02me\x02me");
649 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
650 : get_options()->SafeSocks),
651 : OP_EQ, -1);
652 1 : tt_int_op(0,OP_EQ, socks->socks_version);
653 1 : tt_int_op(0,OP_EQ, socks->replylen);
654 1 : tt_int_op(0,OP_EQ, socks->reply[0]);
655 1 : tt_int_op(0,OP_EQ, socks->reply[1]);
656 :
657 1 : done:
658 1 : ;
659 1 : }
660 :
661 : /** Perform malformed SOCKS 5 commands */
662 : static void
663 1 : test_socks_5_malformed_commands(void *ptr)
664 : {
665 1 : SOCKS_TEST_INIT();
666 :
667 : /* XXX: Stringified address length > MAX_SOCKS_ADDR_LEN will never happen */
668 :
669 : /** SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369, with SafeSocks set
670 : */
671 1 : ADD_DATA(buf, "\x05\x01\x00");
672 1 : ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
673 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
674 : OP_EQ, -1);
675 :
676 1 : tt_int_op(5,OP_EQ,socks->socks_version);
677 1 : tt_int_op(10,OP_EQ,socks->replylen);
678 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
679 1 : tt_int_op(SOCKS5_NOT_ALLOWED,OP_EQ,socks->reply[1]);
680 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
681 :
682 1 : buf_clear(buf);
683 1 : socks_request_clear(socks);
684 :
685 : /* SOCKS 5 Send RESOLVE_PTR [F1] for FQDN torproject.org */
686 1 : ADD_DATA(buf, "\x05\x01\x00");
687 1 : ADD_DATA(buf, "\x05\xF1\x00\x03\x0Etorproject.org\x11\x11");
688 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
689 : get_options()->SafeSocks),OP_EQ, -1);
690 :
691 1 : tt_int_op(5,OP_EQ,socks->socks_version);
692 1 : tt_int_op(10,OP_EQ,socks->replylen);
693 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
694 1 : tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
695 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
696 :
697 1 : buf_clear(buf);
698 1 : socks_request_clear(socks);
699 :
700 : /* XXX: len + 1 > MAX_SOCKS_ADDR_LEN (FQDN request) will never happen */
701 :
702 : /* SOCKS 5 Send CONNECT [01] to FQDN """"".com */
703 1 : ADD_DATA(buf, "\x05\x01\x00");
704 1 : ADD_DATA(buf, "\x05\x01\x00\x03\x09\"\"\"\"\".com\x11\x11");
705 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
706 : get_options()->SafeSocks),OP_EQ, -1);
707 :
708 1 : tt_int_op(5,OP_EQ,socks->socks_version);
709 1 : tt_int_op(10,OP_EQ,socks->replylen);
710 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
711 1 : tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
712 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
713 :
714 1 : buf_clear(buf);
715 1 : socks_request_clear(socks);
716 :
717 : /* SOCKS 5 Send CONNECT [01] to address type 0x23 */
718 1 : ADD_DATA(buf, "\x05\x01\x00");
719 1 : ADD_DATA(buf, "\x05\x01\x00\x23\x02\x02\x02\x02\x11\x11");
720 1 : tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
721 : get_options()->SafeSocks),OP_EQ, -1);
722 :
723 1 : tt_int_op(5,OP_EQ,socks->socks_version);
724 1 : tt_int_op(10,OP_EQ,socks->replylen);
725 1 : tt_int_op(5,OP_EQ,socks->reply[0]);
726 : /* trunnel parsing will fail with -1 */
727 1 : tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
728 1 : tt_int_op(1,OP_EQ,socks->reply[3]);
729 :
730 1 : done:
731 1 : ;
732 1 : }
733 :
734 : static void
735 1 : test_socks_5_bad_arguments(void *ptr)
736 : {
737 1 : SOCKS_TEST_INIT();
738 1 : setup_capture_of_logs(LOG_DEBUG);
739 :
740 : /* Socks5, bogus hostname */
741 1 : ADD_DATA(buf, "\x05\x01\x00" "\x05\x01\x00\x03\x03" "---" "\x00\x50" );
742 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
743 1 : buf_clear(buf);
744 1 : expect_log_msg_containing("Your application (using socks5 to port 80) "
745 1 : "gave Tor a malformed hostname: ");
746 1 : mock_clean_saved_logs();
747 1 : socks_request_clear(socks);
748 :
749 1 : done:
750 1 : teardown_capture_of_logs();
751 1 : }
752 :
753 : /** check for correct behavior when the socks command has not arrived. */
754 : static void
755 1 : test_socks_truncated(void *ptr)
756 : {
757 1 : const struct {
758 : enum { NONE, AUTH, ALL } setup;
759 : const char *body;
760 : size_t len;
761 1 : } commands[] = {
762 : /* SOCKS4 */
763 : /* Connect, to an IP. */
764 : { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04\x00", 9},
765 : /* Connect, to an IP, with authentication. */
766 : { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04hello\x00", 14},
767 : /* SOCKS4A */
768 : /* Connect, to a hostname */
769 : { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01\x00www.example.com\x00", 25},
770 : /* Connect, to a hostname, with authentication */
771 : { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01hi\x00www.example.com\x00", 27},
772 : /* SOCKS5 */
773 : /* initial handshake */
774 : { NONE, "\x05\x00", 2 },
775 : /* no-auth handshake */
776 : { NONE, "\x05\x03\x99\x21\x10", 5 },
777 : /* SOCSK5, username-password, all empty. */
778 : { AUTH, "\x01\x00\x00", 3 },
779 : /* SOCSK5, username-password, 1 char each. */
780 : { AUTH, "\x01\x01x\x01y", 5 },
781 : /* SOCSK5, username-password, max length. */
782 : { AUTH, "\x01\xff"
783 : "Ogni tempo ha il suo fascismo: se ne notano i segni premonitori "
784 : "dovunque la concentrazione di potere nega al cittadino la "
785 : "possibilit\xc3\xa0 e la capacit\xc3\xa0 di esprimere ed attuare la "
786 : "sua volont\xc3\xa0. A questo si arriva in molti modi, non "
787 : "necessariamente col terror"
788 : "\xff"
789 : "e dell'intimidazione poliziesca, ma anche negando o distorcendo "
790 : "l'informazione, inquinando la giustizia, paralizzando la scuola, "
791 : "diffondendo in molti modi sottili la nostalgia per un mondo in cui "
792 : "regnava sovrano l'ordine, ed in cui la sicurezza dei pochi "
793 : /* privilegiati riposava sul lavoro forzato e sul silenzio forzato dei
794 : molti. -- Primo Levi */ , 513 },
795 : /* Socks5, IPv4 address */
796 : { ALL, "\x05\x01\x00\x01\x01\x02\x03\x04\x20\x20", 10 },
797 : /* Socks5, IPv6 address */
798 : { ALL, "\x05\x01\x00\x04"
799 : "\x49\x20\x48\x41\x5a\x20\x45\x41\x53\x54\x45\x52\x20\x45\x47\x47"
800 : "\x20\x20", 22 },
801 : /* Socks5, hostname, empty. */
802 : { ALL, "\x05\x01\x00\x03" "\x00" "\x00\x50", 7 },
803 : /* Socks5, hostname, moderate. */
804 : { ALL, "\x05\x01\x00\x03" "\x11" "onion.example.com" "\x00\x50", 24 },
805 : /* Socks5, hostname, maximum. */
806 : { ALL, "\x05\x01\x00\x03" "\xff"
807 : "whatsoever.I.shall.see.or.hear.in.the.course.of.my.profession.as.well."
808 : "as.outside.my.profession.in.my.intercourse.with.men.if.it.be.what."
809 : "should.not.be.published.abroad.I.will.never.divulge.holding.such."
810 : "things.to.be.holy.secrets.x.hippocratic.oath.wikipedia"
811 : "\x00\x50", 262 },
812 : };
813 1 : unsigned i, j;
814 1 : SOCKS_TEST_INIT();
815 15 : for (i = 0; i < ARRAY_LENGTH(commands); ++i) {
816 942 : for (j = 0; j < commands[i].len; ++j) {
817 928 : switch (commands[i].setup) {
818 : default: FALLTHROUGH;
819 : case NONE:
820 : /* This test calls for no setup on the socks state. */
821 : break;
822 521 : case AUTH:
823 : /* This test calls for the socks state to be waiting for
824 : * username/password authentication */
825 521 : ADD_DATA(buf, "\x05\x01\x02");
826 521 : tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
827 521 : tt_int_op(0, OP_EQ, buf_datalen(buf));
828 : break;
829 325 : case ALL:
830 : /* This test calls for the socks state to be waiting for
831 : * the connection request */
832 325 : ADD_DATA(buf, "\x05\x01\x00");
833 325 : tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
834 325 : tt_int_op(0, OP_EQ, buf_datalen(buf));
835 : }
836 :
837 928 : TT_BLATHER(("Checking command %u, length %u, omitting char %u", i, j,
838 : (unsigned)commands[i].body[j]));
839 928 : buf_add(buf, commands[i].body, j);
840 : /* This should return 0 meaning "not done yet" */
841 928 : tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
842 928 : tt_uint_op(j, OP_EQ, buf_datalen(buf)); /* Nothing was drained */
843 928 : buf_clear(buf);
844 928 : socks_request_free(testdata->req);
845 928 : socks = testdata->req = socks_request_new();
846 : }
847 : }
848 1 : done:
849 1 : ;
850 1 : }
851 :
852 : static void
853 1 : test_socks_wrong_protocol(void *ptr)
854 : {
855 1 : SOCKS_TEST_INIT();
856 1 : setup_capture_of_logs(LOG_DEBUG);
857 :
858 : /* HTTP request. */
859 1 : ADD_DATA(buf, "GET /index.html HTTP/1.0" );
860 1 : tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
861 1 : buf_clear(buf);
862 1 : expect_log_msg_containing("Socks version 71 not recognized. "
863 1 : "(This port is not an HTTP proxy;");
864 1 : mock_clean_saved_logs();
865 1 : socks_request_clear(socks);
866 :
867 1 : done:
868 1 : teardown_capture_of_logs();
869 1 : }
870 :
871 : /* Check our client-side socks4 parsing (that is to say, our parsing of
872 : * server responses).
873 : */
874 : static void
875 1 : test_socks_client_v4(void *arg)
876 : {
877 1 : (void)arg;
878 1 : buf_t *buf = buf_new();
879 1 : char *reason = NULL;
880 :
881 : /* Legit socks4 response, success */
882 1 : ADD_DATA(buf, "\x04\x5a\x20\x25\x01\x02\x03\x04");
883 1 : tt_int_op(1, OP_EQ,
884 : fetch_from_buf_socks_client(buf, PROXY_SOCKS4_WANT_CONNECT_OK,
885 : &reason));
886 1 : tt_ptr_op(reason, OP_EQ, NULL);
887 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
888 :
889 : /* Legit socks4 response, failure. */
890 1 : ADD_DATA(buf, "\x04\x5b\x20\x25\x01\x02\x03\x04");
891 1 : tt_int_op(-1, OP_EQ,
892 : fetch_from_buf_socks_client(buf, PROXY_SOCKS4_WANT_CONNECT_OK,
893 : &reason));
894 1 : tt_ptr_op(reason, OP_NE, NULL);
895 1 : tt_str_op(reason, OP_EQ, "server rejected connection");
896 :
897 1 : done:
898 1 : buf_free(buf);
899 1 : tor_free(reason);
900 1 : }
901 :
902 : /* Check our client-side socks5 authentication-negotiation parsing (that is to
903 : * say, our parsing of server responses).
904 : */
905 : static void
906 1 : test_socks_client_v5_auth(void *arg)
907 : {
908 1 : (void)arg;
909 1 : buf_t *buf = buf_new();
910 1 : char *reason = NULL;
911 :
912 : /* Legit socks5 responses, got a method we like. */
913 1 : ADD_DATA(buf, "\x05\x00");
914 1 : tt_int_op(1, OP_EQ,
915 : fetch_from_buf_socks_client(buf,
916 : PROXY_SOCKS5_WANT_AUTH_METHOD_NONE,
917 : &reason));
918 1 : tt_ptr_op(reason, OP_EQ, NULL);
919 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
920 :
921 : /* Same, but we wanted something else. */
922 1 : ADD_DATA(buf, "\x05\x00");
923 1 : tt_int_op(1, OP_EQ,
924 : fetch_from_buf_socks_client(buf,
925 : PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
926 : &reason));
927 1 : tt_ptr_op(reason, OP_EQ, NULL);
928 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
929 :
930 : /* Same, and they offered a password. */
931 1 : ADD_DATA(buf, "\x05\x02");
932 1 : tt_int_op(2, OP_EQ,
933 : fetch_from_buf_socks_client(buf,
934 : PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
935 : &reason));
936 1 : tt_ptr_op(reason, OP_EQ, NULL);
937 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
938 :
939 : /* They rejected our method, or selected something we don't know. */
940 1 : ADD_DATA(buf, "\x05\xff");
941 1 : tt_int_op(-1, OP_EQ,
942 : fetch_from_buf_socks_client(buf,
943 : PROXY_SOCKS5_WANT_AUTH_METHOD_NONE,
944 : &reason));
945 1 : tt_str_op(reason, OP_EQ, "server doesn't support any of our available "
946 : "authentication methods");
947 1 : buf_clear(buf);
948 1 : tor_free(reason);
949 1 : ADD_DATA(buf, "\x05\xff");
950 1 : tt_int_op(-1, OP_EQ,
951 : fetch_from_buf_socks_client(buf,
952 : PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
953 : &reason));
954 1 : tt_str_op(reason, OP_EQ, "server doesn't support any of our available "
955 : "authentication methods");
956 1 : tor_free(reason);
957 1 : buf_clear(buf);
958 :
959 : /* Now check for authentication responses: check success and failure. */
960 1 : ADD_DATA(buf, "\x01\x00");
961 1 : tt_int_op(1, OP_EQ,
962 : fetch_from_buf_socks_client(buf,
963 : PROXY_SOCKS5_WANT_AUTH_RFC1929_OK,
964 : &reason));
965 1 : tt_ptr_op(reason, OP_EQ, NULL);
966 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
967 :
968 1 : ADD_DATA(buf, "\x01\xf0");
969 1 : tt_int_op(-1, OP_EQ,
970 : fetch_from_buf_socks_client(buf,
971 : PROXY_SOCKS5_WANT_AUTH_RFC1929_OK,
972 : &reason));
973 1 : tt_ptr_op(reason, OP_NE, NULL);
974 1 : tt_str_op(reason, OP_EQ, "authentication failed");
975 :
976 1 : done:
977 1 : buf_free(buf);
978 1 : tor_free(reason);
979 1 : }
980 :
981 : /* Check our client-side socks5 connect parsing (that is to say, our parsing
982 : * of server responses).
983 : */
984 : static void
985 1 : test_socks_client_v5_connect(void *arg)
986 : {
987 1 : (void)arg;
988 1 : buf_t *buf = buf_new();
989 1 : char *reason = NULL;
990 :
991 : /* Legit socks5 responses, success, ipv4. */
992 1 : ADD_DATA(buf, "\x05\x00\x00\x01\x01\x02\x03\x04\x00\x05");
993 1 : tt_int_op(1, OP_EQ,
994 : fetch_from_buf_socks_client(buf,
995 : PROXY_SOCKS5_WANT_CONNECT_OK,
996 : &reason));
997 1 : tt_ptr_op(reason, OP_EQ, NULL);
998 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
999 :
1000 : /* Legit socks5 responses, success, ipv6. */
1001 1 : ADD_DATA(buf, "\x05\x00\x00\x04"
1002 : "abcdefghijklmnop"
1003 : "\x00\x05");
1004 1 : tt_int_op(1, OP_EQ,
1005 : fetch_from_buf_socks_client(buf,
1006 : PROXY_SOCKS5_WANT_CONNECT_OK,
1007 : &reason));
1008 1 : tt_ptr_op(reason, OP_EQ, NULL);
1009 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
1010 :
1011 : /* Legit socks5 responses, success, hostname. */
1012 1 : ADD_DATA(buf, "\x05\x00\x00\x03\x12"
1013 : "gopher.example.com"
1014 : "\x00\x05");
1015 1 : tt_int_op(1, OP_EQ,
1016 : fetch_from_buf_socks_client(buf,
1017 : PROXY_SOCKS5_WANT_CONNECT_OK,
1018 : &reason));
1019 1 : tt_ptr_op(reason, OP_EQ, NULL);
1020 1 : tt_int_op(buf_datalen(buf), OP_EQ, 0);
1021 :
1022 : /* Legit socks5 responses, failure, hostname. */
1023 1 : ADD_DATA(buf, "\x05\x03\x00\x03\x12"
1024 : "gopher.example.com"
1025 : "\x00\x05");
1026 1 : tt_int_op(-1, OP_EQ,
1027 : fetch_from_buf_socks_client(buf,
1028 : PROXY_SOCKS5_WANT_CONNECT_OK,
1029 : &reason));
1030 1 : tt_ptr_op(reason, OP_NE, NULL);
1031 1 : tt_str_op(reason, OP_EQ, "Network unreachable");
1032 1 : tor_free(reason);
1033 1 : buf_clear(buf);
1034 :
1035 : /* Bogus socks5 responses: what is address type 0x17? */
1036 1 : ADD_DATA(buf, "\x05\x03\x00\x17\x12 blah blah");
1037 1 : tt_int_op(-1, OP_EQ,
1038 : fetch_from_buf_socks_client(buf,
1039 : PROXY_SOCKS5_WANT_CONNECT_OK,
1040 : &reason));
1041 1 : tt_ptr_op(reason, OP_NE, NULL);
1042 1 : tt_str_op(reason, OP_EQ, "invalid response to connect request");
1043 1 : buf_clear(buf);
1044 :
1045 1 : done:
1046 1 : buf_free(buf);
1047 1 : tor_free(reason);
1048 1 : }
1049 :
1050 : static void
1051 1 : test_socks_client_truncated(void *arg)
1052 : {
1053 1 : (void)arg;
1054 1 : buf_t *buf = buf_new();
1055 1 : char *reason = NULL;
1056 :
1057 : #define S(str) str, (sizeof(str)-1)
1058 1 : const struct {
1059 : int state;
1060 : const char *body;
1061 : size_t len;
1062 1 : } replies[] = {
1063 : { PROXY_SOCKS4_WANT_CONNECT_OK, S("\x04\x5a\x20\x25\x01\x02\x03\x04") },
1064 : { PROXY_SOCKS4_WANT_CONNECT_OK, S("\x04\x5b\x20\x25\x01\x02\x03\x04") },
1065 : { PROXY_SOCKS5_WANT_AUTH_METHOD_NONE, S("\x05\x00") },
1066 : { PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929, S("\x05\x00") },
1067 : { PROXY_SOCKS5_WANT_AUTH_RFC1929_OK, S("\x01\x00") },
1068 : { PROXY_SOCKS5_WANT_CONNECT_OK,
1069 : S("\x05\x00\x00\x01\x01\x02\x03\x04\x00\x05") },
1070 : { PROXY_SOCKS5_WANT_CONNECT_OK,
1071 : S("\x05\x00\x00\x04" "abcdefghijklmnop" "\x00\x05") },
1072 : { PROXY_SOCKS5_WANT_CONNECT_OK,
1073 : S("\x05\x00\x00\x03\x12" "gopher.example.com" "\x00\x05") },
1074 : { PROXY_SOCKS5_WANT_CONNECT_OK,
1075 : S("\x05\x03\x00\x03\x12" "gopher.example.com""\x00\x05") },
1076 : { PROXY_SOCKS5_WANT_CONNECT_OK,
1077 : S("\x05\x03\x00\x17") },
1078 : };
1079 1 : unsigned i, j;
1080 11 : for (i = 0; i < ARRAY_LENGTH(replies); ++i) {
1081 118 : for (j = 0; j < replies[i].len; ++j) {
1082 108 : TT_BLATHER(("Checking command %u, length %u", i, j));
1083 108 : buf_add(buf, replies[i].body, j);
1084 : /* This should return 0 meaning "not done yet" */
1085 108 : tt_int_op(0, OP_EQ,
1086 : fetch_from_buf_socks_client(buf, replies[i].state, &reason));
1087 108 : tt_uint_op(j, OP_EQ, buf_datalen(buf)); /* Nothing was drained */
1088 108 : buf_clear(buf);
1089 108 : tt_ptr_op(reason, OP_EQ, NULL);
1090 : }
1091 : }
1092 :
1093 1 : done:
1094 1 : tor_free(reason);
1095 1 : buf_free(buf);
1096 1 : }
1097 :
1098 : #define SOCKSENT(name) \
1099 : { #name, test_socks_##name, TT_FORK, &socks_setup, NULL }
1100 :
1101 : struct testcase_t socks_tests[] = {
1102 : SOCKSENT(4_unsupported_commands),
1103 : SOCKSENT(4_supported_commands),
1104 : SOCKSENT(4_bad_arguments),
1105 :
1106 : SOCKSENT(5_unsupported_commands),
1107 : SOCKSENT(5_supported_commands),
1108 : SOCKSENT(5_no_authenticate),
1109 : SOCKSENT(5_auth_unsupported_type),
1110 : SOCKSENT(5_auth_unsupported_version),
1111 : SOCKSENT(5_auth_before_negotiation),
1112 : SOCKSENT(5_authenticate),
1113 : SOCKSENT(5_authenticate_empty_user_pass),
1114 : SOCKSENT(5_authenticate_with_data),
1115 : SOCKSENT(5_malformed_commands),
1116 : SOCKSENT(5_bad_arguments),
1117 :
1118 : SOCKSENT(truncated),
1119 :
1120 : SOCKSENT(wrong_protocol),
1121 :
1122 : { "client/v4", test_socks_client_v4, TT_FORK, NULL, NULL },
1123 : { "client/v5_auth", test_socks_client_v5_auth, TT_FORK, NULL, NULL },
1124 : { "client/v5_connect", test_socks_client_v5_connect, TT_FORK, NULL, NULL },
1125 : { "client/truncated", test_socks_client_truncated, TT_FORK, NULL, NULL },
1126 :
1127 : END_OF_TESTCASES
1128 : };
|