LCOV - code coverage report
Current view: top level - app/main - main.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 142 607 23.4 %
Date: 2021-11-24 03:28:48 Functions: 9 21 42.9 %

          Line data    Source code
       1             : /* Copyright (c) 2001 Matej Pfajfar.
       2             :  * Copyright (c) 2001-2004, Roger Dingledine.
       3             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       4             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * \file main.c
       9             :  * \brief Invocation module.  Initializes subsystems and runs the main loop.
      10             :  **/
      11             : 
      12             : #include "core/or/or.h"
      13             : 
      14             : #include "app/config/config.h"
      15             : #include "app/config/statefile.h"
      16             : #include "app/config/quiet_level.h"
      17             : #include "app/main/main.h"
      18             : #include "app/main/ntmain.h"
      19             : #include "app/main/risky_options.h"
      20             : #include "app/main/shutdown.h"
      21             : #include "app/main/subsysmgr.h"
      22             : #include "core/mainloop/connection.h"
      23             : #include "core/mainloop/cpuworker.h"
      24             : #include "core/mainloop/mainloop.h"
      25             : #include "core/mainloop/mainloop_pubsub.h"
      26             : #include "core/mainloop/netstatus.h"
      27             : #include "core/or/channel.h"
      28             : #include "core/or/channelpadding.h"
      29             : #include "core/or/circuitpadding.h"
      30             : #include "core/or/circuitlist.h"
      31             : #include "core/or/command.h"
      32             : #include "core/or/connection_or.h"
      33             : #include "core/or/relay.h"
      34             : #include "core/or/status.h"
      35             : #include "feature/api/tor_api.h"
      36             : #include "feature/api/tor_api_internal.h"
      37             : #include "feature/client/addressmap.h"
      38             : #include "feature/control/control.h"
      39             : #include "feature/control/control_auth.h"
      40             : #include "feature/control/control_events.h"
      41             : #include "feature/dirauth/keypin.h"
      42             : #include "feature/dirauth/process_descs.h"
      43             : #include "feature/dircache/consdiffmgr.h"
      44             : #include "feature/dirparse/routerparse.h"
      45             : #include "feature/hibernate/hibernate.h"
      46             : #include "feature/hs/hs_dos.h"
      47             : #include "feature/hs/hs_service.h"
      48             : #include "feature/nodelist/authcert.h"
      49             : #include "feature/nodelist/networkstatus.h"
      50             : #include "feature/nodelist/routerlist.h"
      51             : #include "feature/relay/dns.h"
      52             : #include "feature/relay/ext_orport.h"
      53             : #include "feature/relay/routerkeys.h"
      54             : #include "feature/relay/routermode.h"
      55             : #include "feature/stats/predict_ports.h"
      56             : #include "feature/stats/bwhist.h"
      57             : #include "feature/stats/rephist.h"
      58             : #include "lib/compress/compress.h"
      59             : #include "lib/buf/buffers.h"
      60             : #include "lib/crypt_ops/crypto_format.h"
      61             : #include "lib/crypt_ops/crypto_rand.h"
      62             : #include "lib/crypt_ops/crypto_s2k.h"
      63             : #include "lib/net/resolve.h"
      64             : #include "lib/trace/trace.h"
      65             : 
      66             : #include "lib/process/waitpid.h"
      67             : #include "lib/pubsub/pubsub_build.h"
      68             : 
      69             : #include "lib/meminfo/meminfo.h"
      70             : #include "lib/osinfo/uname.h"
      71             : #include "lib/osinfo/libc.h"
      72             : #include "lib/sandbox/sandbox.h"
      73             : #include "lib/fs/lockfile.h"
      74             : #include "lib/tls/tortls.h"
      75             : #include "lib/evloop/compat_libevent.h"
      76             : #include "lib/encoding/confline.h"
      77             : #include "lib/evloop/timers.h"
      78             : #include "lib/crypt_ops/crypto_init.h"
      79             : #include "lib/version/torversion.h"
      80             : 
      81             : #include <event2/event.h>
      82             : 
      83             : #include "feature/dirauth/authmode.h"
      84             : #include "feature/dirauth/shared_random.h"
      85             : 
      86             : #include "core/or/or_connection_st.h"
      87             : #include "core/or/port_cfg_st.h"
      88             : 
      89             : #ifdef HAVE_UNISTD_H
      90             : #include <unistd.h>
      91             : #endif
      92             : 
      93             : #ifdef HAVE_SYSTEMD
      94             : #   if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
      95             : /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse
      96             :  * Coverity. Here's a kludge to unconfuse it.
      97             :  */
      98             : #   define __INCLUDE_LEVEL__ 2
      99             : #endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */
     100             : #include <systemd/sd-daemon.h>
     101             : #endif /* defined(HAVE_SYSTEMD) */
     102             : 
     103             : #ifdef HAVE_RUST
     104             : // helper function defined in Rust to output a log message indicating if tor is
     105             : // running with Rust enabled. See src/rust/tor_util
     106             : void rust_log_welcome_string(void);
     107             : #endif
     108             : 
     109             : /********* PROTOTYPES **********/
     110             : 
     111             : static void dumpmemusage(int severity);
     112             : static void dumpstats(int severity); /* log stats */
     113             : static void process_signal(int sig);
     114             : 
     115             : /** Called when we get a SIGHUP: reload configuration files and keys,
     116             :  * retry all connections, and so on. */
     117             : static int
     118           0 : do_hup(void)
     119             : {
     120           0 :   const or_options_t *options = get_options();
     121             : 
     122           0 :   log_notice(LD_GENERAL,"Received reload signal (hup). Reloading config and "
     123             :              "resetting internal state.");
     124           0 :   if (accounting_is_enabled(options))
     125           0 :     accounting_record_bandwidth_usage(time(NULL), get_or_state());
     126             : 
     127           0 :   router_reset_warnings();
     128           0 :   routerlist_reset_warnings();
     129             :   /* first, reload config variables, in case they've changed */
     130           0 :   if (options->ReloadTorrcOnSIGHUP) {
     131             :     /* no need to provide argc/v, they've been cached in init_from_config */
     132           0 :     int init_rv = options_init_from_torrc(0, NULL);
     133           0 :     if (init_rv < 0) {
     134           0 :       log_err(LD_CONFIG,"Reading config failed--see warnings above. "
     135             :               "For usage, try -h.");
     136           0 :       return -1;
     137           0 :     } else if (BUG(init_rv > 0)) {
     138             :       // LCOV_EXCL_START
     139             :       /* This should be impossible: the only "return 1" cases in
     140             :        * options_init_from_torrc are ones caused by command-line arguments;
     141             :        * but they can't change while Tor is running. */
     142             :       return -1;
     143             :       // LCOV_EXCL_STOP
     144             :     }
     145           0 :     options = get_options(); /* they have changed now */
     146             :     /* Logs are only truncated the first time they are opened, but were
     147             :        probably intended to be cleaned up on signal. */
     148           0 :     if (options->TruncateLogFile)
     149           0 :       truncate_logs();
     150             :   } else {
     151           0 :     char *msg = NULL;
     152           0 :     log_notice(LD_GENERAL, "Not reloading config file: the controller told "
     153             :                "us not to.");
     154             :     /* Make stuff get rescanned, reloaded, etc. */
     155           0 :     if (set_options((or_options_t*)options, &msg) < 0) {
     156           0 :       if (!msg)
     157           0 :         msg = tor_strdup("Unknown error");
     158           0 :       log_warn(LD_GENERAL, "Unable to re-set previous options: %s", msg);
     159           0 :       tor_free(msg);
     160             :     }
     161             :   }
     162           0 :   if (authdir_mode(options)) {
     163             :     /* reload the approved-routers file */
     164           0 :     if (dirserv_load_fingerprint_file() < 0) {
     165             :       /* warnings are logged from dirserv_load_fingerprint_file() directly */
     166           0 :       log_info(LD_GENERAL, "Error reloading fingerprints. "
     167             :                "Continuing with old list.");
     168             :     }
     169             :   }
     170             : 
     171             :   /* Rotate away from the old dirty circuits. This has to be done
     172             :    * after we've read the new options, but before we start using
     173             :    * circuits for directory fetches. */
     174           0 :   circuit_mark_all_dirty_circs_as_unusable();
     175             : 
     176             :   /* retry appropriate downloads */
     177           0 :   router_reset_status_download_failures();
     178           0 :   router_reset_descriptor_download_failures();
     179           0 :   if (!net_is_disabled())
     180           0 :     update_networkstatus_downloads(time(NULL));
     181             : 
     182             :   /* We'll retry routerstatus downloads in about 10 seconds; no need to
     183             :    * force a retry there. */
     184             : 
     185           0 :   if (server_mode(options)) {
     186             :     /* Maybe we've been given a new ed25519 key or certificate?
     187             :      */
     188           0 :     time_t now = approx_time();
     189           0 :     int new_signing_key = load_ed_keys(options, now);
     190           0 :     if (new_signing_key < 0 ||
     191           0 :         generate_ed_link_cert(options, now, new_signing_key > 0)) {
     192           0 :       log_warn(LD_OR, "Problem reloading Ed25519 keys; still using old keys.");
     193             :     }
     194             : 
     195             :     /* Update cpuworker and dnsworker processes, so they get up-to-date
     196             :      * configuration options. */
     197           0 :     cpuworkers_rotate_keyinfo();
     198           0 :     dns_reset();
     199             :   }
     200             :   return 0;
     201             : }
     202             : 
     203             : /** Libevent callback: invoked when we get a signal.
     204             :  */
     205             : static void
     206           0 : signal_callback(evutil_socket_t fd, short events, void *arg)
     207             : {
     208           0 :   const int *sigptr = arg;
     209           0 :   const int sig = *sigptr;
     210           0 :   (void)fd;
     211           0 :   (void)events;
     212             : 
     213           0 :   update_current_time(time(NULL));
     214           0 :   process_signal(sig);
     215           0 : }
     216             : 
     217             : /** Do the work of acting on a signal received in <b>sig</b> */
     218             : static void
     219           0 : process_signal(int sig)
     220             : {
     221           0 :   switch (sig)
     222             :     {
     223           0 :     case SIGTERM:
     224           0 :       log_notice(LD_GENERAL,"Catching signal TERM, exiting cleanly.");
     225           0 :       tor_shutdown_event_loop_and_exit(0);
     226           0 :       break;
     227           0 :     case SIGINT:
     228           0 :       if (!server_mode(get_options())) { /* do it now */
     229           0 :         log_notice(LD_GENERAL,"Interrupt: exiting cleanly.");
     230           0 :         tor_shutdown_event_loop_and_exit(0);
     231           0 :         return;
     232             :       }
     233             : #ifdef HAVE_SYSTEMD
     234           0 :       sd_notify(0, "STOPPING=1");
     235             : #endif
     236           0 :       hibernate_begin_shutdown();
     237           0 :       break;
     238             : #ifdef SIGPIPE
     239             :     case SIGPIPE:
     240           0 :       log_debug(LD_GENERAL,"Caught SIGPIPE. Ignoring.");
     241           0 :       break;
     242             : #endif
     243           0 :     case SIGUSR1:
     244             :       /* prefer to log it at INFO, but make sure we always see it */
     245           0 :       dumpstats(get_min_log_level()<LOG_INFO ? get_min_log_level() : LOG_INFO);
     246           0 :       control_event_signal(sig);
     247           0 :       break;
     248           0 :     case SIGUSR2:
     249           0 :       switch_logs_debug();
     250           0 :       log_debug(LD_GENERAL,"Caught USR2, going to loglevel debug. "
     251             :                 "Send HUP to change back.");
     252           0 :       control_event_signal(sig);
     253           0 :       break;
     254           0 :     case SIGHUP:
     255             : #ifdef HAVE_SYSTEMD
     256           0 :       sd_notify(0, "RELOADING=1");
     257             : #endif
     258           0 :       if (do_hup() < 0) {
     259           0 :         log_warn(LD_CONFIG,"Restart failed (config error?). Exiting.");
     260           0 :         tor_shutdown_event_loop_and_exit(1);
     261           0 :         return;
     262             :       }
     263             : #ifdef HAVE_SYSTEMD
     264           0 :       sd_notify(0, "READY=1");
     265             : #endif
     266           0 :       control_event_signal(sig);
     267           0 :       break;
     268             : #ifdef SIGCHLD
     269           0 :     case SIGCHLD:
     270           0 :       notify_pending_waitpid_callbacks();
     271           0 :       break;
     272             : #endif
     273           0 :     case SIGNEWNYM: {
     274           0 :       do_signewnym(time(NULL));
     275           0 :       break;
     276             :     }
     277           0 :     case SIGCLEARDNSCACHE:
     278           0 :       addressmap_clear_transient();
     279           0 :       control_event_signal(sig);
     280           0 :       break;
     281           0 :     case SIGHEARTBEAT:
     282           0 :       log_heartbeat(time(NULL));
     283           0 :       control_event_signal(sig);
     284           0 :       break;
     285           0 :     case SIGACTIVE:
     286             :       /* "SIGACTIVE" counts as ersatz user activity. */
     287           0 :       note_user_activity(approx_time());
     288           0 :       control_event_signal(sig);
     289           0 :       break;
     290           0 :     case SIGDORMANT:
     291             :       /* "SIGDORMANT" means to ignore past user activity */
     292           0 :       log_notice(LD_GENERAL, "Going dormant because of controller request.");
     293           0 :       reset_user_activity(0);
     294           0 :       set_network_participation(false);
     295           0 :       schedule_rescan_periodic_events();
     296           0 :       control_event_signal(sig);
     297           0 :       break;
     298             :   }
     299             : }
     300             : 
     301             : #ifdef _WIN32
     302             : /** Activate SIGINT on receiving a control signal in console. */
     303             : static BOOL WINAPI
     304             : process_win32_console_ctrl(DWORD ctrl_type)
     305             : {
     306             :   /* Ignore type of the ctrl signal */
     307             :   (void) ctrl_type;
     308             : 
     309             :   activate_signal(SIGINT);
     310             :   return TRUE;
     311             : }
     312             : #endif /* defined(_WIN32) */
     313             : 
     314             : /**
     315             :  * Write current memory usage information to the log.
     316             :  */
     317             : static void
     318           0 : dumpmemusage(int severity)
     319             : {
     320           0 :   connection_dump_buffer_mem_stats(severity);
     321           0 :   tor_log(severity, LD_GENERAL, "In rephist: %"PRIu64" used by %d Tors.",
     322             :       (rephist_total_alloc), rephist_total_num);
     323           0 :   dump_routerlist_mem_usage(severity);
     324           0 :   dump_cell_pool_usage(severity);
     325           0 :   dump_dns_mem_usage(severity);
     326           0 : }
     327             : 
     328             : /** Write all statistics to the log, with log level <b>severity</b>. Called
     329             :  * in response to a SIGUSR1. */
     330             : static void
     331           0 : dumpstats(int severity)
     332             : {
     333           0 :   time_t now = time(NULL);
     334           0 :   time_t elapsed;
     335           0 :   size_t rbuf_cap, wbuf_cap, rbuf_len, wbuf_len;
     336             : 
     337           0 :   tor_log(severity, LD_GENERAL, "Dumping stats:");
     338             : 
     339           0 :   SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
     340           0 :     int i = conn_sl_idx;
     341           0 :     tor_log(severity, LD_GENERAL,
     342             :         "Conn %d (socket %d) is a %s, created %d secs ago",
     343             :         i, (int)conn->s,
     344             :         connection_describe(conn),
     345           0 :         (int)(now - conn->timestamp_created));
     346           0 :     if (!connection_is_listener(conn)) {
     347           0 :       tor_log(severity,LD_GENERAL,
     348             :           "Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
     349             :           i,
     350           0 :           (int)connection_get_inbuf_len(conn),
     351           0 :           (int)buf_allocation(conn->inbuf),
     352           0 :           (int)(now - conn->timestamp_last_read_allowed));
     353           0 :       tor_log(severity,LD_GENERAL,
     354             :           "Conn %d: %d bytes waiting on outbuf "
     355             :           "(len %d, last written %d secs ago)",i,
     356           0 :           (int)connection_get_outbuf_len(conn),
     357           0 :           (int)buf_allocation(conn->outbuf),
     358           0 :           (int)(now - conn->timestamp_last_write_allowed));
     359           0 :       if (conn->type == CONN_TYPE_OR) {
     360           0 :         or_connection_t *or_conn = TO_OR_CONN(conn);
     361           0 :         if (or_conn->tls) {
     362           0 :           if (tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len,
     363             :                                        &wbuf_cap, &wbuf_len) == 0) {
     364           0 :             tor_log(severity, LD_GENERAL,
     365             :                 "Conn %d: %d/%d bytes used on OpenSSL read buffer; "
     366             :                 "%d/%d bytes used on write buffer.",
     367             :                 i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap);
     368             :           }
     369             :         }
     370             :       }
     371             :     }
     372           0 :     circuit_dump_by_conn(conn, severity); /* dump info about all the circuits
     373             :                                            * using this conn */
     374           0 :   } SMARTLIST_FOREACH_END(conn);
     375             : 
     376           0 :   channel_dumpstats(severity);
     377           0 :   channel_listener_dumpstats(severity);
     378             : 
     379           0 :   tor_log(severity, LD_NET,
     380             :       "Cells processed: %"PRIu64" padding\n"
     381             :       "                 %"PRIu64" create\n"
     382             :       "                 %"PRIu64" created\n"
     383             :       "                 %"PRIu64" relay\n"
     384             :       "                        (%"PRIu64" relayed)\n"
     385             :       "                        (%"PRIu64" delivered)\n"
     386             :       "                 %"PRIu64" destroy",
     387             :       (stats_n_padding_cells_processed),
     388             :       (stats_n_create_cells_processed),
     389             :       (stats_n_created_cells_processed),
     390             :       (stats_n_relay_cells_processed),
     391             :       (stats_n_relay_cells_relayed),
     392             :       (stats_n_relay_cells_delivered),
     393             :       (stats_n_destroy_cells_processed));
     394           0 :   if (stats_n_data_cells_packaged)
     395           0 :     tor_log(severity,LD_NET,"Average packaged cell fullness: %2.3f%%",
     396           0 :         100*(((double)stats_n_data_bytes_packaged) /
     397           0 :              ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) );
     398           0 :   if (stats_n_data_cells_received)
     399           0 :     tor_log(severity,LD_NET,"Average delivered cell fullness: %2.3f%%",
     400           0 :         100*(((double)stats_n_data_bytes_received) /
     401           0 :              ((double)stats_n_data_cells_received*RELAY_PAYLOAD_SIZE)) );
     402             : 
     403           0 :   cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_TAP, "TAP");
     404           0 :   cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_NTOR,"ntor");
     405             : 
     406           0 :   if (now - time_of_process_start >= 0)
     407           0 :     elapsed = now - time_of_process_start;
     408             :   else
     409             :     elapsed = 0;
     410             : 
     411           0 :   if (elapsed) {
     412           0 :     tor_log(severity, LD_NET,
     413             :         "Average bandwidth: %"PRIu64"/%d = %d bytes/sec reading",
     414             :         (get_bytes_read()),
     415             :         (int)elapsed,
     416           0 :         (int) (get_bytes_read()/elapsed));
     417           0 :     tor_log(severity, LD_NET,
     418             :         "Average bandwidth: %"PRIu64"/%d = %d bytes/sec writing",
     419             :         (get_bytes_written()),
     420             :         (int)elapsed,
     421           0 :         (int) (get_bytes_written()/elapsed));
     422             :   }
     423             : 
     424           0 :   tor_log(severity, LD_NET, "--------------- Dumping memory information:");
     425           0 :   dumpmemusage(severity);
     426             : 
     427           0 :   rep_hist_dump_stats(now,severity);
     428           0 :   hs_service_dump_stats(severity);
     429           0 : }
     430             : 
     431             : #ifdef _WIN32
     432             : #define UNIX_ONLY 0
     433             : #else
     434             : #define UNIX_ONLY 1
     435             : #endif
     436             : 
     437             : static struct {
     438             :   /** A numeric code for this signal. Must match the signal value if
     439             :    * try_to_register is true. */
     440             :   int signal_value;
     441             :   /** True if we should try to register this signal with libevent and catch
     442             :    * corresponding posix signals. False otherwise. */
     443             :   int try_to_register;
     444             :   /** Pointer to hold the event object constructed for this signal. */
     445             :   struct event *signal_event;
     446             : } signal_handlers[] = {
     447             : #ifdef SIGINT
     448             :   { SIGINT, UNIX_ONLY, NULL }, /* do a controlled slow shutdown */
     449             : #endif
     450             : #ifdef SIGTERM
     451             :   { SIGTERM, UNIX_ONLY, NULL }, /* to terminate now */
     452             : #endif
     453             : #ifdef SIGPIPE
     454             :   { SIGPIPE, UNIX_ONLY, NULL }, /* otherwise SIGPIPE kills us */
     455             : #endif
     456             : #ifdef SIGUSR1
     457             :   { SIGUSR1, UNIX_ONLY, NULL }, /* dump stats */
     458             : #endif
     459             : #ifdef SIGUSR2
     460             :   { SIGUSR2, UNIX_ONLY, NULL }, /* go to loglevel debug */
     461             : #endif
     462             : #ifdef SIGHUP
     463             :   { SIGHUP, UNIX_ONLY, NULL }, /* to reload config, retry conns, etc */
     464             : #endif
     465             : #ifdef SIGXFSZ
     466             :   { SIGXFSZ, UNIX_ONLY, NULL }, /* handle file-too-big resource exhaustion */
     467             : #endif
     468             : #ifdef SIGCHLD
     469             :   { SIGCHLD, UNIX_ONLY, NULL }, /* handle dns/cpu workers that exit */
     470             : #endif
     471             :   /* These are controller-only */
     472             :   { SIGNEWNYM, 0, NULL },
     473             :   { SIGCLEARDNSCACHE, 0, NULL },
     474             :   { SIGHEARTBEAT, 0, NULL },
     475             :   { SIGACTIVE, 0, NULL },
     476             :   { SIGDORMANT, 0, NULL },
     477             :   { -1, -1, NULL }
     478             : };
     479             : 
     480             : /** Set up the signal handler events for this process, and register them
     481             :  * with libevent if appropriate. */
     482             : void
     483           0 : handle_signals(void)
     484             : {
     485           0 :   int i;
     486           0 :   const int enabled = !get_options()->DisableSignalHandlers;
     487             : 
     488           0 :   for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
     489             :     /* Signal handlers are only registered with libevent if they need to catch
     490             :      * real POSIX signals.  We construct these signal handler events in either
     491             :      * case, though, so that controllers can activate them with the SIGNAL
     492             :      * command.
     493             :      */
     494           0 :     if (enabled && signal_handlers[i].try_to_register) {
     495           0 :       signal_handlers[i].signal_event =
     496           0 :         tor_evsignal_new(tor_libevent_get_base(),
     497             :                          signal_handlers[i].signal_value,
     498             :                          signal_callback,
     499             :                          &signal_handlers[i].signal_value);
     500           0 :       if (event_add(signal_handlers[i].signal_event, NULL))
     501           0 :         log_warn(LD_BUG, "Error from libevent when adding "
     502             :                  "event for signal %d",
     503             :                  signal_handlers[i].signal_value);
     504             :     } else {
     505           0 :       signal_handlers[i].signal_event =
     506           0 :         tor_event_new(tor_libevent_get_base(), -1,
     507             :                       EV_SIGNAL, signal_callback,
     508           0 :                       &signal_handlers[i].signal_value);
     509             :     }
     510             :   }
     511             : 
     512             : #ifdef _WIN32
     513             :     /* Windows lacks traditional POSIX signals but WinAPI provides a function
     514             :      * to handle control signals like Ctrl+C in the console, we can use this to
     515             :      * simulate the SIGINT signal */
     516             :     if (enabled) SetConsoleCtrlHandler(process_win32_console_ctrl, TRUE);
     517             : #endif /* defined(_WIN32) */
     518           0 : }
     519             : 
     520             : /* Cause the signal handler for signal_num to be called in the event loop. */
     521             : void
     522           0 : activate_signal(int signal_num)
     523             : {
     524           0 :   int i;
     525           0 :   for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
     526           0 :     if (signal_handlers[i].signal_value == signal_num) {
     527           0 :       event_active(signal_handlers[i].signal_event, EV_SIGNAL, 1);
     528           0 :       return;
     529             :     }
     530             :   }
     531             : }
     532             : 
     533             : /** Main entry point for the Tor command-line client.  Return 0 on "success",
     534             :  * negative on "failure", and positive on "success and exit".
     535             :  */
     536             : int
     537         235 : tor_init(int argc, char *argv[])
     538             : {
     539         235 :   char progname[256];
     540         235 :   quiet_level_t quiet = QUIET_NONE;
     541         235 :   bool running_tor = false;
     542             : 
     543         235 :   time_of_process_start = time(NULL);
     544         235 :   tor_init_connection_lists();
     545             :   /* Have the log set up with our application name. */
     546         235 :   tor_snprintf(progname, sizeof(progname), "Tor %s", get_version());
     547         235 :   log_set_application_name(progname);
     548             : 
     549             :   /* Initialize the history structures. */
     550         235 :   rep_hist_init();
     551         235 :   bwhist_init();
     552             :   /* Initialize the service cache. */
     553         235 :   addressmap_init(); /* Init the client dns cache. Do it always, since it's
     554             :                       * cheap. */
     555             : 
     556             :   /* Initialize the HS subsystem. */
     557         235 :   hs_init();
     558             : 
     559             :   {
     560             :     /* We check for the "quiet"/"hush" settings first, since they decide
     561             :        whether we log anything at all to stdout. */
     562         235 :     parsed_cmdline_t *cmdline;
     563         235 :     cmdline = config_parse_commandline(argc, argv, 1);
     564         235 :     if (cmdline) {
     565         235 :       quiet = cmdline->quiet_level;
     566         235 :       running_tor = (cmdline->command == CMD_RUN_TOR);
     567             :     }
     568         235 :     parsed_cmdline_free(cmdline);
     569             :   }
     570             : 
     571             :  /* give it somewhere to log to initially */
     572         235 :   add_default_log_for_quiet_level(quiet);
     573         235 :   quiet_level = quiet;
     574             : 
     575             :   {
     576         235 :     const char *version = get_version();
     577             : 
     578         235 :     log_notice(LD_GENERAL, "Tor %s running on %s with Libevent %s, "
     579             :                "%s %s, Zlib %s, Liblzma %s, Libzstd %s and %s %s as libc.",
     580             :                version,
     581             :                get_uname(),
     582             :                tor_libevent_get_version_str(),
     583             :                crypto_get_library_name(),
     584             :                crypto_get_library_version_string(),
     585             :                tor_compress_supports_method(ZLIB_METHOD) ?
     586             :                  tor_compress_version_str(ZLIB_METHOD) : "N/A",
     587             :                tor_compress_supports_method(LZMA_METHOD) ?
     588             :                  tor_compress_version_str(LZMA_METHOD) : "N/A",
     589             :                tor_compress_supports_method(ZSTD_METHOD) ?
     590             :                  tor_compress_version_str(ZSTD_METHOD) : "N/A",
     591             :                tor_libc_get_name() ?
     592             :                  tor_libc_get_name() : "Unknown",
     593             :                tor_libc_get_version_str());
     594             : 
     595         235 :     log_notice(LD_GENERAL, "Tor can't help you if you use it wrong! "
     596             :                "Learn how to be safe at "
     597             :                "https://www.torproject.org/download/download#warning");
     598             : 
     599         235 :     if (strstr(version, "alpha") || strstr(version, "beta"))
     600         235 :       log_notice(LD_GENERAL, "This version is not a stable Tor release. "
     601             :                  "Expect more bugs than usual.");
     602             : 
     603         235 :     if (strlen(risky_option_list) && running_tor) {
     604           4 :       log_warn(LD_GENERAL, "This build of Tor has been compiled with one "
     605             :                "or more options that might make it less reliable or secure! "
     606             :                "They are:%s", risky_option_list);
     607             :     }
     608             : 
     609         235 :     tor_compress_log_init_warnings();
     610             :   }
     611             : 
     612             : #ifdef HAVE_RUST
     613             :   rust_log_welcome_string();
     614             : #endif /* defined(HAVE_RUST) */
     615             : 
     616             :   /* Warn _if_ the tracing subsystem is built in. */
     617         235 :   tracing_log_warning();
     618             : 
     619         235 :   int init_rv = options_init_from_torrc(argc,argv);
     620         235 :   if (init_rv < 0) {
     621          36 :     log_err(LD_CONFIG,"Reading config failed--see warnings above.");
     622          36 :     return -1;
     623         199 :   } else if (init_rv > 0) {
     624             :     // We succeeded, and should exit anyway -- probably the user just said
     625             :     // "--version" or something like that.
     626             :     return 1;
     627             :   }
     628             : 
     629             :   /* Initialize channelpadding and circpad parameters to defaults
     630             :    * until we get a consensus */
     631         194 :   channelpadding_new_consensus_params(NULL);
     632         194 :   circpad_new_consensus_params(NULL);
     633             : 
     634             :   /* Initialize circuit padding to defaults+torrc until we get a consensus */
     635         194 :   circpad_machines_init();
     636             : 
     637             :   /* Initialize hidden service DoS subsystem. We need to do this once the
     638             :    * configuration object has been set because it can be accessed. */
     639         194 :   hs_dos_init();
     640             : 
     641             :   /* Initialize predicted ports list after loading options */
     642         194 :   predicted_ports_init();
     643             : 
     644             : #ifndef _WIN32
     645         194 :   if (geteuid()==0)
     646           0 :     log_warn(LD_GENERAL,"You are running Tor as root. You don't need to, "
     647             :              "and you probably shouldn't.");
     648             : #endif
     649             : 
     650             :   /* Scan/clean unparseable descriptors; after reading config */
     651         194 :   routerparse_init();
     652             : 
     653         194 :   return 0;
     654             : }
     655             : 
     656             : /** A lockfile structure, used to prevent two Tors from messing with the
     657             :  * data directory at once.  If this variable is non-NULL, we're holding
     658             :  * the lockfile. */
     659             : static tor_lockfile_t *lockfile = NULL;
     660             : 
     661             : /** Try to grab the lock file described in <b>options</b>, if we do not
     662             :  * already have it.  If <b>err_if_locked</b> is true, warn if somebody else is
     663             :  * holding the lock, and exit if we can't get it after waiting.  Otherwise,
     664             :  * return -1 if we can't get the lockfile.  Return 0 on success.
     665             :  */
     666             : int
     667          21 : try_locking(const or_options_t *options, int err_if_locked)
     668             : {
     669          21 :   if (lockfile)
     670             :     return 0;
     671             :   else {
     672          21 :     char *fname = options_get_datadir_fname(options, "lock");
     673          21 :     int already_locked = 0;
     674          21 :     tor_lockfile_t *lf = tor_lockfile_lock(fname, 0, &already_locked);
     675          21 :     tor_free(fname);
     676          21 :     if (!lf) {
     677           0 :       if (err_if_locked && already_locked) {
     678           0 :         int r;
     679           0 :         log_warn(LD_GENERAL, "It looks like another Tor process is running "
     680             :                  "with the same data directory.  Waiting 5 seconds to see "
     681             :                  "if it goes away.");
     682             : #ifndef _WIN32
     683           0 :         sleep(5);
     684             : #else
     685             :         Sleep(5000);
     686             : #endif
     687           0 :         r = try_locking(options, 0);
     688           0 :         if (r<0) {
     689           0 :           log_err(LD_GENERAL, "No, it's still there.  Exiting.");
     690           0 :           return -1;
     691             :         }
     692             :         return r;
     693             :       }
     694             :       return -1;
     695             :     }
     696          21 :     lockfile = lf;
     697          21 :     return 0;
     698             :   }
     699             : }
     700             : 
     701             : /** Return true iff we've successfully acquired the lock file. */
     702             : int
     703          45 : have_lockfile(void)
     704             : {
     705          45 :   return lockfile != NULL;
     706             : }
     707             : 
     708             : /** If we have successfully acquired the lock file, release it. */
     709             : void
     710         235 : release_lockfile(void)
     711             : {
     712         235 :   if (lockfile) {
     713          21 :     tor_lockfile_unlock(lockfile);
     714          21 :     lockfile = NULL;
     715             :   }
     716         235 : }
     717             : 
     718             : /**
     719             :  * Remove the specified file, and log a warning if the operation fails for
     720             :  * any reason other than the file not existing. Ignores NULL filenames.
     721             :  */
     722             : void
     723           0 : tor_remove_file(const char *filename)
     724             : {
     725           0 :   if (filename && tor_unlink(filename) != 0 && errno != ENOENT) {
     726           0 :     log_warn(LD_FS, "Couldn't unlink %s: %s",
     727             :                filename, strerror(errno));
     728             :   }
     729           0 : }
     730             : 
     731             : /** Read/create keys as needed, and echo our fingerprint to stdout. */
     732             : static int
     733          19 : do_list_fingerprint(void)
     734             : {
     735          19 :   const or_options_t *options = get_options();
     736          19 :   const char *arg = options->command_arg;
     737          19 :   char rsa[FINGERPRINT_LEN + 1];
     738          19 :   crypto_pk_t *k;
     739          19 :   const ed25519_public_key_t *edkey;
     740          19 :   const char *nickname = options->Nickname;
     741          19 :   sandbox_disable_getaddrinfo_cache();
     742             : 
     743          19 :   bool show_rsa = !strcmp(arg, "") || !strcmp(arg, "rsa");
     744          19 :   bool show_ed25519 = !strcmp(arg, "ed25519");
     745          19 :   if (!show_rsa && !show_ed25519) {
     746           0 :     log_err(LD_GENERAL,
     747             :       "If you give a key type, you must specify 'rsa' or 'ed25519'. Exiting.");
     748           0 :     return -1;
     749             :   }
     750             : 
     751          19 :   if (!server_mode(options)) {
     752           0 :     log_err(LD_GENERAL,
     753             :             "Clients don't have long-term identity keys. Exiting.");
     754           0 :     return -1;
     755             :   }
     756          19 :   tor_assert(nickname);
     757          19 :   if (init_keys() < 0) {
     758           5 :     log_err(LD_GENERAL, "Error initializing keys; exiting.");
     759           5 :     return -1;
     760             :   }
     761          14 :   if (!(k = get_server_identity_key())) {
     762           0 :     log_err(LD_GENERAL, "Error: missing RSA identity key.");
     763           0 :     return -1;
     764             :   }
     765          14 :   if (crypto_pk_get_fingerprint(k, rsa, 1) < 0) {
     766           0 :     log_err(LD_BUG, "Error computing RSA fingerprint");
     767           0 :     return -1;
     768             :   }
     769          14 :   if (!(edkey = get_master_identity_key())) {
     770           0 :     log_err(LD_GENERAL,"Error: missing ed25519 identity key.");
     771           0 :     return -1;
     772             :   }
     773          14 :   if (show_rsa) {
     774          14 :     printf("%s %s\n", nickname, rsa);
     775             :   }
     776          14 :   if (show_ed25519) {
     777           0 :     char ed25519[ED25519_BASE64_LEN + 1];
     778           0 :     digest256_to_base64(ed25519, (const char *) edkey->pubkey);
     779           0 :     printf("%s %s\n", nickname, ed25519);
     780             :   }
     781             :   return 0;
     782             : }
     783             : 
     784             : /** Entry point for password hashing: take the desired password from
     785             :  * the command line, and print its salted hash to stdout. **/
     786             : static void
     787           0 : do_hash_password(void)
     788             : {
     789             : 
     790           0 :   char output[256];
     791           0 :   char key[S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN];
     792             : 
     793           0 :   crypto_rand(key, S2K_RFC2440_SPECIFIER_LEN-1);
     794           0 :   key[S2K_RFC2440_SPECIFIER_LEN-1] = (uint8_t)96; /* Hash 64 K of data. */
     795           0 :   secret_to_key_rfc2440(key+S2K_RFC2440_SPECIFIER_LEN, DIGEST_LEN,
     796           0 :                 get_options()->command_arg, strlen(get_options()->command_arg),
     797             :                 key);
     798           0 :   base16_encode(output, sizeof(output), key, sizeof(key));
     799           0 :   printf("16:%s\n",output);
     800           0 : }
     801             : 
     802             : /** Entry point for configuration dumping: write the configuration to
     803             :  * stdout. */
     804             : static int
     805         110 : do_dump_config(void)
     806             : {
     807         110 :   const or_options_t *options = get_options();
     808         110 :   const char *arg = options->command_arg;
     809         110 :   int how;
     810         110 :   char *opts;
     811             : 
     812         110 :   if (!strcmp(arg, "short")) {
     813             :     how = OPTIONS_DUMP_MINIMAL;
     814           0 :   } else if (!strcmp(arg, "non-builtin")) {
     815             :     // Deprecated since 0.4.5.1-alpha.
     816           0 :     fprintf(stderr, "'non-builtin' is deprecated; use 'short' instead.\n");
     817           0 :     how = OPTIONS_DUMP_MINIMAL;
     818           0 :   } else if (!strcmp(arg, "full")) {
     819             :     how = OPTIONS_DUMP_ALL;
     820             :   } else {
     821           0 :     fprintf(stderr, "No valid argument to --dump-config found!\n");
     822           0 :     fprintf(stderr, "Please select 'short' or 'full'.\n");
     823             : 
     824           0 :     return -1;
     825             :   }
     826             : 
     827         110 :   opts = options_dump(options, how);
     828         110 :   printf("%s", opts);
     829         110 :   tor_free(opts);
     830             : 
     831         110 :   return 0;
     832             : }
     833             : 
     834             : static void
     835           0 : init_addrinfo(void)
     836             : {
     837           0 :   if (! server_mode(get_options()) || get_options()->Address) {
     838             :     /* We don't need to seed our own hostname, because we won't be calling
     839             :      * resolve_my_address on it.
     840             :      */
     841           0 :     return;
     842             :   }
     843           0 :   char hname[256];
     844             : 
     845             :   // host name to sandbox
     846           0 :   gethostname(hname, sizeof(hname));
     847           0 :   tor_add_addrinfo(hname);
     848             : }
     849             : 
     850             : static sandbox_cfg_t*
     851           0 : sandbox_init_filter(void)
     852             : {
     853           0 :   const or_options_t *options = get_options();
     854           0 :   sandbox_cfg_t *cfg = sandbox_cfg_new();
     855             : 
     856           0 :   sandbox_cfg_allow_openat_filename(&cfg,
     857             :       get_cachedir_fname("cached-status"));
     858             : 
     859             : #define OPEN(name)                              \
     860             :   sandbox_cfg_allow_open_filename(&cfg, tor_strdup(name))
     861             : 
     862             : #define OPENDIR(dir)                            \
     863             :   sandbox_cfg_allow_opendir_dirname(&cfg, tor_strdup(dir))
     864             : 
     865             : #define OPEN_DATADIR(name)                      \
     866             :   sandbox_cfg_allow_open_filename(&cfg, get_datadir_fname(name))
     867             : 
     868             : #define OPEN_DATADIR2(name, name2)                       \
     869             :   sandbox_cfg_allow_open_filename(&cfg, get_datadir_fname2((name), (name2)))
     870             : 
     871             : #define OPEN_DATADIR_SUFFIX(name, suffix) do {  \
     872             :     OPEN_DATADIR(name);                         \
     873             :     OPEN_DATADIR(name suffix);                  \
     874             :   } while (0)
     875             : 
     876             : #define OPEN_DATADIR2_SUFFIX(name, name2, suffix) do {  \
     877             :     OPEN_DATADIR2(name, name2);                         \
     878             :     OPEN_DATADIR2(name, name2 suffix);                  \
     879             :   } while (0)
     880             : 
     881             : // KeyDirectory is a directory, but it is only opened in check_private_dir
     882             : // which calls open instead of opendir
     883             : #define OPEN_KEY_DIRECTORY() \
     884             :   OPEN(options->KeyDirectory)
     885             : #define OPEN_CACHEDIR(name)                      \
     886             :   sandbox_cfg_allow_open_filename(&cfg, get_cachedir_fname(name))
     887             : #define OPEN_CACHEDIR_SUFFIX(name, suffix) do {  \
     888             :     OPEN_CACHEDIR(name);                         \
     889             :     OPEN_CACHEDIR(name suffix);                  \
     890             :   } while (0)
     891             : #define OPEN_KEYDIR(name)                      \
     892             :   sandbox_cfg_allow_open_filename(&cfg, get_keydir_fname(name))
     893             : #define OPEN_KEYDIR_SUFFIX(name, suffix) do {    \
     894             :     OPEN_KEYDIR(name);                           \
     895             :     OPEN_KEYDIR(name suffix);                    \
     896             :   } while (0)
     897             : 
     898             :   // DataDirectory is a directory, but it is only opened in check_private_dir
     899             :   // which calls open instead of opendir
     900           0 :   OPEN(options->DataDirectory);
     901           0 :   OPEN_KEY_DIRECTORY();
     902             : 
     903           0 :   OPEN_CACHEDIR_SUFFIX("cached-certs", ".tmp");
     904           0 :   OPEN_CACHEDIR_SUFFIX("cached-consensus", ".tmp");
     905           0 :   OPEN_CACHEDIR_SUFFIX("unverified-consensus", ".tmp");
     906           0 :   OPEN_CACHEDIR_SUFFIX("unverified-microdesc-consensus", ".tmp");
     907           0 :   OPEN_CACHEDIR_SUFFIX("cached-microdesc-consensus", ".tmp");
     908           0 :   OPEN_CACHEDIR_SUFFIX("cached-microdescs", ".tmp");
     909           0 :   OPEN_CACHEDIR_SUFFIX("cached-microdescs.new", ".tmp");
     910           0 :   OPEN_CACHEDIR_SUFFIX("cached-descriptors", ".tmp");
     911           0 :   OPEN_CACHEDIR_SUFFIX("cached-descriptors.new", ".tmp");
     912           0 :   OPEN_CACHEDIR("cached-descriptors.tmp.tmp");
     913           0 :   OPEN_CACHEDIR_SUFFIX("cached-extrainfo", ".tmp");
     914           0 :   OPEN_CACHEDIR_SUFFIX("cached-extrainfo.new", ".tmp");
     915           0 :   OPEN_CACHEDIR("cached-extrainfo.tmp.tmp");
     916             : 
     917           0 :   OPEN_DATADIR_SUFFIX("state", ".tmp");
     918           0 :   OPEN_DATADIR_SUFFIX("sr-state", ".tmp");
     919           0 :   OPEN_DATADIR_SUFFIX("unparseable-desc", ".tmp");
     920           0 :   OPEN_DATADIR_SUFFIX("v3-status-votes", ".tmp");
     921           0 :   OPEN_DATADIR("key-pinning-journal");
     922           0 :   OPEN("/dev/srandom");
     923           0 :   OPEN("/dev/urandom");
     924           0 :   OPEN("/dev/random");
     925           0 :   OPEN("/etc/hosts");
     926           0 :   OPEN("/proc/meminfo");
     927             : 
     928           0 :   if (options->BridgeAuthoritativeDir)
     929           0 :     OPEN_DATADIR_SUFFIX("networkstatus-bridges", ".tmp");
     930             : 
     931           0 :   if (authdir_mode(options))
     932           0 :     OPEN_DATADIR("approved-routers");
     933             : 
     934           0 :   if (options->ServerDNSResolvConfFile)
     935           0 :     sandbox_cfg_allow_open_filename(&cfg,
     936             :                                 tor_strdup(options->ServerDNSResolvConfFile));
     937             :   else
     938           0 :     sandbox_cfg_allow_open_filename(&cfg, tor_strdup("/etc/resolv.conf"));
     939             : 
     940           0 :   const char *torrc_defaults_fname = get_torrc_fname(1);
     941           0 :   if (torrc_defaults_fname) {
     942           0 :     sandbox_cfg_allow_open_filename(&cfg, tor_strdup(torrc_defaults_fname));
     943             :   }
     944           0 :   const char *torrc_fname = get_torrc_fname(0);
     945           0 :   if (torrc_fname) {
     946           0 :     sandbox_cfg_allow_open_filename(&cfg, tor_strdup(torrc_fname));
     947             :     // allow torrc backup and torrc.tmp to make SAVECONF work
     948           0 :     char *torrc_bck = NULL;
     949           0 :     tor_asprintf(&torrc_bck, CONFIG_BACKUP_PATTERN, torrc_fname);
     950           0 :     sandbox_cfg_allow_rename(&cfg, tor_strdup(torrc_fname), torrc_bck);
     951           0 :     char *torrc_tmp = NULL;
     952           0 :     tor_asprintf(&torrc_tmp, "%s.tmp", torrc_fname);
     953           0 :     sandbox_cfg_allow_rename(&cfg, torrc_tmp, tor_strdup(torrc_fname));
     954           0 :     sandbox_cfg_allow_open_filename(&cfg, tor_strdup(torrc_tmp));
     955             :     // we need to stat the existing backup file
     956           0 :     sandbox_cfg_allow_stat_filename(&cfg, tor_strdup(torrc_bck));
     957             :   }
     958             : 
     959           0 :   SMARTLIST_FOREACH(options->FilesOpenedByIncludes, char *, f, {
     960             :     if (file_status(f) == FN_DIR) {
     961             :       OPENDIR(f);
     962             :     } else {
     963             :       OPEN(f);
     964             :     }
     965             :   });
     966             : 
     967             : #define RENAME_SUFFIX(name, suffix)        \
     968             :   sandbox_cfg_allow_rename(&cfg,           \
     969             :       get_datadir_fname(name suffix),      \
     970             :       get_datadir_fname(name))
     971             : 
     972             : #define RENAME_SUFFIX2(prefix, name, suffix) \
     973             :   sandbox_cfg_allow_rename(&cfg,                                        \
     974             :                            get_datadir_fname2(prefix, name suffix),     \
     975             :                            get_datadir_fname2(prefix, name))
     976             : 
     977             : #define RENAME_CACHEDIR_SUFFIX(name, suffix)        \
     978             :   sandbox_cfg_allow_rename(&cfg,           \
     979             :       get_cachedir_fname(name suffix),      \
     980             :       get_cachedir_fname(name))
     981             : 
     982             : #define RENAME_KEYDIR_SUFFIX(name, suffix)    \
     983             :   sandbox_cfg_allow_rename(&cfg,           \
     984             :       get_keydir_fname(name suffix),      \
     985             :       get_keydir_fname(name))
     986             : 
     987           0 :   RENAME_CACHEDIR_SUFFIX("cached-certs", ".tmp");
     988           0 :   RENAME_CACHEDIR_SUFFIX("cached-consensus", ".tmp");
     989           0 :   RENAME_CACHEDIR_SUFFIX("unverified-consensus", ".tmp");
     990           0 :   RENAME_CACHEDIR_SUFFIX("unverified-microdesc-consensus", ".tmp");
     991           0 :   RENAME_CACHEDIR_SUFFIX("cached-microdesc-consensus", ".tmp");
     992           0 :   RENAME_CACHEDIR_SUFFIX("cached-microdescs", ".tmp");
     993           0 :   RENAME_CACHEDIR_SUFFIX("cached-microdescs", ".new");
     994           0 :   RENAME_CACHEDIR_SUFFIX("cached-microdescs.new", ".tmp");
     995           0 :   RENAME_CACHEDIR_SUFFIX("cached-descriptors", ".tmp");
     996           0 :   RENAME_CACHEDIR_SUFFIX("cached-descriptors", ".new");
     997           0 :   RENAME_CACHEDIR_SUFFIX("cached-descriptors.new", ".tmp");
     998           0 :   RENAME_CACHEDIR_SUFFIX("cached-extrainfo", ".tmp");
     999           0 :   RENAME_CACHEDIR_SUFFIX("cached-extrainfo", ".new");
    1000           0 :   RENAME_CACHEDIR_SUFFIX("cached-extrainfo.new", ".tmp");
    1001             : 
    1002           0 :   RENAME_SUFFIX("state", ".tmp");
    1003           0 :   RENAME_SUFFIX("sr-state", ".tmp");
    1004           0 :   RENAME_SUFFIX("unparseable-desc", ".tmp");
    1005           0 :   RENAME_SUFFIX("v3-status-votes", ".tmp");
    1006             : 
    1007           0 :   if (options->BridgeAuthoritativeDir)
    1008           0 :     RENAME_SUFFIX("networkstatus-bridges", ".tmp");
    1009             : 
    1010             : #define STAT_DATADIR(name)                      \
    1011             :   sandbox_cfg_allow_stat_filename(&cfg, get_datadir_fname(name))
    1012             : 
    1013             : #define STAT_CACHEDIR(name)                                             \
    1014             :   sandbox_cfg_allow_stat_filename(&cfg, get_cachedir_fname(name))
    1015             : 
    1016             : #define STAT_DATADIR2(name, name2)                                      \
    1017             :   sandbox_cfg_allow_stat_filename(&cfg, get_datadir_fname2((name), (name2)))
    1018             : 
    1019             : #define STAT_KEY_DIRECTORY() \
    1020             :   sandbox_cfg_allow_stat_filename(&cfg, tor_strdup(options->KeyDirectory))
    1021             : 
    1022           0 :   STAT_DATADIR(NULL);
    1023           0 :   STAT_DATADIR("lock");
    1024           0 :   STAT_DATADIR("state");
    1025           0 :   STAT_DATADIR("router-stability");
    1026             : 
    1027           0 :   STAT_CACHEDIR("cached-extrainfo.new");
    1028             : 
    1029             :   {
    1030           0 :     smartlist_t *files = smartlist_new();
    1031           0 :     tor_log_get_logfile_names(files);
    1032           0 :     SMARTLIST_FOREACH(files, char *, file_name, {
    1033             :       /* steals reference */
    1034             :       sandbox_cfg_allow_open_filename(&cfg, file_name);
    1035             :     });
    1036           0 :     smartlist_free(files);
    1037             :   }
    1038             : 
    1039             :   {
    1040           0 :     smartlist_t *files = smartlist_new();
    1041           0 :     smartlist_t *dirs = smartlist_new();
    1042           0 :     hs_service_lists_fnames_for_sandbox(files, dirs);
    1043           0 :     SMARTLIST_FOREACH(files, char *, file_name, {
    1044             :       char *tmp_name = NULL;
    1045             :       tor_asprintf(&tmp_name, "%s.tmp", file_name);
    1046             :       sandbox_cfg_allow_rename(&cfg,
    1047             :                                tor_strdup(tmp_name), tor_strdup(file_name));
    1048             :       /* steals references */
    1049             :       sandbox_cfg_allow_open_filename(&cfg, file_name);
    1050             :       sandbox_cfg_allow_open_filename(&cfg, tmp_name);
    1051             :     });
    1052           0 :     SMARTLIST_FOREACH(dirs, char *, dir, {
    1053             :       /* steals reference */
    1054             :       sandbox_cfg_allow_stat_filename(&cfg, dir);
    1055             :     });
    1056           0 :     smartlist_free(files);
    1057           0 :     smartlist_free(dirs);
    1058             :   }
    1059             : 
    1060             :   {
    1061           0 :     char *fname;
    1062           0 :     if ((fname = get_controller_cookie_file_name())) {
    1063           0 :       sandbox_cfg_allow_open_filename(&cfg, fname);
    1064             :     }
    1065           0 :     if ((fname = get_ext_or_auth_cookie_file_name())) {
    1066           0 :       sandbox_cfg_allow_open_filename(&cfg, fname);
    1067             :     }
    1068             :   }
    1069             : 
    1070           0 :   SMARTLIST_FOREACH_BEGIN(get_configured_ports(), port_cfg_t *, port) {
    1071           0 :     if (!port->is_unix_addr)
    1072           0 :       continue;
    1073             :     /* When we open an AF_UNIX address, we want permission to open the
    1074             :      * directory that holds it. */
    1075           0 :     char *dirname = tor_strdup(port->unix_addr);
    1076           0 :     if (get_parent_directory(dirname) == 0) {
    1077           0 :       OPENDIR(dirname);
    1078             :     }
    1079           0 :     tor_free(dirname);
    1080           0 :     sandbox_cfg_allow_chmod_filename(&cfg, tor_strdup(port->unix_addr));
    1081           0 :     sandbox_cfg_allow_chown_filename(&cfg, tor_strdup(port->unix_addr));
    1082           0 :   } SMARTLIST_FOREACH_END(port);
    1083             : 
    1084           0 :   if (options->DirPortFrontPage) {
    1085           0 :     sandbox_cfg_allow_open_filename(&cfg,
    1086             :                                     tor_strdup(options->DirPortFrontPage));
    1087             :   }
    1088             : 
    1089             :   // orport
    1090           0 :   if (server_mode(get_options())) {
    1091             : 
    1092           0 :     OPEN_KEYDIR_SUFFIX("secret_id_key", ".tmp");
    1093           0 :     OPEN_KEYDIR_SUFFIX("secret_onion_key", ".tmp");
    1094           0 :     OPEN_KEYDIR_SUFFIX("secret_onion_key_ntor", ".tmp");
    1095           0 :     OPEN_KEYDIR("secret_id_key.old");
    1096           0 :     OPEN_KEYDIR("secret_onion_key.old");
    1097           0 :     OPEN_KEYDIR("secret_onion_key_ntor.old");
    1098             : 
    1099           0 :     OPEN_KEYDIR_SUFFIX("ed25519_master_id_secret_key", ".tmp");
    1100           0 :     OPEN_KEYDIR_SUFFIX("ed25519_master_id_secret_key_encrypted", ".tmp");
    1101           0 :     OPEN_KEYDIR_SUFFIX("ed25519_master_id_public_key", ".tmp");
    1102           0 :     OPEN_KEYDIR_SUFFIX("ed25519_signing_secret_key", ".tmp");
    1103           0 :     OPEN_KEYDIR_SUFFIX("ed25519_signing_secret_key_encrypted", ".tmp");
    1104           0 :     OPEN_KEYDIR_SUFFIX("ed25519_signing_public_key", ".tmp");
    1105           0 :     OPEN_KEYDIR_SUFFIX("ed25519_signing_cert", ".tmp");
    1106             : 
    1107           0 :     OPEN_DATADIR2_SUFFIX("stats", "bridge-stats", ".tmp");
    1108           0 :     OPEN_DATADIR2_SUFFIX("stats", "dirreq-stats", ".tmp");
    1109             : 
    1110           0 :     OPEN_DATADIR2_SUFFIX("stats", "entry-stats", ".tmp");
    1111           0 :     OPEN_DATADIR2_SUFFIX("stats", "exit-stats", ".tmp");
    1112           0 :     OPEN_DATADIR2_SUFFIX("stats", "buffer-stats", ".tmp");
    1113           0 :     OPEN_DATADIR2_SUFFIX("stats", "conn-stats", ".tmp");
    1114           0 :     OPEN_DATADIR2_SUFFIX("stats", "hidserv-stats", ".tmp");
    1115           0 :     OPEN_DATADIR2_SUFFIX("stats", "hidserv-v3-stats", ".tmp");
    1116             : 
    1117           0 :     OPEN_DATADIR("approved-routers");
    1118           0 :     OPEN_DATADIR_SUFFIX("fingerprint", ".tmp");
    1119           0 :     OPEN_DATADIR_SUFFIX("fingerprint-ed25519", ".tmp");
    1120           0 :     OPEN_DATADIR_SUFFIX("hashed-fingerprint", ".tmp");
    1121           0 :     OPEN_DATADIR_SUFFIX("router-stability", ".tmp");
    1122             : 
    1123           0 :     OPEN("/etc/resolv.conf");
    1124             : 
    1125           0 :     RENAME_SUFFIX("fingerprint", ".tmp");
    1126           0 :     RENAME_SUFFIX("fingerprint-ed25519", ".tmp");
    1127           0 :     RENAME_KEYDIR_SUFFIX("secret_onion_key_ntor", ".tmp");
    1128             : 
    1129           0 :     RENAME_KEYDIR_SUFFIX("secret_id_key", ".tmp");
    1130           0 :     RENAME_KEYDIR_SUFFIX("secret_id_key.old", ".tmp");
    1131           0 :     RENAME_KEYDIR_SUFFIX("secret_onion_key", ".tmp");
    1132           0 :     RENAME_KEYDIR_SUFFIX("secret_onion_key.old", ".tmp");
    1133             : 
    1134           0 :     RENAME_SUFFIX2("stats", "bridge-stats", ".tmp");
    1135           0 :     RENAME_SUFFIX2("stats", "dirreq-stats", ".tmp");
    1136           0 :     RENAME_SUFFIX2("stats", "entry-stats", ".tmp");
    1137           0 :     RENAME_SUFFIX2("stats", "exit-stats", ".tmp");
    1138           0 :     RENAME_SUFFIX2("stats", "buffer-stats", ".tmp");
    1139           0 :     RENAME_SUFFIX2("stats", "conn-stats", ".tmp");
    1140           0 :     RENAME_SUFFIX2("stats", "hidserv-stats", ".tmp");
    1141           0 :     RENAME_SUFFIX2("stats", "hidserv-v3-stats", ".tmp");
    1142           0 :     RENAME_SUFFIX("hashed-fingerprint", ".tmp");
    1143           0 :     RENAME_SUFFIX("router-stability", ".tmp");
    1144             : 
    1145           0 :     RENAME_KEYDIR_SUFFIX("ed25519_master_id_secret_key", ".tmp");
    1146           0 :     RENAME_KEYDIR_SUFFIX("ed25519_master_id_secret_key_encrypted", ".tmp");
    1147           0 :     RENAME_KEYDIR_SUFFIX("ed25519_master_id_public_key", ".tmp");
    1148           0 :     RENAME_KEYDIR_SUFFIX("ed25519_signing_secret_key", ".tmp");
    1149           0 :     RENAME_KEYDIR_SUFFIX("ed25519_signing_cert", ".tmp");
    1150             : 
    1151           0 :     sandbox_cfg_allow_rename(&cfg,
    1152             :              get_keydir_fname("secret_onion_key"),
    1153             :              get_keydir_fname("secret_onion_key.old"));
    1154           0 :     sandbox_cfg_allow_rename(&cfg,
    1155             :              get_keydir_fname("secret_onion_key_ntor"),
    1156             :              get_keydir_fname("secret_onion_key_ntor.old"));
    1157             : 
    1158           0 :     STAT_KEY_DIRECTORY();
    1159           0 :     OPEN_DATADIR("stats");
    1160           0 :     STAT_DATADIR("stats");
    1161           0 :     STAT_DATADIR2("stats", "dirreq-stats");
    1162             : 
    1163           0 :     consdiffmgr_register_with_sandbox(&cfg);
    1164             :   }
    1165             : 
    1166           0 :   init_addrinfo();
    1167             : 
    1168           0 :   return cfg;
    1169             : }
    1170             : 
    1171             : int
    1172           0 : run_tor_main_loop(void)
    1173             : {
    1174           0 :   handle_signals();
    1175           0 :   timers_initialize();
    1176           0 :   initialize_mainloop_events();
    1177             : 
    1178             :   /* load the private keys, if we're supposed to have them, and set up the
    1179             :    * TLS context. */
    1180           0 :   if (! client_identity_key_is_set()) {
    1181           0 :     if (init_keys() < 0) {
    1182           0 :       log_err(LD_OR, "Error initializing keys; exiting");
    1183           0 :       return -1;
    1184             :     }
    1185             :   }
    1186             : 
    1187             :   /* Set up our buckets */
    1188           0 :   connection_bucket_init();
    1189             : 
    1190             :   /* initialize the bootstrap status events to know we're starting up */
    1191           0 :   control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
    1192             : 
    1193             :   /* Initialize the keypinning log. */
    1194           0 :   if (authdir_mode_v3(get_options())) {
    1195           0 :     char *fname = get_datadir_fname("key-pinning-journal");
    1196           0 :     int r = 0;
    1197           0 :     if (keypin_load_journal(fname)<0) {
    1198           0 :       log_err(LD_DIR, "Error loading key-pinning journal: %s",strerror(errno));
    1199           0 :       r = -1;
    1200             :     }
    1201           0 :     if (keypin_open_journal(fname)<0) {
    1202           0 :       log_err(LD_DIR, "Error opening key-pinning journal: %s",strerror(errno));
    1203           0 :       r = -1;
    1204             :     }
    1205           0 :     tor_free(fname);
    1206           0 :     if (r)
    1207           0 :       return r;
    1208             :   }
    1209             :   {
    1210             :     /* This is the old name for key-pinning-journal.  These got corrupted
    1211             :      * in a couple of cases by #16530, so we started over. See #16580 for
    1212             :      * the rationale and for other options we didn't take.  We can remove
    1213             :      * this code once all the authorities that ran 0.2.7.1-alpha-dev are
    1214             :      * upgraded.
    1215             :      */
    1216           0 :     char *fname = get_datadir_fname("key-pinning-entries");
    1217           0 :     unlink(fname);
    1218           0 :     tor_free(fname);
    1219             :   }
    1220             : 
    1221           0 :   if (trusted_dirs_reload_certs()) {
    1222           0 :     log_warn(LD_DIR,
    1223             :              "Couldn't load all cached v3 certificates. Starting anyway.");
    1224             :   }
    1225           0 :   if (router_reload_consensus_networkstatus()) {
    1226             :     return -1;
    1227             :   }
    1228             :   /* load the routers file, or assign the defaults. */
    1229           0 :   if (router_reload_router_list()) {
    1230             :     return -1;
    1231             :   }
    1232             :   /* load the networkstatuses. (This launches a download for new routers as
    1233             :    * appropriate.)
    1234             :    */
    1235           0 :   const time_t now = time(NULL);
    1236           0 :   directory_info_has_arrived(now, 1, 0);
    1237             : 
    1238           0 :   if (server_mode(get_options()) || dir_server_mode(get_options())) {
    1239             :     /* launch cpuworkers. Need to do this *after* we've read the onion key. */
    1240           0 :     cpu_init();
    1241             :   }
    1242           0 :   consdiffmgr_enable_background_compression();
    1243             : 
    1244             :   /* Setup shared random protocol subsystem. */
    1245           0 :   if (authdir_mode_v3(get_options())) {
    1246           0 :     if (sr_init(1) < 0) {
    1247             :       return -1;
    1248             :     }
    1249             :   }
    1250             : 
    1251             :   /* initialize dns resolve map, spawn workers if needed */
    1252           0 :   if (dns_init() < 0) {
    1253           0 :     if (get_options()->ServerDNSAllowBrokenConfig)
    1254           0 :       log_warn(LD_GENERAL, "Couldn't set up any working nameservers. "
    1255             :                "Network not up yet?  Will try again soon.");
    1256             :     else {
    1257           0 :       log_err(LD_GENERAL,"Error initializing dns subsystem; exiting.  To "
    1258             :               "retry instead, set the ServerDNSAllowBrokenResolvConf option.");
    1259             :     }
    1260             :   }
    1261             : 
    1262             : #ifdef HAVE_SYSTEMD
    1263             :   {
    1264           0 :     const int r = sd_notify(0, "READY=1");
    1265           0 :     if (r < 0) {
    1266           0 :       log_warn(LD_GENERAL, "Unable to send readiness to systemd: %s",
    1267             :                strerror(r));
    1268           0 :     } else if (r > 0) {
    1269           0 :       log_notice(LD_GENERAL, "Signaled readiness to systemd");
    1270             :     } else {
    1271           0 :       log_info(LD_GENERAL, "Systemd NOTIFY_SOCKET not present.");
    1272             :     }
    1273             :   }
    1274             : #endif /* defined(HAVE_SYSTEMD) */
    1275             : 
    1276           0 :   return do_main_loop();
    1277             : }
    1278             : 
    1279             : /** Install the publish/subscribe relationships for all the subsystems. */
    1280             : void
    1281         235 : pubsub_install(void)
    1282             : {
    1283         235 :     pubsub_builder_t *builder = pubsub_builder_new();
    1284         235 :     int r = subsystems_add_pubsub(builder);
    1285         235 :     tor_assert(r == 0);
    1286         235 :     r = tor_mainloop_connect_pubsub(builder); // consumes builder
    1287         235 :     tor_assert(r == 0);
    1288         235 : }
    1289             : 
    1290             : /** Connect the mainloop to its publish/subscribe message delivery events if
    1291             :  * appropriate, and configure the global channels appropriately. */
    1292             : void
    1293         194 : pubsub_connect(void)
    1294             : {
    1295         194 :   if (get_options()->command == CMD_RUN_TOR) {
    1296           0 :     tor_mainloop_connect_pubsub_events();
    1297             :     /* XXXX For each pubsub channel, its delivery strategy should be set at
    1298             :      * this XXXX point, using tor_mainloop_set_delivery_strategy().
    1299             :      */
    1300           0 :     tor_mainloop_set_delivery_strategy("orconn", DELIV_IMMEDIATE);
    1301           0 :     tor_mainloop_set_delivery_strategy("ocirc", DELIV_IMMEDIATE);
    1302             :   }
    1303         194 : }
    1304             : 
    1305             : /* Main entry point for the Tor process.  Called from tor_main(), and by
    1306             :  * anybody embedding Tor. */
    1307             : int
    1308         235 : tor_run_main(const tor_main_configuration_t *tor_cfg)
    1309             : {
    1310         235 :   int result = 0;
    1311             : 
    1312             : #ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
    1313         235 :   event_set_mem_functions(tor_malloc_, tor_realloc_, tor_free_);
    1314             : #endif
    1315             : 
    1316         235 :   subsystems_init();
    1317             : 
    1318         235 :   init_protocol_warning_severity_level();
    1319             : 
    1320         235 :   int argc = tor_cfg->argc + tor_cfg->argc_owned;
    1321         235 :   char **argv = tor_calloc(argc, sizeof(char*));
    1322         235 :   memcpy(argv, tor_cfg->argv, tor_cfg->argc*sizeof(char*));
    1323         235 :   if (tor_cfg->argc_owned)
    1324         235 :     memcpy(argv + tor_cfg->argc, tor_cfg->argv_owned,
    1325           0 :            tor_cfg->argc_owned*sizeof(char*));
    1326             : 
    1327         235 :   int done = 0;
    1328         235 :   result = nt_service_parse_options(argc, argv, &done);
    1329         235 :   if (POSSIBLE(done))
    1330             :     goto done;
    1331             : 
    1332         235 :   pubsub_install();
    1333             : 
    1334             :   {
    1335         235 :     int init_rv = tor_init(argc, argv);
    1336         235 :     if (init_rv) {
    1337          41 :       tor_free_all(0);
    1338          41 :       result = (init_rv < 0) ? -1 : 0;
    1339          41 :       goto done;
    1340             :     }
    1341             :   }
    1342             : 
    1343         194 :   pubsub_connect();
    1344             : 
    1345         194 :   if (get_options()->Sandbox && get_options()->command == CMD_RUN_TOR) {
    1346           0 :     sandbox_cfg_t* cfg = sandbox_init_filter();
    1347             : 
    1348           0 :     if (sandbox_init(cfg)) {
    1349           0 :       tor_free(argv);
    1350           0 :       log_err(LD_BUG,"Failed to create syscall sandbox filter");
    1351           0 :       tor_free_all(0);
    1352           0 :       return -1;
    1353             :     }
    1354           0 :     tor_make_getaddrinfo_cache_active();
    1355             : 
    1356             :     // registering libevent rng
    1357             : #ifdef HAVE_EVUTIL_SECURE_RNG_SET_URANDOM_DEVICE_FILE
    1358           0 :     evutil_secure_rng_set_urandom_device_file(
    1359           0 :         (char*) sandbox_intern_string("/dev/urandom"));
    1360             : #endif
    1361             :   }
    1362             : 
    1363         194 :   switch (get_options()->command) {
    1364           0 :   case CMD_RUN_TOR:
    1365           0 :     nt_service_set_state(SERVICE_RUNNING);
    1366           0 :     result = run_tor_main_loop();
    1367           0 :     break;
    1368           4 :   case CMD_KEYGEN:
    1369           4 :     result = load_ed_keys(get_options(), time(NULL)) < 0;
    1370           4 :     break;
    1371           5 :   case CMD_KEY_EXPIRATION:
    1372           5 :     init_keys();
    1373           5 :     result = log_cert_expiration();
    1374           5 :     break;
    1375          19 :   case CMD_LIST_FINGERPRINT:
    1376          19 :     result = do_list_fingerprint();
    1377          19 :     break;
    1378           0 :   case CMD_HASH_PASSWORD:
    1379           0 :     do_hash_password();
    1380           0 :     result = 0;
    1381           0 :     break;
    1382          56 :   case CMD_VERIFY_CONFIG:
    1383          56 :     if (quiet_level == QUIET_NONE)
    1384          56 :       printf("Configuration was valid\n");
    1385             :     result = 0;
    1386             :     break;
    1387         110 :   case CMD_DUMP_CONFIG:
    1388         110 :     result = do_dump_config();
    1389         110 :     break;
    1390           0 :   case CMD_RUN_UNITTESTS: /* only set by test.c */
    1391             :   case CMD_IMMEDIATE: /* Handled in config.c */
    1392             :   default:
    1393           0 :     log_warn(LD_BUG,"Illegal command number %d: internal error.",
    1394             :              get_options()->command);
    1395           0 :     result = -1;
    1396             :   }
    1397         194 :   tor_cleanup();
    1398         235 :  done:
    1399         235 :   tor_free(argv);
    1400         235 :   return result;
    1401             : }

Generated by: LCOV version 1.14