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 }