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
cfg_add_owned_arg(tor_main_configuration_t * cfg,const char * arg)57 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   char **new_argv = raw_realloc(cfg->argv_owned,
62                                 sizeof(char*) * (cfg->argc_owned+1));
63   if (new_argv == NULL)
64     return -1;
65   cfg->argv_owned = new_argv;
66   if (NULL == (cfg->argv_owned[cfg->argc_owned] = raw_strdup(arg)))
67     return -1;
68   ++cfg->argc_owned;
69   return 0;
70 }
71 
72 tor_main_configuration_t *
tor_main_configuration_new(void)73 tor_main_configuration_new(void)
74 {
75   static const char *fake_argv[] = { "tor" };
76   tor_main_configuration_t *cfg = raw_malloc(sizeof(*cfg));
77   if (cfg == NULL)
78     return NULL;
79 
80   memset(cfg, 0, sizeof(*cfg));
81 
82   cfg->argc = 1;
83   cfg->argv = (char **) fake_argv;
84 
85   cfg->owning_controller_socket = TOR_INVALID_SOCKET;
86 
87   return cfg;
88 }
89 
90 int
tor_main_configuration_set_command_line(tor_main_configuration_t * cfg,int argc,char * argv[])91 tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
92                                         int argc, char *argv[])
93 {
94   if (cfg == NULL)
95     return -1;
96   cfg->argc = argc;
97   cfg->argv = argv;
98   return 0;
99 }
100 
101 tor_control_socket_t
tor_main_configuration_setup_control_socket(tor_main_configuration_t * cfg)102 tor_main_configuration_setup_control_socket(tor_main_configuration_t *cfg)
103 {
104   if (SOCKET_OK(cfg->owning_controller_socket))
105     return INVALID_TOR_CONTROL_SOCKET;
106 
107   tor_socket_t fds[2];
108   if (raw_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
109     return INVALID_TOR_CONTROL_SOCKET;
110   }
111   char buf[32];
112   snprintf(buf, sizeof(buf), "%"PRIu64, (uint64_t)fds[1]);
113 
114   cfg_add_owned_arg(cfg, "__OwningControllerFD");
115   cfg_add_owned_arg(cfg, buf);
116 
117   cfg->owning_controller_socket = fds[1];
118   return fds[0];
119 }
120 
121 void
tor_main_configuration_free(tor_main_configuration_t * cfg)122 tor_main_configuration_free(tor_main_configuration_t *cfg)
123 {
124   if (cfg == NULL)
125     return;
126   if (cfg->argv_owned) {
127     for (int i = 0; i < cfg->argc_owned; ++i) {
128       raw_free(cfg->argv_owned[i]);
129     }
130     raw_free(cfg->argv_owned);
131   }
132   if (SOCKET_OK(cfg->owning_controller_socket)) {
133     raw_closesocket(cfg->owning_controller_socket);
134   }
135   raw_free(cfg);
136 }
137 
138 const char *
tor_api_get_provider_version(void)139 tor_api_get_provider_version(void)
140 {
141   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
tor_main(int argc,char * argv[])153 tor_main(int argc, char *argv[])
154 {
155   tor_main_configuration_t *cfg = tor_main_configuration_new();
156   if (!cfg) {
157     puts("INTERNAL ERROR: Allocation failure. Cannot proceed");
158     return 1;
159   }
160   if (tor_main_configuration_set_command_line(cfg, argc, argv) < 0) {
161     puts("INTERNAL ERROR: Can't set command line. Cannot proceed.");
162     return 1;
163   }
164   int rv = tor_run_main(cfg);
165   tor_main_configuration_free(cfg);
166   return rv;
167 }
168