Prop210: Refactor connection_get_* to produce lists and counts
[tor.git] / src / test / test_socks.c
blob465e427930ba6e3abedda414602b632e5d8c169b
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2015, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "or.h"
7 #include "buffers.h"
8 #include "config.h"
9 #include "test.h"
11 typedef struct socks_test_data_t {
12 socks_request_t *req;
13 buf_t *buf;
14 } socks_test_data_t;
16 static void *
17 socks_test_setup(const struct testcase_t *testcase)
19 socks_test_data_t *data = tor_malloc(sizeof(socks_test_data_t));
20 (void)testcase;
21 data->buf = buf_new_with_capacity(256);
22 data->req = socks_request_new();
23 config_register_addressmaps(get_options());
24 return data;
26 static int
27 socks_test_cleanup(const struct testcase_t *testcase, void *ptr)
29 socks_test_data_t *data = ptr;
30 (void)testcase;
31 buf_free(data->buf);
32 socks_request_free(data->req);
33 tor_free(data);
34 return 1;
37 const struct testcase_setup_t socks_setup = {
38 socks_test_setup, socks_test_cleanup
41 #define SOCKS_TEST_INIT() \
42 socks_test_data_t *testdata = ptr; \
43 buf_t *buf = testdata->buf; \
44 socks_request_t *socks = testdata->req;
45 #define ADD_DATA(buf, s) \
46 write_to_buf(s, sizeof(s)-1, buf)
48 static void
49 socks_request_clear(socks_request_t *socks)
51 tor_free(socks->username);
52 tor_free(socks->password);
53 memset(socks, 0, sizeof(socks_request_t));
56 /** Perform unsupported SOCKS 4 commands */
57 static void
58 test_socks_4_unsupported_commands(void *ptr)
60 SOCKS_TEST_INIT();
62 /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
63 ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
64 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
65 get_options()->SafeSocks) == -1);
66 tt_int_op(4,OP_EQ, socks->socks_version);
67 tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
69 done:
73 /** Perform supported SOCKS 4 commands */
74 static void
75 test_socks_4_supported_commands(void *ptr)
77 SOCKS_TEST_INIT();
79 tt_int_op(0,OP_EQ, buf_datalen(buf));
81 /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */
82 ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
83 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
84 get_options()->SafeSocks) == 1);
85 tt_int_op(4,OP_EQ, socks->socks_version);
86 tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
87 tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
88 tt_str_op("2.2.2.3",OP_EQ, socks->address);
89 tt_int_op(4370,OP_EQ, socks->port);
90 tt_assert(socks->got_auth == 0);
91 tt_assert(! socks->username);
93 tt_int_op(0,OP_EQ, buf_datalen(buf));
94 socks_request_clear(socks);
96 /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/
97 ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
98 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
99 get_options()->SafeSocks) == 1);
100 tt_int_op(4,OP_EQ, socks->socks_version);
101 tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
102 tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
103 tt_str_op("2.2.2.4",OP_EQ, socks->address);
104 tt_int_op(4370,OP_EQ, socks->port);
105 tt_assert(socks->got_auth == 1);
106 tt_assert(socks->username);
107 tt_int_op(2,OP_EQ, socks->usernamelen);
108 tt_mem_op("me",OP_EQ, socks->username, 2);
110 tt_int_op(0,OP_EQ, buf_datalen(buf));
111 socks_request_clear(socks);
113 /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
114 ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
115 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
116 get_options()->SafeSocks) == 1);
117 tt_int_op(4,OP_EQ, socks->socks_version);
118 tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
119 tt_str_op("torproject.org",OP_EQ, socks->address);
121 tt_int_op(0,OP_EQ, buf_datalen(buf));
123 done:
127 /** Perform unsupported SOCKS 5 commands */
128 static void
129 test_socks_5_unsupported_commands(void *ptr)
131 SOCKS_TEST_INIT();
133 /* SOCKS 5 Send unsupported BIND [02] command */
134 ADD_DATA(buf, "\x05\x02\x00\x01");
136 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
137 get_options()->SafeSocks),OP_EQ, 0);
138 tt_int_op(0,OP_EQ, buf_datalen(buf));
139 tt_int_op(5,OP_EQ, socks->socks_version);
140 tt_int_op(2,OP_EQ, socks->replylen);
141 tt_int_op(5,OP_EQ, socks->reply[0]);
142 tt_int_op(0,OP_EQ, socks->reply[1]);
143 ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
144 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
145 get_options()->SafeSocks),OP_EQ, -1);
147 tt_int_op(5,OP_EQ,socks->socks_version);
148 tt_int_op(10,OP_EQ,socks->replylen);
149 tt_int_op(5,OP_EQ,socks->reply[0]);
150 tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
151 tt_int_op(1,OP_EQ,socks->reply[3]);
153 buf_clear(buf);
154 socks_request_clear(socks);
156 /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
157 ADD_DATA(buf, "\x05\x02\x00\x01");
158 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
159 get_options()->SafeSocks),OP_EQ, 0);
160 tt_int_op(5,OP_EQ, socks->socks_version);
161 tt_int_op(2,OP_EQ, socks->replylen);
162 tt_int_op(5,OP_EQ, socks->reply[0]);
163 tt_int_op(0,OP_EQ, socks->reply[1]);
164 ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
165 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
166 get_options()->SafeSocks),OP_EQ, -1);
168 tt_int_op(5,OP_EQ,socks->socks_version);
169 tt_int_op(10,OP_EQ,socks->replylen);
170 tt_int_op(5,OP_EQ,socks->reply[0]);
171 tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
172 tt_int_op(1,OP_EQ,socks->reply[3]);
174 done:
178 /** Perform supported SOCKS 5 commands */
179 static void
180 test_socks_5_supported_commands(void *ptr)
182 SOCKS_TEST_INIT();
184 /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
185 ADD_DATA(buf, "\x05\x01\x00");
186 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
187 get_options()->SafeSocks),OP_EQ, 0);
188 tt_int_op(5,OP_EQ, socks->socks_version);
189 tt_int_op(2,OP_EQ, socks->replylen);
190 tt_int_op(5,OP_EQ, socks->reply[0]);
191 tt_int_op(0,OP_EQ, socks->reply[1]);
193 ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
194 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
195 get_options()->SafeSocks),OP_EQ, 1);
196 tt_str_op("2.2.2.2",OP_EQ, socks->address);
197 tt_int_op(4369,OP_EQ, socks->port);
199 tt_int_op(0,OP_EQ, buf_datalen(buf));
200 socks_request_clear(socks);
202 /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
203 ADD_DATA(buf, "\x05\x01\x00");
204 ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
205 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
206 get_options()->SafeSocks),OP_EQ, 1);
208 tt_int_op(5,OP_EQ, socks->socks_version);
209 tt_int_op(2,OP_EQ, socks->replylen);
210 tt_int_op(5,OP_EQ, socks->reply[0]);
211 tt_int_op(0,OP_EQ, socks->reply[1]);
212 tt_str_op("torproject.org",OP_EQ, socks->address);
213 tt_int_op(4369,OP_EQ, socks->port);
215 tt_int_op(0,OP_EQ, buf_datalen(buf));
216 socks_request_clear(socks);
218 /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
219 ADD_DATA(buf, "\x05\x01\x00");
220 ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
221 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
222 get_options()->SafeSocks) == 1);
223 tt_int_op(5,OP_EQ, socks->socks_version);
224 tt_int_op(2,OP_EQ, socks->replylen);
225 tt_int_op(5,OP_EQ, socks->reply[0]);
226 tt_int_op(0,OP_EQ, socks->reply[1]);
227 tt_str_op("torproject.org",OP_EQ, socks->address);
229 tt_int_op(0,OP_EQ, buf_datalen(buf));
230 socks_request_clear(socks);
232 /* SOCKS 5 Should reject RESOLVE [F0] request for IPv4 address
233 * string if SafeSocks is enabled. */
235 ADD_DATA(buf, "\x05\x01\x00");
236 ADD_DATA(buf, "\x05\xF0\x00\x03\x07");
237 ADD_DATA(buf, "8.8.8.8");
238 ADD_DATA(buf, "\x01\x02");
239 tt_assert(fetch_from_buf_socks(buf,socks,get_options()->TestSocks,1)
240 == -1);
242 tt_int_op(5,OP_EQ,socks->socks_version);
243 tt_int_op(10,OP_EQ,socks->replylen);
244 tt_int_op(5,OP_EQ,socks->reply[0]);
245 tt_int_op(SOCKS5_NOT_ALLOWED,OP_EQ,socks->reply[1]);
246 tt_int_op(1,OP_EQ,socks->reply[3]);
248 socks_request_clear(socks);
250 /* SOCKS 5 should reject RESOLVE [F0] reject for IPv6 address
251 * string if SafeSocks is enabled. */
253 ADD_DATA(buf, "\x05\x01\x00");
254 ADD_DATA(buf, "\x05\xF0\x00\x03\x27");
255 ADD_DATA(buf, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
256 ADD_DATA(buf, "\x01\x02");
257 tt_assert(fetch_from_buf_socks(buf,socks,get_options()->TestSocks,1)
258 == -1);
260 tt_int_op(5,OP_EQ,socks->socks_version);
261 tt_int_op(10,OP_EQ,socks->replylen);
262 tt_int_op(5,OP_EQ,socks->reply[0]);
263 tt_int_op(SOCKS5_NOT_ALLOWED,OP_EQ,socks->reply[1]);
264 tt_int_op(1,OP_EQ,socks->reply[3]);
266 socks_request_clear(socks);
268 /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
269 ADD_DATA(buf, "\x05\x01\x00");
270 ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
271 tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
272 get_options()->SafeSocks) == 1);
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]);
277 tt_str_op("2.2.2.5",OP_EQ, socks->address);
279 tt_int_op(0,OP_EQ, buf_datalen(buf));
281 done:
285 /** Perform SOCKS 5 authentication */
286 static void
287 test_socks_5_no_authenticate(void *ptr)
289 SOCKS_TEST_INIT();
291 /*SOCKS 5 No Authentication */
292 ADD_DATA(buf,"\x05\x01\x00");
293 tt_assert(!fetch_from_buf_socks(buf, socks,
294 get_options()->TestSocks,
295 get_options()->SafeSocks));
296 tt_int_op(2,OP_EQ, socks->replylen);
297 tt_int_op(5,OP_EQ, socks->reply[0]);
298 tt_int_op(SOCKS_NO_AUTH,OP_EQ, socks->reply[1]);
300 tt_int_op(0,OP_EQ, buf_datalen(buf));
302 /*SOCKS 5 Send username/password anyway - pretend to be broken */
303 ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01");
304 tt_assert(!fetch_from_buf_socks(buf, socks,
305 get_options()->TestSocks,
306 get_options()->SafeSocks));
307 tt_int_op(5,OP_EQ, socks->socks_version);
308 tt_int_op(2,OP_EQ, socks->replylen);
309 tt_int_op(1,OP_EQ, socks->reply[0]);
310 tt_int_op(0,OP_EQ, socks->reply[1]);
312 tt_int_op(2,OP_EQ, socks->usernamelen);
313 tt_int_op(2,OP_EQ, socks->passwordlen);
315 tt_mem_op("\x01\x01",OP_EQ, socks->username, 2);
316 tt_mem_op("\x01\x01",OP_EQ, socks->password, 2);
318 done:
322 /** Perform SOCKS 5 authentication */
323 static void
324 test_socks_5_authenticate(void *ptr)
326 SOCKS_TEST_INIT();
328 /* SOCKS 5 Negotiate username/password authentication */
329 ADD_DATA(buf, "\x05\x01\x02");
331 tt_assert(!fetch_from_buf_socks(buf, socks,
332 get_options()->TestSocks,
333 get_options()->SafeSocks));
334 tt_int_op(2,OP_EQ, socks->replylen);
335 tt_int_op(5,OP_EQ, socks->reply[0]);
336 tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
337 tt_int_op(5,OP_EQ, socks->socks_version);
339 tt_int_op(0,OP_EQ, buf_datalen(buf));
341 /* SOCKS 5 Send username/password */
342 ADD_DATA(buf, "\x01\x02me\x08mypasswd");
343 tt_assert(!fetch_from_buf_socks(buf, socks,
344 get_options()->TestSocks,
345 get_options()->SafeSocks));
346 tt_int_op(5,OP_EQ, socks->socks_version);
347 tt_int_op(2,OP_EQ, socks->replylen);
348 tt_int_op(1,OP_EQ, socks->reply[0]);
349 tt_int_op(0,OP_EQ, socks->reply[1]);
351 tt_int_op(2,OP_EQ, socks->usernamelen);
352 tt_int_op(8,OP_EQ, socks->passwordlen);
354 tt_mem_op("me",OP_EQ, socks->username, 2);
355 tt_mem_op("mypasswd",OP_EQ, socks->password, 8);
357 done:
361 /** Perform SOCKS 5 authentication and send data all in one go */
362 static void
363 test_socks_5_authenticate_with_data(void *ptr)
365 SOCKS_TEST_INIT();
367 /* SOCKS 5 Negotiate username/password authentication */
368 ADD_DATA(buf, "\x05\x01\x02");
370 tt_assert(!fetch_from_buf_socks(buf, socks,
371 get_options()->TestSocks,
372 get_options()->SafeSocks));
373 tt_int_op(2,OP_EQ, socks->replylen);
374 tt_int_op(5,OP_EQ, socks->reply[0]);
375 tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
376 tt_int_op(5,OP_EQ, socks->socks_version);
378 tt_int_op(0,OP_EQ, buf_datalen(buf));
380 /* SOCKS 5 Send username/password */
381 /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
382 ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
383 tt_assert(fetch_from_buf_socks(buf, socks,
384 get_options()->TestSocks,
385 get_options()->SafeSocks) == 1);
386 tt_int_op(5,OP_EQ, socks->socks_version);
387 tt_int_op(2,OP_EQ, socks->replylen);
388 tt_int_op(1,OP_EQ, socks->reply[0]);
389 tt_int_op(0,OP_EQ, socks->reply[1]);
391 tt_str_op("2.2.2.2",OP_EQ, socks->address);
392 tt_int_op(4369,OP_EQ, socks->port);
394 tt_int_op(2,OP_EQ, socks->usernamelen);
395 tt_int_op(3,OP_EQ, socks->passwordlen);
396 tt_mem_op("me",OP_EQ, socks->username, 2);
397 tt_mem_op("you",OP_EQ, socks->password, 3);
399 done:
403 /** Perform SOCKS 5 authentication before method negotiated */
404 static void
405 test_socks_5_auth_before_negotiation(void *ptr)
407 SOCKS_TEST_INIT();
409 /* SOCKS 5 Send username/password */
410 ADD_DATA(buf, "\x01\x02me\x02me");
411 tt_assert(fetch_from_buf_socks(buf, socks,
412 get_options()->TestSocks,
413 get_options()->SafeSocks) == -1);
414 tt_int_op(0,OP_EQ, socks->socks_version);
415 tt_int_op(0,OP_EQ, socks->replylen);
416 tt_int_op(0,OP_EQ, socks->reply[0]);
417 tt_int_op(0,OP_EQ, socks->reply[1]);
419 done:
423 /** Perform malformed SOCKS 5 commands */
424 static void
425 test_socks_5_malformed_commands(void *ptr)
427 SOCKS_TEST_INIT();
429 /* XXX: Stringified address length > MAX_SOCKS_ADDR_LEN will never happen */
431 /** SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369, with SafeSocks set
433 ADD_DATA(buf, "\x05\x01\x00");
434 ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
435 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
436 OP_EQ, -1);
438 tt_int_op(5,OP_EQ,socks->socks_version);
439 tt_int_op(10,OP_EQ,socks->replylen);
440 tt_int_op(5,OP_EQ,socks->reply[0]);
441 tt_int_op(SOCKS5_NOT_ALLOWED,OP_EQ,socks->reply[1]);
442 tt_int_op(1,OP_EQ,socks->reply[3]);
444 buf_clear(buf);
445 socks_request_clear(socks);
447 /* SOCKS 5 Send RESOLVE_PTR [F1] for FQDN torproject.org */
448 ADD_DATA(buf, "\x05\x01\x00");
449 ADD_DATA(buf, "\x05\xF1\x00\x03\x0Etorproject.org\x11\x11");
450 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
451 get_options()->SafeSocks),OP_EQ, -1);
453 tt_int_op(5,OP_EQ,socks->socks_version);
454 tt_int_op(10,OP_EQ,socks->replylen);
455 tt_int_op(5,OP_EQ,socks->reply[0]);
456 tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
457 tt_int_op(1,OP_EQ,socks->reply[3]);
459 buf_clear(buf);
460 socks_request_clear(socks);
462 /* XXX: len + 1 > MAX_SOCKS_ADDR_LEN (FQDN request) will never happen */
464 /* SOCKS 5 Send CONNECT [01] to FQDN """"".com */
465 ADD_DATA(buf, "\x05\x01\x00");
466 ADD_DATA(buf, "\x05\x01\x00\x03\x09\"\"\"\"\".com\x11\x11");
467 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
468 get_options()->SafeSocks),OP_EQ, -1);
470 tt_int_op(5,OP_EQ,socks->socks_version);
471 tt_int_op(10,OP_EQ,socks->replylen);
472 tt_int_op(5,OP_EQ,socks->reply[0]);
473 tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
474 tt_int_op(1,OP_EQ,socks->reply[3]);
476 buf_clear(buf);
477 socks_request_clear(socks);
479 /* SOCKS 5 Send CONNECT [01] to address type 0x23 */
480 ADD_DATA(buf, "\x05\x01\x00");
481 ADD_DATA(buf, "\x05\x01\x00\x23\x02\x02\x02\x02\x11\x11");
482 tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
483 get_options()->SafeSocks),OP_EQ, -1);
485 tt_int_op(5,OP_EQ,socks->socks_version);
486 tt_int_op(10,OP_EQ,socks->replylen);
487 tt_int_op(5,OP_EQ,socks->reply[0]);
488 tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
489 tt_int_op(1,OP_EQ,socks->reply[3]);
491 done:
495 #define SOCKSENT(name) \
496 { #name, test_socks_##name, TT_FORK, &socks_setup, NULL }
498 struct testcase_t socks_tests[] = {
499 SOCKSENT(4_unsupported_commands),
500 SOCKSENT(4_supported_commands),
502 SOCKSENT(5_unsupported_commands),
503 SOCKSENT(5_supported_commands),
504 SOCKSENT(5_no_authenticate),
505 SOCKSENT(5_auth_before_negotiation),
506 SOCKSENT(5_authenticate),
507 SOCKSENT(5_authenticate_with_data),
508 SOCKSENT(5_malformed_commands),
510 END_OF_TESTCASES