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