tor

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

tor_api.c (4299B)


      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 tor_api.c
      9 **/
     10 
     11 #ifdef _WIN32
     12 #include <winsock2.h>
     13 #include <windows.h>
     14 #endif
     15 
     16 #include "feature/api/tor_api.h"
     17 
     18 // Include this after the above headers, to insure that they don't
     19 // depend on anything else.
     20 #include "orconfig.h"
     21 #include "lib/cc/compat_compiler.h"
     22 #include "lib/cc/torint.h"
     23 #include "feature/api/tor_api_internal.h"
     24 
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 
     29 // We don't want to use tor_malloc and tor_free here, since this needs
     30 // to run before anything is initialized at all, and ought to run when
     31 // we're not linked to anything at all.
     32 
     33 #define raw_malloc malloc
     34 #define raw_free free
     35 #define raw_realloc realloc
     36 #define raw_strdup strdup
     37 
     38 #ifdef _WIN32
     39 #include "lib/net/socketpair.h"
     40 #define raw_socketpair tor_ersatz_socketpair
     41 #define raw_closesocket closesocket
     42 #if !defined(HAVE_SNPRINTF)
     43 #define snprintf _snprintf
     44 #endif
     45 #else /* !defined(_WIN32) */
     46 #define raw_socketpair socketpair
     47 #define raw_closesocket close
     48 #endif /* defined(_WIN32) */
     49 
     50 #ifdef HAVE_UNISTD_H
     51 #include <unistd.h>
     52 #endif
     53 
     54 /**
     55 * Helper: Add a copy of <b>arg</b> to the owned arguments of <b>cfg</b>.
     56 * Return 0 on success, -1 on failure.
     57 */
     58 static int
     59 cfg_add_owned_arg(tor_main_configuration_t *cfg, const char *arg)
     60 {
     61  /* We aren't using amortized realloc here, because libc should do it for us,
     62   * and because this function is not critical-path. */
     63  char **new_argv = raw_realloc(cfg->argv_owned,
     64                                sizeof(char*) * (cfg->argc_owned+1));
     65  if (new_argv == NULL)
     66    return -1;
     67  cfg->argv_owned = new_argv;
     68  if (NULL == (cfg->argv_owned[cfg->argc_owned] = raw_strdup(arg)))
     69    return -1;
     70  ++cfg->argc_owned;
     71  return 0;
     72 }
     73 
     74 tor_main_configuration_t *
     75 tor_main_configuration_new(void)
     76 {
     77  static const char *fake_argv[] = { "tor" };
     78  tor_main_configuration_t *cfg = raw_malloc(sizeof(*cfg));
     79  if (cfg == NULL)
     80    return NULL;
     81 
     82  memset(cfg, 0, sizeof(*cfg));
     83 
     84  cfg->argc = 1;
     85  cfg->argv = (char **) fake_argv;
     86 
     87  cfg->owning_controller_socket = TOR_INVALID_SOCKET;
     88 
     89  return cfg;
     90 }
     91 
     92 int
     93 tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
     94                                        int argc, char *argv[])
     95 {
     96  if (cfg == NULL)
     97    return -1;
     98  cfg->argc = argc;
     99  cfg->argv = argv;
    100  return 0;
    101 }
    102 
    103 tor_control_socket_t
    104 tor_main_configuration_setup_control_socket(tor_main_configuration_t *cfg)
    105 {
    106  if (SOCKET_OK(cfg->owning_controller_socket))
    107    return INVALID_TOR_CONTROL_SOCKET;
    108 
    109  tor_socket_t fds[2];
    110  if (raw_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
    111    return INVALID_TOR_CONTROL_SOCKET;
    112  }
    113  char buf[32];
    114  snprintf(buf, sizeof(buf), "%"PRIu64, (uint64_t)fds[1]);
    115 
    116  cfg_add_owned_arg(cfg, "__OwningControllerFD");
    117  cfg_add_owned_arg(cfg, buf);
    118 
    119  cfg->owning_controller_socket = fds[1];
    120  return fds[0];
    121 }
    122 
    123 void
    124 tor_main_configuration_free(tor_main_configuration_t *cfg)
    125 {
    126  if (cfg == NULL)
    127    return;
    128  if (cfg->argv_owned) {
    129    for (int i = 0; i < cfg->argc_owned; ++i) {
    130      raw_free(cfg->argv_owned[i]);
    131    }
    132    raw_free(cfg->argv_owned);
    133  }
    134  if (SOCKET_OK(cfg->owning_controller_socket)) {
    135    raw_closesocket(cfg->owning_controller_socket);
    136  }
    137  raw_free(cfg);
    138 }
    139 
    140 const char *
    141 tor_api_get_provider_version(void)
    142 {
    143  return "tor " VERSION;
    144 }
    145 
    146 /* Main entry point for the Tor process.  Called from main().
    147 *
    148 * This function is distinct from main() only so we can link main.c into
    149 * the unittest binary without conflicting with the unittests' main.
    150 *
    151 * Some embedders have historically called this function; but that usage is
    152 * deprecated: they should use tor_run_main() instead.
    153 */
    154 int
    155 tor_main(int argc, char *argv[])
    156 {
    157  tor_main_configuration_t *cfg = tor_main_configuration_new();
    158  if (!cfg) {
    159    puts("INTERNAL ERROR: Allocation failure. Cannot proceed");
    160    return 1;
    161  }
    162  if (tor_main_configuration_set_command_line(cfg, argc, argv) < 0) {
    163    puts("INTERNAL ERROR: Can't set command line. Cannot proceed.");
    164    return 1;
    165  }
    166  int rv = tor_run_main(cfg);
    167  tor_main_configuration_free(cfg);
    168  return rv;
    169 }