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