2 #include "../../src/net.h"
3 #include "../../src/netutl.h"
4 #include "../../src/proxy.h"
5 #include "../../src/xalloc.h"
7 static const char *user = "foo";
8 static const size_t userlen = sizeof("foo") - 1;
10 static const char *pass = "bar";
11 static const size_t passlen = sizeof("bar") - 1;
13 static int teardown(void **state) {
28 static void test_socks_req_len_socks4_ipv4(void **state) {
31 const sockaddr_t sa = str2sockaddr("127.0.0.1", "4242");
33 size_t len = socks_req_len(PROXY_SOCKS4, &sa);
34 assert_int_equal(9, len);
36 proxyuser = xstrdup(user);
37 len = socks_req_len(PROXY_SOCKS4, &sa);
38 assert_int_equal(9 + userlen, len);
41 static void test_socks_req_len_socks4_ipv6(void **state) {
44 sockaddr_t sa = str2sockaddr("::1", "4242");
45 size_t len = socks_req_len(PROXY_SOCKS4, &sa);
46 assert_int_equal(0, len);
49 static void test_socks_req_len_socks5_ipv4(void **state) {
52 sockaddr_t sa = str2sockaddr("127.0.0.1", "4242");
56 size_t len = socks_req_len(PROXY_SOCKS5, &sa);
57 assert_int_equal(baselen, len);
59 // Setting only password must not change result
60 proxypass = xstrdup(pass);
61 len = socks_req_len(PROXY_SOCKS5, &sa);
62 assert_int_equal(baselen, len);
65 proxyuser = xstrdup(user);
66 len = socks_req_len(PROXY_SOCKS5, &sa);
67 assert_int_equal(baselen + 3 + userlen + passlen, len);
70 static void test_socks_req_len_socks5_ipv6(void **state) {
73 sockaddr_t sa = str2sockaddr("::1", "4242");
77 size_t len = socks_req_len(PROXY_SOCKS5, &sa);
78 assert_int_equal(baselen, len);
80 // Setting only user must not change result
81 proxyuser = xstrdup(user);
82 len = socks_req_len(PROXY_SOCKS5, &sa);
83 assert_int_equal(baselen, len);
86 proxypass = xstrdup(pass);
87 len = socks_req_len(PROXY_SOCKS5, &sa);
88 assert_int_equal(baselen + 3 + userlen + passlen, len);
91 static void test_socks_req_len_wrong_types(void **state) {
94 sockaddr_t sa = str2sockaddr("::1", "4242");
96 assert_int_equal(0, socks_req_len(PROXY_NONE, &sa));
97 assert_int_equal(0, socks_req_len(PROXY_SOCKS4A, &sa));
98 assert_int_equal(0, socks_req_len(PROXY_HTTP, &sa));
99 assert_int_equal(0, socks_req_len(PROXY_EXEC, &sa));
102 static void test_socks_req_len_wrong_family(void **state) {
105 sockaddr_t sa = {.sa.sa_family = AF_UNKNOWN};
106 assert_int_equal(0, socks_req_len(PROXY_SOCKS4, &sa));
107 assert_int_equal(0, socks_req_len(PROXY_SOCKS5, &sa));
110 static void test_check_socks_resp_wrong_types(void **state) {
113 uint8_t buf[512] = {0};
114 assert_false(check_socks_resp(PROXY_NONE, buf, sizeof(buf)));
115 assert_false(check_socks_resp(PROXY_SOCKS4A, buf, sizeof(buf)));
116 assert_false(check_socks_resp(PROXY_HTTP, buf, sizeof(buf)));
117 assert_false(check_socks_resp(PROXY_EXEC, buf, sizeof(buf)));
120 PACKED(struct socks4_response {
127 static const uint32_t localhost_ipv4 = 0x7F000001;
129 static void test_check_socks_resp_socks4_ok(void **state) {
132 const struct socks4_response resp = {
135 .port = htons(12345),
136 .addr = htonl(localhost_ipv4),
138 assert_true(check_socks_resp(PROXY_SOCKS4, &resp, sizeof(resp)));
141 static void test_check_socks_resp_socks4_bad(void **state) {
144 const uint8_t short_len[] = {0x00, 0x5A};
145 assert_false(check_socks_resp(PROXY_SOCKS4, short_len, sizeof(short_len)));
147 const struct socks4_response bad_version = {
150 .port = htons(12345),
151 .addr = htonl(0x7F000001),
153 assert_false(check_socks_resp(PROXY_SOCKS4, &bad_version, sizeof(bad_version)));
155 const struct socks4_response status_denied = {
158 .port = htons(12345),
159 .addr = htonl(0x7F000001),
161 assert_false(check_socks_resp(PROXY_SOCKS4, &status_denied, sizeof(status_denied)));
164 PACKED(struct socks5_response {
166 uint8_t socks_version;
176 uint8_t socks_version;
195 PACKED(struct socks5_test_resp_t {
211 typedef struct socks5_test_resp_t socks5_test_resp_t;
213 static socks5_test_resp_t *make_good_socks5_ipv4(void) {
214 static const socks5_test_resp_t reference = {
216 .choice = {.socks_version = 0x05, .auth_method = 0x02},
218 .status = {.auth_version = 0x01, .auth_status = 0x00},
220 .socks_version = 0x05,
227 .ipv4 = {.addr = 0x01020304, .port = 0x123},
230 socks5_test_resp_t *result = xmalloc(sizeof(socks5_test_resp_t));
231 memcpy(result, &reference, sizeof(reference));
235 static socks5_test_resp_t *make_good_socks5_ipv6(void) {
236 static const socks5_test_resp_t reference = {
238 .choice = {.socks_version = 0x05, .auth_method = 0x02},
240 .status = {.auth_version = 0x01, .auth_status = 0x00},
242 .socks_version = 0x05,
251 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 socks5_test_resp_t *result = xmalloc(sizeof(socks5_test_resp_t));
259 memcpy(result, &reference, sizeof(reference));
263 static void test_check_socks_resp_socks5_ok_ipv4(void **state) {
266 socks5_test_resp_t *resp = make_good_socks5_ipv4();
267 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp)));
271 static void test_check_socks_resp_socks5_ok_ipv6(void **state) {
274 socks5_test_resp_t *resp = make_good_socks5_ipv6();
275 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp)));
279 static void test_check_socks_resp_socks5_short(void **state) {
282 const uint8_t resp[] = {0x05, 0x02};
283 assert_false(check_socks_resp(PROXY_SOCKS5, resp, sizeof(resp)));
286 // Define a test that assigns a bad value to one of the fields and checks that it fails
287 #define BREAK_SOCKS5_FIELD_TEST(proto, name, expr) \
288 static void test_check_socks_resp_socks5_bad_##name##_##proto(void **state) { \
290 socks5_test_resp_t *resp = make_good_socks5_##proto(); \
291 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp))); \
293 assert_false(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp))); \
297 // Define a test group for IPv4 or IPv6
298 #define BREAK_SOCKS5_TEST_GROUP(proto) \
299 BREAK_SOCKS5_FIELD_TEST(proto, resp_socks_version, resp->resp.pass.resp.socks_version = 0x4) \
300 BREAK_SOCKS5_FIELD_TEST(proto, resp_conn_status, resp->resp.pass.resp.conn_status = 0x1) \
301 BREAK_SOCKS5_FIELD_TEST(proto, resp_addr_type, resp->resp.pass.resp.addr_type = 0x42) \
302 BREAK_SOCKS5_FIELD_TEST(proto, choice_socks_version, resp->resp.choice.socks_version = 0x04) \
303 BREAK_SOCKS5_FIELD_TEST(proto, choice_auth_method, resp->resp.choice.auth_method = 0x12) \
304 BREAK_SOCKS5_FIELD_TEST(proto, status_auth_version, resp->resp.pass.status.auth_version = 0x2) \
305 BREAK_SOCKS5_FIELD_TEST(proto, status_auth_status, resp->resp.pass.status.auth_status = 0x1)
307 BREAK_SOCKS5_TEST_GROUP(ipv4)
308 BREAK_SOCKS5_TEST_GROUP(ipv6)
310 static void test_create_socks_req_socks4(void **state) {
313 const uint8_t ref[8] = {0x04, 0x01, 0x00, 0x7b, 0x01, 0x01, 0x01, 0x01};
314 const sockaddr_t sa = str2sockaddr("1.1.1.1", "123");
317 assert_int_equal(sizeof(ref), create_socks_req(PROXY_SOCKS4, buf, &sa));
318 assert_memory_equal(ref, buf, sizeof(ref));
321 static void test_create_socks_req_socks5_ipv4_anon(void **state) {
324 const sockaddr_t sa = str2sockaddr("2.2.2.2", "16962");
326 const uint8_t ref[13] = {
328 0x05, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42,
331 uint8_t buf[sizeof(ref)];
332 assert_int_equal(12, create_socks_req(PROXY_SOCKS5, buf, &sa));
333 assert_memory_equal(ref, buf, sizeof(ref));
336 static void test_create_socks_req_socks5_ipv4_password(void **state) {
339 proxyuser = xstrdup(user);
340 proxypass = xstrdup(pass);
342 const sockaddr_t sa = str2sockaddr("2.2.2.2", "16962");
344 const uint8_t ref[22] = {
346 0x01, (uint8_t)userlen, 'f', 'o', 'o', (uint8_t)passlen, 'b', 'a', 'r',
347 0x05, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42,
350 uint8_t buf[sizeof(ref)];
351 assert_int_equal(14, create_socks_req(PROXY_SOCKS5, buf, &sa));
352 assert_memory_equal(ref, buf, sizeof(ref));
355 static void test_create_socks_req_socks5_ipv6_anon(void **state) {
358 const sockaddr_t sa = str2sockaddr("1111:2222::3333:4444:5555", "18504");
360 const uint8_t ref[25] = {
362 0x05, 0x01, 0x00, 0x04,
363 0x11, 0x11, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55,
367 uint8_t anon_buf[sizeof(ref)];
368 assert_int_equal(24, create_socks_req(PROXY_SOCKS5, anon_buf, &sa));
369 assert_memory_equal(ref, anon_buf, sizeof(ref));
373 static void test_create_socks_req_socks5_ipv6_password(void **state) {
376 proxyuser = xstrdup(user);
377 proxypass = xstrdup(pass);
379 const sockaddr_t sa = str2sockaddr("4444:2222::6666:4444:1212", "12850");
381 const uint8_t ref[34] = {
383 0x01, (uint8_t)userlen, 'f', 'o', 'o', (uint8_t)passlen, 'b', 'a', 'r',
384 0x05, 0x01, 0x00, 0x04,
385 0x44, 0x44, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x44, 0x44, 0x12, 0x12,
389 uint8_t anon_buf[sizeof(ref)];
390 assert_int_equal(26, create_socks_req(PROXY_SOCKS5, anon_buf, &sa));
391 assert_memory_equal(ref, anon_buf, sizeof(ref));
395 const struct CMUnitTest tests[] = {
396 cmocka_unit_test_teardown(test_socks_req_len_socks4_ipv4, teardown),
397 cmocka_unit_test_teardown(test_socks_req_len_socks4_ipv6, teardown),
398 cmocka_unit_test_teardown(test_socks_req_len_socks5_ipv4, teardown),
399 cmocka_unit_test_teardown(test_socks_req_len_socks5_ipv6, teardown),
400 cmocka_unit_test_teardown(test_socks_req_len_wrong_types, teardown),
401 cmocka_unit_test_teardown(test_socks_req_len_wrong_family, teardown),
403 cmocka_unit_test(test_check_socks_resp_wrong_types),
404 cmocka_unit_test(test_check_socks_resp_socks4_ok),
405 cmocka_unit_test(test_check_socks_resp_socks4_bad),
406 cmocka_unit_test(test_check_socks_resp_socks5_ok_ipv4),
407 cmocka_unit_test(test_check_socks_resp_socks5_ok_ipv6),
408 cmocka_unit_test(test_check_socks_resp_socks5_short),
410 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_socks_version_ipv4),
411 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_conn_status_ipv4),
412 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_addr_type_ipv4),
413 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_socks_version_ipv4),
414 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_auth_method_ipv4),
415 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_version_ipv4),
416 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_status_ipv4),
418 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_socks_version_ipv6),
419 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_conn_status_ipv6),
420 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_addr_type_ipv6),
421 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_socks_version_ipv6),
422 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_auth_method_ipv6),
423 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_version_ipv6),
424 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_status_ipv6),
426 cmocka_unit_test_teardown(test_create_socks_req_socks4, teardown),
427 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv4_anon, teardown),
428 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv4_password, teardown),
429 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv6_anon, teardown),
430 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv6_password, teardown),
432 return cmocka_run_group_tests(tests, NULL, NULL);