LCOV - code coverage report
Current view: top level - test - test_pt.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 341 343 99.4 %
Date: 2021-11-24 03:28:48 Functions: 10 10 100.0 %

          Line data    Source code
       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 */
       5             : 
       6             : #include "orconfig.h"
       7             : #define PT_PRIVATE
       8             : #define STATEFILE_PRIVATE
       9             : #define CONTROL_EVENTS_PRIVATE
      10             : #define PROCESS_PRIVATE
      11             : #include "core/or/or.h"
      12             : #include "app/config/config.h"
      13             : #include "lib/confmgt/confmgt.h"
      14             : #include "feature/control/control.h"
      15             : #include "feature/control/control_events.h"
      16             : #include "feature/client/transports.h"
      17             : #include "core/or/circuitbuild.h"
      18             : #include "app/config/statefile.h"
      19             : #include "test/test.h"
      20             : #include "lib/encoding/confline.h"
      21             : #include "lib/net/resolve.h"
      22             : #include "lib/process/process.h"
      23             : 
      24             : #include "app/config/or_state_st.h"
      25             : 
      26             : #include "test/log_test_helpers.h"
      27             : 
      28             : static void
      29          12 : reset_mp(managed_proxy_t *mp)
      30             : {
      31          12 :   mp->conf_state = PT_PROTO_LAUNCHED;
      32          16 :   SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
      33          12 :   smartlist_clear(mp->transports);
      34          12 : }
      35             : 
      36             : static void
      37           1 : test_pt_parsing(void *arg)
      38             : {
      39           1 :   char line[200];
      40           1 :   transport_t *transport = NULL;
      41           1 :   tor_addr_t test_addr;
      42             : 
      43           1 :   managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
      44           1 :   (void)arg;
      45           1 :   mp->conf_state = PT_PROTO_INFANT;
      46           1 :   mp->transports = smartlist_new();
      47             : 
      48             :   /* incomplete cmethod */
      49           1 :   strlcpy(line,"CMETHOD trebuchet",sizeof(line));
      50           1 :   tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0);
      51             : 
      52           1 :   reset_mp(mp);
      53             : 
      54             :   /* wrong proxy type */
      55           1 :   strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line));
      56           1 :   tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0);
      57             : 
      58           1 :   reset_mp(mp);
      59             : 
      60             :   /* wrong addrport */
      61           1 :   strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line));
      62           1 :   tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0);
      63             : 
      64           1 :   reset_mp(mp);
      65             : 
      66             :   /* correct line */
      67           1 :   strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
      68           1 :   tt_int_op(parse_cmethod_line(line, mp), OP_EQ, 0);
      69           1 :   tt_int_op(smartlist_len(mp->transports), OP_EQ, 1);
      70           1 :   transport = smartlist_get(mp->transports, 0);
      71             :   /* test registered address of transport */
      72           1 :   tor_addr_parse(&test_addr, "127.0.0.1");
      73           1 :   tt_assert(tor_addr_eq(&test_addr, &transport->addr));
      74             :   /* test registered port of transport */
      75           1 :   tt_uint_op(transport->port, OP_EQ, 1999);
      76             :   /* test registered SOCKS version of transport */
      77           1 :   tt_int_op(transport->socks_version, OP_EQ, PROXY_SOCKS5);
      78             :   /* test registered name of transport */
      79           1 :   tt_str_op(transport->name,OP_EQ, "trebuchet");
      80             : 
      81           1 :   reset_mp(mp);
      82             : 
      83             :   /* incomplete smethod */
      84           1 :   strlcpy(line,"SMETHOD trebuchet",sizeof(line));
      85           1 :   tt_int_op(parse_smethod_line(line, mp), OP_LT, 0);
      86             : 
      87           1 :   reset_mp(mp);
      88             : 
      89             :   /* wrong addr type */
      90           1 :   strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line));
      91           1 :   tt_int_op(parse_smethod_line(line, mp), OP_LT, 0);
      92             : 
      93           1 :   reset_mp(mp);
      94             : 
      95             :   /* cowwect */
      96           1 :   strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line));
      97           1 :   tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0);
      98           1 :   tt_int_op(smartlist_len(mp->transports), OP_EQ, 1);
      99           1 :   transport = smartlist_get(mp->transports, 0);
     100             :   /* test registered address of transport */
     101           1 :   tor_addr_parse(&test_addr, "127.0.0.2");
     102           1 :   tt_assert(tor_addr_eq(&test_addr, &transport->addr));
     103             :   /* test registered port of transport */
     104           1 :   tt_uint_op(transport->port, OP_EQ, 2999);
     105             :   /* test registered name of transport */
     106           1 :   tt_str_op(transport->name,OP_EQ, "trebuchy");
     107             : 
     108           1 :   reset_mp(mp);
     109             : 
     110             :   /* Include some arguments. Good ones. */
     111           1 :   strlcpy(line,"SMETHOD trebuchet 127.0.0.1:9999 "
     112             :           "ARGS:counterweight=3,sling=snappy",
     113             :           sizeof(line));
     114           1 :   tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0);
     115           1 :   tt_int_op(1, OP_EQ, smartlist_len(mp->transports));
     116             :   {
     117           1 :     const transport_t *transport_ = smartlist_get(mp->transports, 0);
     118           1 :     tt_assert(transport_);
     119           1 :     tt_str_op(transport_->name, OP_EQ, "trebuchet");
     120           1 :     tt_int_op(transport_->port, OP_EQ, 9999);
     121           1 :     tt_str_op(fmt_addr(&transport_->addr), OP_EQ, "127.0.0.1");
     122           1 :     tt_str_op(transport_->extra_info_args, OP_EQ,
     123             :               "counterweight=3,sling=snappy");
     124             :   }
     125           1 :   reset_mp(mp);
     126             : 
     127             :   /* unsupported version */
     128           1 :   strlcpy(line,"VERSION 666",sizeof(line));
     129           1 :   tt_int_op(parse_version(line, mp), OP_LT, 0);
     130             : 
     131             :   /* incomplete VERSION */
     132           1 :   strlcpy(line,"VERSION ",sizeof(line));
     133           1 :   tt_int_op(parse_version(line, mp), OP_LT, 0);
     134             : 
     135             :   /* correct VERSION */
     136           1 :   strlcpy(line,"VERSION 1",sizeof(line));
     137           1 :   tt_int_op(parse_version(line, mp), OP_EQ, 0);
     138             : 
     139           1 :  done:
     140           1 :   reset_mp(mp);
     141           1 :   smartlist_free(mp->transports);
     142           1 :   tor_free(mp);
     143           1 : }
     144             : 
     145             : static void
     146           1 : test_pt_get_transport_options(void *arg)
     147             : {
     148           1 :   char **execve_args;
     149           1 :   smartlist_t *transport_list = smartlist_new();
     150           1 :   managed_proxy_t *mp;
     151           1 :   or_options_t *options = get_options_mutable();
     152           1 :   char *opt_str = NULL;
     153           1 :   config_line_t *cl = NULL;
     154           1 :   (void)arg;
     155             : 
     156           1 :   execve_args = tor_malloc(sizeof(char*)*2);
     157           1 :   execve_args[0] = tor_strdup("cheeseshop");
     158           1 :   execve_args[1] = NULL;
     159             : 
     160           1 :   mp = managed_proxy_create(transport_list, execve_args, 1);
     161           1 :   tt_ptr_op(mp, OP_NE, NULL);
     162           1 :   opt_str = get_transport_options_for_server_proxy(mp);
     163           1 :   tt_ptr_op(opt_str, OP_EQ, NULL);
     164             : 
     165           1 :   smartlist_add_strdup(mp->transports_to_launch, "gruyere");
     166           1 :   smartlist_add_strdup(mp->transports_to_launch, "roquefort");
     167           1 :   smartlist_add_strdup(mp->transports_to_launch, "stnectaire");
     168             : 
     169           1 :   tt_assert(options);
     170             : 
     171           1 :   cl = tor_malloc_zero(sizeof(config_line_t));
     172           1 :   cl->value = tor_strdup("gruyere melty=10 hardness=se;ven");
     173           1 :   options->ServerTransportOptions = cl;
     174             : 
     175           1 :   cl = tor_malloc_zero(sizeof(config_line_t));
     176           1 :   cl->value = tor_strdup("stnectaire melty=4 hardness=three");
     177           1 :   cl->next = options->ServerTransportOptions;
     178           1 :   options->ServerTransportOptions = cl;
     179             : 
     180           1 :   cl = tor_malloc_zero(sizeof(config_line_t));
     181           1 :   cl->value = tor_strdup("pepperjack melty=12 hardness=five");
     182           1 :   cl->next = options->ServerTransportOptions;
     183           1 :   options->ServerTransportOptions = cl;
     184             : 
     185           1 :   opt_str = get_transport_options_for_server_proxy(mp);
     186           1 :   tt_str_op(opt_str, OP_EQ,
     187             :             "gruyere:melty=10;gruyere:hardness=se\\;ven;"
     188             :             "stnectaire:melty=4;stnectaire:hardness=three");
     189             : 
     190           1 :  done:
     191           1 :   tor_free(opt_str);
     192           1 :   config_free_lines(cl);
     193           1 :   managed_proxy_destroy(mp, 0);
     194           1 :   smartlist_free(transport_list);
     195           1 : }
     196             : 
     197             : static void
     198           1 : test_pt_protocol(void *arg)
     199             : {
     200           1 :   char line[200];
     201             : 
     202           1 :   managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
     203           1 :   (void)arg;
     204           1 :   mp->conf_state = PT_PROTO_LAUNCHED;
     205           1 :   mp->transports = smartlist_new();
     206           1 :   mp->argv = tor_calloc(2, sizeof(char *));
     207           1 :   mp->argv[0] = tor_strdup("<testcase>");
     208             : 
     209             :   /* various wrong protocol runs: */
     210             : 
     211           1 :   strlcpy(line,"VERSION 1",sizeof(line));
     212           1 :   handle_proxy_line(line, mp);
     213           1 :   tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
     214             : 
     215           1 :   strlcpy(line,"VERSION 1",sizeof(line));
     216           1 :   handle_proxy_line(line, mp);
     217           1 :   tt_assert(mp->conf_state == PT_PROTO_BROKEN);
     218             : 
     219           1 :   reset_mp(mp);
     220             : 
     221           1 :   strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
     222           1 :   handle_proxy_line(line, mp);
     223           1 :   tt_assert(mp->conf_state == PT_PROTO_BROKEN);
     224             : 
     225           1 :   reset_mp(mp);
     226             : 
     227             :   /* correct protocol run: */
     228           1 :   strlcpy(line,"VERSION 1",sizeof(line));
     229           1 :   handle_proxy_line(line, mp);
     230           1 :   tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
     231             : 
     232           1 :   strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
     233           1 :   handle_proxy_line(line, mp);
     234           1 :   tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
     235             : 
     236           1 :   strlcpy(line,"CMETHODS DONE",sizeof(line));
     237           1 :   handle_proxy_line(line, mp);
     238           1 :   tt_assert(mp->conf_state == PT_PROTO_CONFIGURED);
     239             : 
     240           1 :  done:
     241           1 :   reset_mp(mp);
     242           1 :   smartlist_free(mp->transports);
     243           1 :   tor_free(mp->argv[0]);
     244           1 :   tor_free(mp->argv);
     245           1 :   tor_free(mp);
     246           1 : }
     247             : 
     248             : static void
     249           1 : test_pt_get_extrainfo_string(void *arg)
     250             : {
     251           1 :   managed_proxy_t *mp1 = NULL, *mp2 = NULL;
     252           1 :   char **argv1, **argv2;
     253           1 :   smartlist_t *t1 = smartlist_new(), *t2 = smartlist_new();
     254           1 :   int r;
     255           1 :   char *s = NULL;
     256           1 :   (void) arg;
     257             : 
     258           1 :   argv1 = tor_malloc_zero(sizeof(char*)*3);
     259           1 :   argv1[0] = tor_strdup("ewige");
     260           1 :   argv1[1] = tor_strdup("Blumenkraft");
     261           1 :   argv1[2] = NULL;
     262           1 :   argv2 = tor_malloc_zero(sizeof(char*)*4);
     263           1 :   argv2[0] = tor_strdup("und");
     264           1 :   argv2[1] = tor_strdup("ewige");
     265           1 :   argv2[2] = tor_strdup("Schlangenkraft");
     266           1 :   argv2[3] = NULL;
     267             : 
     268           1 :   mp1 = managed_proxy_create(t1, argv1, 1);
     269           1 :   mp2 = managed_proxy_create(t2, argv2, 1);
     270             : 
     271           1 :   r = parse_smethod_line("SMETHOD hagbard 127.0.0.1:5555", mp1);
     272           1 :   tt_int_op(r, OP_EQ, 0);
     273           1 :   r = parse_smethod_line("SMETHOD celine 127.0.0.1:1723 ARGS:card=no-enemy",
     274             :                          mp2);
     275           1 :   tt_int_op(r, OP_EQ, 0);
     276             : 
     277             :   /* Force these proxies to look "completed" or they won't generate output. */
     278           1 :   mp1->conf_state = mp2->conf_state = PT_PROTO_COMPLETED;
     279             : 
     280           1 :   s = pt_get_extra_info_descriptor_string();
     281           1 :   tt_assert(s);
     282           1 :   tt_str_op(s, OP_EQ,
     283             :             "transport hagbard 127.0.0.1:5555\n"
     284             :             "transport celine 127.0.0.1:1723 card=no-enemy\n");
     285             : 
     286           1 :  done:
     287             :   /* XXXX clean up better */
     288           1 :   smartlist_free(t1);
     289           1 :   smartlist_free(t2);
     290           1 :   tor_free(s);
     291           1 : }
     292             : 
     293             : static int
     294           8 : process_read_stdout_replacement(process_t *process, buf_t *buffer)
     295             : {
     296           8 :   (void)process;
     297           8 :   static int times_called = 0;
     298             : 
     299             :   /* Generate some dummy CMETHOD lines the first 5 times. The 6th
     300             :      time, send 'CMETHODS DONE' to finish configuring the proxy. */
     301           8 :   times_called++;
     302             : 
     303           8 :   if (times_called <= 5) {
     304           5 :     buf_add_printf(buffer, "SMETHOD mock%d 127.0.0.1:555%d\n",
     305             :                            times_called, times_called);
     306           3 :   } else if (times_called <= 6) {
     307           1 :     buf_add_string(buffer, "SMETHODS DONE\n");
     308           2 :   } else if (times_called <= 7) {
     309           1 :     buf_add_string(buffer, "LOG SEVERITY=error MESSAGE=\"Oh noes, something "
     310             :                            "bad happened. What do we do!?\"\n");
     311           1 :     buf_add_string(buffer, "LOG SEVERITY=warning MESSAGE=\"warning msg\"\n");
     312           1 :     buf_add_string(buffer, "LOG SEVERITY=notice MESSAGE=\"notice msg\"\n");
     313           1 :     buf_add_string(buffer, "LOG SEVERITY=info MESSAGE=\"info msg\"\n");
     314           1 :     buf_add_string(buffer, "LOG SEVERITY=debug MESSAGE=\"debug msg\"\n");
     315           1 :   } else if (times_called <= 8) {
     316           1 :     buf_add_string(buffer, "STATUS TRANSPORT=a K_1=a K_2=b K_3=\"foo bar\"\n");
     317           1 :     buf_add_string(buffer, "STATUS TRANSPORT=b K_1=a K_2=b K_3=\"foo bar\"\n");
     318           1 :     buf_add_string(buffer, "STATUS TRANSPORT=c K_1=a K_2=b K_3=\"foo bar\"\n");
     319             :   }
     320             : 
     321           8 :   return (int)buf_datalen(buffer);
     322             : }
     323             : 
     324             : static or_state_t *dummy_state = NULL;
     325             : 
     326             : static or_state_t *
     327          11 : get_or_state_replacement(void)
     328             : {
     329          11 :   return dummy_state;
     330             : }
     331             : 
     332             : static int controlevent_n = 0;
     333             : static uint16_t controlevent_event = 0;
     334             : static smartlist_t *controlevent_msgs = NULL;
     335             : 
     336             : static void
     337          13 : queue_control_event_string_replacement(uint16_t event, char *msg)
     338             : {
     339          13 :   ++controlevent_n;
     340          13 :   controlevent_event = event;
     341          13 :   if (!controlevent_msgs)
     342           1 :     controlevent_msgs = smartlist_new();
     343          13 :   smartlist_add(controlevent_msgs, msg);
     344          13 : }
     345             : 
     346             : /* Test the configure_proxy() function. */
     347             : static void
     348           1 : test_pt_configure_proxy(void *arg)
     349             : {
     350           1 :   int i, retval;
     351           1 :   managed_proxy_t *mp = NULL;
     352           1 :   (void) arg;
     353             : 
     354           1 :   dummy_state = or_state_new();
     355             : 
     356           1 :   MOCK(process_read_stdout, process_read_stdout_replacement);
     357           1 :   MOCK(get_or_state,
     358             :        get_or_state_replacement);
     359           1 :   MOCK(queue_control_event_string,
     360             :        queue_control_event_string_replacement);
     361             : 
     362           1 :   control_testing_set_global_event_mask(EVENT_TRANSPORT_LAUNCHED);
     363             : 
     364           1 :   mp = tor_malloc_zero(sizeof(managed_proxy_t));
     365           1 :   mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
     366           1 :   mp->transports = smartlist_new();
     367           1 :   mp->transports_to_launch = smartlist_new();
     368           1 :   mp->argv = tor_malloc_zero(sizeof(char*)*2);
     369           1 :   mp->argv[0] = tor_strdup("<testcase>");
     370           1 :   mp->is_server = 1;
     371             : 
     372             :   /* Configure the process. */
     373           1 :   mp->process = process_new("");
     374           1 :   process_set_stdout_read_callback(mp->process, managed_proxy_stdout_callback);
     375           1 :   process_set_data(mp->process, mp);
     376             : 
     377             :   /* Test the return value of configure_proxy() by calling it some
     378             :      times while it is uninitialized and then finally finalizing its
     379             :      configuration. */
     380           1 :   for (i = 0 ; i < 5 ; i++) {
     381             :     /* force a read from our mocked stdout reader. */
     382           5 :     process_notify_event_stdout(mp->process);
     383             :     /* try to configure our proxy. */
     384           5 :     retval = configure_proxy(mp);
     385             :     /* retval should be zero because proxy hasn't finished configuring yet */
     386           5 :     tt_int_op(retval, OP_EQ, 0);
     387             :     /* check the number of registered transports */
     388           5 :     tt_int_op(smartlist_len(mp->transports), OP_EQ, i+1);
     389             :     /* check that the mp is still waiting for transports */
     390          11 :     tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
     391             :   }
     392             : 
     393             :   /* Get the SMETHOD DONE written to the process. */
     394           1 :   process_notify_event_stdout(mp->process);
     395             : 
     396             :   /* this last configure_proxy() should finalize the proxy configuration. */
     397           1 :   retval = configure_proxy(mp);
     398             :   /* retval should be 1 since the proxy finished configuring */
     399           1 :   tt_int_op(retval, OP_EQ, 1);
     400             :   /* check the mp state */
     401           1 :   tt_assert(mp->conf_state == PT_PROTO_COMPLETED);
     402             : 
     403           1 :   tt_int_op(controlevent_n, OP_EQ, 5);
     404           1 :   tt_int_op(controlevent_event, OP_EQ, EVENT_TRANSPORT_LAUNCHED);
     405           1 :   tt_int_op(smartlist_len(controlevent_msgs), OP_EQ, 5);
     406           1 :   smartlist_sort_strings(controlevent_msgs);
     407           1 :   tt_str_op(smartlist_get(controlevent_msgs, 0), OP_EQ,
     408             :             "650 TRANSPORT_LAUNCHED server mock1 127.0.0.1 5551\r\n");
     409           1 :   tt_str_op(smartlist_get(controlevent_msgs, 1), OP_EQ,
     410             :             "650 TRANSPORT_LAUNCHED server mock2 127.0.0.1 5552\r\n");
     411           1 :   tt_str_op(smartlist_get(controlevent_msgs, 2), OP_EQ,
     412             :             "650 TRANSPORT_LAUNCHED server mock3 127.0.0.1 5553\r\n");
     413           1 :   tt_str_op(smartlist_get(controlevent_msgs, 3), OP_EQ,
     414             :             "650 TRANSPORT_LAUNCHED server mock4 127.0.0.1 5554\r\n");
     415           1 :   tt_str_op(smartlist_get(controlevent_msgs, 4), OP_EQ,
     416             :             "650 TRANSPORT_LAUNCHED server mock5 127.0.0.1 5555\r\n");
     417             : 
     418             :   /* Get the log message out. */
     419           1 :   setup_full_capture_of_logs(LOG_ERR);
     420           1 :   process_notify_event_stdout(mp->process);
     421           1 :   expect_single_log_msg_containing("Oh noes, something bad happened");
     422           1 :   teardown_capture_of_logs();
     423             : 
     424           1 :   tt_int_op(controlevent_n, OP_EQ, 10);
     425           1 :   tt_int_op(controlevent_event, OP_EQ, EVENT_PT_LOG);
     426           1 :   tt_int_op(smartlist_len(controlevent_msgs), OP_EQ, 10);
     427           1 :   tt_str_op(smartlist_get(controlevent_msgs, 5), OP_EQ,
     428             :             "650 PT_LOG PT=<testcase> SEVERITY=error "
     429             :             "MESSAGE=\"Oh noes, "
     430             :             "something bad happened. What do we do!?\"\r\n");
     431           1 :   tt_str_op(smartlist_get(controlevent_msgs, 6), OP_EQ,
     432             :             "650 PT_LOG PT=<testcase> SEVERITY=warning "
     433             :             "MESSAGE=\"warning msg\"\r\n");
     434           1 :   tt_str_op(smartlist_get(controlevent_msgs, 7), OP_EQ,
     435             :             "650 PT_LOG PT=<testcase> SEVERITY=notice "
     436             :             "MESSAGE=\"notice msg\"\r\n");
     437           1 :   tt_str_op(smartlist_get(controlevent_msgs, 8), OP_EQ,
     438             :             "650 PT_LOG PT=<testcase> SEVERITY=info "
     439             :             "MESSAGE=\"info msg\"\r\n");
     440           1 :   tt_str_op(smartlist_get(controlevent_msgs, 9), OP_EQ,
     441             :             "650 PT_LOG PT=<testcase> SEVERITY=debug "
     442             :             "MESSAGE=\"debug msg\"\r\n");
     443             : 
     444             :   /* Get the STATUS messages out. */
     445           1 :   process_notify_event_stdout(mp->process);
     446             : 
     447           1 :   tt_int_op(controlevent_n, OP_EQ, 13);
     448           1 :   tt_int_op(controlevent_event, OP_EQ, EVENT_PT_STATUS);
     449           1 :   tt_int_op(smartlist_len(controlevent_msgs), OP_EQ, 13);
     450             : 
     451           1 :   tt_str_op(smartlist_get(controlevent_msgs, 10), OP_EQ,
     452             :             "650 PT_STATUS "
     453             :             "PT=<testcase> TRANSPORT=a K_1=a K_2=b K_3=\"foo bar\"\r\n");
     454           1 :   tt_str_op(smartlist_get(controlevent_msgs, 11), OP_EQ,
     455             :             "650 PT_STATUS "
     456             :             "PT=<testcase> TRANSPORT=b K_1=a K_2=b K_3=\"foo bar\"\r\n");
     457           1 :   tt_str_op(smartlist_get(controlevent_msgs, 12), OP_EQ,
     458             :             "650 PT_STATUS "
     459             :             "PT=<testcase> TRANSPORT=c K_1=a K_2=b K_3=\"foo bar\"\r\n");
     460             : 
     461             :   { /* check that the transport info were saved properly in the tor state */
     462           1 :     config_line_t *transport_in_state = NULL;
     463           1 :     smartlist_t *transport_info_sl = smartlist_new();
     464           1 :     char *name_of_transport = NULL;
     465           1 :     char *bindaddr = NULL;
     466             : 
     467             :     /* Get the bindaddr for "mock1" and check it against the bindaddr
     468             :        that the mocked tor_get_lines_from_handle() generated. */
     469           1 :     transport_in_state = get_transport_in_state_by_name("mock1");
     470           1 :     tt_assert(transport_in_state);
     471           1 :     smartlist_split_string(transport_info_sl, transport_in_state->value,
     472             :                            NULL, 0, 0);
     473           1 :     name_of_transport = smartlist_get(transport_info_sl, 0);
     474           1 :     bindaddr = smartlist_get(transport_info_sl, 1);
     475           1 :     tt_str_op(name_of_transport, OP_EQ, "mock1");
     476           1 :     tt_str_op(bindaddr, OP_EQ, "127.0.0.1:5551");
     477             : 
     478           3 :     SMARTLIST_FOREACH(transport_info_sl, char *, cp, tor_free(cp));
     479           1 :     smartlist_free(transport_info_sl);
     480             :   }
     481             : 
     482           1 :  done:
     483           1 :   teardown_capture_of_logs();
     484           1 :   or_state_free(dummy_state);
     485           1 :   UNMOCK(process_read_stdout);
     486           1 :   UNMOCK(get_or_state);
     487           1 :   UNMOCK(queue_control_event_string);
     488           1 :   if (controlevent_msgs) {
     489          14 :     SMARTLIST_FOREACH(controlevent_msgs, char *, cp, tor_free(cp));
     490           1 :     smartlist_free(controlevent_msgs);
     491           1 :     controlevent_msgs = NULL;
     492             :   }
     493           1 :   if (mp->transports) {
     494           6 :     SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
     495           1 :     smartlist_free(mp->transports);
     496             :   }
     497           1 :   smartlist_free(mp->transports_to_launch);
     498           1 :   process_free(mp->process);
     499           1 :   tor_free(mp->argv[0]);
     500           1 :   tor_free(mp->argv);
     501           1 :   tor_free(mp);
     502           1 : }
     503             : 
     504             : /* Test the get_pt_proxy_uri() function. */
     505             : static void
     506           1 : test_get_pt_proxy_uri(void *arg)
     507             : {
     508           1 :   or_options_t *options = get_options_mutable();
     509           1 :   char *uri = NULL;
     510           1 :   int ret;
     511           1 :   (void) arg;
     512             : 
     513             :   /* Test with no proxy. */
     514           1 :   uri = get_pt_proxy_uri();
     515           1 :   tt_ptr_op(uri, OP_EQ, NULL);
     516             : 
     517             :   /* Test with a SOCKS4 proxy. */
     518           1 :   options->Socks4Proxy = tor_strdup("192.0.2.1:1080");
     519           2 :   ret = tor_addr_port_lookup(options->Socks4Proxy,
     520           1 :                              &options->Socks4ProxyAddr,
     521             :                              &options->Socks4ProxyPort);
     522           1 :   tt_int_op(ret, OP_EQ, 0);
     523           1 :   uri = get_pt_proxy_uri();
     524           1 :   tt_str_op(uri, OP_EQ, "socks4a://192.0.2.1:1080");
     525           1 :   tor_free(uri);
     526           1 :   tor_free(options->Socks4Proxy);
     527             : 
     528             :   /* Test with a SOCKS5 proxy, no username/password. */
     529           1 :   options->Socks5Proxy = tor_strdup("192.0.2.1:1080");
     530           2 :   ret = tor_addr_port_lookup(options->Socks5Proxy,
     531           1 :                              &options->Socks5ProxyAddr,
     532             :                              &options->Socks5ProxyPort);
     533           1 :   tt_int_op(ret, OP_EQ, 0);
     534           1 :   uri = get_pt_proxy_uri();
     535           1 :   tt_str_op(uri, OP_EQ, "socks5://192.0.2.1:1080");
     536           1 :   tor_free(uri);
     537             : 
     538             :   /* Test with a SOCKS5 proxy, with username/password. */
     539           1 :   options->Socks5ProxyUsername = tor_strdup("hwest");
     540           1 :   options->Socks5ProxyPassword = tor_strdup("r34n1m470r");
     541           1 :   uri = get_pt_proxy_uri();
     542           1 :   tt_str_op(uri, OP_EQ, "socks5://hwest:r34n1m470r@192.0.2.1:1080");
     543           1 :   tor_free(uri);
     544           1 :   tor_free(options->Socks5Proxy);
     545           1 :   tor_free(options->Socks5ProxyUsername);
     546           1 :   tor_free(options->Socks5ProxyPassword);
     547             : 
     548             :   /* Test with a HTTPS proxy, no authenticator. */
     549           1 :   options->HTTPSProxy = tor_strdup("192.0.2.1:80");
     550           2 :   ret = tor_addr_port_lookup(options->HTTPSProxy,
     551           1 :                              &options->HTTPSProxyAddr,
     552             :                              &options->HTTPSProxyPort);
     553           1 :   tt_int_op(ret, OP_EQ, 0);
     554           1 :   uri = get_pt_proxy_uri();
     555           1 :   tt_str_op(uri, OP_EQ, "http://192.0.2.1:80");
     556           1 :   tor_free(uri);
     557             : 
     558             :   /* Test with a HTTPS proxy, with authenticator. */
     559           1 :   options->HTTPSProxyAuthenticator = tor_strdup("hwest:r34n1m470r");
     560           1 :   uri = get_pt_proxy_uri();
     561           1 :   tt_str_op(uri, OP_EQ, "http://hwest:r34n1m470r@192.0.2.1:80");
     562           1 :   tor_free(uri);
     563           1 :   tor_free(options->HTTPSProxy);
     564           1 :   tor_free(options->HTTPSProxyAuthenticator);
     565             : 
     566             :   /* Token nod to the fact that IPv6 exists. */
     567           1 :   options->Socks4Proxy = tor_strdup("[2001:db8::1]:1080");
     568           1 :   ret = tor_addr_port_lookup(options->Socks4Proxy,
     569             :                              &options->Socks4ProxyAddr,
     570             :                              &options->Socks4ProxyPort);
     571           1 :   tt_int_op(ret, OP_EQ, 0);
     572           1 :   uri = get_pt_proxy_uri();
     573           1 :   tt_str_op(uri, OP_EQ, "socks4a://[2001:db8::1]:1080");
     574           1 :   tor_free(uri);
     575           1 :   tor_free(options->Socks4Proxy);
     576             : 
     577           0 :  done:
     578           1 :   if (uri)
     579           0 :     tor_free(uri);
     580           1 : }
     581             : 
     582             : #ifndef COCCI
     583             : #define PT_LEGACY(name)                                               \
     584             :   { (#name), test_pt_ ## name , 0, NULL, NULL }
     585             : #endif
     586             : 
     587             : struct testcase_t pt_tests[] = {
     588             :   PT_LEGACY(parsing),
     589             :   PT_LEGACY(protocol),
     590             :   { "get_transport_options", test_pt_get_transport_options, TT_FORK,
     591             :     NULL, NULL },
     592             :   { "get_extrainfo_string", test_pt_get_extrainfo_string, TT_FORK,
     593             :     NULL, NULL },
     594             :   { "configure_proxy",test_pt_configure_proxy, TT_FORK,
     595             :     NULL, NULL },
     596             :   { "get_pt_proxy_uri", test_get_pt_proxy_uri, TT_FORK,
     597             :     NULL, NULL },
     598             :   END_OF_TESTCASES
     599             : };

Generated by: LCOV version 1.14