test_pt.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2013, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define PT_PRIVATE
  7. #define UTIL_PRIVATE
  8. #include "or.h"
  9. #include "transports.h"
  10. #include "circuitbuild.h"
  11. #include "util.h"
  12. #include "statefile.h"
  13. #include "test.h"
  14. static void
  15. reset_mp(managed_proxy_t *mp)
  16. {
  17. mp->conf_state = PT_PROTO_LAUNCHED;
  18. SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
  19. smartlist_clear(mp->transports);
  20. }
  21. static void
  22. test_pt_parsing(void)
  23. {
  24. char line[200];
  25. transport_t *transport = NULL;
  26. tor_addr_t test_addr;
  27. managed_proxy_t *mp = tor_malloc(sizeof(managed_proxy_t));
  28. mp->conf_state = PT_PROTO_INFANT;
  29. mp->transports = smartlist_new();
  30. /* incomplete cmethod */
  31. strlcpy(line,"CMETHOD trebuchet",sizeof(line));
  32. test_assert(parse_cmethod_line(line, mp) < 0);
  33. reset_mp(mp);
  34. /* wrong proxy type */
  35. strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line));
  36. test_assert(parse_cmethod_line(line, mp) < 0);
  37. reset_mp(mp);
  38. /* wrong addrport */
  39. strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line));
  40. test_assert(parse_cmethod_line(line, mp) < 0);
  41. reset_mp(mp);
  42. /* correct line */
  43. strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
  44. test_assert(parse_cmethod_line(line, mp) == 0);
  45. test_assert(smartlist_len(mp->transports) == 1);
  46. transport = smartlist_get(mp->transports, 0);
  47. /* test registered address of transport */
  48. tor_addr_parse(&test_addr, "127.0.0.1");
  49. test_assert(tor_addr_eq(&test_addr, &transport->addr));
  50. /* test registered port of transport */
  51. test_assert(transport->port == 1999);
  52. /* test registered SOCKS version of transport */
  53. test_assert(transport->socks_version == PROXY_SOCKS5);
  54. /* test registered name of transport */
  55. test_streq(transport->name, "trebuchet");
  56. reset_mp(mp);
  57. /* incomplete smethod */
  58. strlcpy(line,"SMETHOD trebuchet",sizeof(line));
  59. test_assert(parse_smethod_line(line, mp) < 0);
  60. reset_mp(mp);
  61. /* wrong addr type */
  62. strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line));
  63. test_assert(parse_smethod_line(line, mp) < 0);
  64. reset_mp(mp);
  65. /* cowwect */
  66. strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line));
  67. test_assert(parse_smethod_line(line, mp) == 0);
  68. test_assert(smartlist_len(mp->transports) == 1);
  69. transport = smartlist_get(mp->transports, 0);
  70. /* test registered address of transport */
  71. tor_addr_parse(&test_addr, "127.0.0.2");
  72. test_assert(tor_addr_eq(&test_addr, &transport->addr));
  73. /* test registered port of transport */
  74. test_assert(transport->port == 2999);
  75. /* test registered name of transport */
  76. test_streq(transport->name, "trebuchy");
  77. reset_mp(mp);
  78. /* unsupported version */
  79. strlcpy(line,"VERSION 666",sizeof(line));
  80. test_assert(parse_version(line, mp) < 0);
  81. /* incomplete VERSION */
  82. strlcpy(line,"VERSION ",sizeof(line));
  83. test_assert(parse_version(line, mp) < 0);
  84. /* correct VERSION */
  85. strlcpy(line,"VERSION 1",sizeof(line));
  86. test_assert(parse_version(line, mp) == 0);
  87. done:
  88. tor_free(mp);
  89. }
  90. static void
  91. test_pt_protocol(void)
  92. {
  93. char line[200];
  94. managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
  95. mp->conf_state = PT_PROTO_LAUNCHED;
  96. mp->transports = smartlist_new();
  97. mp->argv = tor_malloc_zero(sizeof(char*)*2);
  98. mp->argv[0] = tor_strdup("<testcase>");
  99. /* various wrong protocol runs: */
  100. strlcpy(line,"VERSION 1",sizeof(line));
  101. handle_proxy_line(line, mp);
  102. test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
  103. strlcpy(line,"VERSION 1",sizeof(line));
  104. handle_proxy_line(line, mp);
  105. test_assert(mp->conf_state == PT_PROTO_BROKEN);
  106. reset_mp(mp);
  107. strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
  108. handle_proxy_line(line, mp);
  109. test_assert(mp->conf_state == PT_PROTO_BROKEN);
  110. reset_mp(mp);
  111. /* correct protocol run: */
  112. strlcpy(line,"VERSION 1",sizeof(line));
  113. handle_proxy_line(line, mp);
  114. test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
  115. strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
  116. handle_proxy_line(line, mp);
  117. test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
  118. strlcpy(line,"CMETHODS DONE",sizeof(line));
  119. handle_proxy_line(line, mp);
  120. test_assert(mp->conf_state == PT_PROTO_CONFIGURED);
  121. done:
  122. tor_free(mp);
  123. }
  124. #ifdef _WIN32
  125. #define STDIN_HANDLE HANDLE
  126. #else
  127. #define STDIN_HANDLE FILE
  128. #endif
  129. static smartlist_t *
  130. tor_get_lines_from_handle_replacement(STDIN_HANDLE *handle,
  131. enum stream_status *stream_status_out)
  132. {
  133. (void) handle;
  134. (void) stream_status_out;
  135. static int times_called = 0;
  136. smartlist_t *retval_sl = smartlist_new();
  137. /* Generate some dummy CMETHOD lines the first 5 times. The 6th
  138. time, send 'CMETHODS DONE' to finish configuring the proxy. */
  139. if (times_called++ != 5) {
  140. smartlist_add_asprintf(retval_sl, "CMETHOD mock%d socks5 127.0.0.1:555%d",
  141. times_called, times_called);
  142. } else {
  143. smartlist_add(retval_sl, tor_strdup("CMETHODS DONE"));
  144. }
  145. return retval_sl;
  146. }
  147. /* NOP mock */
  148. static void
  149. tor_process_handle_destroy_replacement(process_handle_t *process_handle,
  150. int also_terminate_process)
  151. {
  152. (void) process_handle;
  153. (void) also_terminate_process;
  154. }
  155. static or_state_t *dummy_state = NULL;
  156. static or_state_t *
  157. get_or_state_replacement(void)
  158. {
  159. return dummy_state;
  160. }
  161. /* Test the configure_proxy() function. */
  162. static void
  163. test_pt_configure_proxy(void *arg)
  164. {
  165. (void) arg;
  166. int i;
  167. managed_proxy_t *mp = NULL;
  168. dummy_state = tor_malloc_zero(sizeof(or_state_t));
  169. MOCK(tor_get_lines_from_handle,
  170. tor_get_lines_from_handle_replacement);
  171. MOCK(tor_process_handle_destroy,
  172. tor_process_handle_destroy_replacement);
  173. MOCK(get_or_state,
  174. get_or_state_replacement);
  175. mp = tor_malloc(sizeof(managed_proxy_t));
  176. mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
  177. mp->transports = smartlist_new();
  178. mp->transports_to_launch = smartlist_new();
  179. mp->process_handle = tor_malloc_zero(sizeof(process_handle_t));
  180. mp->argv = tor_malloc_zero(sizeof(char*)*2);
  181. mp->argv[0] = tor_strdup("<testcase>");
  182. /* Test the return value of configure_proxy() by calling it some
  183. times while it is uninitialized and then finally finalizing its
  184. configuration. */
  185. for (i = 0 ; i < 5 ; i++) {
  186. test_assert(configure_proxy(mp) == 0);
  187. }
  188. test_assert(configure_proxy(mp) == 1);
  189. done:
  190. tor_free(dummy_state);
  191. UNMOCK(tor_get_lines_from_handle);
  192. UNMOCK(tor_process_handle_destroy);
  193. }
  194. #define PT_LEGACY(name) \
  195. { #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
  196. struct testcase_t pt_tests[] = {
  197. PT_LEGACY(parsing),
  198. PT_LEGACY(protocol),
  199. { "configure_proxy",test_pt_configure_proxy, TT_FORK,
  200. NULL, NULL },
  201. END_OF_TESTCASES
  202. };