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) {
25 static void test_socks_req_len_socks4_ipv4(void **state) {
28 const sockaddr_t sa = str2sockaddr("127.0.0.1", "4242");
30 size_t len = socks_req_len(PROXY_SOCKS4, &sa);
31 assert_int_equal(9, len);
33 proxyuser = xstrdup(user);
34 len = socks_req_len(PROXY_SOCKS4, &sa);
35 assert_int_equal(9 + userlen, len);
38 static void test_socks_req_len_socks4_ipv6(void **state) {
41 sockaddr_t sa = str2sockaddr("::1", "4242");
42 size_t len = socks_req_len(PROXY_SOCKS4, &sa);
43 assert_int_equal(0, len);
46 static void test_socks_req_len_socks5_ipv4(void **state) {
49 sockaddr_t sa = str2sockaddr("127.0.0.1", "4242");
53 size_t len = socks_req_len(PROXY_SOCKS5, &sa);
54 assert_int_equal(baselen, len);
56 // Setting only password must not change result
57 proxypass = xstrdup(pass);
58 len = socks_req_len(PROXY_SOCKS5, &sa);
59 assert_int_equal(baselen, len);
62 proxyuser = xstrdup(user);
63 len = socks_req_len(PROXY_SOCKS5, &sa);
64 assert_int_equal(baselen + 3 + userlen + passlen, len);
67 static void test_socks_req_len_socks5_ipv6(void **state) {
70 sockaddr_t sa = str2sockaddr("::1", "4242");
74 size_t len = socks_req_len(PROXY_SOCKS5, &sa);
75 assert_int_equal(baselen, len);
77 // Setting only user must not change result
78 proxyuser = xstrdup(user);
79 len = socks_req_len(PROXY_SOCKS5, &sa);
80 assert_int_equal(baselen, len);
83 proxypass = xstrdup(pass);
84 len = socks_req_len(PROXY_SOCKS5, &sa);
85 assert_int_equal(baselen + 3 + userlen + passlen, len);
88 static void test_socks_req_len_wrong_types(void **state) {
91 sockaddr_t sa = str2sockaddr("::1", "4242");
93 assert_int_equal(0, socks_req_len(PROXY_NONE, &sa));
94 assert_int_equal(0, socks_req_len(PROXY_SOCKS4A, &sa));
95 assert_int_equal(0, socks_req_len(PROXY_HTTP, &sa));
96 assert_int_equal(0, socks_req_len(PROXY_EXEC, &sa));
99 static void test_socks_req_len_wrong_family(void **state) {
102 sockaddr_t sa = {.sa.sa_family = AF_UNKNOWN};
103 assert_int_equal(0, socks_req_len(PROXY_SOCKS4, &sa));
104 assert_int_equal(0, socks_req_len(PROXY_SOCKS5, &sa));
107 static void test_check_socks_resp_wrong_types(void **state) {
110 uint8_t buf[512] = {0};
111 assert_false(check_socks_resp(PROXY_NONE, buf, sizeof(buf)));
112 assert_false(check_socks_resp(PROXY_SOCKS4A, buf, sizeof(buf)));
113 assert_false(check_socks_resp(PROXY_HTTP, buf, sizeof(buf)));
114 assert_false(check_socks_resp(PROXY_EXEC, buf, sizeof(buf)));
117 PACKED(struct socks4_response {
124 static const uint32_t localhost_ipv4 = 0x7F000001;
126 static void test_check_socks_resp_socks4_ok(void **state) {
129 const struct socks4_response resp = {
132 .port = htons(12345),
133 .addr = htonl(localhost_ipv4),
135 assert_true(check_socks_resp(PROXY_SOCKS4, &resp, sizeof(resp)));
138 static void test_check_socks_resp_socks4_bad(void **state) {
141 const uint8_t short_len[] = {0x00, 0x5A};
142 assert_false(check_socks_resp(PROXY_SOCKS4, short_len, sizeof(short_len)));
144 const struct socks4_response bad_version = {
147 .port = htons(12345),
148 .addr = htonl(0x7F000001),
150 assert_false(check_socks_resp(PROXY_SOCKS4, &bad_version, sizeof(bad_version)));
152 const struct socks4_response status_denied = {
155 .port = htons(12345),
156 .addr = htonl(0x7F000001),
158 assert_false(check_socks_resp(PROXY_SOCKS4, &status_denied, sizeof(status_denied)));
161 PACKED(struct socks5_response {
163 uint8_t socks_version;
173 uint8_t socks_version;
192 PACKED(struct socks5_test_resp_t {
208 typedef struct socks5_test_resp_t socks5_test_resp_t;
210 static socks5_test_resp_t *make_good_socks5_ipv4(void) {
211 static const socks5_test_resp_t reference = {
213 .choice = {.socks_version = 0x05, .auth_method = 0x02},
215 .status = {.auth_version = 0x01, .auth_status = 0x00},
217 .socks_version = 0x05,
224 .ipv4 = {.addr = 0x01020304, .port = 0x123},
227 socks5_test_resp_t *result = xmalloc(sizeof(socks5_test_resp_t));
228 memcpy(result, &reference, sizeof(reference));
232 static socks5_test_resp_t *make_good_socks5_ipv6(void) {
233 static const socks5_test_resp_t reference = {
235 .choice = {.socks_version = 0x05, .auth_method = 0x02},
237 .status = {.auth_version = 0x01, .auth_status = 0x00},
239 .socks_version = 0x05,
248 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 socks5_test_resp_t *result = xmalloc(sizeof(socks5_test_resp_t));
256 memcpy(result, &reference, sizeof(reference));
260 static void test_check_socks_resp_socks5_ok_ipv4(void **state) {
263 socks5_test_resp_t *resp = make_good_socks5_ipv4();
264 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp)));
268 static void test_check_socks_resp_socks5_ok_ipv6(void **state) {
271 socks5_test_resp_t *resp = make_good_socks5_ipv6();
272 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp)));
276 static void test_check_socks_resp_socks5_short(void **state) {
279 const uint8_t resp[] = {0x05, 0x02};
280 assert_false(check_socks_resp(PROXY_SOCKS5, resp, sizeof(resp)));
283 // Define a test that assigns a bad value to one of the fields and checks that it fails
284 #define BREAK_SOCKS5_FIELD_TEST(proto, name, expr) \
285 static void test_check_socks_resp_socks5_bad_##name##_##proto(void **state) { \
287 socks5_test_resp_t *resp = make_good_socks5_##proto(); \
288 assert_true(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp))); \
290 assert_false(check_socks_resp(PROXY_SOCKS5, resp, sizeof(*resp))); \
294 // Define a test group for IPv4 or IPv6
295 #define BREAK_SOCKS5_TEST_GROUP(proto) \
296 BREAK_SOCKS5_FIELD_TEST(proto, resp_socks_version, resp->resp.pass.resp.socks_version = 0x4) \
297 BREAK_SOCKS5_FIELD_TEST(proto, resp_conn_status, resp->resp.pass.resp.conn_status = 0x1) \
298 BREAK_SOCKS5_FIELD_TEST(proto, resp_addr_type, resp->resp.pass.resp.addr_type = 0x42) \
299 BREAK_SOCKS5_FIELD_TEST(proto, choice_socks_version, resp->resp.choice.socks_version = 0x04) \
300 BREAK_SOCKS5_FIELD_TEST(proto, choice_auth_method, resp->resp.choice.auth_method = 0x12) \
301 BREAK_SOCKS5_FIELD_TEST(proto, status_auth_version, resp->resp.pass.status.auth_version = 0x2) \
302 BREAK_SOCKS5_FIELD_TEST(proto, status_auth_status, resp->resp.pass.status.auth_status = 0x1)
304 BREAK_SOCKS5_TEST_GROUP(ipv4)
305 BREAK_SOCKS5_TEST_GROUP(ipv6)
307 static void test_create_socks_req_socks4(void **state) {
310 const uint8_t ref[8] = {0x04, 0x01, 0x00, 0x7b, 0x01, 0x01, 0x01, 0x01};
311 const sockaddr_t sa = str2sockaddr("1.1.1.1", "123");
314 assert_int_equal(sizeof(ref), create_socks_req(PROXY_SOCKS4, buf, &sa));
315 assert_memory_equal(ref, buf, sizeof(ref));
318 static void test_create_socks_req_socks5_ipv4_anon(void **state) {
321 const sockaddr_t sa = str2sockaddr("2.2.2.2", "16962");
323 const uint8_t ref[13] = {
325 0x05, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42,
328 uint8_t buf[sizeof(ref)];
329 assert_int_equal(12, create_socks_req(PROXY_SOCKS5, buf, &sa));
330 assert_memory_equal(ref, buf, sizeof(ref));
333 static void test_create_socks_req_socks5_ipv4_password(void **state) {
336 proxyuser = xstrdup(user);
337 proxypass = xstrdup(pass);
339 const sockaddr_t sa = str2sockaddr("2.2.2.2", "16962");
341 const uint8_t ref[22] = {
343 0x01, (uint8_t)userlen, 'f', 'o', 'o', (uint8_t)passlen, 'b', 'a', 'r',
344 0x05, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42,
347 uint8_t buf[sizeof(ref)];
348 assert_int_equal(14, create_socks_req(PROXY_SOCKS5, buf, &sa));
349 assert_memory_equal(ref, buf, sizeof(ref));
352 static void test_create_socks_req_socks5_ipv6_anon(void **state) {
355 const sockaddr_t sa = str2sockaddr("1111:2222::3333:4444:5555", "18504");
357 const uint8_t ref[25] = {
359 0x05, 0x01, 0x00, 0x04,
360 0x11, 0x11, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55,
364 uint8_t anon_buf[sizeof(ref)];
365 assert_int_equal(24, create_socks_req(PROXY_SOCKS5, anon_buf, &sa));
366 assert_memory_equal(ref, anon_buf, sizeof(ref));
370 static void test_create_socks_req_socks5_ipv6_password(void **state) {
373 proxyuser = xstrdup(user);
374 proxypass = xstrdup(pass);
376 const sockaddr_t sa = str2sockaddr("4444:2222::6666:4444:1212", "12850");
378 const uint8_t ref[34] = {
380 0x01, (uint8_t)userlen, 'f', 'o', 'o', (uint8_t)passlen, 'b', 'a', 'r',
381 0x05, 0x01, 0x00, 0x04,
382 0x44, 0x44, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x44, 0x44, 0x12, 0x12,
386 uint8_t anon_buf[sizeof(ref)];
387 assert_int_equal(26, create_socks_req(PROXY_SOCKS5, anon_buf, &sa));
388 assert_memory_equal(ref, anon_buf, sizeof(ref));
392 const struct CMUnitTest tests[] = {
393 cmocka_unit_test_teardown(test_socks_req_len_socks4_ipv4, teardown),
394 cmocka_unit_test_teardown(test_socks_req_len_socks4_ipv6, teardown),
395 cmocka_unit_test_teardown(test_socks_req_len_socks5_ipv4, teardown),
396 cmocka_unit_test_teardown(test_socks_req_len_socks5_ipv6, teardown),
397 cmocka_unit_test_teardown(test_socks_req_len_wrong_types, teardown),
398 cmocka_unit_test_teardown(test_socks_req_len_wrong_family, teardown),
400 cmocka_unit_test(test_check_socks_resp_wrong_types),
401 cmocka_unit_test(test_check_socks_resp_socks4_ok),
402 cmocka_unit_test(test_check_socks_resp_socks4_bad),
403 cmocka_unit_test(test_check_socks_resp_socks5_ok_ipv4),
404 cmocka_unit_test(test_check_socks_resp_socks5_ok_ipv6),
405 cmocka_unit_test(test_check_socks_resp_socks5_short),
407 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_socks_version_ipv4),
408 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_conn_status_ipv4),
409 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_addr_type_ipv4),
410 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_socks_version_ipv4),
411 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_auth_method_ipv4),
412 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_version_ipv4),
413 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_status_ipv4),
415 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_socks_version_ipv6),
416 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_conn_status_ipv6),
417 cmocka_unit_test(test_check_socks_resp_socks5_bad_resp_addr_type_ipv6),
418 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_socks_version_ipv6),
419 cmocka_unit_test(test_check_socks_resp_socks5_bad_choice_auth_method_ipv6),
420 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_version_ipv6),
421 cmocka_unit_test(test_check_socks_resp_socks5_bad_status_auth_status_ipv6),
423 cmocka_unit_test_teardown(test_create_socks_req_socks4, teardown),
424 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv4_anon, teardown),
425 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv4_password, teardown),
426 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv6_anon, teardown),
427 cmocka_unit_test_teardown(test_create_socks_req_socks5_ipv6_password, teardown),
429 return cmocka_run_group_tests(tests, NULL, NULL);