tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

transports.c (73813B)


      1 /* Copyright (c) 2011-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file transports.c
      6 * \brief Pluggable Transports related code.
      7 *
      8 * \details
      9 * Each managed proxy is represented by a <b>managed_proxy_t</b>.
     10 * Each managed proxy can support multiple transports.
     11 * Each managed proxy gets configured through a multistep process.
     12 *
     13 * ::managed_proxy_list contains all the managed proxies this tor
     14 * instance is supporting.
     15 * In the ::managed_proxy_list there are ::unconfigured_proxies_n
     16 * managed proxies that are still unconfigured.
     17 *
     18 * In every run_scheduled_event() tick, we attempt to launch and then
     19 * configure the unconfigured managed proxies, using the configuration
     20 * protocol defined in the 180_pluggable_transport.txt proposal. A
     21 * managed proxy might need several ticks to get fully configured.
     22 *
     23 * When a managed proxy is fully configured, we register all its
     24 * transports to the circuitbuild.c subsystem. At that point the
     25 * transports are owned by the circuitbuild.c subsystem.
     26 *
     27 * When a managed proxy fails to follow the 180 configuration
     28 * protocol, it gets marked as broken and gets destroyed.
     29 *
     30 * <b>In a little more detail:</b>
     31 *
     32 * While we are serially parsing torrc, we store all the transports
     33 * that a proxy should spawn in its <em>transports_to_launch</em>
     34 * element.
     35 *
     36 * When we finish reading the torrc, we spawn the managed proxy and
     37 * expect {S,C}METHOD lines from its output. We add transports
     38 * described by METHOD lines to its <em>transports</em> element, as
     39 * transport_t structs.
     40 *
     41 * When the managed proxy stops spitting METHOD lines (signified by a
     42 * '{S,C}METHODS DONE' message) we pass copies of its transports to
     43 * the bridge subsystem. We keep copies of the 'transport_t's on the
     44 * managed proxy to be able to associate the proxy with its
     45 * transports, and we pass copies to the bridge subsystem so that
     46 * transports can be associated with bridges.
     47 * [ XXX We should try see whether the two copies are really needed
     48 * and maybe cut it into a single copy of the 'transport_t' shared
     49 * between the managed proxy and the bridge subsystem. Preliminary
     50 * analysis shows that both copies are needed with the current code
     51 * logic, because of race conditions that can cause dangling
     52 * pointers. ]
     53 *
     54 * <b>In even more detail, this is what happens when a config read
     55 * (like a SIGHUP or a SETCONF) occurs:</b>
     56 *
     57 * We immediately destroy all unconfigured proxies (We shouldn't have
     58 * unconfigured proxies in the first place, except when the config
     59 * read happens immediately after tor is launched.).
     60 *
     61 * We mark all managed proxies and transports to signify that they
     62 * must be removed if they don't contribute by the new torrc
     63 * (we mark using the <b>marked_for_removal</b> element).
     64 * We also mark all managed proxies to signify that they might need to
     65 * be restarted so that they end up supporting all the transports the
     66 * new torrc wants them to support
     67 * (we mark using the <b>was_around_before_config_read</b> element).
     68 * We also clear their <b>transports_to_launch</b> list so that we can
     69 * put there the transports we need to launch according to the new
     70 * torrc.
     71 *
     72 * We then start parsing torrc again.
     73 *
     74 * Every time we encounter a transport line using a managed proxy that
     75 * was around before the config read, we cleanse that proxy from the
     76 * removal mark.  We also toggle the <b>check_if_restarts_needed</b>
     77 * flag, so that on the next <b>pt_configure_remaining_proxies</b>
     78 * tick, we investigate whether we need to restart the proxy so that
     79 * it also spawns the new transports.  If the post-config-read
     80 * <b>transports_to_launch</b> list is identical to the pre-config-read
     81 * one, it means that no changes were introduced to this proxy during
     82 * the config read and no restart has to take place.
     83 *
     84 * During the post-config-read torrc parsing, we unmark all transports
     85 * spawned by managed proxies that we find in our torrc.
     86 * We do that so that if we don't need to restart a managed proxy, we
     87 * can continue using its old transports normally.
     88 * If we end up restarting the proxy, we destroy and unregister all
     89 * old transports from the circuitbuild.c subsystem.
     90 **/
     91 
     92 #include "lib/string/printf.h"
     93 #include "lib/evloop/compat_libevent.h"
     94 #define PT_PRIVATE
     95 #include "core/or/or.h"
     96 #include "feature/client/bridges.h"
     97 #include "app/config/config.h"
     98 #include "core/mainloop/connection.h"
     99 #include "core/or/circuitbuild.h"
    100 #include "feature/hibernate/hibernate.h"
    101 #include "feature/client/transports.h"
    102 #include "feature/relay/router.h"
    103 #include "feature/relay/relay_find_addr.h"
    104 /* 31851: split the server transport code out of the client module */
    105 #include "feature/relay/transport_config.h"
    106 #include "app/config/statefile.h"
    107 #include "core/or/connection_or.h"
    108 #include "feature/relay/ext_orport.h"
    109 #include "feature/control/control_events.h"
    110 #include "lib/encoding/confline.h"
    111 #include "lib/encoding/kvline.h"
    112 
    113 #include "lib/process/process.h"
    114 #include "lib/process/env.h"
    115 
    116 static smartlist_t *
    117 create_managed_proxy_environment(const managed_proxy_t *mp);
    118 
    119 static inline int proxy_configuration_finished(const managed_proxy_t *mp);
    120 
    121 static void handle_finished_proxy(managed_proxy_t *mp);
    122 static void parse_method_error(const char *line, int is_server_method);
    123 #define parse_server_method_error(l) parse_method_error(l, 1)
    124 #define parse_client_method_error(l) parse_method_error(l, 0)
    125 
    126 /** Managed proxy protocol strings */
    127 #define PROTO_ENV_ERROR "ENV-ERROR"
    128 #define PROTO_NEG_SUCCESS "VERSION"
    129 #define PROTO_NEG_FAIL "VERSION-ERROR no-version"
    130 #define PROTO_CMETHOD "CMETHOD"
    131 #define PROTO_SMETHOD "SMETHOD"
    132 #define PROTO_CMETHOD_ERROR "CMETHOD-ERROR"
    133 #define PROTO_SMETHOD_ERROR "SMETHOD-ERROR"
    134 #define PROTO_CMETHODS_DONE "CMETHODS DONE"
    135 #define PROTO_SMETHODS_DONE "SMETHODS DONE"
    136 #define PROTO_PROXY_DONE "PROXY DONE"
    137 #define PROTO_PROXY_ERROR "PROXY-ERROR"
    138 #define PROTO_LOG "LOG"
    139 #define PROTO_STATUS "STATUS"
    140 
    141 /** The first and only supported - at the moment - configuration
    142    protocol version. */
    143 #define PROTO_VERSION_ONE 1
    144 
    145 /** A list of pluggable transports found in torrc. */
    146 static smartlist_t *transport_list = NULL;
    147 
    148 /** Returns a transport_t struct for a transport proxy supporting the
    149    protocol <b>name</b> listening at <b>addr</b>:<b>port</b> using
    150    SOCKS version <b>socks_ver</b>. */
    151 STATIC transport_t *
    152 transport_new(const tor_addr_t *addr, uint16_t port,
    153              const char *name, int socks_ver,
    154              const char *extra_info_args)
    155 {
    156  transport_t *t = tor_malloc_zero(sizeof(transport_t));
    157 
    158  tor_addr_copy(&t->addr, addr);
    159  t->port = port;
    160  t->name = tor_strdup(name);
    161  t->socks_version = socks_ver;
    162  if (extra_info_args)
    163    t->extra_info_args = tor_strdup(extra_info_args);
    164 
    165  return t;
    166 }
    167 
    168 /** Free the pluggable transport struct <b>transport</b>. */
    169 void
    170 transport_free_(transport_t *transport)
    171 {
    172  if (!transport)
    173    return;
    174 
    175  tor_free(transport->name);
    176  tor_free(transport->extra_info_args);
    177  tor_free(transport);
    178 }
    179 
    180 /** Mark every entry of the transport list to be removed on our next call to
    181 * sweep_transport_list unless it has first been un-marked. */
    182 void
    183 mark_transport_list(void)
    184 {
    185  if (!transport_list)
    186    transport_list = smartlist_new();
    187  SMARTLIST_FOREACH(transport_list, transport_t *, t,
    188                    t->marked_for_removal = 1);
    189 }
    190 
    191 /** Remove every entry of the transport list that was marked with
    192 * mark_transport_list if it has not subsequently been un-marked. */
    193 void
    194 sweep_transport_list(void)
    195 {
    196  if (!transport_list)
    197    transport_list = smartlist_new();
    198  SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, t) {
    199    if (t->marked_for_removal) {
    200      SMARTLIST_DEL_CURRENT(transport_list, t);
    201      transport_free(t);
    202    }
    203  } SMARTLIST_FOREACH_END(t);
    204 }
    205 
    206 /** Initialize the pluggable transports list to empty, creating it if
    207 *  needed. */
    208 static void
    209 clear_transport_list(void)
    210 {
    211  if (!transport_list)
    212    transport_list = smartlist_new();
    213  SMARTLIST_FOREACH(transport_list, transport_t *, t, transport_free(t));
    214  smartlist_clear(transport_list);
    215 }
    216 
    217 /** Return a deep copy of <b>transport</b>. */
    218 static transport_t *
    219 transport_copy(const transport_t *transport)
    220 {
    221  transport_t *new_transport = NULL;
    222 
    223  tor_assert(transport);
    224 
    225  new_transport = tor_malloc_zero(sizeof(transport_t));
    226 
    227  new_transport->socks_version = transport->socks_version;
    228  new_transport->name = tor_strdup(transport->name);
    229  tor_addr_copy(&new_transport->addr, &transport->addr);
    230  new_transport->port = transport->port;
    231  new_transport->marked_for_removal = transport->marked_for_removal;
    232 
    233  return new_transport;
    234 }
    235 
    236 /** Returns the transport in our transport list that has the name <b>name</b>.
    237 *  Else returns NULL. */
    238 MOCK_IMPL(transport_t *,
    239 transport_get_by_name,(const char *name))
    240 {
    241  tor_assert(name);
    242 
    243  if (!transport_list)
    244    return NULL;
    245 
    246  SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) {
    247    if (!strcmp(transport->name, name))
    248      return transport;
    249  } SMARTLIST_FOREACH_END(transport);
    250 
    251  return NULL;
    252 }
    253 
    254 /** Resolve any conflicts that the insertion of transport <b>t</b>
    255 *  might cause.
    256 *  Return 0 if <b>t</b> is OK and should be registered, 1 if there is
    257 *  a transport identical to <b>t</b> already registered and -1 if
    258 *  <b>t</b> cannot be added due to conflicts. */
    259 static int
    260 transport_resolve_conflicts(const transport_t *t)
    261 {
    262  /* This is how we resolve transport conflicts:
    263 
    264     If there is already a transport with the same name and addrport,
    265     we either have duplicate torrc lines OR we are here post-HUP and
    266     this transport was here pre-HUP as well. In any case, mark the
    267     old transport so that it doesn't get removed and ignore the new
    268     one. Our caller has to free the new transport so we return '1' to
    269     signify this.
    270 
    271     If there is already a transport with the same name but different
    272     addrport:
    273     * if it's marked for removal, it means that it either has a lower
    274     priority than 't' in torrc (otherwise the mark would have been
    275     cleared by the paragraph above), or it doesn't exist at all in
    276     the post-HUP torrc. We destroy the old transport and register 't'.
    277     * if it's *not* marked for removal, it means that it was newly
    278     added in the post-HUP torrc or that it's of higher priority, in
    279     this case we ignore 't'. */
    280  transport_t *t_tmp = transport_get_by_name(t->name);
    281  if (t_tmp) { /* same name */
    282    if (tor_addr_eq(&t->addr, &t_tmp->addr) && (t->port == t_tmp->port)) {
    283      /* same name *and* addrport */
    284      t_tmp->marked_for_removal = 0;
    285      return 1;
    286    } else { /* same name but different addrport */
    287      char *new_transport_addrport =
    288        tor_strdup(fmt_addrport(&t->addr, t->port));
    289      if (t_tmp->marked_for_removal) { /* marked for removal */
    290        log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s' "
    291                   "but there was already a transport marked for deletion at "
    292                   "'%s'. We deleted the old transport and registered the "
    293                   "new one.", t->name, new_transport_addrport,
    294                   fmt_addrport(&t_tmp->addr, t_tmp->port));
    295        smartlist_remove(transport_list, t_tmp);
    296        transport_free(t_tmp);
    297        tor_free(new_transport_addrport);
    298      } else { /* *not* marked for removal */
    299        log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s' "
    300                   "but the same transport already exists at '%s'. "
    301                   "Skipping.", t->name, new_transport_addrport,
    302                   fmt_addrport(&t_tmp->addr, t_tmp->port));
    303        tor_free(new_transport_addrport);
    304        return -1;
    305      }
    306      tor_free(new_transport_addrport);
    307    }
    308  }
    309 
    310  return 0;
    311 }
    312 
    313 /** Add transport <b>t</b> to the internal list of pluggable
    314 *  transports.
    315 *  Returns 0 if the transport was added correctly, 1 if the same
    316 *  transport was already registered (in this case the caller must
    317 *  free the transport) and -1 if there was an error.  */
    318 static int
    319 transport_add(transport_t *t)
    320 {
    321  int r;
    322  tor_assert(t);
    323 
    324  r = transport_resolve_conflicts(t);
    325 
    326  switch (r) {
    327  case 0: /* should register transport */
    328    if (!transport_list)
    329      transport_list = smartlist_new();
    330    smartlist_add(transport_list, t);
    331    return 0;
    332  default: /* let our caller know the return code */
    333    return r;
    334  }
    335 }
    336 
    337 /** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
    338 *  <b>name</b> is set to the name of the protocol this proxy uses.
    339 *  <b>socks_ver</b> is set to the SOCKS version of the proxy. */
    340 MOCK_IMPL(int,
    341 transport_add_from_config, (const tor_addr_t *addr, uint16_t port,
    342                            const char *name, int socks_ver))
    343 {
    344  transport_t *t = transport_new(addr, port, name, socks_ver, NULL);
    345 
    346  int r = transport_add(t);
    347 
    348  switch (r) {
    349  case -1:
    350  default:
    351    log_notice(LD_GENERAL, "Could not add transport %s at %s. Skipping.",
    352               t->name, fmt_addrport(&t->addr, t->port));
    353    transport_free(t);
    354    return -1;
    355  case 1:
    356    log_info(LD_GENERAL, "Successfully registered transport %s at %s.",
    357             t->name, fmt_addrport(&t->addr, t->port));
    358     transport_free(t); /* falling */
    359     return 0;
    360  case 0:
    361    log_info(LD_GENERAL, "Successfully registered transport %s at %s.",
    362             t->name, fmt_addrport(&t->addr, t->port));
    363    return 0;
    364  }
    365 }
    366 
    367 /** List of unconfigured managed proxies. */
    368 static smartlist_t *managed_proxy_list = NULL;
    369 /** Number of still unconfigured proxies. */
    370 static int unconfigured_proxies_n = 0;
    371 /** Boolean: True iff we might need to restart some proxies. */
    372 static int check_if_restarts_needed = 0;
    373 
    374 /** Return true iff we have a managed_proxy_t in the global list is for the
    375 * given transport name. */
    376 bool
    377 managed_proxy_has_transport(const char *transport_name)
    378 {
    379  tor_assert(transport_name);
    380 
    381  if (!managed_proxy_list) {
    382    return false;
    383  }
    384 
    385  SMARTLIST_FOREACH_BEGIN(managed_proxy_list, const managed_proxy_t *, mp) {
    386    SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, const char *, name) {
    387      if (!strcasecmp(name, transport_name)) {
    388        return true;
    389      }
    390    } SMARTLIST_FOREACH_END(name);
    391  } SMARTLIST_FOREACH_END(mp);
    392 
    393  return false;
    394 }
    395 
    396 /** Return true if there are still unconfigured managed proxies, or proxies
    397 * that need restarting. */
    398 int
    399 pt_proxies_configuration_pending(void)
    400 {
    401  return unconfigured_proxies_n || check_if_restarts_needed;
    402 }
    403 
    404 /** Assert that the unconfigured_proxies_n value correctly matches the number
    405 * of proxies in a state other than PT_PROTO_COMPLETE. */
    406 static void
    407 assert_unconfigured_count_ok(void)
    408 {
    409  int n_completed = 0;
    410  if (!managed_proxy_list) {
    411    tor_assert(unconfigured_proxies_n == 0);
    412    return;
    413  }
    414 
    415  SMARTLIST_FOREACH(managed_proxy_list, managed_proxy_t *, mp, {
    416      if (mp->conf_state == PT_PROTO_COMPLETED)
    417        ++n_completed;
    418  });
    419 
    420  tor_assert(n_completed + unconfigured_proxies_n ==
    421             smartlist_len(managed_proxy_list));
    422 }
    423 
    424 /** Return true if <b>mp</b> has the same argv as <b>proxy_argv</b> */
    425 static int
    426 managed_proxy_has_argv(const managed_proxy_t *mp, char **proxy_argv)
    427 {
    428  char **tmp1=proxy_argv;
    429  char **tmp2=mp->argv;
    430 
    431  tor_assert(tmp1);
    432  tor_assert(tmp2);
    433 
    434  while (*tmp1 && *tmp2) {
    435    if (strcmp(*tmp1++, *tmp2++))
    436      return 0;
    437  }
    438 
    439  if (!*tmp1 && !*tmp2)
    440    return 1;
    441 
    442  return 0;
    443 }
    444 
    445 /** Return a managed proxy with the same argv as <b>proxy_argv</b>.
    446 *  If no such managed proxy exists, return NULL. */
    447 static managed_proxy_t *
    448 get_managed_proxy_by_argv_and_type(char **proxy_argv, int is_server)
    449 {
    450  if (!managed_proxy_list)
    451    return NULL;
    452 
    453  SMARTLIST_FOREACH_BEGIN(managed_proxy_list,  managed_proxy_t *, mp) {
    454    if (managed_proxy_has_argv(mp, proxy_argv) &&
    455        mp->is_server == is_server)
    456      return mp;
    457  } SMARTLIST_FOREACH_END(mp);
    458 
    459  return NULL;
    460 }
    461 
    462 /** Add <b>transport</b> to managed proxy <b>mp</b>. */
    463 static void
    464 add_transport_to_proxy(const char *transport, managed_proxy_t *mp)
    465 {
    466  tor_assert(mp->transports_to_launch);
    467  if (!smartlist_contains_string(mp->transports_to_launch, transport))
    468    smartlist_add_strdup(mp->transports_to_launch, transport);
    469 }
    470 
    471 /** Called when a SIGHUP occurs. Returns true if managed proxy
    472 *  <b>mp</b> needs to be restarted after the SIGHUP, based on the new
    473 *  torrc. */
    474 static int
    475 proxy_needs_restart(const managed_proxy_t *mp)
    476 {
    477  int ret = 1;
    478  char* proxy_uri;
    479 
    480  /* If the PT proxy config has changed, then all existing pluggable transports
    481   * should be restarted.
    482   */
    483 
    484  proxy_uri = get_pt_proxy_uri();
    485  if (strcmp_opt(proxy_uri, mp->proxy_uri) != 0)
    486    goto needs_restart;
    487 
    488  /* mp->transport_to_launch is populated with the names of the
    489     transports that must be launched *after* the SIGHUP.
    490     mp->transports is populated with the transports that were
    491     launched *before* the SIGHUP.
    492 
    493     Check if all the transports that need to be launched are already
    494     launched: */
    495 
    496  tor_assert(smartlist_len(mp->transports_to_launch) > 0);
    497  if (BUG(mp->conf_state != PT_PROTO_COMPLETED)) {
    498    goto needs_restart;
    499  }
    500 
    501  if (smartlist_len(mp->transports_to_launch) != smartlist_len(mp->transports))
    502    goto needs_restart;
    503 
    504  SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) {
    505    if (!smartlist_contains_string(mp->transports_to_launch, t->name))
    506      goto needs_restart;
    507 
    508  } SMARTLIST_FOREACH_END(t);
    509 
    510  ret = 0;
    511 needs_restart:
    512  tor_free(proxy_uri);
    513  return ret;
    514 }
    515 
    516 /** Managed proxy <b>mp</b> must be restarted. Do all the necessary
    517 *  preparations and then flag its state so that it will be relaunched
    518 *  in the next tick. */
    519 static void
    520 proxy_prepare_for_restart(managed_proxy_t *mp)
    521 {
    522  transport_t *t_tmp = NULL;
    523 
    524  /* Rate limit this log as a regurlarly dying PT would log this once every
    525   * second (retry time). Every 5 minutes is likely loud enough to notice. */
    526  static ratelim_t log_died_lim = RATELIM_INIT(300);
    527  log_fn_ratelim(&log_died_lim, LOG_WARN, LD_PT,
    528                 "Managed proxy at '%s' died in state %s", mp->argv[0],
    529                 managed_proxy_state_to_string(mp->conf_state));
    530 
    531  /* destroy the process handle and terminate the process. */
    532  if (mp->process) {
    533    process_set_data(mp->process, NULL);
    534    if (we_are_shutting_down())
    535      log_notice(LD_CONFIG, "Managed proxy \"%s\" having PID %" PRIu64 " "
    536                            "is being terminated...", mp->argv[0],
    537                            process_get_pid(mp->process));
    538    process_terminate(mp->process);
    539  }
    540 
    541  /* destroy all its registered transports, since we will no longer
    542     use them. */
    543  SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) {
    544    t_tmp = transport_get_by_name(t->name);
    545    if (t_tmp)
    546      t_tmp->marked_for_removal = 1;
    547  } SMARTLIST_FOREACH_END(t);
    548  sweep_transport_list();
    549 
    550  /* free the transport in mp->transports */
    551  SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
    552  smartlist_clear(mp->transports);
    553 
    554  /* Reset the proxy's HTTPS/SOCKS proxy */
    555  tor_free(mp->proxy_uri);
    556  mp->proxy_uri = get_pt_proxy_uri();
    557  mp->proxy_supported = 0;
    558 
    559  if (mp->conf_state == PT_PROTO_COMPLETED)
    560    unconfigured_proxies_n++;
    561 
    562  /* flag it as an infant proxy so that it gets launched on next tick */
    563  managed_proxy_set_state(mp, PT_PROTO_INFANT);
    564 }
    565 
    566 /** Launch managed proxy <b>mp</b>. */
    567 static int
    568 launch_managed_proxy(managed_proxy_t *mp)
    569 {
    570  tor_assert(mp);
    571 
    572  smartlist_t *env = create_managed_proxy_environment(mp);
    573 
    574  /* Configure our process. */
    575  tor_assert(mp->process == NULL);
    576  mp->process = process_new(mp->argv[0]);
    577  process_set_data(mp->process, mp);
    578  process_set_stdout_read_callback(mp->process, managed_proxy_stdout_callback);
    579  process_set_stderr_read_callback(mp->process, managed_proxy_stderr_callback);
    580  process_set_exit_callback(mp->process, managed_proxy_exit_callback);
    581  process_set_protocol(mp->process, PROCESS_PROTOCOL_LINE);
    582  process_reset_environment(mp->process, env);
    583 
    584  /* Cleanup our env. */
    585  SMARTLIST_FOREACH(env, char *, x, tor_free(x));
    586  smartlist_free(env);
    587 
    588  /* Skip the argv[0] as we get that from process_new(argv[0]). */
    589  for (int i = 1; mp->argv[i] != NULL; ++i)
    590    process_append_argument(mp->process, mp->argv[i]);
    591 
    592  if (process_exec(mp->process) != PROCESS_STATUS_RUNNING) {
    593    log_warn(LD_CONFIG, "Managed proxy at '%s' failed at launch.",
    594             mp->argv[0]);
    595    return -1;
    596  }
    597 
    598  log_info(LD_CONFIG,
    599           "Managed proxy at '%s' has spawned with PID '%" PRIu64 "'.",
    600           mp->argv[0], process_get_pid(mp->process));
    601  managed_proxy_set_state(mp, PT_PROTO_LAUNCHED);
    602 
    603  return 0;
    604 }
    605 
    606 /** Check if any of the managed proxies we are currently trying to
    607 *  configure has anything new to say. */
    608 void
    609 pt_configure_remaining_proxies(void)
    610 {
    611  int at_least_a_proxy_config_finished = 0;
    612  smartlist_t *tmp = smartlist_new();
    613 
    614  log_debug(LD_CONFIG, "Configuring remaining managed proxies (%d)!",
    615            unconfigured_proxies_n);
    616 
    617  /* Iterate over tmp, not managed_proxy_list, since configure_proxy can
    618   * remove elements from managed_proxy_list. */
    619  smartlist_add_all(tmp, managed_proxy_list);
    620 
    621  assert_unconfigured_count_ok();
    622 
    623  SMARTLIST_FOREACH_BEGIN(tmp,  managed_proxy_t *, mp) {
    624    tor_assert(mp->conf_state != PT_PROTO_BROKEN &&
    625               mp->conf_state != PT_PROTO_FAILED_LAUNCH);
    626 
    627    if (mp->was_around_before_config_read) {
    628      /* This proxy is marked by a config read. Check whether we need
    629         to restart it. */
    630 
    631      mp->was_around_before_config_read = 0;
    632 
    633      if (proxy_needs_restart(mp)) {
    634        log_info(LD_GENERAL, "Preparing managed proxy '%s' for restart.",
    635                 mp->argv[0]);
    636        proxy_prepare_for_restart(mp);
    637      } else { /* it doesn't need to be restarted. */
    638        log_info(LD_GENERAL, "Nothing changed for managed proxy '%s' after "
    639                 "HUP: not restarting.", mp->argv[0]);
    640      }
    641 
    642      continue;
    643    }
    644 
    645    /* If the proxy is not fully configured, try to configure it
    646       further. */
    647    if (!proxy_configuration_finished(mp))
    648      if (configure_proxy(mp) == 1)
    649        at_least_a_proxy_config_finished = 1;
    650 
    651  } SMARTLIST_FOREACH_END(mp);
    652 
    653  smartlist_free(tmp);
    654  check_if_restarts_needed = 0;
    655  assert_unconfigured_count_ok();
    656 
    657  if (at_least_a_proxy_config_finished)
    658    mark_my_descriptor_dirty("configured managed proxies");
    659 }
    660 
    661 /** event callback to launch managed proxy after a delay */
    662 STATIC void
    663 launch_proxy_ev(mainloop_event_t *event, void *v)
    664 {
    665  managed_proxy_t *mp = v;
    666 
    667  (void) event;
    668 
    669  tor_assert(mp);
    670  if (BUG(mp->conf_state != PT_PROTO_WAITING)) {
    671    return;
    672  }
    673 
    674  if (launch_managed_proxy(mp) < 0) { /* launch fail */
    675    managed_proxy_set_state(mp, PT_PROTO_FAILED_LAUNCH);
    676    handle_finished_proxy(mp);
    677  }
    678 }
    679 
    680 /** Attempt to continue configuring managed proxy <b>mp</b>.
    681 *  Return 1 if the transport configuration finished, and return 0
    682 *  otherwise (if we still have more configuring to do for this
    683 *  proxy). */
    684 STATIC int
    685 configure_proxy(managed_proxy_t *mp)
    686 {
    687  /* if we haven't launched the proxy yet, do it now */
    688  if (mp->conf_state == PT_PROTO_INFANT) {
    689    const struct timeval delay_tv = { 1, 0 };
    690    if (!mp->process_launch_ev) {
    691      mp->process_launch_ev = mainloop_event_new(launch_proxy_ev, mp);
    692    }
    693    mainloop_event_schedule(mp->process_launch_ev, &delay_tv);
    694    managed_proxy_set_state(mp, PT_PROTO_WAITING);
    695 
    696    return 0;
    697  }
    698 
    699  tor_assert(mp->conf_state != PT_PROTO_INFANT);
    700  tor_assert(mp->process);
    701  return mp->conf_state == PT_PROTO_COMPLETED;
    702 }
    703 
    704 /** Register server managed proxy <b>mp</b> transports to state */
    705 static void
    706 register_server_proxy(const managed_proxy_t *mp)
    707 {
    708  tor_assert(mp->conf_state != PT_PROTO_COMPLETED);
    709 
    710  SMARTLIST_FOREACH_BEGIN(mp->transports, transport_t *, t) {
    711    save_transport_to_state(t->name, &t->addr, t->port);
    712    log_notice(LD_GENERAL, "Registered server transport '%s' at '%s'",
    713               t->name, fmt_addrport(&t->addr, t->port));
    714    control_event_transport_launched("server", t->name, &t->addr, t->port);
    715  } SMARTLIST_FOREACH_END(t);
    716  pt_update_bridge_lines();
    717 }
    718 
    719 /** Register all the transports supported by client managed proxy
    720 *  <b>mp</b> to the bridge subsystem. */
    721 static void
    722 register_client_proxy(const managed_proxy_t *mp)
    723 {
    724  int r;
    725 
    726  tor_assert(mp->conf_state != PT_PROTO_COMPLETED);
    727 
    728  SMARTLIST_FOREACH_BEGIN(mp->transports, transport_t *, t) {
    729    transport_t *transport_tmp = transport_copy(t);
    730    r = transport_add(transport_tmp);
    731    switch (r) {
    732    case -1:
    733      log_notice(LD_GENERAL, "Could not add transport %s. Skipping.", t->name);
    734      transport_free(transport_tmp);
    735      break;
    736    case 0:
    737      log_info(LD_GENERAL, "Successfully registered transport %s", t->name);
    738      control_event_transport_launched("client", t->name, &t->addr, t->port);
    739      break;
    740    case 1:
    741      log_info(LD_GENERAL, "Successfully registered transport %s", t->name);
    742      control_event_transport_launched("client", t->name, &t->addr, t->port);
    743      transport_free(transport_tmp);
    744      break;
    745    }
    746  } SMARTLIST_FOREACH_END(t);
    747 }
    748 
    749 /** Register the transports of managed proxy <b>mp</b>. */
    750 static inline void
    751 register_proxy(const managed_proxy_t *mp)
    752 {
    753  if (mp->is_server)
    754    register_server_proxy(mp);
    755  else
    756    register_client_proxy(mp);
    757 }
    758 
    759 /** Free memory allocated by managed proxy <b>mp</b>. */
    760 STATIC void
    761 managed_proxy_destroy(managed_proxy_t *mp,
    762                      int also_terminate_process)
    763 {
    764  SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
    765 
    766  /* free the transports smartlist */
    767  smartlist_free(mp->transports);
    768 
    769  /* free the transports_to_launch smartlist */
    770  SMARTLIST_FOREACH(mp->transports_to_launch, char *, t, tor_free(t));
    771  smartlist_free(mp->transports_to_launch);
    772 
    773  /* remove it from the list of managed proxies */
    774  if (managed_proxy_list)
    775    smartlist_remove(managed_proxy_list, mp);
    776 
    777  /* free the argv */
    778  free_execve_args(mp->argv);
    779 
    780  /* free the outgoing proxy URI */
    781  tor_free(mp->proxy_uri);
    782 
    783  /* free our version, if any is set. */
    784  tor_free(mp->version);
    785  tor_free(mp->implementation);
    786 
    787  /* do we want to terminate our process if it's still running? */
    788  if (also_terminate_process && mp->process) {
    789    /* Note that we do not call process_free(mp->process) here because we let
    790     * the exit handler in managed_proxy_exit_callback() return `true` which
    791     * makes the process subsystem deallocate the process_t. */
    792    process_set_data(mp->process, NULL);
    793    process_terminate(mp->process);
    794  }
    795 
    796  if (mp->process_launch_ev)
    797    mainloop_event_free(mp->process_launch_ev);
    798 
    799  tor_free(mp);
    800 }
    801 
    802 /** Convert the tor proxy options to a URI suitable for TOR_PT_PROXY.
    803 * Return a newly allocated string containing the URI, or NULL if no
    804 * proxy is set. */
    805 STATIC char *
    806 get_pt_proxy_uri(void)
    807 {
    808  const or_options_t *options = get_options();
    809  char *uri = NULL;
    810 
    811  /* XXX: Currently TCPProxy is not supported in TOR_PT_PROXY because
    812   * there isn't a standard URI scheme for some proxy protocols, such as
    813   * haproxy. */
    814  if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
    815    char addr[TOR_ADDR_BUF_LEN+1];
    816 
    817    if (options->Socks4Proxy) {
    818      tor_addr_to_str(addr, &options->Socks4ProxyAddr, sizeof(addr), 1);
    819      tor_asprintf(&uri, "socks4a://%s:%d", addr, options->Socks4ProxyPort);
    820    } else if (options->Socks5Proxy) {
    821      tor_addr_to_str(addr, &options->Socks5ProxyAddr, sizeof(addr), 1);
    822      if (!options->Socks5ProxyUsername && !options->Socks5ProxyPassword) {
    823        tor_asprintf(&uri, "socks5://%s:%d", addr, options->Socks5ProxyPort);
    824      } else {
    825        tor_asprintf(&uri, "socks5://%s:%s@%s:%d",
    826                     options->Socks5ProxyUsername,
    827                     options->Socks5ProxyPassword,
    828                     addr, options->Socks5ProxyPort);
    829      }
    830    } else if (options->HTTPSProxy) {
    831      tor_addr_to_str(addr, &options->HTTPSProxyAddr, sizeof(addr), 1);
    832      if (!options->HTTPSProxyAuthenticator) {
    833        tor_asprintf(&uri, "http://%s:%d", addr, options->HTTPSProxyPort);
    834      } else {
    835        tor_asprintf(&uri, "http://%s@%s:%d", options->HTTPSProxyAuthenticator,
    836                     addr, options->HTTPSProxyPort);
    837      }
    838    }
    839  }
    840 
    841  return uri;
    842 }
    843 
    844 /** Handle a configured or broken managed proxy <b>mp</b>. */
    845 static void
    846 handle_finished_proxy(managed_proxy_t *mp)
    847 {
    848  switch (mp->conf_state) {
    849  case PT_PROTO_BROKEN: /* if broken: */
    850    managed_proxy_destroy(mp, 1); /* annihilate it. */
    851    break;
    852  case PT_PROTO_FAILED_LAUNCH: /* if it failed before launching: */
    853    managed_proxy_destroy(mp, 0); /* destroy it but don't terminate */
    854    break;
    855  case PT_PROTO_CONFIGURED: /* if configured correctly: */
    856    if (mp->proxy_uri && !mp->proxy_supported) {
    857      log_warn(LD_CONFIG, "Managed proxy '%s' did not configure the "
    858               "specified outgoing proxy and will be terminated.",
    859               mp->argv[0]);
    860      managed_proxy_destroy(mp, 1); /* annihilate it. */
    861      break;
    862    }
    863 
    864    /* register its transports */
    865    register_proxy(mp);
    866 
    867    /* and mark it as completed. */
    868    managed_proxy_set_state(mp, PT_PROTO_COMPLETED);
    869    break;
    870  case PT_PROTO_INFANT:
    871  case PT_PROTO_WAITING:
    872  case PT_PROTO_LAUNCHED:
    873  case PT_PROTO_ACCEPTING_METHODS:
    874  case PT_PROTO_COMPLETED:
    875  default:
    876    log_warn(LD_CONFIG, "Unexpected state '%d' of managed proxy '%s'.",
    877             (int)mp->conf_state, mp->argv[0]);
    878    tor_assert(0);
    879  }
    880 
    881  unconfigured_proxies_n--;
    882 }
    883 
    884 /** Return true if the configuration of the managed proxy <b>mp</b> is
    885    finished. */
    886 static inline int
    887 proxy_configuration_finished(const managed_proxy_t *mp)
    888 {
    889  return (mp->conf_state == PT_PROTO_CONFIGURED ||
    890          mp->conf_state == PT_PROTO_BROKEN ||
    891          mp->conf_state == PT_PROTO_FAILED_LAUNCH);
    892 }
    893 
    894 /** This function is called when a proxy sends an {S,C}METHODS DONE message. */
    895 static void
    896 handle_methods_done(const managed_proxy_t *mp)
    897 {
    898  tor_assert(mp->transports);
    899 
    900  if (smartlist_len(mp->transports) == 0)
    901    log_warn(LD_GENERAL, "Managed proxy '%s' was spawned successfully, "
    902               "but it didn't launch any pluggable transport listeners!",
    903               mp->argv[0]);
    904 
    905  log_info(LD_CONFIG, "%s managed proxy '%s' configuration completed!",
    906           mp->is_server ? "Server" : "Client",
    907           mp->argv[0]);
    908 }
    909 
    910 /** Handle a configuration protocol <b>line</b> received from a
    911 *  managed proxy <b>mp</b>. */
    912 STATIC void
    913 handle_proxy_line(const char *line, managed_proxy_t *mp)
    914 {
    915  log_info(LD_PT, "Got a line from managed proxy '%s': (%s)",
    916           mp->argv[0], line);
    917 
    918  if (!strcmpstart(line, PROTO_ENV_ERROR)) {
    919    if (mp->conf_state != PT_PROTO_LAUNCHED)
    920      goto err;
    921 
    922    parse_env_error(line);
    923    goto err;
    924  } else if (!strcmpstart(line, PROTO_NEG_FAIL)) {
    925    if (mp->conf_state != PT_PROTO_LAUNCHED)
    926      goto err;
    927 
    928    log_warn(LD_CONFIG, "Managed proxy could not pick a "
    929             "configuration protocol version.");
    930    goto err;
    931  } else if (!strcmpstart(line, PROTO_NEG_SUCCESS)) {
    932    if (mp->conf_state != PT_PROTO_LAUNCHED)
    933      goto err;
    934 
    935    if (parse_version(line,mp) < 0)
    936      goto err;
    937 
    938    tor_assert(mp->conf_protocol != 0);
    939    managed_proxy_set_state(mp, PT_PROTO_ACCEPTING_METHODS);
    940    return;
    941  } else if (!strcmpstart(line, PROTO_CMETHODS_DONE)) {
    942    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    943      goto err;
    944 
    945    handle_methods_done(mp);
    946 
    947    managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
    948    return;
    949  } else if (!strcmpstart(line, PROTO_SMETHODS_DONE)) {
    950    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    951      goto err;
    952 
    953    handle_methods_done(mp);
    954 
    955    managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
    956    return;
    957  } else if (!strcmpstart(line, PROTO_CMETHOD_ERROR)) {
    958    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    959      goto err;
    960 
    961    /* Log the error but do not kill the managed proxy.
    962     * A proxy may contain several transports and if one
    963     * of them is misconfigured, we still want to use
    964     * the other transports. A managed proxy with no usable
    965     * transports will log a warning.
    966     * See https://gitlab.torproject.org/tpo/core/tor/-/issues/7362
    967     * */
    968    parse_client_method_error(line);
    969    return;
    970  } else if (!strcmpstart(line, PROTO_SMETHOD_ERROR)) {
    971    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    972      goto err;
    973 
    974    /* Log the error but do not kill the managed proxy */
    975    parse_server_method_error(line);
    976    return;
    977  } else if (!strcmpstart(line, PROTO_CMETHOD)) {
    978    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    979      goto err;
    980 
    981    if (parse_cmethod_line(line, mp) < 0)
    982      goto err;
    983 
    984    return;
    985  } else if (!strcmpstart(line, PROTO_SMETHOD)) {
    986    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    987      goto err;
    988 
    989    if (parse_smethod_line(line, mp) < 0)
    990      goto err;
    991 
    992    return;
    993  } else if (!strcmpstart(line, PROTO_PROXY_DONE)) {
    994    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
    995      goto err;
    996 
    997    if (mp->proxy_uri) {
    998      mp->proxy_supported = 1;
    999      return;
   1000    }
   1001 
   1002    /* No proxy was configured, this should log */
   1003  } else if (!strcmpstart(line, PROTO_PROXY_ERROR)) {
   1004    if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
   1005      goto err;
   1006 
   1007    parse_proxy_error(line);
   1008    goto err;
   1009 
   1010    /* We check for the additional " " after the PROTO_LOG * PROTO_STATUS
   1011     * string to make sure we can later extend this big if/else-if table with
   1012     * something that begins with "LOG" without having to get the order right.
   1013     * */
   1014  } else if (!strcmpstart(line, PROTO_LOG " ")) {
   1015    parse_log_line(line, mp);
   1016    return;
   1017  } else if (!strcmpstart(line, PROTO_STATUS " ")) {
   1018    parse_status_line(line, mp);
   1019    return;
   1020  }
   1021 
   1022  log_notice(LD_GENERAL, "Unknown line received by managed proxy (%s).", line);
   1023  return;
   1024 
   1025 err:
   1026  managed_proxy_set_state(mp, PT_PROTO_BROKEN);
   1027  log_warn(LD_CONFIG, "Managed proxy at '%s' failed the configuration protocol"
   1028           " and will be destroyed.", mp->argv[0]);
   1029 }
   1030 
   1031 /** Parses an ENV-ERROR <b>line</b> and warns the user accordingly. */
   1032 STATIC void
   1033 parse_env_error(const char *line)
   1034 {
   1035  /* (Length of the protocol string) plus (a space) and (the first char of
   1036     the error message) */
   1037  if (strlen(line) < (strlen(PROTO_ENV_ERROR) + 2))
   1038    log_notice(LD_CONFIG, "Managed proxy sent us an %s without an error "
   1039               "message.", PROTO_ENV_ERROR);
   1040 
   1041  log_warn(LD_CONFIG, "Managed proxy couldn't understand the "
   1042           "pluggable transport environment variables. (%s)",
   1043           line+strlen(PROTO_ENV_ERROR)+1);
   1044 }
   1045 
   1046 /** Handles a VERSION <b>line</b>. Updates the configuration protocol
   1047 *  version in <b>mp</b>. */
   1048 STATIC int
   1049 parse_version(const char *line, managed_proxy_t *mp)
   1050 {
   1051  if (strlen(line) < (strlen(PROTO_NEG_SUCCESS) + 2)) {
   1052    log_warn(LD_CONFIG, "Managed proxy sent us malformed %s line.",
   1053             PROTO_NEG_SUCCESS);
   1054    return -1;
   1055  }
   1056 
   1057  if (strcmp("1", line+strlen(PROTO_NEG_SUCCESS)+1)) { /* hardcoded temp */
   1058    log_warn(LD_CONFIG, "Managed proxy tried to negotiate on version '%s'. "
   1059             "We only support version '1'", line+strlen(PROTO_NEG_SUCCESS)+1);
   1060    return -1;
   1061  }
   1062 
   1063  mp->conf_protocol = PROTO_VERSION_ONE; /* temp. till more versions appear */
   1064  return 0;
   1065 }
   1066 
   1067 /** Parses {C,S}METHOD-ERROR <b>line</b> and warns the user
   1068 *  accordingly.  If <b>is_server</b> it is an SMETHOD-ERROR,
   1069 *  otherwise it is a CMETHOD-ERROR. */
   1070 static void
   1071 parse_method_error(const char *line, int is_server)
   1072 {
   1073  const char* error = is_server ?
   1074    PROTO_SMETHOD_ERROR : PROTO_CMETHOD_ERROR;
   1075 
   1076  /* (Length of the protocol string) plus (a space) and (the first char of
   1077     the error message) */
   1078  if (strlen(line) < (strlen(error) + 2))
   1079    log_warn(LD_CONFIG, "Managed proxy sent us an %s without an error "
   1080             "message.", error);
   1081 
   1082  log_warn(LD_CONFIG, "%s managed proxy encountered a method error. (%s)",
   1083           is_server ? "Server" : "Client",
   1084           line+strlen(error)+1);
   1085 }
   1086 
   1087 /** A helper for parse_{c,s}method_line(), bootstraps its
   1088 *  functionalities. If <b>is_smethod</b> is true then the
   1089 *  the line to parse is a SMETHOD line otherwise it is a
   1090 *  CMETHOD line*/
   1091 static int
   1092 parse_method_line_helper(const char *line,
   1093                         managed_proxy_t *mp,
   1094                         int is_smethod)
   1095 {
   1096  int item_index = 0;
   1097  int r;
   1098 
   1099  char *transport_name=NULL;
   1100  char *args_string=NULL;
   1101  char *addrport=NULL;
   1102  int socks_ver=PROXY_NONE;
   1103  char *address=NULL;
   1104  uint16_t port = 0;
   1105 
   1106  const char *method_str = is_smethod ? PROTO_SMETHOD : PROTO_CMETHOD;
   1107  const int min_args_count = is_smethod ? 3 : 4;
   1108 
   1109  tor_addr_t tor_addr;
   1110  transport_t *transport=NULL;
   1111  smartlist_t *items= smartlist_new();
   1112 
   1113  smartlist_split_string(items, line, NULL,
   1114                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
   1115  if (smartlist_len(items) < min_args_count) {
   1116    log_warn(LD_CONFIG, "Managed proxy sent us a %s line "
   1117             "with too few arguments.", method_str);
   1118    goto err;
   1119  }
   1120 
   1121  tor_assert(!strcmp(smartlist_get(items, item_index),method_str));
   1122  ++item_index;
   1123 
   1124  transport_name = smartlist_get(items,item_index);
   1125  ++item_index;
   1126  if (!string_is_C_identifier(transport_name)) {
   1127    log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
   1128             transport_name);
   1129    goto err;
   1130  }
   1131 
   1132  /** Check for the proxy method sent to us in CMETHOD line. */
   1133  if (!is_smethod) {
   1134    const char *socks_ver_str = smartlist_get(items,item_index);
   1135    ++item_index;
   1136 
   1137    if (!strcmp(socks_ver_str,"socks4")) {
   1138      socks_ver = PROXY_SOCKS4;
   1139    } else if (!strcmp(socks_ver_str,"socks5")) {
   1140      socks_ver = PROXY_SOCKS5;
   1141    } else {
   1142      log_warn(LD_CONFIG, "Client managed proxy sent us a proxy protocol "
   1143               "we don't recognize. (%s)", socks_ver_str);
   1144      goto err;
   1145    }
   1146  }
   1147 
   1148  addrport = smartlist_get(items, item_index);
   1149  ++item_index;
   1150  if (tor_addr_port_split(LOG_WARN, addrport, &address, &port)<0) {
   1151    log_warn(LD_CONFIG, "Error parsing transport address '%s'", addrport);
   1152    goto err;
   1153  }
   1154 
   1155  if (!port) {
   1156    log_warn(LD_CONFIG,
   1157             "Transport address '%s' has no port.", addrport);
   1158    goto err;
   1159  }
   1160 
   1161  if (tor_addr_parse(&tor_addr, address) < 0) {
   1162    log_warn(LD_CONFIG, "Error parsing transport address '%s'", address);
   1163    goto err;
   1164  }
   1165 
   1166  /** Check for options in the SMETHOD line. */
   1167  if (is_smethod && smartlist_len(items) > min_args_count) {
   1168    /* Seems like there are also some [options] in the SMETHOD line.
   1169       Let's see if we can parse them. */
   1170    char *options_string = smartlist_get(items, item_index);
   1171    log_debug(LD_CONFIG, "Got options_string: %s", options_string);
   1172    if (!strcmpstart(options_string, "ARGS:")) {
   1173      args_string = options_string+strlen("ARGS:");
   1174      log_debug(LD_CONFIG, "Got ARGS: %s", args_string);
   1175    }
   1176  }
   1177 
   1178  transport = transport_new(&tor_addr, port, transport_name,
   1179                            socks_ver, args_string);
   1180 
   1181  smartlist_add(mp->transports, transport);
   1182 
   1183  /** Logs info about line parsing success for client or server */
   1184  if (is_smethod) {
   1185    log_info(LD_CONFIG, "Server transport %s at %s:%d.",
   1186             transport_name, address, (int)port);
   1187  } else {
   1188    log_info(LD_CONFIG, "Transport %s at %s:%d with SOCKS %d. "
   1189             "Attached to managed proxy.",
   1190             transport_name, address, (int)port, socks_ver);
   1191  }
   1192 
   1193  r=0;
   1194  goto done;
   1195 
   1196 err:
   1197  r = -1;
   1198 
   1199 done:
   1200  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
   1201  smartlist_free(items);
   1202  tor_free(address);
   1203  return r;
   1204 }
   1205 
   1206 /** Parses an SMETHOD <b>line</b> and if well-formed it registers the
   1207 *  new transport in <b>mp</b>. */
   1208 STATIC int
   1209 parse_smethod_line(const char *line, managed_proxy_t *mp)
   1210 {
   1211  /* Example of legit SMETHOD line:
   1212     SMETHOD obfs2 0.0.0.0:25612 ARGS:secret=supersekrit,key=superkey */
   1213  return parse_method_line_helper(line, mp, 1);
   1214 }
   1215 
   1216 /** Parses a CMETHOD <b>line</b>, and if well-formed it registers
   1217 *  the new transport in <b>mp</b>. */
   1218 STATIC int
   1219 parse_cmethod_line(const char *line, managed_proxy_t *mp)
   1220 {
   1221  /* Example of legit CMETHOD line:
   1222     CMETHOD obfs2 socks5 127.0.0.1:35713 */
   1223  return parse_method_line_helper(line, mp, 0);
   1224 }
   1225 
   1226 /** Parses an PROXY-ERROR <b>line</b> and warns the user accordingly. */
   1227 STATIC void
   1228 parse_proxy_error(const char *line)
   1229 {
   1230  /* (Length of the protocol string) plus (a space) and (the first char of
   1231     the error message) */
   1232  if (strlen(line) < (strlen(PROTO_PROXY_ERROR) + 2))
   1233    log_notice(LD_CONFIG, "Managed proxy sent us an %s without an error "
   1234               "message.", PROTO_PROXY_ERROR);
   1235 
   1236  log_warn(LD_CONFIG, "Managed proxy failed to configure the "
   1237           "pluggable transport's outgoing proxy. (%s)",
   1238           line+strlen(PROTO_PROXY_ERROR)+1);
   1239 }
   1240 
   1241 /** Parses a LOG <b>line</b> and emit log events accordingly. */
   1242 STATIC void
   1243 parse_log_line(const char *line, managed_proxy_t *mp)
   1244 {
   1245  tor_assert(line);
   1246  tor_assert(mp);
   1247 
   1248  config_line_t *values = NULL;
   1249  char *log_message = NULL;
   1250 
   1251  if (strlen(line) < (strlen(PROTO_LOG) + 1)) {
   1252    log_warn(LD_PT, "Managed proxy sent us a %s line "
   1253                    "with missing argument.", PROTO_LOG);
   1254    goto done;
   1255  }
   1256 
   1257  const char *data = line + strlen(PROTO_LOG) + 1;
   1258  values = kvline_parse(data, KV_QUOTED);
   1259 
   1260  if (! values) {
   1261    log_warn(LD_PT, "Managed proxy \"%s\" wrote an invalid LOG message: %s",
   1262             mp->argv[0], data);
   1263    goto done;
   1264  }
   1265 
   1266  const config_line_t *severity = config_line_find(values, "SEVERITY");
   1267  const config_line_t *message = config_line_find(values, "MESSAGE");
   1268 
   1269  /* Check if we got a message. */
   1270  if (! message) {
   1271    log_warn(LD_PT, "Managed proxy \"%s\" wrote a LOG line without "
   1272                    "MESSAGE: %s", mp->argv[0], escaped(data));
   1273    goto done;
   1274  }
   1275 
   1276  /* Check if severity is there and whether it's valid. */
   1277  if (! severity) {
   1278    log_warn(LD_PT, "Managed proxy \"%s\" wrote a LOG line without "
   1279                    "SEVERITY: %s", mp->argv[0], escaped(data));
   1280    goto done;
   1281  }
   1282 
   1283  int log_severity = managed_proxy_severity_parse(severity->value);
   1284 
   1285  if (log_severity == -1) {
   1286    log_warn(LD_PT, "Managed proxy \"%s\" wrote a LOG line with an "
   1287                    "invalid severity level: %s",
   1288                    mp->argv[0], severity->value);
   1289    goto done;
   1290  }
   1291 
   1292  tor_log(log_severity, LD_PT, "Managed proxy \"%s\": %s",
   1293          mp->argv[0], message->value);
   1294 
   1295  /* Prepend the PT name. */
   1296  config_line_prepend(&values, "PT", mp->argv[0]);
   1297  log_message = kvline_encode(values, KV_QUOTED);
   1298 
   1299  /* Emit control port event. */
   1300  control_event_pt_log(log_message);
   1301 
   1302 done:
   1303  config_free_lines(values);
   1304  tor_free(log_message);
   1305 }
   1306 
   1307 /** Parses a STATUS <b>line</b> and emit control events accordingly. */
   1308 STATIC void
   1309 parse_status_line(const char *line, managed_proxy_t *mp)
   1310 {
   1311  tor_assert(line);
   1312  tor_assert(mp);
   1313 
   1314  config_line_t *values = NULL;
   1315  char *status_message = NULL;
   1316 
   1317  if (strlen(line) < (strlen(PROTO_STATUS) + 1)) {
   1318    log_warn(LD_PT, "Managed proxy sent us a %s line "
   1319                    "with missing argument.", PROTO_STATUS);
   1320    goto done;
   1321  }
   1322 
   1323  const char *data = line + strlen(PROTO_STATUS) + 1;
   1324 
   1325  values = kvline_parse(data, KV_QUOTED);
   1326 
   1327  if (! values) {
   1328    log_warn(LD_PT, "Managed proxy \"%s\" wrote an invalid "
   1329             "STATUS message: %s", mp->argv[0], escaped(data));
   1330    goto done;
   1331  }
   1332 
   1333  /* Handle the different messages. */
   1334  handle_status_message(values, mp);
   1335 
   1336  /* Prepend the PT name. */
   1337  config_line_prepend(&values, "PT", mp->argv[0]);
   1338  status_message = kvline_encode(values, KV_QUOTED);
   1339 
   1340  /* We have checked that TRANSPORT is there, we can now emit the STATUS event
   1341   * via the control port. */
   1342  control_event_pt_status(status_message);
   1343 
   1344 done:
   1345  config_free_lines(values);
   1346  tor_free(status_message);
   1347 }
   1348 
   1349 STATIC void
   1350 handle_status_message(const config_line_t *values,
   1351                      managed_proxy_t *mp)
   1352 {
   1353  if (config_count_key(values, "TYPE") > 1) {
   1354      log_warn(LD_PT, "Managed proxy \"%s\" has multiple TYPE key which "
   1355                      "is not allowed.", mp->argv[0]);
   1356      return;
   1357  }
   1358  const config_line_t *message_type = config_line_find(values, "TYPE");
   1359 
   1360  /* Check if we have a TYPE field? */
   1361  if (message_type == NULL) {
   1362    log_debug(LD_PT, "Managed proxy \"%s\" wrote a STATUS line without "
   1363                     "a defined message TYPE", mp->argv[0]);
   1364    return;
   1365  }
   1366 
   1367  /* Handle VERSION messages. */
   1368  if (! strcasecmp(message_type->value, "version")) {
   1369    const config_line_t *version = config_line_find(values, "VERSION");
   1370    const config_line_t *implementation = config_line_find(values,
   1371                                                           "IMPLEMENTATION");
   1372 
   1373    if (version == NULL) {
   1374      log_warn(LD_PT, "Managed proxy \"%s\" wrote a STATUS TYPE=version line "
   1375                      "with a missing VERSION field", mp->argv[0]);
   1376      return;
   1377    }
   1378 
   1379    if (implementation == NULL) {
   1380      log_warn(LD_PT, "Managed proxy \"%s\" wrote a STATUS TYPE=version line "
   1381                      "with a missing IMPLEMENTATION field", mp->argv[0]);
   1382      return;
   1383    }
   1384 
   1385    tor_free(mp->version);
   1386    mp->version = tor_strdup(version->value);
   1387 
   1388    tor_free(mp->implementation);
   1389    mp->implementation = tor_strdup(implementation->value);
   1390 
   1391    return;
   1392  }
   1393 }
   1394 
   1395 /** Return a newly allocated string that tor should place in
   1396 * TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
   1397 * manged proxy in <b>mp</b>. Return NULL if no such options are found. */
   1398 STATIC char *
   1399 get_transport_options_for_server_proxy(const managed_proxy_t *mp)
   1400 {
   1401  char *options_string = NULL;
   1402  smartlist_t *string_sl = smartlist_new();
   1403 
   1404  tor_assert(mp->is_server);
   1405 
   1406  /** Loop over the transports of the proxy. If we have options for
   1407      any of them, format them appropriately and place them in our
   1408      smartlist. Finally, join our smartlist to get the final
   1409      string. */
   1410  SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, const char *, transport) {
   1411    smartlist_t *options_tmp_sl = NULL;
   1412    options_tmp_sl = pt_get_options_for_server_transport(transport);
   1413    if (!options_tmp_sl)
   1414      continue;
   1415 
   1416    /** Loop over the options of this transport, escape them, and
   1417        place them in the smartlist. */
   1418    SMARTLIST_FOREACH_BEGIN(options_tmp_sl, const char *, options) {
   1419      char *escaped_opts = tor_escape_str_for_pt_args(options, ":;\\");
   1420      smartlist_add_asprintf(string_sl, "%s:%s",
   1421                             transport, escaped_opts);
   1422      tor_free(escaped_opts);
   1423    } SMARTLIST_FOREACH_END(options);
   1424 
   1425    SMARTLIST_FOREACH(options_tmp_sl, char *, c, tor_free(c));
   1426    smartlist_free(options_tmp_sl);
   1427  } SMARTLIST_FOREACH_END(transport);
   1428 
   1429  if (smartlist_len(string_sl)) {
   1430    options_string = smartlist_join_strings(string_sl, ";", 0, NULL);
   1431  }
   1432 
   1433  SMARTLIST_FOREACH(string_sl, char *, t, tor_free(t));
   1434  smartlist_free(string_sl);
   1435 
   1436  return options_string;
   1437 }
   1438 
   1439 /** Return the string that tor should place in TOR_PT_SERVER_BINDADDR
   1440 *  while configuring the server managed proxy in <b>mp</b>. The
   1441 *  string is stored in the heap, and it's the responsibility of
   1442 *  the caller to deallocate it after its use. */
   1443 static char *
   1444 get_bindaddr_for_server_proxy(const managed_proxy_t *mp)
   1445 {
   1446  char *bindaddr_result = NULL;
   1447  char *bindaddr_tmp = NULL;
   1448  smartlist_t *string_tmp = smartlist_new();
   1449 
   1450  tor_assert(mp->is_server);
   1451 
   1452  SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, char *, t) {
   1453    bindaddr_tmp = get_stored_bindaddr_for_server_transport(t);
   1454 
   1455    smartlist_add_asprintf(string_tmp, "%s-%s", t, bindaddr_tmp);
   1456 
   1457    tor_free(bindaddr_tmp);
   1458  } SMARTLIST_FOREACH_END(t);
   1459 
   1460  bindaddr_result = smartlist_join_strings(string_tmp, ",", 0, NULL);
   1461 
   1462  SMARTLIST_FOREACH(string_tmp, char *, t, tor_free(t));
   1463  smartlist_free(string_tmp);
   1464 
   1465  return bindaddr_result;
   1466 }
   1467 
   1468 /** Return a newly allocated process_environment_t * for <b>mp</b>'s
   1469 * process. */
   1470 static smartlist_t *
   1471 create_managed_proxy_environment(const managed_proxy_t *mp)
   1472 {
   1473  const or_options_t *options = get_options();
   1474 
   1475  /* Environment variables to be added to or set in mp's environment. */
   1476  smartlist_t *envs = smartlist_new();
   1477  /* XXXX The next time someone touches this code, shorten the name of
   1478   * set_environment_variable_in_smartlist, add a
   1479   * set_env_var_in_smartlist_asprintf function, and get rid of the
   1480   * silly extra envs smartlist. */
   1481 
   1482  /* The final environment to be passed to mp. */
   1483  smartlist_t *merged_env_vars = get_current_process_environment_variables();
   1484 
   1485  {
   1486    char *state_tmp = get_datadir_fname("pt_state/"); /* XXX temp */
   1487    smartlist_add_asprintf(envs, "TOR_PT_STATE_LOCATION=%s", state_tmp);
   1488    tor_free(state_tmp);
   1489  }
   1490 
   1491  smartlist_add_strdup(envs, "TOR_PT_MANAGED_TRANSPORT_VER=1");
   1492 
   1493  {
   1494    char *transports_to_launch =
   1495      smartlist_join_strings(mp->transports_to_launch, ",", 0, NULL);
   1496 
   1497    smartlist_add_asprintf(envs,
   1498                           mp->is_server ?
   1499                           "TOR_PT_SERVER_TRANSPORTS=%s" :
   1500                           "TOR_PT_CLIENT_TRANSPORTS=%s",
   1501                           transports_to_launch);
   1502 
   1503    tor_free(transports_to_launch);
   1504  }
   1505 
   1506  if (mp->is_server) {
   1507    {
   1508      char *orport_tmp =
   1509        get_first_listener_addrport_string(CONN_TYPE_OR_LISTENER);
   1510      if (orport_tmp) {
   1511        smartlist_add_asprintf(envs, "TOR_PT_ORPORT=%s", orport_tmp);
   1512        tor_free(orport_tmp);
   1513      }
   1514    }
   1515 
   1516    {
   1517      char *bindaddr_tmp = get_bindaddr_for_server_proxy(mp);
   1518      smartlist_add_asprintf(envs, "TOR_PT_SERVER_BINDADDR=%s", bindaddr_tmp);
   1519      tor_free(bindaddr_tmp);
   1520    }
   1521 
   1522    {
   1523      char *server_transport_options =
   1524        get_transport_options_for_server_proxy(mp);
   1525      if (server_transport_options) {
   1526        smartlist_add_asprintf(envs, "TOR_PT_SERVER_TRANSPORT_OPTIONS=%s",
   1527                               server_transport_options);
   1528        tor_free(server_transport_options);
   1529      }
   1530    }
   1531 
   1532    /* XXXX Remove the '=' here once versions of obfsproxy which
   1533     * assert that this env var exists are sufficiently dead.
   1534     *
   1535     * (If we remove this line entirely, some joker will stick this
   1536     * variable in Tor's environment and crash PTs that try to parse
   1537     * it even when not run in server mode.) */
   1538 
   1539    if (options->ExtORPort_lines) {
   1540      char *ext_or_addrport_tmp =
   1541        get_first_listener_addrport_string(CONN_TYPE_EXT_OR_LISTENER);
   1542      char *cookie_file_loc = get_ext_or_auth_cookie_file_name();
   1543 
   1544      if (ext_or_addrport_tmp) {
   1545        smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=%s",
   1546                               ext_or_addrport_tmp);
   1547      }
   1548      if (cookie_file_loc) {
   1549        smartlist_add_asprintf(envs, "TOR_PT_AUTH_COOKIE_FILE=%s",
   1550                               cookie_file_loc);
   1551      }
   1552 
   1553      tor_free(ext_or_addrport_tmp);
   1554      tor_free(cookie_file_loc);
   1555 
   1556    } else {
   1557      smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=");
   1558    }
   1559  } else {
   1560    /* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the
   1561     * TOR_PT_PROXY line.
   1562     */
   1563 
   1564    if (mp->proxy_uri) {
   1565      smartlist_add_asprintf(envs, "TOR_PT_PROXY=%s", mp->proxy_uri);
   1566    }
   1567  }
   1568 
   1569  /* All new versions of tor will keep stdin open, so PTs can use it
   1570   * as a reliable termination detection mechanism.
   1571   */
   1572  smartlist_add_asprintf(envs, "TOR_PT_EXIT_ON_STDIN_CLOSE=1");
   1573 
   1574  /* Specify which IPv4 and IPv6 addresses the PT should make its outgoing
   1575   * connections from. See: https://bugs.torproject.org/5304 for more
   1576   * information about this. */
   1577  {
   1578    /* Set TOR_PT_OUTBOUND_BIND_ADDRESS_V4. */
   1579    const tor_addr_t *ipv4_addr = managed_proxy_outbound_address(options,
   1580                                                                 AF_INET);
   1581 
   1582    /* managed_proxy_outbound_address() only returns a non-NULL value if
   1583     * tor_addr_is_null() was false, which means we don't have to check that
   1584     * here. */
   1585    if (ipv4_addr) {
   1586      char *ipv4_addr_str = tor_addr_to_str_dup(ipv4_addr);
   1587      smartlist_add_asprintf(envs,
   1588                             "TOR_PT_OUTBOUND_BIND_ADDRESS_V4=%s",
   1589                             ipv4_addr_str);
   1590      tor_free(ipv4_addr_str);
   1591    }
   1592 
   1593    /* Set TOR_PT_OUTBOUND_BIND_ADDRESS_V6. */
   1594    const tor_addr_t *ipv6_addr = managed_proxy_outbound_address(options,
   1595                                                                 AF_INET6);
   1596    if (ipv6_addr) {
   1597      char *ipv6_addr_str = tor_addr_to_str_dup(ipv6_addr);
   1598      smartlist_add_asprintf(envs,
   1599                             "TOR_PT_OUTBOUND_BIND_ADDRESS_V6=[%s]",
   1600                             ipv6_addr_str);
   1601      tor_free(ipv6_addr_str);
   1602    }
   1603  }
   1604 
   1605  SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
   1606    set_environment_variable_in_smartlist(merged_env_vars, env_var,
   1607                                          tor_free_, 1);
   1608  } SMARTLIST_FOREACH_END(env_var);
   1609 
   1610  smartlist_free(envs);
   1611 
   1612  return merged_env_vars;
   1613 }
   1614 
   1615 /** Create and return a new managed proxy for <b>transport</b> using
   1616 *  <b>proxy_argv</b>.  Also, add it to the global managed proxy list. If
   1617 *  <b>is_server</b> is true, it's a server managed proxy.  Takes ownership of
   1618 *  <b>proxy_argv</b>.
   1619 *
   1620 * Requires that proxy_argv have at least one element. */
   1621 STATIC managed_proxy_t *
   1622 managed_proxy_create(const smartlist_t *with_transport_list,
   1623                     char **proxy_argv, int is_server)
   1624 {
   1625  managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
   1626  managed_proxy_set_state(mp, PT_PROTO_INFANT);
   1627  mp->is_server = is_server;
   1628  mp->argv = proxy_argv;
   1629  mp->transports = smartlist_new();
   1630  mp->proxy_uri = get_pt_proxy_uri();
   1631 
   1632  /* Gets set in launch_managed_proxy(). */
   1633  mp->process = NULL;
   1634 
   1635  mp->transports_to_launch = smartlist_new();
   1636  SMARTLIST_FOREACH(with_transport_list, const char *, transport,
   1637                    add_transport_to_proxy(transport, mp));
   1638 
   1639  /* register the managed proxy */
   1640  if (!managed_proxy_list)
   1641    managed_proxy_list = smartlist_new();
   1642  smartlist_add(managed_proxy_list, mp);
   1643  unconfigured_proxies_n++;
   1644 
   1645  assert_unconfigured_count_ok();
   1646 
   1647  return mp;
   1648 }
   1649 
   1650 /** Register proxy with <b>proxy_argv</b>, supporting transports in
   1651 *  <b>transport_list</b>, to the managed proxy subsystem.
   1652 *  If <b>is_server</b> is true, then the proxy is a server proxy.
   1653 *
   1654 * Takes ownership of proxy_argv.
   1655 *
   1656 * Requires that proxy_argv be a NULL-terminated array of command-line
   1657 * elements, containing at least one element.
   1658 **/
   1659 MOCK_IMPL(void,
   1660 pt_kickstart_proxy, (const smartlist_t *with_transport_list,
   1661                     char **proxy_argv, int is_server))
   1662 {
   1663  managed_proxy_t *mp=NULL;
   1664  transport_t *old_transport = NULL;
   1665 
   1666  if (!proxy_argv || !proxy_argv[0]) {
   1667    return;
   1668  }
   1669 
   1670  mp = get_managed_proxy_by_argv_and_type(proxy_argv, is_server);
   1671 
   1672  if (!mp) { /* we haven't seen this proxy before */
   1673    managed_proxy_create(with_transport_list, proxy_argv, is_server);
   1674 
   1675  } else { /* known proxy. add its transport to its transport list */
   1676    if (mp->was_around_before_config_read) {
   1677      /* If this managed proxy was around even before we read the
   1678         config this time, it means that it was already enabled before
   1679         and is not useless and should be kept. If it's marked for
   1680         removal, unmark it and make sure that we check whether it
   1681         needs to be restarted. */
   1682      if (mp->marked_for_removal) {
   1683        mp->marked_for_removal = 0;
   1684        check_if_restarts_needed = 1;
   1685      }
   1686 
   1687      /* For each new transport, check if the managed proxy used to
   1688         support it before the SIGHUP. If that was the case, make sure
   1689         it doesn't get removed because we might reuse it. */
   1690      SMARTLIST_FOREACH_BEGIN(with_transport_list, const char *, transport) {
   1691        old_transport = transport_get_by_name(transport);
   1692        if (old_transport)
   1693          old_transport->marked_for_removal = 0;
   1694      } SMARTLIST_FOREACH_END(transport);
   1695    }
   1696 
   1697    SMARTLIST_FOREACH(with_transport_list, const char *, transport,
   1698                      add_transport_to_proxy(transport, mp));
   1699    free_execve_args(proxy_argv);
   1700  }
   1701 }
   1702 
   1703 /** Frees the array of pointers in <b>arg</b> used as arguments to
   1704    execve(2). */
   1705 STATIC void
   1706 free_execve_args(char **arg)
   1707 {
   1708  char **tmp = arg;
   1709  while (*tmp) /* use the fact that the last element of the array is a
   1710                  NULL pointer to know when to stop freeing */
   1711    tor_free_(*tmp++);
   1712 
   1713  tor_free(arg);
   1714 }
   1715 
   1716 /** Tor will read its config.
   1717 *  Prepare the managed proxy list so that proxies not used in the new
   1718 *  config will shutdown, and proxies that need to spawn different
   1719 *  transports will do so. */
   1720 void
   1721 pt_prepare_proxy_list_for_config_read(void)
   1722 {
   1723  if (!managed_proxy_list)
   1724    return;
   1725 
   1726  assert_unconfigured_count_ok();
   1727  SMARTLIST_FOREACH_BEGIN(managed_proxy_list, managed_proxy_t *, mp) {
   1728    /* Destroy unconfigured proxies. */
   1729    if (mp->conf_state != PT_PROTO_COMPLETED) {
   1730      SMARTLIST_DEL_CURRENT(managed_proxy_list, mp);
   1731      managed_proxy_destroy(mp, 1);
   1732      unconfigured_proxies_n--;
   1733      continue;
   1734    }
   1735 
   1736    tor_assert(mp->conf_state == PT_PROTO_COMPLETED);
   1737 
   1738    /* Mark all proxies for removal, and also note that they have been
   1739       here before the config read. */
   1740    mp->marked_for_removal = 1;
   1741    mp->was_around_before_config_read = 1;
   1742    SMARTLIST_FOREACH(mp->transports_to_launch, char *, t, tor_free(t));
   1743    smartlist_clear(mp->transports_to_launch);
   1744  } SMARTLIST_FOREACH_END(mp);
   1745 
   1746  assert_unconfigured_count_ok();
   1747 
   1748  tor_assert(unconfigured_proxies_n == 0);
   1749 }
   1750 
   1751 /** Return a smartlist containing the ports where our pluggable
   1752 *  transports are listening. */
   1753 smartlist_t *
   1754 get_transport_proxy_ports(void)
   1755 {
   1756  smartlist_t *sl = NULL;
   1757 
   1758  if (!managed_proxy_list)
   1759    return NULL;
   1760 
   1761  /** XXX assume that external proxy ports have been forwarded
   1762      manually */
   1763  SMARTLIST_FOREACH_BEGIN(managed_proxy_list, const managed_proxy_t *, mp) {
   1764    if (!mp->is_server || mp->conf_state != PT_PROTO_COMPLETED)
   1765      continue;
   1766 
   1767    if (!sl) sl = smartlist_new();
   1768 
   1769    tor_assert(mp->transports);
   1770    SMARTLIST_FOREACH(mp->transports, const transport_t *, t,
   1771                      smartlist_add_asprintf(sl, "%u:%u", t->port, t->port));
   1772 
   1773  } SMARTLIST_FOREACH_END(mp);
   1774 
   1775  return sl;
   1776 }
   1777 
   1778 /** Return the pluggable transport string that we should display in
   1779 *  our extra-info descriptor. If we shouldn't display such a string,
   1780 *  or we have nothing to display, return NULL. The string is
   1781 *  allocated on the heap and it's the responsibility of the caller to
   1782 *  free it. */
   1783 char *
   1784 pt_get_extra_info_descriptor_string(void)
   1785 {
   1786  char *the_string = NULL;
   1787  smartlist_t *string_chunks = NULL;
   1788 
   1789  if (!managed_proxy_list)
   1790    return NULL;
   1791 
   1792  string_chunks = smartlist_new();
   1793 
   1794  /* For each managed proxy, add its transports to the chunks list. */
   1795  SMARTLIST_FOREACH_BEGIN(managed_proxy_list,  const managed_proxy_t *, mp) {
   1796    if ((!mp->is_server) || (mp->conf_state != PT_PROTO_COMPLETED))
   1797      continue;
   1798 
   1799    tor_assert(mp->transports);
   1800 
   1801    SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) {
   1802      char *transport_args = NULL;
   1803      const char *addrport = NULL;
   1804 
   1805      /* If the transport proxy returned "0.0.0.0" as its address, and
   1806       * we know our external IP address, use it. Otherwise, use the
   1807       * returned address. */
   1808      if (tor_addr_is_null(&t->addr)) {
   1809        tor_addr_t addr;
   1810        /* Attempt to find the IPv4 and then attempt to find the IPv6 if we
   1811         * can't find it. */
   1812        bool found = relay_find_addr_to_publish(get_options(), AF_INET,
   1813                                                RELAY_FIND_ADDR_NO_FLAG,
   1814                                                &addr);
   1815        if (!found) {
   1816          found = relay_find_addr_to_publish(get_options(), AF_INET6,
   1817                                             RELAY_FIND_ADDR_NO_FLAG, &addr);
   1818        }
   1819        if (!found) {
   1820          log_err(LD_PT, "Unable to find address for transport %s", t->name);
   1821          continue;
   1822        }
   1823        addrport = fmt_addrport(&addr, t->port);
   1824      } else {
   1825        addrport = fmt_addrport(&t->addr, t->port);
   1826      }
   1827 
   1828      /* If this transport has any arguments with it, prepend a space
   1829         to them so that we can add them to the transport line. */
   1830      if (t->extra_info_args)
   1831        tor_asprintf(&transport_args, " %s", t->extra_info_args);
   1832 
   1833      smartlist_add_asprintf(string_chunks,
   1834                             "transport %s %s%s",
   1835                             t->name, addrport,
   1836                             transport_args ? transport_args : "");
   1837 
   1838      tor_free(transport_args);
   1839    } SMARTLIST_FOREACH_END(t);
   1840 
   1841    /* Set transport-info line. */
   1842    {
   1843      char *version = NULL;
   1844      char *impl = NULL;
   1845 
   1846      if (mp->version) {
   1847        tor_asprintf(&version, " version=%s", mp->version);
   1848      }
   1849      if (mp->implementation) {
   1850        tor_asprintf(&impl, " implementation=%s", mp->implementation);
   1851      }
   1852      /* Always put in the line even if empty. Else, we don't know to which
   1853       * transport this applies to. */
   1854      smartlist_add_asprintf(string_chunks, "transport-info%s%s",
   1855                             version ? version: "", impl ? impl: "");
   1856      tor_free(version);
   1857      tor_free(impl);
   1858    }
   1859  } SMARTLIST_FOREACH_END(mp);
   1860 
   1861  if (smartlist_len(string_chunks) == 0) {
   1862    smartlist_free(string_chunks);
   1863    return NULL;
   1864  }
   1865 
   1866  /* Join all the chunks into the final string. */
   1867  the_string = smartlist_join_strings(string_chunks, "\n", 1, NULL);
   1868 
   1869  SMARTLIST_FOREACH(string_chunks, char *, s, tor_free(s));
   1870  smartlist_free(string_chunks);
   1871 
   1872  return the_string;
   1873 }
   1874 
   1875 /** Log the bridge lines that clients can use to connect. */
   1876 void
   1877 pt_update_bridge_lines(void)
   1878 {
   1879  char fingerprint[FINGERPRINT_LEN+1];
   1880  smartlist_t *string_chunks = NULL;
   1881 
   1882  if (!server_identity_key_is_set() || !managed_proxy_list)
   1883    return;
   1884 
   1885  if (crypto_pk_get_fingerprint(get_server_identity_key(), fingerprint, 0)<0) {
   1886    log_err(LD_BUG, "Error computing fingerprint");
   1887    return;
   1888  }
   1889 
   1890  string_chunks = smartlist_new();
   1891 
   1892  SMARTLIST_FOREACH_BEGIN(managed_proxy_list, const managed_proxy_t *, mp) {
   1893    if (!mp->is_server)
   1894      continue;
   1895 
   1896    tor_assert(mp->transports);
   1897 
   1898    SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) {
   1899      char *transport_args = NULL;
   1900      const char *saddr = NULL;
   1901 
   1902      /* If the transport proxy returned "0.0.0.0" as its address, display
   1903       * our external address if we know it, or a placeholder if we don't */
   1904      if (tor_addr_is_null(&t->addr)) {
   1905        tor_addr_t addr;
   1906        /* Attempt to find the IPv4 and then attempt to find the IPv6 if we
   1907         * can't find it. */
   1908        bool found = relay_find_addr_to_publish(get_options(), AF_INET,
   1909                                                RELAY_FIND_ADDR_NO_FLAG,
   1910                                                &addr);
   1911        if (!found) {
   1912          found = relay_find_addr_to_publish(get_options(), AF_INET6,
   1913                                             RELAY_FIND_ADDR_NO_FLAG, &addr);
   1914        }
   1915        if (found && !tor_addr_is_null(&addr)) {
   1916          saddr = fmt_and_decorate_addr(&addr);
   1917        } else {
   1918          saddr = "<IP ADDRESS>";
   1919        }
   1920      } else {
   1921        saddr = fmt_and_decorate_addr(&t->addr);
   1922      }
   1923 
   1924      /* If this transport has any arguments with it, prepend a space
   1925       * to them so that we can add them to the transport line, and replace
   1926       * commas with spaces to make it a valid bridge line. */
   1927      if (t->extra_info_args) {
   1928        tor_asprintf(&transport_args, " %s", t->extra_info_args);
   1929        for (int i = 0; transport_args[i]; i++) {
   1930          if (transport_args[i] == ',') {
   1931            transport_args[i] = ' ';
   1932          }
   1933        }
   1934      }
   1935 
   1936      smartlist_add_asprintf(string_chunks, "Bridge %s %s:%d %s%s",
   1937                             t->name, saddr, t->port, fingerprint,
   1938                             transport_args ? transport_args : "");
   1939      tor_free(transport_args);
   1940    } SMARTLIST_FOREACH_END(t);
   1941  } SMARTLIST_FOREACH_END(mp);
   1942 
   1943  /* If we have any valid bridgelines, join them into a single string, and
   1944   * save them to disk. Don't create an empty file. */
   1945  if (smartlist_len(string_chunks) != 0) {
   1946    char *str = smartlist_join_strings(string_chunks, "\n", 1, NULL);
   1947    char *fname = get_datadir_fname("bridgelines");
   1948    if (write_str_to_file_if_not_equal(fname, str)) {
   1949      log_warn(LD_FS, "Couldn't save bridge lines to disk");
   1950    } else {
   1951      log_info(LD_FS, "Saved bridge lines to disk");
   1952    }
   1953    tor_free(fname);
   1954    tor_free(str);
   1955  }
   1956 
   1957  SMARTLIST_FOREACH(string_chunks, char *, s, tor_free(s));
   1958  smartlist_free(string_chunks);
   1959 }
   1960 
   1961 /** Stringify the SOCKS arguments in <b>socks_args</b> according to
   1962 *  180_pluggable_transport.txt.  The string is allocated on the heap
   1963 *  and it's the responsibility of the caller to free it after use. */
   1964 char *
   1965 pt_stringify_socks_args(const smartlist_t *socks_args)
   1966 {
   1967  /* tmp place to store escaped socks arguments, so that we can
   1968     concatenate them up afterwards */
   1969  smartlist_t *sl_tmp = NULL;
   1970  char *escaped_string = NULL;
   1971  char *new_string = NULL;
   1972 
   1973  tor_assert(socks_args);
   1974  tor_assert(smartlist_len(socks_args) > 0);
   1975 
   1976  sl_tmp = smartlist_new();
   1977 
   1978  SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) {
   1979    /* Escape ';' and '\'. */
   1980    escaped_string = tor_escape_str_for_pt_args(s, ";\\");
   1981    if (!escaped_string)
   1982      goto done;
   1983 
   1984    smartlist_add(sl_tmp, escaped_string);
   1985  } SMARTLIST_FOREACH_END(s);
   1986 
   1987  new_string = smartlist_join_strings(sl_tmp, ";", 0, NULL);
   1988 
   1989 done:
   1990  SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
   1991  smartlist_free(sl_tmp);
   1992 
   1993  return new_string;
   1994 }
   1995 
   1996 /** Return a string of the SOCKS arguments that we should pass to the
   1997 *  pluggable transports proxy in <b>addr</b>:<b>port</b> according to
   1998 *  180_pluggable_transport.txt.  The string is allocated on the heap
   1999 *  and it's the responsibility of the caller to free it after use. */
   2000 char *
   2001 pt_get_socks_args_for_proxy_addrport(const tor_addr_t *addr, uint16_t port)
   2002 {
   2003  const smartlist_t *socks_args = NULL;
   2004 
   2005  socks_args = get_socks_args_by_bridge_addrport(addr, port);
   2006  if (!socks_args)
   2007    return NULL;
   2008 
   2009  return pt_stringify_socks_args(socks_args);
   2010 }
   2011 
   2012 /** The tor config was read.
   2013 *  Destroy all managed proxies that were marked by a previous call to
   2014 *  prepare_proxy_list_for_config_read() and are not used by the new
   2015 *  config. */
   2016 void
   2017 sweep_proxy_list(void)
   2018 {
   2019  if (!managed_proxy_list)
   2020    return;
   2021  assert_unconfigured_count_ok();
   2022  SMARTLIST_FOREACH_BEGIN(managed_proxy_list, managed_proxy_t *, mp) {
   2023    if (mp->marked_for_removal) {
   2024      SMARTLIST_DEL_CURRENT(managed_proxy_list, mp);
   2025      managed_proxy_destroy(mp, 1);
   2026    }
   2027  } SMARTLIST_FOREACH_END(mp);
   2028  assert_unconfigured_count_ok();
   2029 }
   2030 
   2031 /** Release all storage held by the pluggable transports subsystem. */
   2032 void
   2033 pt_free_all(void)
   2034 {
   2035  if (transport_list) {
   2036    clear_transport_list();
   2037    smartlist_free(transport_list);
   2038    transport_list = NULL;
   2039  }
   2040 
   2041  if (managed_proxy_list) {
   2042    /* If the proxy is in PT_PROTO_COMPLETED, it has registered its
   2043       transports and it's the duty of the circuitbuild.c subsystem to
   2044       free them. Otherwise, it hasn't registered its transports yet
   2045       and we should free them here. */
   2046    SMARTLIST_FOREACH(managed_proxy_list, managed_proxy_t *, mp, {
   2047        SMARTLIST_DEL_CURRENT(managed_proxy_list, mp);
   2048        managed_proxy_destroy(mp, 1);
   2049    });
   2050 
   2051    smartlist_free(managed_proxy_list);
   2052    managed_proxy_list=NULL;
   2053  }
   2054 }
   2055 
   2056 /** Return a newly allocated string equal to <b>string</b>, except that every
   2057 * character in <b>chars_to_escape</b> is preceded by a backslash. */
   2058 char *
   2059 tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape)
   2060 {
   2061  char *new_string = NULL;
   2062  char *new_cp = NULL;
   2063  size_t length, new_length;
   2064 
   2065  tor_assert(string);
   2066 
   2067  length = strlen(string);
   2068 
   2069  if (!length) /* If we were given the empty string, return the same. */
   2070    return tor_strdup("");
   2071  /* (new_length > SIZE_MAX) => ((length * 2) + 1 > SIZE_MAX) =>
   2072     (length*2 > SIZE_MAX - 1) => (length > (SIZE_MAX - 1)/2) */
   2073  if (length > (SIZE_MAX - 1)/2) /* check for overflow */
   2074    return NULL;
   2075 
   2076  /* this should be enough even if all characters must be escaped */
   2077  new_length = (length * 2) + 1;
   2078 
   2079  new_string = new_cp = tor_malloc(new_length);
   2080 
   2081  while (*string) {
   2082    if (strchr(chars_to_escape, *string))
   2083      *new_cp++ = '\\';
   2084 
   2085    *new_cp++ = *string++;
   2086  }
   2087 
   2088  *new_cp = '\0'; /* NUL-terminate the new string */
   2089 
   2090  return new_string;
   2091 }
   2092 
   2093 /** Callback function that is called when our PT process have data on its
   2094 * stdout. Our process can be found in <b>process</b>, the data can be found in
   2095 * <b>line</b> and the length of our line is given in <b>size</b>. */
   2096 STATIC void
   2097 managed_proxy_stdout_callback(process_t *process,
   2098                              const char *line,
   2099                              size_t size)
   2100 {
   2101  tor_assert(process);
   2102  tor_assert(line);
   2103 
   2104  (void)size;
   2105 
   2106  managed_proxy_t *mp = process_get_data(process);
   2107 
   2108  if (mp == NULL)
   2109    return;
   2110 
   2111  handle_proxy_line(line, mp);
   2112 
   2113  if (proxy_configuration_finished(mp))
   2114    handle_finished_proxy(mp);
   2115 }
   2116 
   2117 /** Callback function that is called when our PT process have data on its
   2118 * stderr. Our process can be found in <b>process</b>, the data can be found in
   2119 * <b>line</b> and the length of our line is given in <b>size</b>. */
   2120 STATIC void
   2121 managed_proxy_stderr_callback(process_t *process,
   2122                              const char *line,
   2123                              size_t size)
   2124 {
   2125  tor_assert(process);
   2126  tor_assert(line);
   2127 
   2128  (void)size;
   2129 
   2130  managed_proxy_t *mp = process_get_data(process);
   2131 
   2132  if (BUG(mp == NULL))
   2133    return;
   2134 
   2135  log_info(LD_PT,
   2136           "Managed proxy at '%s' reported via standard error: %s",
   2137           mp->argv[0], line);
   2138 }
   2139 
   2140 /** Callback function that is called when our PT process terminates. The
   2141 * process exit code can be found in <b>exit_code</b> and our process can be
   2142 * found in <b>process</b>. Returns true iff we want the process subsystem to
   2143 * free our process_t handle for us. */
   2144 STATIC bool
   2145 managed_proxy_exit_callback(process_t *process, process_exit_code_t exit_code)
   2146 {
   2147  tor_assert(process);
   2148 
   2149  managed_proxy_t *mp = process_get_data(process);
   2150  const char *name = mp ? mp->argv[0] : "N/A";
   2151 
   2152  if (!we_are_shutting_down())
   2153    log_warn(LD_PT, "Managed proxy \"%s\" having PID %" PRIu64 " "
   2154                    "terminated with status code %" PRIu64,
   2155                    name, process_get_pid(process), exit_code);
   2156  else
   2157    log_notice(LD_PT, "Managed proxy \"%s\" having PID %" PRIu64 " "
   2158                      "has exited.", name, process_get_pid(process));
   2159 
   2160  if (mp) {
   2161    /* We remove this process_t from the mp. */
   2162    tor_assert(mp->process == process);
   2163    mp->process = NULL;
   2164 
   2165    /* Prepare the proxy for restart. */
   2166    proxy_prepare_for_restart(mp);
   2167 
   2168    if (!we_are_shutting_down()) {
   2169      /* We have proxies we want to restart? */
   2170      pt_configure_remaining_proxies();
   2171    }
   2172  }
   2173 
   2174  /* Returning true here means that the process subsystem will take care of
   2175   * calling process_free() on our process_t. */
   2176  return true;
   2177 }
   2178 
   2179 /** Returns a valid integer log severity level from <b>severity</b> that
   2180 * is compatible with Tor's logging functions. Returns <b>-1</b> on
   2181 * error. */
   2182 STATIC int
   2183 managed_proxy_severity_parse(const char *severity)
   2184 {
   2185  tor_assert(severity);
   2186 
   2187  /* Slightly different than log.c's parse_log_level :-( */
   2188  if (! strcmp(severity, "debug"))
   2189    return LOG_DEBUG;
   2190 
   2191  if (! strcmp(severity, "info"))
   2192    return LOG_INFO;
   2193 
   2194  if (! strcmp(severity, "notice"))
   2195    return LOG_NOTICE;
   2196 
   2197  if (! strcmp(severity, "warning"))
   2198    return LOG_WARN;
   2199 
   2200  if (! strcmp(severity, "error"))
   2201    return LOG_ERR;
   2202 
   2203  return -1;
   2204 }
   2205 
   2206 /** Return the outbound address from the given <b>family</b>. Returns NULL if
   2207 * the user haven't specified a specific outbound address in either
   2208 * OutboundBindAddress or OutboundBindAddressPT. */
   2209 STATIC const tor_addr_t *
   2210 managed_proxy_outbound_address(const or_options_t *options, sa_family_t family)
   2211 {
   2212  tor_assert(options);
   2213 
   2214  const tor_addr_t *address = NULL;
   2215  int family_index;
   2216 
   2217  switch (family) {
   2218  case AF_INET:
   2219    family_index = 0;
   2220    break;
   2221  case AF_INET6:
   2222    family_index = 1;
   2223    break;
   2224  default:
   2225    /* LCOV_EXCL_START */
   2226    tor_assert_unreached();
   2227    return NULL;
   2228    /* LCOV_EXCL_STOP */
   2229  }
   2230 
   2231  /* We start by checking if the user specified an address in
   2232   * OutboundBindAddressPT. */
   2233  address = &options->OutboundBindAddresses[OUTBOUND_ADDR_PT][family_index];
   2234 
   2235  if (! tor_addr_is_null(address))
   2236    return address;
   2237 
   2238  /* We fallback to check if the user specified an address in
   2239   * OutboundBindAddress. */
   2240  address = &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY][family_index];
   2241 
   2242  if (! tor_addr_is_null(address))
   2243    return address;
   2244 
   2245  /* The user have not specified a preference for outgoing connections. */
   2246  return NULL;
   2247 }
   2248 
   2249 STATIC const char *
   2250 managed_proxy_state_to_string(enum pt_proto_state state)
   2251 {
   2252  switch (state) {
   2253  case PT_PROTO_INFANT:
   2254    return "Infant";
   2255  case PT_PROTO_WAITING:
   2256    return "Waiting";
   2257  case PT_PROTO_LAUNCHED:
   2258    return "Launched";
   2259  case PT_PROTO_ACCEPTING_METHODS:
   2260    return "Accepting methods";
   2261  case PT_PROTO_CONFIGURED:
   2262    return "Configured";
   2263  case PT_PROTO_COMPLETED:
   2264    return "Completed";
   2265  case PT_PROTO_BROKEN:
   2266    return "Broken";
   2267  case PT_PROTO_FAILED_LAUNCH:
   2268    return "Failed to launch";
   2269  }
   2270 
   2271  /* LCOV_EXCL_START */
   2272  tor_assert_unreached();
   2273  return NULL;
   2274  /* LCOV_EXCL_STOP */
   2275 }
   2276 
   2277 /** Set the internal state of the given <b>mp</b> to the given <b>new_state</b>
   2278 * value. */
   2279 STATIC void
   2280 managed_proxy_set_state(managed_proxy_t *mp, enum pt_proto_state new_state)
   2281 {
   2282  if (mp->conf_state == new_state)
   2283    return;
   2284 
   2285  tor_log(LOG_INFO, LD_PT, "Managed proxy \"%s\" changed state: %s -> %s",
   2286          mp->argv[0],
   2287          managed_proxy_state_to_string(mp->conf_state),
   2288          managed_proxy_state_to_string(new_state));
   2289 
   2290  mp->conf_state = new_state;
   2291 }