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 */
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"
16 typedef struct socks_test_data_t
{
22 socks_test_setup(const struct testcase_t
*testcase
)
24 socks_test_data_t
*data
= tor_malloc(sizeof(socks_test_data_t
));
26 data
->buf
= buf_new_with_capacity(256);
27 data
->req
= socks_request_new();
28 config_register_addressmaps(get_options());
32 socks_test_cleanup(const struct testcase_t
*testcase
, void *ptr
)
34 socks_test_data_t
*data
= ptr
;
37 socks_request_free(data
->req
);
42 static const struct testcase_setup_t socks_setup
= {
43 socks_test_setup
, socks_test_cleanup
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)
54 socks_request_clear(socks_request_t
*socks
)
56 tor_free(socks
->username
);
57 tor_free(socks
->password
);
58 memset(socks
, 0, sizeof(socks_request_t
));
61 /** Perform unsupported SOCKS 4 commands */
63 test_socks_4_unsupported_commands(void *ptr
)
67 /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
68 ADD_DATA(buf
, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
69 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
70 get_options()->SafeSocks
),
72 tt_int_op(4,OP_EQ
, socks
->socks_version
);
73 tt_int_op(0,OP_EQ
, socks
->replylen
); /* XXX: shouldn't tor reply? */
79 /** Perform supported SOCKS 4 commands */
81 test_socks_4_supported_commands(void *ptr
)
85 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
87 /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.3:4370 */
88 ADD_DATA(buf
, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
89 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
90 get_options()->SafeSocks
),
92 tt_int_op(4,OP_EQ
, socks
->socks_version
);
93 tt_int_op(0,OP_EQ
, socks
->replylen
); /* XXX: shouldn't tor reply? */
94 tt_int_op(SOCKS_COMMAND_CONNECT
,OP_EQ
, socks
->command
);
95 tt_str_op("2.2.2.3",OP_EQ
, socks
->address
);
96 tt_int_op(4370,OP_EQ
, socks
->port
);
97 tt_assert(socks
->got_auth
== 0);
98 tt_assert(! socks
->username
);
100 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
101 socks_request_clear(socks
);
103 /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.4:4369 with userid*/
104 ADD_DATA(buf
, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
105 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0),
107 tt_int_op(4,OP_EQ
, socks
->socks_version
);
108 tt_int_op(0,OP_EQ
, socks
->replylen
); /* XXX: shouldn't tor reply? */
109 tt_int_op(SOCKS_COMMAND_CONNECT
,OP_EQ
, socks
->command
);
110 tt_str_op("2.2.2.4",OP_EQ
, socks
->address
);
111 tt_int_op(4370,OP_EQ
, socks
->port
);
112 tt_assert(socks
->got_auth
== 1);
113 tt_assert(socks
->username
);
114 tt_int_op(2,OP_EQ
, socks
->usernamelen
);
115 tt_mem_op("me",OP_EQ
, socks
->username
, 2);
117 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
118 socks_request_clear(socks
);
120 /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
121 ADD_DATA(buf
, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
122 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1,
123 get_options()->SafeSocks
),
125 tt_int_op(4,OP_EQ
, socks
->socks_version
);
126 tt_int_op(0,OP_EQ
, socks
->replylen
); /* XXX: shouldn't tor reply? */
127 tt_str_op("torproject.org",OP_EQ
, socks
->address
);
129 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
136 test_socks_4_bad_arguments(void *ptr
)
139 setup_capture_of_logs(LOG_DEBUG
);
141 /* Try with 0 IPv4 address */
142 ADD_DATA(buf
, "\x04\x01\x00\x50\x00\x00\x00\x00\x00");
143 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
144 get_options()->SafeSocks
),
147 expect_log_msg_containing("Port or DestIP is zero.");
148 mock_clean_saved_logs();
150 /* Try with 0 port */
151 ADD_DATA(buf
, "\x04\x01\x00\x00\x01\x02\x03\x04\x00");
152 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
153 get_options()->SafeSocks
),
156 expect_log_msg_containing("Port or DestIP is zero.");
157 mock_clean_saved_logs();
159 /* Try with 2000-byte username (!) */
160 ADD_DATA(buf
, "\x04\x01\x00\x50\x01\x02\x03\x04");
162 for (i
= 0; i
< 200; ++i
) {
163 ADD_DATA(buf
, "1234567890");
165 ADD_DATA(buf
, "\x00");
166 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0),
169 expect_log_msg_containing("socks4: parsing failed - invalid request.");
170 mock_clean_saved_logs();
172 /* Try with 2000-byte hostname */
173 ADD_DATA(buf
, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
174 for (i
= 0; i
< 200; ++i
) {
175 ADD_DATA(buf
, "1234567890");
177 ADD_DATA(buf
, "\x00");
181 buf_pullup(buf
, 9999, &p
, &s
);
183 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0),
186 expect_log_msg_containing("Destaddr too long. Rejecting.");
187 mock_clean_saved_logs();
189 /* Try with 2000-byte hostname, not terminated. */
190 ADD_DATA(buf
, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
191 for (i
= 0; i
< 200; ++i
) {
192 ADD_DATA(buf
, "1234567890");
194 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0),
197 expect_log_msg_containing("parsing failed - invalid request.");
198 mock_clean_saved_logs();
200 /* Socks4, bogus hostname */
201 ADD_DATA(buf
, "\x04\x01\x00\x50\x00\x00\x00\x01\x00" "---\x00" );
202 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0), OP_EQ
, -1);
204 expect_log_msg_containing("Your application (using socks4 to port 80) "
205 "gave Tor a malformed hostname: ");
206 mock_clean_saved_logs();
209 teardown_capture_of_logs();
212 /** Perform unsupported SOCKS 5 commands */
214 test_socks_5_unsupported_commands(void *ptr
)
218 /* SOCKS 5 Send unsupported BIND [02] command */
219 ADD_DATA(buf
, "\x05\x02\x00\x01");
221 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
222 get_options()->SafeSocks
),OP_EQ
, 0);
223 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
224 tt_int_op(5,OP_EQ
, socks
->socks_version
);
225 tt_int_op(2,OP_EQ
, socks
->replylen
);
226 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
227 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
228 ADD_DATA(buf
, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
229 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
230 get_options()->SafeSocks
),OP_EQ
, -1);
232 tt_int_op(5,OP_EQ
,socks
->socks_version
);
233 tt_int_op(10,OP_EQ
,socks
->replylen
);
234 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
235 tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED
,OP_EQ
,socks
->reply
[1]);
236 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
239 socks_request_clear(socks
);
241 /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
242 ADD_DATA(buf
, "\x05\x02\x00\x01");
243 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
244 get_options()->SafeSocks
),OP_EQ
, 0);
245 tt_int_op(5,OP_EQ
, socks
->socks_version
);
246 tt_int_op(2,OP_EQ
, socks
->replylen
);
247 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
248 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
249 ADD_DATA(buf
, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
250 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
251 get_options()->SafeSocks
),OP_EQ
, -1);
253 tt_int_op(5,OP_EQ
,socks
->socks_version
);
254 tt_int_op(10,OP_EQ
,socks
->replylen
);
255 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
256 tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED
,OP_EQ
,socks
->reply
[1]);
257 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
263 /** Perform supported SOCKS 5 commands */
265 test_socks_5_supported_commands(void *ptr
)
269 /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
270 ADD_DATA(buf
, "\x05\x01\x00");
271 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
272 get_options()->SafeSocks
),OP_EQ
, 0);
273 tt_int_op(5,OP_EQ
, socks
->socks_version
);
274 tt_int_op(2,OP_EQ
, socks
->replylen
);
275 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
276 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
278 ADD_DATA(buf
, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
279 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
280 get_options()->SafeSocks
),OP_EQ
, 1);
281 tt_str_op("2.2.2.2",OP_EQ
, socks
->address
);
282 tt_int_op(4369,OP_EQ
, socks
->port
);
284 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
285 socks_request_clear(socks
);
287 /* SOCKS 5 Send CONNECT [01] to one of the ipv6 addresses for
289 ADD_DATA(buf
, "\x05\x01\x00");
290 ADD_DATA(buf
, "\x05\x01\x00\x04"
291 "\x20\x02\x41\xb8\x02\x02\x0d\xeb\x02\x13\x21\xff\xfe\x20\x14\x26"
293 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
294 get_options()->SafeSocks
),OP_EQ
, 1);
295 tt_int_op(5,OP_EQ
, socks
->socks_version
);
296 tt_int_op(2,OP_EQ
, socks
->replylen
);
297 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
298 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
299 tt_str_op("[2002:41b8:202:deb:213:21ff:fe20:1426]",OP_EQ
, socks
->address
);
300 tt_int_op(80,OP_EQ
, socks
->port
);
302 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
303 socks_request_clear(socks
);
305 /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
306 ADD_DATA(buf
, "\x05\x01\x00");
307 ADD_DATA(buf
, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
308 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1,
309 get_options()->SafeSocks
),OP_EQ
, 1);
311 tt_int_op(5,OP_EQ
, socks
->socks_version
);
312 tt_int_op(2,OP_EQ
, socks
->replylen
);
313 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
314 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
315 tt_str_op("torproject.org",OP_EQ
, socks
->address
);
316 tt_int_op(4369,OP_EQ
, socks
->port
);
318 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
319 socks_request_clear(socks
);
321 /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
322 ADD_DATA(buf
, "\x05\x01\x00");
323 ADD_DATA(buf
, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
324 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
325 get_options()->SafeSocks
),
327 tt_int_op(5,OP_EQ
, socks
->socks_version
);
328 tt_int_op(2,OP_EQ
, socks
->replylen
);
329 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
330 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
331 tt_str_op("torproject.org",OP_EQ
, socks
->address
);
333 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
334 socks_request_clear(socks
);
336 /* SOCKS 5 Should NOT reject RESOLVE [F0] request for IPv4 address
337 * string if SafeSocks is enabled. */
339 ADD_DATA(buf
, "\x05\x01\x00");
340 ADD_DATA(buf
, "\x05\xF0\x00\x03\x07");
341 ADD_DATA(buf
, "8.8.8.8");
342 ADD_DATA(buf
, "\x11\x11");
343 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
, 1),
346 tt_str_op("8.8.8.8", OP_EQ
, socks
->address
);
347 tt_int_op(4369, OP_EQ
, socks
->port
);
349 tt_int_op(0, OP_EQ
, buf_datalen(buf
));
351 socks_request_clear(socks
);
353 /* SOCKS 5 should NOT reject RESOLVE [F0] request for IPv6 address
354 * string if SafeSocks is enabled. */
356 ADD_DATA(buf
, "\x05\x01\x00");
357 ADD_DATA(buf
, "\x05\xF0\x00\x03\x29");
358 ADD_DATA(buf
, "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
359 ADD_DATA(buf
, "\x01\x02");
360 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
, 1),
363 tt_str_op("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", OP_EQ
,
365 tt_int_op(258, OP_EQ
, socks
->port
);
367 tt_int_op(0, OP_EQ
, buf_datalen(buf
));
369 socks_request_clear(socks
);
371 /* Also allow bracket-less form. */
373 ADD_DATA(buf
, "\x05\x01\x00");
374 ADD_DATA(buf
, "\x05\xF0\x00\x03\x27");
375 ADD_DATA(buf
, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
376 ADD_DATA(buf
, "\x01\x02");
377 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
, 1),
380 tt_str_op("2001:0db8:85a3:0000:0000:8a2e:0370:7334", OP_EQ
,
382 tt_int_op(258, OP_EQ
, socks
->port
);
384 tt_int_op(0, OP_EQ
, buf_datalen(buf
));
386 socks_request_clear(socks
);
388 /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
389 ADD_DATA(buf
, "\x05\x01\x00");
390 ADD_DATA(buf
, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
391 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
392 get_options()->SafeSocks
),
394 tt_int_op(5,OP_EQ
, socks
->socks_version
);
395 tt_int_op(2,OP_EQ
, socks
->replylen
);
396 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
397 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
398 tt_str_op("2.2.2.5",OP_EQ
, socks
->address
);
400 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
402 socks_request_clear(socks
);
404 /* SOCKS 5 Send RESOLVE_PTR [F1] for an IPv6 address */
405 ADD_DATA(buf
, "\x05\x01\x00");
406 ADD_DATA(buf
, "\x05\xF1\x00\x04"
407 "\x20\x01\x0d\xb8\x85\xa3\x00\x00\x00\x00\x8a\x2e\x03\x70\x73\x34"
409 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
410 get_options()->SafeSocks
),
412 tt_int_op(5,OP_EQ
, socks
->socks_version
);
413 tt_int_op(2,OP_EQ
, socks
->replylen
);
414 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
415 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
416 tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ
, socks
->address
);
418 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
420 socks_request_clear(socks
);
422 /* SOCKS 5 Send RESOLVE_PTR [F1] for a an IPv6 address written as a
423 * string with brackets */
424 ADD_DATA(buf
, "\x05\x01\x00");
425 ADD_DATA(buf
, "\x05\xF1\x00\x03\x1e");
426 ADD_DATA(buf
, "[2001:db8:85a3::8a2e:370:7334]");
427 ADD_DATA(buf
, "\x12\x34");
428 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
429 get_options()->SafeSocks
),
431 tt_int_op(5,OP_EQ
, socks
->socks_version
);
432 tt_int_op(2,OP_EQ
, socks
->replylen
);
433 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
434 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
435 tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ
, socks
->address
);
437 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
443 /** Perform SOCKS 5 authentication */
445 test_socks_5_no_authenticate(void *ptr
)
449 /*SOCKS 5 No Authentication */
450 ADD_DATA(buf
,"\x05\x01\x00");
451 tt_assert(!fetch_from_buf_socks(buf
, socks
,
452 get_options()->TestSocks
,
453 get_options()->SafeSocks
));
454 tt_int_op(2,OP_EQ
, socks
->replylen
);
455 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
456 tt_int_op(SOCKS_NO_AUTH
,OP_EQ
, socks
->reply
[1]);
458 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
460 /*SOCKS 5 Send username/password anyway - pretend to be broken */
461 ADD_DATA(buf
,"\x01\x02\x01\x01\x02\x01\x01");
462 tt_assert(!fetch_from_buf_socks(buf
, socks
,
463 get_options()->TestSocks
,
464 get_options()->SafeSocks
));
465 tt_int_op(5,OP_EQ
, socks
->socks_version
);
466 tt_int_op(2,OP_EQ
, socks
->replylen
);
467 tt_int_op(1,OP_EQ
, socks
->reply
[0]);
468 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
470 tt_int_op(2,OP_EQ
, socks
->usernamelen
);
471 tt_int_op(2,OP_EQ
, socks
->passwordlen
);
473 tt_mem_op("\x01\x01",OP_EQ
, socks
->username
, 2);
474 tt_mem_op("\x01\x01",OP_EQ
, socks
->password
, 2);
480 /** Perform SOCKS 5 authentication */
482 test_socks_5_authenticate(void *ptr
)
486 /* SOCKS 5 Negotiate username/password authentication */
487 ADD_DATA(buf
, "\x05\x01\x02");
489 tt_assert(!fetch_from_buf_socks(buf
, socks
,
490 get_options()->TestSocks
,
491 get_options()->SafeSocks
));
492 tt_int_op(2,OP_EQ
, socks
->replylen
);
493 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
494 tt_int_op(SOCKS_USER_PASS
,OP_EQ
, socks
->reply
[1]);
495 tt_int_op(5,OP_EQ
, socks
->socks_version
);
497 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
499 /* SOCKS 5 Send username/password */
500 ADD_DATA(buf
, "\x01\x02me\x08mypasswd");
501 tt_assert(!fetch_from_buf_socks(buf
, socks
,
502 get_options()->TestSocks
,
503 get_options()->SafeSocks
));
504 tt_int_op(5,OP_EQ
, socks
->socks_version
);
505 tt_int_op(2,OP_EQ
, socks
->replylen
);
506 tt_int_op(1,OP_EQ
, socks
->reply
[0]);
507 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
509 tt_int_op(2,OP_EQ
, socks
->usernamelen
);
510 tt_int_op(8,OP_EQ
, socks
->passwordlen
);
512 tt_mem_op("me",OP_EQ
, socks
->username
, 2);
513 tt_mem_op("mypasswd",OP_EQ
, socks
->password
, 8);
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.
524 test_socks_5_authenticate_empty_user_pass(void *ptr
)
528 /* SOCKS 5 Negotiate username/password authentication */
529 ADD_DATA(buf
, "\x05\x01\x02");
531 tt_assert(!fetch_from_buf_socks(buf
, socks
,
532 get_options()->TestSocks
,
533 get_options()->SafeSocks
));
534 tt_int_op(2,OP_EQ
, socks
->replylen
);
535 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
536 tt_int_op(SOCKS_USER_PASS
,OP_EQ
, socks
->reply
[1]);
537 tt_int_op(5,OP_EQ
, socks
->socks_version
);
539 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
541 /* SOCKS 5 Send username/password auth message with empty user/pass fields */
542 ADD_DATA(buf
, "\x01\x00\x00");
543 tt_assert(!fetch_from_buf_socks(buf
, socks
,
544 get_options()->TestSocks
,
545 get_options()->SafeSocks
));
546 tt_int_op(5,OP_EQ
, socks
->socks_version
);
547 tt_int_op(2,OP_EQ
, socks
->replylen
);
548 tt_int_op(1,OP_EQ
, socks
->reply
[0]);
549 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
551 tt_int_op(0,OP_EQ
, socks
->usernamelen
);
552 tt_int_op(0,OP_EQ
, socks
->passwordlen
);
557 /** Perform SOCKS 5 authentication and send data all in one go */
559 test_socks_5_authenticate_with_data(void *ptr
)
563 /* SOCKS 5 Negotiate username/password authentication */
564 ADD_DATA(buf
, "\x05\x01\x02");
566 tt_assert(!fetch_from_buf_socks(buf
, socks
,
567 get_options()->TestSocks
,
568 get_options()->SafeSocks
));
569 tt_int_op(2,OP_EQ
, socks
->replylen
);
570 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
571 tt_int_op(SOCKS_USER_PASS
,OP_EQ
, socks
->reply
[1]);
572 tt_int_op(5,OP_EQ
, socks
->socks_version
);
574 tt_int_op(0,OP_EQ
, buf_datalen(buf
));
576 /* SOCKS 5 Send username/password */
577 /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
578 ADD_DATA(buf
, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
579 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
580 get_options()->SafeSocks
),
582 tt_int_op(5,OP_EQ
, socks
->socks_version
);
583 tt_int_op(2,OP_EQ
, socks
->replylen
);
584 tt_int_op(1,OP_EQ
, socks
->reply
[0]);
585 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
587 tt_str_op("2.2.2.2",OP_EQ
, socks
->address
);
588 tt_int_op(4369,OP_EQ
, socks
->port
);
590 tt_int_op(2,OP_EQ
, socks
->usernamelen
);
591 tt_int_op(3,OP_EQ
, socks
->passwordlen
);
592 tt_mem_op("me",OP_EQ
, socks
->username
, 2);
593 tt_mem_op("you",OP_EQ
, socks
->password
, 3);
599 /** Try to negotiate an unsupported authentication type */
601 test_socks_5_auth_unsupported_type(void *ptr
)
605 /* None of these authentication types are recognized. */
606 ADD_DATA(buf
, "\x05\x03\x99\x21\x10");
607 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
608 get_options()->SafeSocks
),
610 tt_int_op(0,OP_EQ
, socks
->socks_version
);
611 tt_int_op(2,OP_EQ
, socks
->replylen
);
612 tt_int_op(5,OP_EQ
, socks
->reply
[0]);
613 tt_int_op(0xff,OP_EQ
, socks
->reply
[1]);
619 /** Try to negotiate an unsupported version of username/password auth. */
621 test_socks_5_auth_unsupported_version(void *ptr
)
625 /* Negotiate username/password */
626 ADD_DATA(buf
, "\x05\x01\x02");
627 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
628 get_options()->SafeSocks
),
630 tt_int_op(0,OP_EQ
, buf_datalen(buf
)); /* buf should be drained */
631 /* Now, suggest an unrecognized username/password version */
632 ADD_DATA(buf
, "\x02\x05" "hello" "\x05" "world");
633 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
634 get_options()->SafeSocks
),
641 /** Perform SOCKS 5 authentication before method negotiated */
643 test_socks_5_auth_before_negotiation(void *ptr
)
647 /* SOCKS 5 Send username/password */
648 ADD_DATA(buf
, "\x01\x02me\x02me");
649 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
650 get_options()->SafeSocks
),
652 tt_int_op(0,OP_EQ
, socks
->socks_version
);
653 tt_int_op(0,OP_EQ
, socks
->replylen
);
654 tt_int_op(0,OP_EQ
, socks
->reply
[0]);
655 tt_int_op(0,OP_EQ
, socks
->reply
[1]);
661 /** Perform malformed SOCKS 5 commands */
663 test_socks_5_malformed_commands(void *ptr
)
667 /* XXX: Stringified address length > MAX_SOCKS_ADDR_LEN will never happen */
669 /** SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369, with SafeSocks set
671 ADD_DATA(buf
, "\x05\x01\x00");
672 ADD_DATA(buf
, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
673 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
, 1),
676 tt_int_op(5,OP_EQ
,socks
->socks_version
);
677 tt_int_op(10,OP_EQ
,socks
->replylen
);
678 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
679 tt_int_op(SOCKS5_NOT_ALLOWED
,OP_EQ
,socks
->reply
[1]);
680 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
683 socks_request_clear(socks
);
685 /* SOCKS 5 Send RESOLVE_PTR [F1] for FQDN torproject.org */
686 ADD_DATA(buf
, "\x05\x01\x00");
687 ADD_DATA(buf
, "\x05\xF1\x00\x03\x0Etorproject.org\x11\x11");
688 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
689 get_options()->SafeSocks
),OP_EQ
, -1);
691 tt_int_op(5,OP_EQ
,socks
->socks_version
);
692 tt_int_op(10,OP_EQ
,socks
->replylen
);
693 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
694 tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED
,OP_EQ
,socks
->reply
[1]);
695 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
698 socks_request_clear(socks
);
700 /* XXX: len + 1 > MAX_SOCKS_ADDR_LEN (FQDN request) will never happen */
702 /* SOCKS 5 Send CONNECT [01] to FQDN """"".com */
703 ADD_DATA(buf
, "\x05\x01\x00");
704 ADD_DATA(buf
, "\x05\x01\x00\x03\x09\"\"\"\"\".com\x11\x11");
705 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
706 get_options()->SafeSocks
),OP_EQ
, -1);
708 tt_int_op(5,OP_EQ
,socks
->socks_version
);
709 tt_int_op(10,OP_EQ
,socks
->replylen
);
710 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
711 tt_int_op(SOCKS5_GENERAL_ERROR
,OP_EQ
,socks
->reply
[1]);
712 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
715 socks_request_clear(socks
);
717 /* SOCKS 5 Send CONNECT [01] to address type 0x23 */
718 ADD_DATA(buf
, "\x05\x01\x00");
719 ADD_DATA(buf
, "\x05\x01\x00\x23\x02\x02\x02\x02\x11\x11");
720 tt_int_op(fetch_from_buf_socks(buf
, socks
, get_options()->TestSocks
,
721 get_options()->SafeSocks
),OP_EQ
, -1);
723 tt_int_op(5,OP_EQ
,socks
->socks_version
);
724 tt_int_op(10,OP_EQ
,socks
->replylen
);
725 tt_int_op(5,OP_EQ
,socks
->reply
[0]);
726 /* trunnel parsing will fail with -1 */
727 tt_int_op(SOCKS5_GENERAL_ERROR
,OP_EQ
,socks
->reply
[1]);
728 tt_int_op(1,OP_EQ
,socks
->reply
[3]);
735 test_socks_5_bad_arguments(void *ptr
)
738 setup_capture_of_logs(LOG_DEBUG
);
740 /* Socks5, bogus hostname */
741 ADD_DATA(buf
, "\x05\x01\x00" "\x05\x01\x00\x03\x03" "---" "\x00\x50" );
742 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0), OP_EQ
, -1);
744 expect_log_msg_containing("Your application (using socks5 to port 80) "
745 "gave Tor a malformed hostname: ");
746 mock_clean_saved_logs();
747 socks_request_clear(socks
);
750 teardown_capture_of_logs();
753 /** check for correct behavior when the socks command has not arrived. */
755 test_socks_truncated(void *ptr
)
758 enum { NONE
, AUTH
, ALL
} setup
;
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},
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},
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. */
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"
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"
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"
815 for (i
= 0; i
< ARRAY_LENGTH(commands
); ++i
) {
816 for (j
= 0; j
< commands
[i
].len
; ++j
) {
817 switch (commands
[i
].setup
) {
818 default: FALLTHROUGH
;
820 /* This test calls for no setup on the socks state. */
823 /* This test calls for the socks state to be waiting for
824 * username/password authentication */
825 ADD_DATA(buf
, "\x05\x01\x02");
826 tt_int_op(0, OP_EQ
, fetch_from_buf_socks(buf
, socks
, 0, 0));
827 tt_int_op(0, OP_EQ
, buf_datalen(buf
));
830 /* This test calls for the socks state to be waiting for
831 * the connection request */
832 ADD_DATA(buf
, "\x05\x01\x00");
833 tt_int_op(0, OP_EQ
, fetch_from_buf_socks(buf
, socks
, 0, 0));
834 tt_int_op(0, OP_EQ
, buf_datalen(buf
));
837 TT_BLATHER(("Checking command %u, length %u, omitting char %u", i
, j
,
838 (unsigned)commands
[i
].body
[j
]));
839 buf_add(buf
, commands
[i
].body
, j
);
840 /* This should return 0 meaning "not done yet" */
841 tt_int_op(0, OP_EQ
, fetch_from_buf_socks(buf
, socks
, 0, 0));
842 tt_uint_op(j
, OP_EQ
, buf_datalen(buf
)); /* Nothing was drained */
844 socks_request_free(testdata
->req
);
845 socks
= testdata
->req
= socks_request_new();
853 test_socks_wrong_protocol(void *ptr
)
856 setup_capture_of_logs(LOG_DEBUG
);
859 ADD_DATA(buf
, "GET /index.html HTTP/1.0" );
860 tt_int_op(fetch_from_buf_socks(buf
, socks
, 1, 0), OP_EQ
, -1);
862 expect_log_msg_containing("Socks version 71 not recognized. "
863 "(This port is not an HTTP proxy;");
864 mock_clean_saved_logs();
865 socks_request_clear(socks
);
868 teardown_capture_of_logs();
871 /* Check our client-side socks4 parsing (that is to say, our parsing of
875 test_socks_client_v4(void *arg
)
878 buf_t
*buf
= buf_new();
881 /* Legit socks4 response, success */
882 ADD_DATA(buf
, "\x04\x5a\x20\x25\x01\x02\x03\x04");
884 fetch_from_buf_socks_client(buf
, PROXY_SOCKS4_WANT_CONNECT_OK
,
886 tt_ptr_op(reason
, OP_EQ
, NULL
);
887 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
889 /* Legit socks4 response, failure. */
890 ADD_DATA(buf
, "\x04\x5b\x20\x25\x01\x02\x03\x04");
892 fetch_from_buf_socks_client(buf
, PROXY_SOCKS4_WANT_CONNECT_OK
,
894 tt_ptr_op(reason
, OP_NE
, NULL
);
895 tt_str_op(reason
, OP_EQ
, "server rejected connection");
902 /* Check our client-side socks5 authentication-negotiation parsing (that is to
903 * say, our parsing of server responses).
906 test_socks_client_v5_auth(void *arg
)
909 buf_t
*buf
= buf_new();
912 /* Legit socks5 responses, got a method we like. */
913 ADD_DATA(buf
, "\x05\x00");
915 fetch_from_buf_socks_client(buf
,
916 PROXY_SOCKS5_WANT_AUTH_METHOD_NONE
,
918 tt_ptr_op(reason
, OP_EQ
, NULL
);
919 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
921 /* Same, but we wanted something else. */
922 ADD_DATA(buf
, "\x05\x00");
924 fetch_from_buf_socks_client(buf
,
925 PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929
,
927 tt_ptr_op(reason
, OP_EQ
, NULL
);
928 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
930 /* Same, and they offered a password. */
931 ADD_DATA(buf
, "\x05\x02");
933 fetch_from_buf_socks_client(buf
,
934 PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929
,
936 tt_ptr_op(reason
, OP_EQ
, NULL
);
937 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
939 /* They rejected our method, or selected something we don't know. */
940 ADD_DATA(buf
, "\x05\xff");
942 fetch_from_buf_socks_client(buf
,
943 PROXY_SOCKS5_WANT_AUTH_METHOD_NONE
,
945 tt_str_op(reason
, OP_EQ
, "server doesn't support any of our available "
946 "authentication methods");
949 ADD_DATA(buf
, "\x05\xff");
951 fetch_from_buf_socks_client(buf
,
952 PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929
,
954 tt_str_op(reason
, OP_EQ
, "server doesn't support any of our available "
955 "authentication methods");
959 /* Now check for authentication responses: check success and failure. */
960 ADD_DATA(buf
, "\x01\x00");
962 fetch_from_buf_socks_client(buf
,
963 PROXY_SOCKS5_WANT_AUTH_RFC1929_OK
,
965 tt_ptr_op(reason
, OP_EQ
, NULL
);
966 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
968 ADD_DATA(buf
, "\x01\xf0");
970 fetch_from_buf_socks_client(buf
,
971 PROXY_SOCKS5_WANT_AUTH_RFC1929_OK
,
973 tt_ptr_op(reason
, OP_NE
, NULL
);
974 tt_str_op(reason
, OP_EQ
, "authentication failed");
981 /* Check our client-side socks5 connect parsing (that is to say, our parsing
982 * of server responses).
985 test_socks_client_v5_connect(void *arg
)
988 buf_t
*buf
= buf_new();
991 /* Legit socks5 responses, success, ipv4. */
992 ADD_DATA(buf
, "\x05\x00\x00\x01\x01\x02\x03\x04\x00\x05");
994 fetch_from_buf_socks_client(buf
,
995 PROXY_SOCKS5_WANT_CONNECT_OK
,
997 tt_ptr_op(reason
, OP_EQ
, NULL
);
998 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
1000 /* Legit socks5 responses, success, ipv6. */
1001 ADD_DATA(buf
, "\x05\x00\x00\x04"
1005 fetch_from_buf_socks_client(buf
,
1006 PROXY_SOCKS5_WANT_CONNECT_OK
,
1008 tt_ptr_op(reason
, OP_EQ
, NULL
);
1009 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
1011 /* Legit socks5 responses, success, hostname. */
1012 ADD_DATA(buf
, "\x05\x00\x00\x03\x12"
1013 "gopher.example.com"
1016 fetch_from_buf_socks_client(buf
,
1017 PROXY_SOCKS5_WANT_CONNECT_OK
,
1019 tt_ptr_op(reason
, OP_EQ
, NULL
);
1020 tt_int_op(buf_datalen(buf
), OP_EQ
, 0);
1022 /* Legit socks5 responses, failure, hostname. */
1023 ADD_DATA(buf
, "\x05\x03\x00\x03\x12"
1024 "gopher.example.com"
1026 tt_int_op(-1, OP_EQ
,
1027 fetch_from_buf_socks_client(buf
,
1028 PROXY_SOCKS5_WANT_CONNECT_OK
,
1030 tt_ptr_op(reason
, OP_NE
, NULL
);
1031 tt_str_op(reason
, OP_EQ
, "Network unreachable");
1035 /* Bogus socks5 responses: what is address type 0x17? */
1036 ADD_DATA(buf
, "\x05\x03\x00\x17\x12 blah blah");
1037 tt_int_op(-1, OP_EQ
,
1038 fetch_from_buf_socks_client(buf
,
1039 PROXY_SOCKS5_WANT_CONNECT_OK
,
1041 tt_ptr_op(reason
, OP_NE
, NULL
);
1042 tt_str_op(reason
, OP_EQ
, "invalid response to connect request");
1051 test_socks_client_truncated(void *arg
)
1054 buf_t
*buf
= buf_new();
1055 char *reason
= NULL
;
1057 #define S(str) str, (sizeof(str)-1)
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") },
1080 for (i
= 0; i
< ARRAY_LENGTH(replies
); ++i
) {
1081 for (j
= 0; j
< replies
[i
].len
; ++j
) {
1082 TT_BLATHER(("Checking command %u, length %u", i
, j
));
1083 buf_add(buf
, replies
[i
].body
, j
);
1084 /* This should return 0 meaning "not done yet" */
1086 fetch_from_buf_socks_client(buf
, replies
[i
].state
, &reason
));
1087 tt_uint_op(j
, OP_EQ
, buf_datalen(buf
)); /* Nothing was drained */
1089 tt_ptr_op(reason
, OP_EQ
, NULL
);
1098 #define SOCKSENT(name) \
1099 { #name, test_socks_##name, TT_FORK, &socks_setup, NULL }
1101 struct testcase_t socks_tests
[] = {
1102 SOCKSENT(4_unsupported_commands
),
1103 SOCKSENT(4_supported_commands
),
1104 SOCKSENT(4_bad_arguments
),
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
),
1118 SOCKSENT(truncated
),
1120 SOCKSENT(wrong_protocol
),
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
},