Convert circuituse, command, config, connection, relay, router, test to new logging...
[tor.git] / src / or / config.c
blob96c4b37532693fdc130ef5a1d450093678d9102d
1 /* Copyright 2001 Matej Pfajfar.
2 * Copyright 2001-2004 Roger Dingledine.
3 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
4 /* See LICENSE for licensing information */
5 /* $Id$ */
6 const char config_c_id[] = "$Id$";
8 /**
9 * \file config.c
10 * \brief Code to parse and interpret configuration files.
11 **/
13 #include "or.h"
14 #ifdef MS_WINDOWS
15 #include <shlobj.h>
16 #endif
17 #include "../common/aes.h"
19 /** Enumeration of types which option values can take */
20 typedef enum config_type_t {
21 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
22 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
23 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
24 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
25 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
26 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
27 CONFIG_TYPE_ISOTIME, /**< An ISO-formated time relative to GMT. */
28 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and optional
29 * whitespace. */
30 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
31 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
32 * mixed with other keywords. */
33 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
34 * context-sensitive config lines when fetching.
36 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
37 } config_type_t;
39 /** An abbreviation for a configuration option allowed on the command line. */
40 typedef struct config_abbrev_t {
41 const char *abbreviated;
42 const char *full;
43 int commandline_only;
44 int warn;
45 } config_abbrev_t;
47 /* Handy macro for declaring "In the config file or on the command line,
48 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
49 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
51 /* A list of command-line abbreviations. */
52 static config_abbrev_t _option_abbrevs[] = {
53 PLURAL(ExitNode),
54 PLURAL(EntryNode),
55 PLURAL(ExcludeNode),
56 PLURAL(FirewallPort),
57 PLURAL(LongLivedPort),
58 PLURAL(HiddenServiceNode),
59 PLURAL(HiddenServiceExcludeNode),
60 PLURAL(NumCpu),
61 PLURAL(RendNode),
62 PLURAL(RendExcludeNode),
63 PLURAL(StrictEntryNode),
64 PLURAL(StrictExitNode),
65 { "l", "Log", 1, 0},
66 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
67 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
68 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
69 { "MaxConn", "ConnLimit", 0, 1},
70 { "ORBindAddress", "ORListenAddress", 0, 1},
71 { "DirBindAddress", "DirListenAddress", 0, 1},
72 { "SocksBindAddress", "SocksListenAddress", 0, 1},
73 { NULL, NULL, 0, 0},
75 #undef PLURAL
77 /** A variable allowed in the configuration file or on the command line. */
78 typedef struct config_var_t {
79 const char *name; /**< The full keyword (case insensitive). */
80 config_type_t type; /**< How to interpret the type and turn it into a value. */
81 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
82 const char *initvalue; /**< String (or null) describing initial value. */
83 const char *description;
84 } config_var_t;
86 /** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */
87 #define STRUCT_OFFSET(tp, member) ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
88 /** An entry for config_vars: "The option <b>name</b> has type
89 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
90 * or_options_t.<b>member</b>"
92 #define VAR(name,conftype,member,initvalue) \
93 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), initvalue, NULL }
94 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
95 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
97 /** Array of configuration options. Until we disallow nonstandard
98 * abbreviations, order is significant, since the first matching option will
99 * be chosen first.
101 static config_var_t _option_vars[] = {
102 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
103 VAR("AccountingMaxKB", UINT, _AccountingMaxKB, "0"),
104 VAR("AccountingStart", STRING, AccountingStart, NULL),
105 VAR("Address", STRING, Address, NULL),
106 VAR("AllowUnverifiedNodes",CSV, AllowUnverifiedNodes, "middle,rendezvous"),
107 VAR("AssumeReachable", BOOL, AssumeReachable, "0"),
108 VAR("AuthDirInvalid", LINELIST, AuthDirInvalid, NULL),
109 VAR("AuthDirReject", LINELIST, AuthDirReject, NULL),
110 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
111 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "5 MB"),
112 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "2 MB"),
113 VAR("ClientOnly", BOOL, ClientOnly, "0"),
114 VAR("ConnLimit", UINT, ConnLimit, "1024"),
115 VAR("ContactInfo", STRING, ContactInfo, NULL),
116 VAR("ControlPort", UINT, ControlPort, "0"),
117 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
118 VAR("DataDirectory", STRING, DataDirectory, NULL),
119 VAR("DebugLogFile", STRING, DebugLogFile, NULL),
120 VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL),
121 VAR("DirListenAddress", LINELIST, DirListenAddress, NULL),
122 /* if DirFetchPeriod is 0, see get_dir_fetch_period() in main.c */
123 VAR("DirFetchPeriod", INTERVAL, DirFetchPeriod, "0 seconds"),
124 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
125 VAR("DirPort", UINT, DirPort, "0"),
126 OBSOLETE("DirPostPeriod"),
127 VAR("DirServer", LINELIST, DirServers, NULL),
128 VAR("EntryNodes", STRING, EntryNodes, NULL),
129 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
130 VAR("ExitNodes", STRING, ExitNodes, NULL),
131 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
132 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
133 VAR("FirewallPorts", CSV, FirewallPorts, ""),
134 VAR("Group", STRING, Group, NULL),
135 VAR("HardwareAccel", BOOL, HardwareAccel, "1"),
136 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
137 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
138 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
139 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
140 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
141 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
142 VAR("HttpProxy", STRING, HttpProxy, NULL),
143 VAR("HttpProxyAuthenticator",STRING, HttpProxyAuthenticator,NULL),
144 VAR("HttpsProxy", STRING, HttpsProxy, NULL),
145 VAR("HttpsProxyAuthenticator",STRING,HttpsProxyAuthenticator,NULL),
146 OBSOLETE("IgnoreVersion"),
147 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
148 VAR("Log", LINELIST, Logs, NULL),
149 OBSOLETE("LinkPadding"),
150 VAR("LogFile", LINELIST_S, OldLogOptions, NULL),
151 VAR("LogLevel", LINELIST_S, OldLogOptions, NULL),
152 VAR("LongLivedPorts", CSV, LongLivedPorts, "21,22,706,1863,5050,5190,5222,5223,6667,8300,8888"),
153 VAR("MapAddress", LINELIST, AddressMap, NULL),
154 VAR("MaxAdvertisedBandwidth",MEMUNIT,MaxAdvertisedBandwidth,"128 TB"),
155 VAR("MaxCircuitDirtiness", INTERVAL, MaxCircuitDirtiness, "10 minutes"),
156 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
157 OBSOLETE("MonthlyAccountingStart"),
158 VAR("MyFamily", STRING, MyFamily, NULL),
159 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
160 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
161 VAR("Nickname", STRING, Nickname, NULL),
162 VAR("NoPublish", BOOL, NoPublish, "0"),
163 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
164 VAR("NumCpus", UINT, NumCpus, "1"),
165 VAR("NumHelperNodes", UINT, NumHelperNodes, "3"),
166 VAR("ORListenAddress", LINELIST, ORListenAddress, NULL),
167 VAR("ORPort", UINT, ORPort, "0"),
168 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
169 VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"),
170 VAR("PidFile", STRING, PidFile, NULL),
171 VAR("ProtocolWarnings", BOOL, ProtocolWarnings, "0"),
172 VAR("ReachableAddresses", LINELIST, ReachableAddresses, NULL),
173 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
174 VAR("RecommendedClientVersions", LINELIST, RecommendedClientVersions, NULL),
175 VAR("RecommendedServerVersions", LINELIST, RecommendedServerVersions, NULL),
176 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
177 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
178 VAR("RendNodes", STRING, RendNodes, NULL),
179 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "20 minutes"),
180 VAR("RephistTrackTime", INTERVAL, RephistTrackTime, "24 hours"),
181 OBSOLETE("RouterFile"),
182 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
183 VAR("RunTesting", BOOL, RunTesting, "0"),
184 VAR("SafeLogging", BOOL, SafeLogging, "1"),
185 VAR("ShutdownWaitLength", INTERVAL, ShutdownWaitLength, "30 seconds"),
186 VAR("SocksListenAddress", LINELIST, SocksListenAddress, NULL),
187 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
188 VAR("SocksPort", UINT, SocksPort, "9050"),
189 /* if StatusFetchPeriod is 0, see get_status_fetch_period() in main.c */
190 VAR("StatusFetchPeriod", INTERVAL, StatusFetchPeriod, "0 seconds"),
191 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
192 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
193 VAR("SysLog", LINELIST_S, OldLogOptions, NULL),
194 VAR("TrackHostExits", CSV, TrackHostExits, NULL),
195 VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
196 OBSOLETE("TrafficShaping"),
197 VAR("UseHelperNodes", BOOL, UseHelperNodes, "0"),
198 VAR("User", STRING, User, NULL),
199 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
200 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
201 VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
202 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
204 #undef VAR
206 #define VAR(name,conftype,member,initvalue) \
207 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), initvalue, NULL }
208 static config_var_t _state_vars[] = {
209 VAR("AccountingBytesReadInterval", MEMUNIT, AccountingBytesReadInInterval,NULL),
210 VAR("AccountingBytesWrittenInInterval", MEMUNIT,
211 AccountingBytesWrittenInInterval, NULL),
212 VAR("AccountingExpectedUsage", MEMUNIT, AccountingExpectedUsage, NULL),
213 VAR("AccountingIntervalStart", ISOTIME, AccountingIntervalStart, NULL),
214 VAR("AccountingSecondsActive", INTERVAL, AccountingSecondsActive, NULL),
215 VAR("HelperNode", LINELIST_S, HelperNodes, NULL),
216 VAR("HelperNodeDownSince", LINELIST_S, HelperNodes, NULL),
217 VAR("HelperNodeUnlistedSince", LINELIST_S, HelperNodes, NULL),
218 VAR("HelperNodes", LINELIST_V, HelperNodes, NULL),
219 VAR("LastWritten", ISOTIME, LastWritten, NULL),
221 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
224 #undef VAR
225 #undef OBSOLETE
227 /** DOCDOC*/
228 typedef struct config_var_description_t {
229 const char *name;
230 const char *description;
231 } config_var_description_t;
233 static config_var_description_t options_description[] = {
234 { "Address", "The advertised (external) address we should use." },
235 // { "AccountingStart", ""},
236 { NULL, NULL },
239 static config_var_description_t state_description[] = {
240 { "HelperNode", "One of the nodes we have chosen as a fixed entry" },
241 { "HelperNodeDownSince",
242 "The last helper node has been down since this time." },
243 { "HelperNodeUnlistedSince",
244 "The last helper node has been unlisted since this time." },
245 { NULL, NULL },
248 typedef int (*validate_fn_t)(void*);
250 /** Information on the keys, value types, key-to-struct-member mappings,
251 * variable descriptions, validation functions, and abbreviations for a
252 * configuration or storage format. */
253 typedef struct {
254 size_t size;
255 uint32_t magic;
256 off_t magic_offset;
257 config_abbrev_t *abbrevs;
258 config_var_t *vars;
259 validate_fn_t validate_fn;
260 config_var_description_t *descriptions;
261 } config_format_t;
263 #define CHECK(fmt, cfg) do { \
264 tor_assert(fmt && cfg); \
265 tor_assert((fmt)->magic == *(uint32_t*)(((char*)(cfg))+fmt->magic_offset)); \
266 } while (0)
268 /** Largest allowed config line */
269 #define CONFIG_LINE_T_MAXLEN 4096
271 static void config_line_append(config_line_t **lst,
272 const char *key, const char *val);
273 static void option_clear(config_format_t *fmt, or_options_t *options,
274 config_var_t *var);
275 static void option_reset(config_format_t *fmt, or_options_t *options,
276 config_var_t *var, int use_defaults);
277 static void config_free(config_format_t *fmt, void *options);
278 static int option_is_same(config_format_t *fmt,
279 or_options_t *o1, or_options_t *o2, const char *name);
280 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
281 static int options_validate(or_options_t *options);
282 static int options_act_reversible(or_options_t *old_options);
283 static int options_act(or_options_t *old_options);
284 static int options_transition_allowed(or_options_t *old, or_options_t *new);
285 static int options_transition_affects_workers(or_options_t *old_options,
286 or_options_t *new_options);
287 static int options_transition_affects_descriptor(or_options_t *old_options,
288 or_options_t *new_options);
289 static int check_nickname_list(const char *lst, const char *name);
290 static void config_register_addressmaps(or_options_t *options);
292 static int parse_dir_server_line(const char *line, int validate_only);
293 static int parse_redirect_line(smartlist_t *result,
294 config_line_t *line);
295 static int parse_log_severity_range(const char *range, int *min_out,
296 int *max_out);
297 static int convert_log_option(or_options_t *options,
298 config_line_t *level_opt,
299 config_line_t *file_opt, int isDaemon);
300 static int add_single_log_option(or_options_t *options, int minSeverity,
301 int maxSeverity,
302 const char *type, const char *fname);
303 static int normalize_log_options(or_options_t *options);
304 static int validate_data_directory(or_options_t *options);
305 static int write_configuration_file(const char *fname, or_options_t *options);
306 static config_line_t *get_assigned_option(config_format_t *fmt,
307 or_options_t *options, const char *key);
308 static void config_init(config_format_t *fmt, void *options);
309 static int or_state_validate(or_state_t *options);
311 static uint64_t config_parse_memunit(const char *s, int *ok);
312 static int config_parse_interval(const char *s, int *ok);
313 static void print_cvs_version(void);
314 static void parse_reachable_addresses(void);
315 static int init_libevent(void);
316 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
317 static void check_libevent_version(const char *m, const char *v, int server);
318 #endif
320 /*static*/ or_options_t *options_new(void);
322 #define OR_OPTIONS_MAGIC 9090909
324 static config_format_t options_format = {
325 sizeof(or_options_t),
326 OR_OPTIONS_MAGIC,
327 STRUCT_OFFSET(or_options_t, _magic),
328 _option_abbrevs,
329 _option_vars,
330 (validate_fn_t)options_validate,
331 options_description
334 #define OR_STATE_MAGIC 0x57A73f57
336 static config_format_t state_format = {
337 sizeof(or_state_t),
338 OR_STATE_MAGIC,
339 STRUCT_OFFSET(or_state_t, _magic),
340 NULL,
341 _state_vars,
342 (validate_fn_t)or_state_validate,
343 state_description
347 * Functions to read and write the global options pointer.
350 /** Command-line and config-file options. */
351 static or_options_t *global_options = NULL;
352 /** Name of most recently read torrc file. */
353 static char *torrc_fname = NULL;
354 /** Persistant serialized state. */
355 static or_state_t *global_state = NULL;
356 /** DOCDOC */
357 static addr_policy_t *reachable_addr_policy = NULL;
359 static void *
360 config_alloc(config_format_t *fmt)
362 void *opts = opts = tor_malloc_zero(fmt->size);
363 *(uint32_t*)(((char*)opts)+fmt->magic_offset) = fmt->magic;
364 CHECK(fmt, opts);
365 return opts;
368 /** Return the currently configured options. */
369 or_options_t *
370 get_options(void)
372 tor_assert(global_options);
373 return global_options;
376 /** Change the current global options to contain <b>new_val</b> instead of
377 * their current value; take action based on the new value; free the old value
378 * as necessary.
381 set_options(or_options_t *new_val)
383 or_options_t *old_options = global_options;
384 global_options = new_val;
385 /* Note that we pass the *old* options below, for comparison. It
386 * pulls the new options directly out of global_options. */
387 if (options_act_reversible(old_options)<0) {
388 global_options = old_options;
389 return -1;
391 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
392 log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying.");
393 exit(1);
395 if (old_options)
396 config_free(&options_format, old_options);
398 return 0;
401 void
402 config_free_all(void)
404 if (global_options) {
405 config_free(&options_format, global_options);
406 global_options = NULL;
408 if (global_state) {
409 config_free(&state_format, global_state);
410 global_state = NULL;
412 tor_free(torrc_fname);
413 if (reachable_addr_policy) {
414 addr_policy_free(reachable_addr_policy);
415 reachable_addr_policy = NULL;
419 /** If options->SafeLogging is on, return a not very useful string,
420 * else return address.
422 const char *
423 safe_str(const char *address)
425 if (get_options()->SafeLogging)
426 return "[scrubbed]";
427 else
428 return address;
431 /** Fetch the active option list, and take actions based on it. All of the
432 * things we do should survive being done repeatedly. If present,
433 * <b>old_options</b> contains the previous value of the options.
435 * Return 0 if all goes well, return -1 if things went badly.
437 static int
438 options_act_reversible(or_options_t *old_options)
440 smartlist_t *new_listeners = smartlist_create();
441 smartlist_t *replaced_listeners = smartlist_create();
442 static int libevent_initialized = 0;
443 or_options_t *options = get_options();
444 int running_tor = options->command == CMD_RUN_TOR;
445 int set_conn_limit = 0;
446 int r = -1;
448 if (running_tor && options->RunAsDaemon) {
449 /* No need to roll back, since you can't change the value. */
450 start_daemon();
453 /* Setuid/setgid as appropriate */
454 if (options->User || options->Group) {
455 if (switch_id(options->User, options->Group) != 0) {
456 /* No need to roll back, since you can't change the value. */
457 goto done;
461 /* Set up libevent. */
462 if (running_tor && !libevent_initialized) {
463 if (init_libevent())
464 goto done;
465 libevent_initialized = 1;
468 /* Ensure data directory is private; create if possible. */
469 if (check_private_dir(options->DataDirectory, CPD_CREATE)<0) {
470 log_fn(LOG_ERR, "Couldn't access/create private data directory \"%s\"",
471 options->DataDirectory);
472 /* No need to roll back, since you can't change the value. */
473 goto done;
476 /* Bail out at this point if we're not going to be a client or server:
477 * we don't run */
478 if (options->command != CMD_RUN_TOR)
479 goto commit;
481 options->_ConnLimit =
482 set_max_file_descriptors((unsigned)options->ConnLimit, MAXCONNECTIONS);
483 if (options->_ConnLimit < 0)
484 goto rollback;
485 set_conn_limit = 1;
487 if (retry_all_listeners(0, replaced_listeners, new_listeners) < 0) {
488 log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
489 goto rollback;
492 commit:
493 r = 0;
494 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
496 log_fn(LOG_NOTICE, "Closing old %s on %s:%d",
497 conn_type_to_string(conn->type), conn->address, conn->port);
498 connection_close_immediate(conn);
499 connection_mark_for_close(conn);
501 goto done;
503 rollback:
504 r = -1;
506 if (set_conn_limit && old_options)
507 set_max_file_descriptors((unsigned)old_options->ConnLimit,MAXCONNECTIONS);
509 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
511 log_fn(LOG_NOTICE, "Closing %s on %s:%d",
512 conn_type_to_string(conn->type), conn->address, conn->port);
513 connection_close_immediate(conn);
514 connection_mark_for_close(conn);
517 done:
518 smartlist_free(new_listeners);
519 smartlist_free(replaced_listeners);
520 return r;
523 /** Fetch the active option list, and take actions based on it. All of the
524 * things we do should survive being done repeatedly. If present,
525 * <b>old_options</b> contains the previous value of the options.
527 * Return 0 if all goes well, return -1 if it's time to die.
529 * Note 2: We haven't moved all the "act on new configuration" logic
530 * here yet. Some is still in do_hup() and other places.
532 static int
533 options_act(or_options_t *old_options)
535 config_line_t *cl;
536 char *fn;
537 size_t len;
538 or_options_t *options = get_options();
539 int running_tor = options->command == CMD_RUN_TOR;
541 clear_trusted_dir_servers();
542 for (cl = options->DirServers; cl; cl = cl->next) {
543 if (parse_dir_server_line(cl->value, 0)<0) {
544 log_fn(LOG_ERR,
545 "Bug: Previously validated DirServer line could not be added!");
546 return -1;
550 if (running_tor && rend_config_services(options, 0)<0) {
551 log_fn(LOG_ERR,
552 "Bug: Previously validated hidden services line could not be added!");
553 return -1;
556 if (options->EntryNodes && strlen(options->EntryNodes))
557 options->UseHelperNodes = 0;
559 if (running_tor) {
560 len = strlen(options->DataDirectory)+32;
561 fn = tor_malloc(len);
562 tor_snprintf(fn, len, "%s/cached-status", options->DataDirectory);
563 if (check_private_dir(fn, CPD_CREATE) != 0) {
564 log_fn(LOG_ERR, "Couldn't access/create private data directory \"%s\"",
565 fn);
566 tor_free(fn);
567 return -1;
569 tor_free(fn);
572 /* Bail out at this point if we're not going to be a client or server:
573 * we want to not fork, and to log stuff to stderr. */
574 if (options->command != CMD_RUN_TOR)
575 return 0;
577 mark_logs_temp(); /* Close current logs once new logs are open. */
578 if (options_init_logs(options, 0)<0) /* Configure the log(s) */
579 return -1;
581 /* Close the temporary log we used while starting up, if it isn't already
582 * gone. */
583 close_temp_logs();
584 add_callback_log(LOG_ERR, LOG_ERR, control_event_logmsg);
585 control_adjust_event_log_severity();
587 /* Load state */
588 if (! global_state)
589 if (or_state_load())
590 return -1;
593 smartlist_t *sl = smartlist_create();
594 for (cl = options->RedirectExit; cl; cl = cl->next) {
595 if (parse_redirect_line(sl, cl)<0)
596 return -1;
598 set_exit_redirects(sl);
601 /* Finish backgrounding the process */
602 if (running_tor && options->RunAsDaemon) {
603 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
604 finish_daemon(options->DataDirectory);
607 /* Write our pid to the pid file. If we do not have write permissions we
608 * will log a warning */
609 if (running_tor && options->PidFile)
610 write_pidfile(options->PidFile);
612 /* Register addressmap directives */
613 config_register_addressmaps(options);
615 /* Update address policies. */
616 parse_socks_policy();
617 parse_dir_policy();
618 parse_authdir_policy();
619 parse_reachable_addresses();
621 init_cookie_authentication(options->CookieAuthentication);
623 /* reload keys as needed for rendezvous services. */
624 if (rend_service_load_keys()<0) {
625 log_fn(LOG_ERR,"Error loading rendezvous service keys");
626 return -1;
629 /* Set up accounting */
630 if (accounting_parse_options(options, 0)<0) {
631 log_fn(LOG_ERR,"Error in accounting options");
632 return -1;
634 if (accounting_is_enabled(options))
635 configure_accounting(time(NULL));
637 if (!running_tor)
638 return 0;
640 /* Check for transitions that need action. */
641 if (old_options) {
642 if (options->UseHelperNodes && !old_options->UseHelperNodes) {
643 log_fn(LOG_INFO, "Switching to helper nodes; abandoning previous circuits");
644 circuit_mark_all_unused_circs();
645 circuit_expire_all_dirty_circs();
648 if (options_transition_affects_workers(old_options, options)) {
649 log_fn(LOG_INFO,"Worker-related options changed. Rotating workers.");
650 cpuworkers_rotate();
651 dnsworkers_rotate();
655 /* Since our options changed, we might need to regenerate and upload our
656 * server descriptor.
658 if (!old_options || options_transition_affects_descriptor(old_options, options))
659 mark_my_descriptor_dirty();
661 return 0;
665 * Functions to parse config options
668 /** If <b>option</b> is an official abbreviation for a longer option,
669 * return the longer option. Otherwise return <b>option</b>.
670 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
671 * apply abbreviations that work for the config file and the command line.
672 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
673 static const char *
674 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
675 int warn_obsolete)
677 int i;
678 if (! fmt->abbrevs)
679 return option;
680 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
681 /* Abbreviations are casei. */
682 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
683 (command_line || !fmt->abbrevs[i].commandline_only)) {
684 if (warn_obsolete && fmt->abbrevs[i].warn) {
685 log_fn(LOG_WARN,
686 "The configuration option '%s' is deprecated; use '%s' instead.",
687 fmt->abbrevs[i].abbreviated,
688 fmt->abbrevs[i].full);
690 return fmt->abbrevs[i].full;
693 return option;
696 /** Helper: Read a list of configuration options from the command line.
697 * If successful, put them in *<b>result</b> and return 0, and return
698 * -1 and leave *<b>result</b> alone. */
699 static int
700 config_get_commandlines(int argc, char **argv, config_line_t **result)
702 config_line_t *front = NULL;
703 config_line_t **new = &front;
704 char *s;
705 int i = 1;
707 while (i < argc) {
708 if (!strcmp(argv[i],"-f") ||
709 !strcmp(argv[i],"--hash-password")) {
710 i += 2; /* command-line option with argument. ignore them. */
711 continue;
712 } else if (!strcmp(argv[i],"--list-fingerprint")) {
713 i += 1; /* command-line option. ignore it. */
714 continue;
715 } else if (!strcmp(argv[i],"--nt-service")) {
716 i += 1;
717 continue;
719 if (i == argc-1) {
720 log_fn(LOG_WARN,"Command-line option '%s' with no value. Failing.",
721 argv[i]);
722 config_free_lines(front);
723 return -1;
726 *new = tor_malloc_zero(sizeof(config_line_t));
727 s = argv[i];
729 while (*s == '-')
730 s++;
732 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
733 (*new)->value = tor_strdup(argv[i+1]);
734 (*new)->next = NULL;
735 log(LOG_DEBUG,"Commandline: parsed keyword '%s', value '%s'",
736 (*new)->key, (*new)->value);
738 new = &((*new)->next);
739 i += 2;
741 *result = front;
742 return 0;
745 /** Helper: allocate a new configuration option mapping 'key' to 'val',
746 * append it to *<b>lst</b>. */
747 static void
748 config_line_append(config_line_t **lst,
749 const char *key,
750 const char *val)
752 config_line_t *newline;
754 newline = tor_malloc(sizeof(config_line_t));
755 newline->key = tor_strdup(key);
756 newline->value = tor_strdup(val);
757 newline->next = NULL;
758 while (*lst)
759 lst = &((*lst)->next);
761 (*lst) = newline;
764 /** Helper: parse the config string and strdup into key/value
765 * strings. Set *result to the list, or NULL if parsing the string
766 * failed. Return 0 on success, -1 on failure. Warn and ignore any
767 * misformatted lines. */
769 config_get_lines(char *string, config_line_t **result)
771 config_line_t *list = NULL, **next;
772 char *k, *v;
774 next = &list;
775 do {
776 string = parse_line_from_str(string, &k, &v);
777 if (!string) {
778 config_free_lines(list);
779 return -1;
781 if (k && v) {
782 /* This list can get long, so we keep a pointer to the end of it
783 * rather than using config_line_append over and over and getting n^2
784 * performance. This is the only really long list. */
785 *next = tor_malloc(sizeof(config_line_t));
786 (*next)->key = tor_strdup(k);
787 (*next)->value = tor_strdup(v);
788 (*next)->next = NULL;
789 next = &((*next)->next);
791 } while (*string);
793 *result = list;
794 return 0;
798 * Free all the configuration lines on the linked list <b>front</b>.
800 void
801 config_free_lines(config_line_t *front)
803 config_line_t *tmp;
805 while (front) {
806 tmp = front;
807 front = tmp->next;
809 tor_free(tmp->key);
810 tor_free(tmp->value);
811 tor_free(tmp);
815 /** DOCDOC */
816 static const char *
817 config_find_description(config_format_t *fmt, const char *name)
819 int i;
820 for (i=0; fmt->descriptions[i].name; ++i) {
821 if (!strcasecmp(name, fmt->descriptions[i].name))
822 return fmt->descriptions[i].description;
824 return NULL;
827 /** If <b>key</b> is a configuration option, return the corresponding
828 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
829 * warn, and return the corresponding config_var_t. Otherwise return NULL.
831 static config_var_t *
832 config_find_option(config_format_t *fmt, const char *key)
834 int i;
835 size_t keylen = strlen(key);
836 if (!keylen)
837 return NULL; /* if they say "--" on the commandline, it's not an option */
838 /* First, check for an exact (case-insensitive) match */
839 for (i=0; fmt->vars[i].name; ++i) {
840 if (!strcasecmp(key, fmt->vars[i].name)) {
841 return &fmt->vars[i];
844 /* If none, check for an abbreviated match */
845 for (i=0; fmt->vars[i].name; ++i) {
846 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
847 log_fn(LOG_WARN, "The abbreviation '%s' is deprecated. "
848 "Please use '%s' instead",
849 key, fmt->vars[i].name);
850 return &fmt->vars[i];
853 /* Okay, unrecognized options */
854 return NULL;
858 * Functions to assign config options.
861 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
862 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
864 * Called from config_assign_line() and option_reset().
866 static int
867 config_assign_value(config_format_t *fmt, or_options_t *options,
868 config_line_t *c)
870 int i, ok;
871 config_var_t *var;
872 void *lvalue;
874 CHECK(fmt, options);
876 var = config_find_option(fmt, c->key);
877 tor_assert(var);
879 lvalue = ((char*)options) + var->var_offset;
881 switch (var->type) {
883 case CONFIG_TYPE_UINT:
884 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
885 if (!ok) {
886 log(LOG_WARN, "Int keyword '%s %s' is malformed or out of bounds.",
887 c->key,c->value);
888 return -1;
890 *(int *)lvalue = i;
891 break;
893 case CONFIG_TYPE_INTERVAL: {
894 i = config_parse_interval(c->value, &ok);
895 if (!ok) {
896 return -1;
898 *(int *)lvalue = i;
899 break;
902 case CONFIG_TYPE_MEMUNIT: {
903 uint64_t u64 = config_parse_memunit(c->value, &ok);
904 if (!ok) {
905 return -1;
907 *(uint64_t *)lvalue = u64;
908 break;
911 case CONFIG_TYPE_BOOL:
912 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
913 if (!ok) {
914 log(LOG_WARN, "Boolean keyword '%s' expects 0 or 1.", c->key);
915 return -1;
917 *(int *)lvalue = i;
918 break;
920 case CONFIG_TYPE_STRING:
921 tor_free(*(char **)lvalue);
922 *(char **)lvalue = tor_strdup(c->value);
923 break;
925 case CONFIG_TYPE_DOUBLE:
926 *(double *)lvalue = atof(c->value);
927 break;
929 case CONFIG_TYPE_ISOTIME:
930 if (parse_iso_time(c->value, (time_t *)lvalue)) {
931 log(LOG_WARN, "Invalid time '%s' for keyword '%s'", c->value, c->key);
932 return -1;
934 break;
936 case CONFIG_TYPE_CSV:
937 if (*(smartlist_t**)lvalue) {
938 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
939 smartlist_clear(*(smartlist_t**)lvalue);
940 } else {
941 *(smartlist_t**)lvalue = smartlist_create();
944 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
945 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
946 break;
948 case CONFIG_TYPE_LINELIST:
949 case CONFIG_TYPE_LINELIST_S:
950 config_line_append((config_line_t**)lvalue, c->key, c->value);
951 break;
953 case CONFIG_TYPE_OBSOLETE:
954 log_fn(LOG_WARN, "Skipping obsolete configuration option '%s'", c->key);
955 break;
956 case CONFIG_TYPE_LINELIST_V:
957 log_fn(LOG_WARN, "Can't provide value for virtual option '%s'", c->key);
958 return -1;
959 default:
960 tor_assert(0);
961 break;
963 return 0;
966 /** If <b>c</b> is a syntactically valid configuration line, update
967 * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
968 * -2 for bad value.
970 * If <b>clear_first</b> is set, clear the value first. Then if
971 * <b>use_defaults</b> is set, set the value to the default.
973 * Called from config_assign().
975 static int
976 config_assign_line(config_format_t *fmt, or_options_t *options,
977 config_line_t *c, int use_defaults, int clear_first)
979 config_var_t *var;
981 CHECK(fmt, options);
983 var = config_find_option(fmt, c->key);
984 if (!var) {
985 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
986 return -1;
988 /* Put keyword into canonical case. */
989 if (strcmp(var->name, c->key)) {
990 tor_free(c->key);
991 c->key = tor_strdup(var->name);
994 if (!strlen(c->value)) { /* reset or clear it, then return */
995 if (!clear_first) /* not already cleared */
996 option_reset(fmt, options, var, use_defaults);
997 return 0;
1000 if (config_assign_value(fmt, options, c) < 0)
1001 return -2;
1002 return 0;
1005 /** Restore the option named <b>key</b> in options to its default value.
1006 * Called from config_assign(). */
1007 static void
1008 config_reset_line(config_format_t *fmt, or_options_t *options,
1009 const char *key, int use_defaults)
1011 config_var_t *var;
1013 CHECK(fmt, options);
1015 var = config_find_option(fmt, key);
1016 if (!var)
1017 return; /* give error on next pass. */
1019 option_reset(fmt, options, var, use_defaults);
1022 /** Return true iff key is a valid configuration option. */
1024 option_is_recognized(const char *key)
1026 config_var_t *var = config_find_option(&options_format, key);
1027 return (var != NULL);
1030 /** Return the canonical name of a configuration option. */
1031 const char *
1032 option_get_canonical_name(const char *key)
1034 config_var_t *var = config_find_option(&options_format, key);
1035 return var->name;
1038 /** Return a canonicalized list of the options assigned for key.
1040 config_line_t *
1041 option_get_assignment(or_options_t *options, const char *key)
1043 return get_assigned_option(&options_format, options, key);
1046 static config_line_t *
1047 config_lines_dup(const config_line_t *inp)
1049 config_line_t *result = NULL;
1050 config_line_t **next_out = &result;
1051 while (inp) {
1052 *next_out = tor_malloc(sizeof(config_line_t));
1053 (*next_out)->key = tor_strdup(inp->key);
1054 (*next_out)->value = tor_strdup(inp->value);
1055 inp = inp->next;
1056 next_out = &((*next_out)->next);
1058 (*next_out) = NULL;
1059 return result;
1062 static config_line_t *
1063 get_assigned_option(config_format_t *fmt, or_options_t *options, const char *key)
1065 config_var_t *var;
1066 const void *value;
1067 char buf[32];
1068 config_line_t *result;
1069 tor_assert(options && key);
1071 CHECK(fmt, options);
1073 var = config_find_option(fmt, key);
1074 if (!var) {
1075 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", key);
1076 return NULL;
1077 } else if (var->type == CONFIG_TYPE_LINELIST_S) {
1078 log_fn(LOG_WARN, "Can't return context-sensitive '%s' on its own", key);
1079 return NULL;
1081 value = ((char*)options) + var->var_offset;
1083 if (var->type == CONFIG_TYPE_LINELIST ||
1084 var->type == CONFIG_TYPE_LINELIST_V) {
1085 /* Linelist requires special handling: we just copy and return it. */
1086 return config_lines_dup(*(const config_line_t**)value);
1089 result = tor_malloc_zero(sizeof(config_line_t));
1090 result->key = tor_strdup(var->name);
1091 switch (var->type)
1093 case CONFIG_TYPE_STRING:
1094 if (*(char**)value) {
1095 result->value = tor_strdup(*(char**)value);
1096 } else {
1097 tor_free(result->key);
1098 tor_free(result);
1099 return NULL;
1101 break;
1102 case CONFIG_TYPE_ISOTIME:
1103 if (*(time_t*)value) {
1104 result->value = tor_malloc(ISO_TIME_LEN+1);
1105 format_iso_time(result->value, *(time_t*)value);
1106 } else {
1107 tor_free(result->key);
1108 tor_free(result);
1110 break;
1111 case CONFIG_TYPE_INTERVAL:
1112 case CONFIG_TYPE_UINT:
1113 /* This means every or_options_t uint or bool element
1114 * needs to be an int. Not, say, a uint16_t or char. */
1115 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
1116 result->value = tor_strdup(buf);
1117 break;
1118 case CONFIG_TYPE_MEMUNIT:
1119 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
1120 U64_PRINTF_ARG(*(uint64_t*)value));
1121 result->value = tor_strdup(buf);
1122 break;
1123 case CONFIG_TYPE_DOUBLE:
1124 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
1125 result->value = tor_strdup(buf);
1126 break;
1127 case CONFIG_TYPE_BOOL:
1128 result->value = tor_strdup(*(int*)value ? "1" : "0");
1129 break;
1130 case CONFIG_TYPE_CSV:
1131 if (*(smartlist_t**)value)
1132 result->value = smartlist_join_strings(*(smartlist_t**)value,",",0,NULL);
1133 else
1134 result->value = tor_strdup("");
1135 break;
1136 case CONFIG_TYPE_OBSOLETE:
1137 log_fn(LOG_WARN,"You asked me for the value of an obsolete config option '%s'.", key);
1138 tor_free(result->key);
1139 tor_free(result);
1140 return NULL;
1141 default:
1142 tor_free(result->key);
1143 tor_free(result);
1144 log_fn(LOG_WARN,"Bug: unknown type %d for known key '%s'", var->type, key);
1145 return NULL;
1148 return result;
1151 /** Iterate through the linked list of requested options <b>list</b>.
1152 * For each item, convert as appropriate and assign to <b>options</b>.
1153 * If an item is unrecognized, return -1 immediately,
1154 * else return 0 for success.
1156 * If <b>clear_first</b>, interpret config options as replacing (not
1157 * extending) their previous values. If <b>clear_first</b> is set,
1158 * then <b>use_defaults</b> to decide if you set to defaults after
1159 * clearing, or make the value 0 or NULL.
1161 * Here are the use cases:
1162 * 1. A non-empty AllowUnverified line in your torrc. Appends to current
1163 * if linelist, replaces current if csv.
1164 * 2. An empty AllowUnverified line in your torrc. Should clear it.
1165 * 3. "RESETCONF AllowUnverified" sets it to default.
1166 * 4. "SETCONF AllowUnverified" makes it NULL.
1167 * 5. "SETCONF AllowUnverified=foo" clears it and sets it to "foo".
1169 * Use_defaults Clear_first
1170 * 0 0 "append"
1171 * 1 0 undefined, don't use
1172 * 0 1 "set to null first"
1173 * 1 1 "set to defaults first"
1174 * Return 0 on success, -1 on bad key, -2 on bad value.
1178 There are three call cases for config_assign() currently.
1180 Case one: Torrc entry
1181 options_init_from_torrc() calls config_assign(0, 0)
1182 calls config_assign_line(0, 0).
1183 if value is empty, calls option_reset(0) and returns.
1184 calls config_assign_value(), appends.
1186 Case two: setconf
1187 options_trial_assign() calls config_assign(0, 1)
1188 calls config_reset_line(0)
1189 calls option_reset(0)
1190 calls option_clear().
1191 calls config_assign_line(0, 1).
1192 if value is empty, returns.
1193 calls config_assign_value(), appends.
1195 Case three: resetconf
1196 options_trial_assign() calls config_assign(1, 1)
1197 calls config_reset_line(1)
1198 calls option_reset(1)
1199 calls option_clear().
1200 calls config_assign_value(default)
1201 calls config_assign_line(1, 1).
1202 returns.
1204 static int
1205 config_assign(config_format_t *fmt, void *options,
1206 config_line_t *list, int use_defaults, int clear_first)
1208 config_line_t *p;
1210 CHECK(fmt, options);
1212 /* pass 1: normalize keys */
1213 for (p = list; p; p = p->next) {
1214 const char *full = expand_abbrev(fmt, p->key, 0, 1);
1215 if (strcmp(full,p->key)) {
1216 tor_free(p->key);
1217 p->key = tor_strdup(full);
1221 /* pass 2: if we're reading from a resetting source, clear all
1222 * mentioned config options, and maybe set to their defaults. */
1223 if (clear_first) {
1224 for (p = list; p; p = p->next)
1225 config_reset_line(fmt, options, p->key, use_defaults);
1228 /* pass 3: assign. */
1229 while (list) {
1230 int r;
1231 if ((r=config_assign_line(fmt, options, list, use_defaults, clear_first)))
1232 return r;
1233 list = list->next;
1235 return 0;
1238 /** Try assigning <b>list</b> to the global options. You do this by duping
1239 * options, assigning list to the new one, then validating it. If it's
1240 * ok, then throw out the old one and stick with the new one. Else,
1241 * revert to old and return failure. Return 0 on success, -1 on bad
1242 * keys, -2 on bad values, -3 on bad transition, and -4 on failed-to-set.
1245 options_trial_assign(config_line_t *list, int use_defaults, int clear_first)
1247 int r;
1248 or_options_t *trial_options = options_dup(&options_format, get_options());
1250 if ((r=config_assign(&options_format, trial_options,
1251 list, use_defaults, clear_first)) < 0) {
1252 config_free(&options_format, trial_options);
1253 return r;
1256 if (options_validate(trial_options) < 0) {
1257 config_free(&options_format, trial_options);
1258 return -2;
1261 if (options_transition_allowed(get_options(), trial_options) < 0) {
1262 config_free(&options_format, trial_options);
1263 return -3;
1266 if (set_options(trial_options)<0) {
1267 config_free(&options_format, trial_options);
1268 return -4;
1271 /* we liked it. put it in place. */
1272 return 0;
1275 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
1276 * Called from option_reset() and config_free(). */
1277 static void
1278 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
1280 void *lvalue = ((char*)options) + var->var_offset;
1281 switch (var->type) {
1282 case CONFIG_TYPE_STRING:
1283 tor_free(*(char**)lvalue);
1284 break;
1285 case CONFIG_TYPE_DOUBLE:
1286 *(double*)lvalue = 0.0;
1287 break;
1288 case CONFIG_TYPE_ISOTIME:
1289 *(time_t*)lvalue = 0;
1290 case CONFIG_TYPE_INTERVAL:
1291 case CONFIG_TYPE_UINT:
1292 case CONFIG_TYPE_BOOL:
1293 *(int*)lvalue = 0;
1294 break;
1295 case CONFIG_TYPE_MEMUNIT:
1296 *(uint64_t*)lvalue = 0;
1297 break;
1298 case CONFIG_TYPE_CSV:
1299 if (*(smartlist_t**)lvalue) {
1300 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
1301 smartlist_free(*(smartlist_t **)lvalue);
1302 *(smartlist_t **)lvalue = NULL;
1304 break;
1305 case CONFIG_TYPE_LINELIST:
1306 case CONFIG_TYPE_LINELIST_S:
1307 config_free_lines(*(config_line_t **)lvalue);
1308 *(config_line_t **)lvalue = NULL;
1309 break;
1310 case CONFIG_TYPE_LINELIST_V:
1311 /* handled by linelist_s. */
1312 break;
1313 case CONFIG_TYPE_OBSOLETE:
1314 break;
1318 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
1319 * <b>use_defaults</b>, set it to its default value.
1320 * Called by config_init() and option_reset_line() and option_assign_line(). */
1321 static void
1322 option_reset(config_format_t *fmt, or_options_t *options,
1323 config_var_t *var, int use_defaults)
1325 config_line_t *c;
1326 void *lvalue;
1327 CHECK(fmt, options);
1328 option_clear(fmt, options, var); /* clear it first */
1329 if (!use_defaults)
1330 return; /* all done */
1331 lvalue = ((char*)options) + var->var_offset;
1332 if (var->initvalue) {
1333 c = tor_malloc_zero(sizeof(config_line_t));
1334 c->key = tor_strdup(var->name);
1335 c->value = tor_strdup(var->initvalue);
1336 config_assign_value(fmt, options, c);
1337 config_free_lines(c);
1341 /** Set <b>options</b>-&gt;DirServers to contain the default directory
1342 * servers. */
1343 static void
1344 add_default_trusted_dirservers(or_options_t *options)
1346 config_line_append(&options->DirServers, "DirServer",
1347 "moria1 v1 18.244.0.188:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441");
1348 config_line_append(&options->DirServers, "DirServer",
1349 "moria2 v1 18.244.0.114:80 719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF");
1350 config_line_append(&options->DirServers, "DirServer",
1351 "tor26 v1 86.59.5.130:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
1352 // "tor.noreply.org:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
1355 /** Print a usage message for tor. */
1356 static void
1357 print_usage(void)
1359 printf(
1360 "Copyright 2001-2005 Roger Dingledine, Nick Mathewson.\n\n"
1361 "tor -f <torrc> [args]\n"
1362 "See man page for options, or http://tor.eff.org/ for documentation.\n");
1366 * Based on <b>options-\>Address</b>, guess our public IP address and put it
1367 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided, set
1368 * *<b>hostname_out</b> to a new string holding the hostname we used to get
1369 * the address. Return 0 if all is well, or -1 if we can't find a suitable
1370 * public IP address.
1373 resolve_my_address(or_options_t *options, uint32_t *addr_out, char **hostname_out)
1375 struct in_addr in;
1376 struct hostent *rent;
1377 char hostname[256];
1378 int explicit_ip=1;
1379 char tmpbuf[INET_NTOA_BUF_LEN];
1380 static uint32_t old_addr=0;
1381 const char *address = options->Address;
1383 tor_assert(addr_out);
1385 if (address && *address) {
1386 strlcpy(hostname, address, sizeof(hostname));
1387 } else { /* then we need to guess our address */
1388 explicit_ip = 0; /* it's implicit */
1390 if (gethostname(hostname, sizeof(hostname)) < 0) {
1391 log_fn(LOG_WARN,"Error obtaining local hostname");
1392 return -1;
1394 log_fn(LOG_DEBUG,"Guessed local host name as '%s'",hostname);
1397 /* now we know hostname. resolve it and keep only the IP */
1399 if (tor_inet_aton(hostname, &in) == 0) {
1400 /* then we have to resolve it */
1401 explicit_ip = 0;
1402 rent = (struct hostent *)gethostbyname(hostname);
1403 if (!rent) {
1404 log_fn(LOG_WARN,"Could not resolve local Address '%s'. Failing.", hostname);
1405 return -1;
1407 tor_assert(rent->h_length == 4);
1408 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
1411 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1412 if (is_internal_IP(htonl(in.s_addr)) && !options->NoPublish) {
1413 /* make sure we're ok with publishing an internal IP */
1414 if (!options->DirServers) {
1415 /* if they are using the default dirservers, disallow internal IPs always. */
1416 log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
1417 "Tor servers that use the default DirServers must have public IP addresses.",
1418 hostname, tmpbuf);
1419 return -1;
1421 if (!explicit_ip) {
1422 /* even if they've set their own dirservers, require an explicit IP if
1423 * they're using an internal address. */
1424 log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
1425 "Please set the Address config option to be the IP you want to use.",
1426 hostname, tmpbuf);
1427 return -1;
1431 log_fn(LOG_DEBUG, "Resolved Address to '%s'.", tmpbuf);
1432 *addr_out = ntohl(in.s_addr);
1433 if (old_addr && old_addr != *addr_out) {
1434 log_fn(LOG_NOTICE,"Your IP seems to have changed. Updating.");
1435 server_has_changed_ip();
1437 old_addr = *addr_out;
1438 if (hostname_out)
1439 *hostname_out = tor_strdup(hostname);
1440 return 0;
1443 /** Called when we don't have a nickname set. Try to guess a good
1444 * nickname based on the hostname, and return it in a newly allocated string. */
1445 static char *
1446 get_default_nickname(void)
1448 char localhostname[256];
1449 char *cp, *out, *outp;
1451 if (gethostname(localhostname, sizeof(localhostname)) < 0) {
1452 log_fn(LOG_WARN,"Error obtaining local hostname");
1453 return NULL;
1456 /* Put it in lowercase; stop at the first dot. */
1457 for (cp = localhostname; *cp; ++cp) {
1458 if (*cp == '.') {
1459 *cp = '\0';
1460 break;
1462 *cp = tolower(*cp);
1465 /* Strip invalid characters. */
1466 cp = localhostname;
1467 out = outp = tor_malloc(strlen(localhostname) + 1);
1468 while (*cp) {
1469 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
1470 *outp++ = *cp++;
1471 else
1472 cp++;
1474 *outp = '\0';
1476 /* Enforce length. */
1477 if (strlen(out) > MAX_NICKNAME_LEN)
1478 out[MAX_NICKNAME_LEN]='\0';
1480 return out;
1483 /** Release storage held by <b>options</b> */
1484 static void
1485 config_free(config_format_t *fmt, void *options)
1487 int i;
1489 tor_assert(options);
1491 for (i=0; fmt->vars[i].name; ++i)
1492 option_clear(fmt, options, &(fmt->vars[i]));
1493 tor_free(options);
1496 /** Return true iff a and b contain identical keys and values in identical
1497 * order. */
1498 static int
1499 config_lines_eq(config_line_t *a, config_line_t *b)
1501 while (a && b) {
1502 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
1503 return 0;
1504 a = a->next;
1505 b = b->next;
1507 if (a || b)
1508 return 0;
1509 return 1;
1512 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
1513 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1515 static int
1516 option_is_same(config_format_t *fmt,
1517 or_options_t *o1, or_options_t *o2, const char *name)
1519 config_line_t *c1, *c2;
1520 int r = 1;
1521 CHECK(fmt, o1);
1522 CHECK(fmt, o2);
1524 c1 = get_assigned_option(fmt, o1, name);
1525 c2 = get_assigned_option(fmt, o2, name);
1526 r = config_lines_eq(c1, c2);
1527 config_free_lines(c1);
1528 config_free_lines(c2);
1529 return r;
1532 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1533 static or_options_t *
1534 options_dup(config_format_t *fmt, or_options_t *old)
1536 or_options_t *newopts;
1537 int i;
1538 config_line_t *line;
1540 newopts = config_alloc(fmt);
1541 for (i=0; fmt->vars[i].name; ++i) {
1542 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
1543 continue;
1544 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
1545 continue;
1546 line = get_assigned_option(fmt, old, fmt->vars[i].name);
1547 if (line) {
1548 if (config_assign(fmt, newopts, line, 0, 0) < 0) {
1549 log_fn(LOG_WARN,"Bug: config_get_assigned_option() generated "
1550 "something we couldn't config_assign().");
1551 tor_assert(0);
1554 config_free_lines(line);
1556 return newopts;
1559 /** Return a new empty or_options_t. Used for testing. */
1560 or_options_t *
1561 options_new(void)
1563 return config_alloc(&options_format);
1566 /** Set <b>options</b> to hold reasonable defaults for most options.
1567 * Each option defaults to zero. */
1568 void
1569 options_init(or_options_t *options)
1571 config_init(&options_format, options);
1574 /* DOCDOC */
1575 static void
1576 config_init(config_format_t *fmt, void *options)
1578 int i;
1579 config_var_t *var;
1580 CHECK(fmt, options);
1582 for (i=0; fmt->vars[i].name; ++i) {
1583 var = &fmt->vars[i];
1584 if (!var->initvalue)
1585 continue; /* defaults to NULL or 0 */
1586 option_reset(fmt, options, var, 1);
1590 /* DOCDOC */
1591 static char *
1592 config_dump(config_format_t *fmt, void *options, int minimal)
1594 smartlist_t *elements;
1595 or_options_t *defaults;
1596 config_line_t *line;
1597 char *result;
1598 int i;
1599 const char *desc;
1601 defaults = config_alloc(fmt);
1602 config_init(fmt, defaults);
1603 fmt->validate_fn(defaults);
1605 elements = smartlist_create();
1606 for (i=0; fmt->vars[i].name; ++i) {
1607 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
1608 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
1609 continue;
1610 /* Don't save 'hidden' control variables. */
1611 if (!strcmpstart(fmt->vars[i].name, "__"))
1612 continue;
1613 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
1614 continue;
1616 desc = config_find_description(fmt, fmt->vars[i].name);
1617 if (desc) {
1618 size_t len = strlen(desc)+8;
1619 char *tmp = tor_malloc(len);
1620 tor_snprintf(tmp, len, "# %s\n",desc);
1621 smartlist_add(elements, tmp);
1624 line = get_assigned_option(fmt, options, fmt->vars[i].name);
1625 for (; line; line = line->next) {
1626 size_t len = strlen(line->key) + strlen(line->value) + 3;
1627 char *tmp;
1628 tmp = tor_malloc(len);
1629 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
1630 log_fn(LOG_ERR, "Internal error writing log option");
1631 tor_assert(0);
1633 smartlist_add(elements, tmp);
1635 config_free_lines(line);
1638 result = smartlist_join_strings(elements, "", 0, NULL);
1639 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
1640 smartlist_free(elements);
1641 return result;
1644 /** Return a string containing a possible configuration file that would give
1645 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
1646 * include options that are the same as Tor's defaults.
1648 char *
1649 options_dump(or_options_t *options, int minimal)
1651 return config_dump(&options_format, options, minimal);
1654 /* Return 0 if every element of sl is a string holding a decimal
1655 * representation of a port number, or if sl is NULL.
1656 * Otherwise return -1. */
1657 static int
1658 validate_ports_csv(smartlist_t *sl, const char *name)
1660 int i;
1661 int result = 0;
1662 tor_assert(name);
1664 if (!sl)
1665 return 0;
1667 SMARTLIST_FOREACH(sl, const char *, cp,
1669 i = atoi(cp);
1670 if (i < 1 || i > 65535) {
1671 log(LOG_WARN, "Port '%s' out of range in %s", cp, name);
1672 result=-1;
1675 return result;
1678 /** DOCDOC */
1679 static void
1680 parse_reachable_addresses(void)
1682 or_options_t *options = get_options();
1684 addr_policy_free(reachable_addr_policy);
1685 reachable_addr_policy = NULL;
1687 if (config_parse_addr_policy(options->ReachableAddresses,
1688 &reachable_addr_policy,
1689 ADDR_POLICY_ACCEPT)) {
1690 log_fn(LOG_WARN, "Error in ReachableAddresses entry; ignoring.");
1691 return;
1695 /** Return true iff the firewall options might block any address:port
1696 * combination
1699 firewall_is_fascist(void)
1701 return reachable_addr_policy ? 1 : 0;
1704 /** Return true iff we are configured to think that the local fascist
1705 * firewall (if any) will allow a connection to <b>addr</b>:<b>port</b> */
1707 fascist_firewall_allows_address(uint32_t addr, uint16_t port)
1709 addr_policy_result_t p = router_compare_addr_to_addr_policy(
1710 addr, port, reachable_addr_policy);
1712 switch (p) {
1713 case ADDR_POLICY_PROBABLY_ACCEPTED:
1714 case ADDR_POLICY_ACCEPTED:
1715 return 1;
1716 case ADDR_POLICY_PROBABLY_REJECTED:
1717 case ADDR_POLICY_REJECTED:
1718 return 0;
1719 default:
1720 log_fn(LOG_WARN, "Unexpected result: %d", (int)p);
1721 return 0;
1725 /** Return 0 if every setting in <b>options</b> is reasonable. Else
1726 * warn and return -1. Should have no side effects, except for
1727 * normalizing the contents of <b>options</b>. */
1728 static int
1729 options_validate(or_options_t *options)
1731 int result = 0;
1732 config_line_t *cl;
1733 addr_policy_t *addr_policy=NULL;
1735 if (options->ORPort < 0 || options->ORPort > 65535) {
1736 log(LOG_WARN, "ORPort option out of bounds.");
1737 result = -1;
1740 if (options->ORPort == 0 && options->ORListenAddress != NULL) {
1741 log(LOG_WARN, "ORPort must be defined if ORListenAddress is defined.");
1742 result = -1;
1744 if (options->DirPort == 0 && options->DirListenAddress != NULL) {
1745 log(LOG_WARN, "DirPort must be defined if DirListenAddress is defined.");
1746 result = -1;
1748 if (options->SocksPort == 0 && options->SocksListenAddress != NULL) {
1749 log(LOG_WARN, "SocksPort must be defined if SocksListenAddress is defined.");
1750 result = -1;
1753 if (validate_data_directory(options)<0) {
1754 log(LOG_WARN, "Invalid DataDirectory");
1755 result = -1;
1758 if (options->Nickname == NULL) {
1759 if (server_mode(options)) {
1760 if (!(options->Nickname = get_default_nickname()))
1761 return -1;
1762 log_fn(LOG_NOTICE, "Choosing default nickname '%s'", options->Nickname);
1764 } else {
1765 if (!is_legal_nickname(options->Nickname)) {
1766 log_fn(LOG_WARN, "Nickname '%s' is wrong length or contains illegal characters.", options->Nickname);
1767 result = -1;
1771 if (server_mode(options) && !options->ContactInfo)
1772 log_fn(LOG_NOTICE,"Your ContactInfo config option is not set. Please consider setting it, so we can contact you if your server is misconfigured or something else goes wrong.");
1774 if (normalize_log_options(options))
1775 return -1;
1777 /* Special case if no options are given. */
1778 if (!options->Logs) {
1779 config_line_append(&options->Logs, "Log", "notice stdout");
1782 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
1783 return -1;
1785 if (server_mode(options)) {
1786 /* confirm that our address isn't broken, so we can complain now */
1787 uint32_t tmp;
1788 if (resolve_my_address(options, &tmp, NULL) < 0)
1789 result = -1;
1792 if (options->SocksPort < 0 || options->SocksPort > 65535) {
1793 log(LOG_WARN, "SocksPort option out of bounds.");
1794 result = -1;
1797 if (options->SocksPort == 0 && options->ORPort == 0) {
1798 log(LOG_WARN, "SocksPort and ORPort are both undefined? Quitting.");
1799 result = -1;
1802 if (options->ControlPort < 0 || options->ControlPort > 65535) {
1803 log(LOG_WARN, "ControlPort option out of bounds.");
1804 result = -1;
1807 if (options->DirPort < 0 || options->DirPort > 65535) {
1808 log(LOG_WARN, "DirPort option out of bounds.");
1809 result = -1;
1812 if (options->StrictExitNodes &&
1813 (!options->ExitNodes || !strlen(options->ExitNodes))) {
1814 log(LOG_WARN, "StrictExitNodes set, but no ExitNodes listed.");
1817 if (options->StrictEntryNodes &&
1818 (!options->EntryNodes || !strlen(options->EntryNodes))) {
1819 log(LOG_WARN, "StrictEntryNodes set, but no EntryNodes listed.");
1822 if (options->AuthoritativeDir) {
1823 if (!options->ContactInfo) {
1824 log(LOG_WARN, "Authoritative directory servers must set ContactInfo");
1825 result = -1;
1827 if (!options->RecommendedVersions) {
1828 log(LOG_WARN, "Authoritative directory servers must configure RecommendedVersions.");
1829 result = -1;
1831 if (!options->RecommendedClientVersions)
1832 options->RecommendedClientVersions =
1833 config_lines_dup(options->RecommendedVersions);
1834 if (!options->RecommendedServerVersions)
1835 options->RecommendedServerVersions =
1836 config_lines_dup(options->RecommendedVersions);
1839 if (options->AuthoritativeDir && !options->DirPort) {
1840 log(LOG_WARN, "Running as authoritative directory, but no DirPort set.");
1841 result = -1;
1844 if (options->AuthoritativeDir && !options->ORPort) {
1845 log(LOG_WARN, "Running as authoritative directory, but no ORPort set.");
1846 result = -1;
1849 if (options->AuthoritativeDir && options->ClientOnly) {
1850 log(LOG_WARN, "Running as authoritative directory, but ClientOnly also set.");
1851 result = -1;
1854 if (options->AuthoritativeDir && options->NoPublish) {
1855 log(LOG_WARN, "You cannot set both AuthoritativeDir and NoPublish.");
1856 result = -1;
1859 if (options->ConnLimit <= 0) {
1860 log(LOG_WARN, "ConnLimit must be greater than 0, but was set to %d",
1861 options->ConnLimit);
1862 result = -1;
1865 if (options->_AccountingMaxKB) {
1866 log(LOG_WARN, "AccountingMaxKB is deprecated. Say 'AccountingMax %d KB' instead.", options->_AccountingMaxKB);
1867 options->AccountingMax = U64_LITERAL(1024)*options->_AccountingMaxKB;
1868 options->_AccountingMaxKB = 0;
1871 if (validate_ports_csv(options->FirewallPorts,
1872 "FirewallPorts") < 0)
1873 result = -1;
1875 if (validate_ports_csv(options->LongLivedPorts,
1876 "LongLivedPorts") < 0)
1877 result = -1;
1879 if (options->FascistFirewall) {
1880 smartlist_t *instead = smartlist_create();
1881 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
1882 new_line->key = tor_strdup("ReachableAddresses");
1883 /* If we're configured with the old format, we need to prepend some
1884 * open ports. */
1885 if (!smartlist_len(options->FirewallPorts)) {
1886 smartlist_add(options->FirewallPorts, tor_strdup("80"));
1887 smartlist_add(options->FirewallPorts, tor_strdup("443"));
1889 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
1891 int p = atoi(portno);
1892 char *s;
1893 if (p<0) continue;
1894 s = tor_malloc(16);
1895 tor_snprintf(s, 16, "*:%d", p);
1896 smartlist_add(instead, s);
1898 new_line->value = smartlist_join_strings(instead,",",0,NULL);
1899 /* These have been deprecated since 0.1.1.5-alpha-cvs */
1900 log_fn(LOG_WARN, "FascistFirewall and FirewallPorts are deprecated. Instead, use \"ReachableAddresses %s\"", new_line->value);
1901 new_line->next = options->ReachableAddresses;
1902 options->ReachableAddresses = new_line;
1903 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
1904 smartlist_free(instead);
1907 if (options->FascistFirewall || options->ReachableAddresses) {
1908 /* We need to end with a reject *:*, not an implicit accept *:* */
1909 config_line_t **linep = &options->ReachableAddresses;
1910 while (*linep) {
1911 linep = &((*linep)->next);
1913 *linep = tor_malloc_zero(sizeof(config_line_t));
1914 (*linep)->key = tor_strdup("ReachableAddresses");
1915 (*linep)->value = tor_strdup("reject *:*");
1918 options->_AllowUnverified = 0;
1919 if (options->AllowUnverifiedNodes) {
1920 SMARTLIST_FOREACH(options->AllowUnverifiedNodes, const char *, cp, {
1921 if (!strcasecmp(cp, "entry"))
1922 options->_AllowUnverified |= ALLOW_UNVERIFIED_ENTRY;
1923 else if (!strcasecmp(cp, "exit"))
1924 options->_AllowUnverified |= ALLOW_UNVERIFIED_EXIT;
1925 else if (!strcasecmp(cp, "middle"))
1926 options->_AllowUnverified |= ALLOW_UNVERIFIED_MIDDLE;
1927 else if (!strcasecmp(cp, "introduction"))
1928 options->_AllowUnverified |= ALLOW_UNVERIFIED_INTRODUCTION;
1929 else if (!strcasecmp(cp, "rendezvous"))
1930 options->_AllowUnverified |= ALLOW_UNVERIFIED_RENDEZVOUS;
1931 else {
1932 log(LOG_WARN, "Unrecognized value '%s' in AllowUnverifiedNodes",
1933 cp);
1934 result = -1;
1939 if (options->SocksPort >= 1 &&
1940 (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) {
1941 log(LOG_WARN, "PathlenCoinWeight option must be >=0.0 and <1.0.");
1942 result = -1;
1945 #define MIN_DIR_FETCH_PERIOD 600
1946 #define MIN_REND_POST_PERIOD 300
1947 #define MIN_STATUS_FETCH_PERIOD 60
1949 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
1950 #define MAX_CACHE_DIR_FETCH_PERIOD 3600
1951 #define MAX_CACHE_STATUS_FETCH_PERIOD 900
1953 if (options->DirFetchPeriod &&
1954 options->DirFetchPeriod < MIN_DIR_FETCH_PERIOD) {
1955 log(LOG_WARN, "DirFetchPeriod option must be at least %d seconds. Clipping.", MIN_DIR_FETCH_PERIOD);
1956 options->DirFetchPeriod = MIN_DIR_FETCH_PERIOD;
1958 if (options->StatusFetchPeriod &&
1959 options->StatusFetchPeriod < MIN_STATUS_FETCH_PERIOD) {
1960 log(LOG_WARN, "StatusFetchPeriod option must be at least %d seconds. Clipping.", MIN_STATUS_FETCH_PERIOD);
1961 options->StatusFetchPeriod = MIN_STATUS_FETCH_PERIOD;
1963 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
1964 log(LOG_WARN,"RendPostPeriod option must be at least %d seconds. Clipping.",
1965 MIN_REND_POST_PERIOD);
1966 options->RendPostPeriod = MIN_REND_POST_PERIOD;
1969 if (options->DirPort && ! options->AuthoritativeDir) {
1970 if (options->DirFetchPeriod > MAX_CACHE_DIR_FETCH_PERIOD) {
1971 log(LOG_WARN, "Caching directory servers must have DirFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_DIR_FETCH_PERIOD);
1972 options->DirFetchPeriod = MAX_CACHE_DIR_FETCH_PERIOD;
1974 if (options->StatusFetchPeriod > MAX_CACHE_STATUS_FETCH_PERIOD) {
1975 log(LOG_WARN, "Caching directory servers must have StatusFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_STATUS_FETCH_PERIOD);
1976 options->StatusFetchPeriod = MAX_CACHE_STATUS_FETCH_PERIOD;
1980 if (options->DirFetchPeriod > MAX_DIR_PERIOD) {
1981 log(LOG_WARN, "DirFetchPeriod is too large; clipping to %ds.", MAX_DIR_PERIOD);
1982 options->DirFetchPeriod = MAX_DIR_PERIOD;
1984 if (options->StatusFetchPeriod > MAX_DIR_PERIOD) {
1985 log(LOG_WARN, "StatusFetchPeriod is too large; clipping to %ds.", MAX_DIR_PERIOD);
1986 options->StatusFetchPeriod = MAX_DIR_PERIOD;
1988 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
1989 log(LOG_WARN, "RendPostPeriod is too large; clipping to %ds.", MAX_DIR_PERIOD);
1990 options->RendPostPeriod = MAX_DIR_PERIOD;
1993 if (options->KeepalivePeriod < 1) {
1994 log(LOG_WARN,"KeepalivePeriod option must be positive.");
1995 result = -1;
1998 if (options->BandwidthRate > INT_MAX) {
1999 log(LOG_WARN,"BandwidthRate must be less than %d",INT_MAX);
2000 result = -1;
2002 if (options->BandwidthBurst > INT_MAX) {
2003 log(LOG_WARN,"BandwidthBurst must be less than %d",INT_MAX);
2004 result = -1;
2006 if (server_mode(options) &&
2007 options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
2008 log(LOG_WARN,"BandwidthRate is set to %d bytes/second. For servers, it must be at least %d.", (int)options->BandwidthRate, ROUTER_REQUIRED_MIN_BANDWIDTH*2);
2009 result = -1;
2011 if (options->BandwidthRate > options->BandwidthBurst) {
2012 log(LOG_WARN,"BandwidthBurst must be at least equal to BandwidthRate.");
2013 result = -1;
2016 if (accounting_parse_options(options, 1)<0) {
2017 result = -1;
2020 if (options->HttpProxy) { /* parse it now */
2021 if (parse_addr_port(options->HttpProxy, NULL,
2022 &options->HttpProxyAddr, &options->HttpProxyPort) < 0) {
2023 log(LOG_WARN,"HttpProxy failed to parse or resolve. Please fix.");
2024 result = -1;
2026 if (options->HttpProxyPort == 0) { /* give it a default */
2027 options->HttpProxyPort = 80;
2031 if (options->HttpProxyAuthenticator) {
2032 if (strlen(options->HttpProxyAuthenticator) >= 48) {
2033 log(LOG_WARN, "HttpProxyAuthenticator is too long (>= 48 chars).");
2034 result = -1;
2038 if (options->HttpsProxy) { /* parse it now */
2039 if (parse_addr_port(options->HttpsProxy, NULL,
2040 &options->HttpsProxyAddr, &options->HttpsProxyPort) < 0) {
2041 log(LOG_WARN,"HttpsProxy failed to parse or resolve. Please fix.");
2042 result = -1;
2044 if (options->HttpsProxyPort == 0) { /* give it a default */
2045 options->HttpsProxyPort = 443;
2049 if (options->HttpsProxyAuthenticator) {
2050 if (strlen(options->HttpsProxyAuthenticator) >= 48) {
2051 log(LOG_WARN, "HttpsProxyAuthenticator is too long (>= 48 chars).");
2052 result = -1;
2056 if (options->HashedControlPassword) {
2057 if (decode_hashed_password(NULL, options->HashedControlPassword)<0) {
2058 log_fn(LOG_WARN,"Bad HashedControlPassword: wrong length or bad encoding");
2059 result = -1;
2062 if (options->HashedControlPassword && options->CookieAuthentication) {
2063 log_fn(LOG_WARN,"Cannot enable both HashedControlPassword and CookieAuthentication");
2064 result = -1;
2067 if (options->UseHelperNodes && ! options->NumHelperNodes) {
2068 log_fn(LOG_WARN, "Cannot enable UseHelperNodes with NumHelperNodes set to 0");
2069 result = -1;
2072 if (check_nickname_list(options->ExitNodes, "ExitNodes"))
2073 result = -1;
2074 if (check_nickname_list(options->EntryNodes, "EntryNodes"))
2075 result = -1;
2076 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
2077 result = -1;
2078 if (check_nickname_list(options->RendNodes, "RendNodes"))
2079 result = -1;
2080 if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
2081 result = -1;
2082 if (check_nickname_list(options->MyFamily, "MyFamily"))
2083 result = -1;
2084 for (cl = options->NodeFamilies; cl; cl = cl->next) {
2085 if (check_nickname_list(cl->value, "NodeFamily"))
2086 result = -1;
2089 if (config_parse_addr_policy(options->ExitPolicy, &addr_policy, -1)) {
2090 log_fn(LOG_WARN, "Error in Exit Policy entry.");
2091 result = -1;
2093 options_append_default_exit_policy(&addr_policy);
2094 if (server_mode(options)) {
2095 exit_policy_implicitly_allows_local_networks(addr_policy, 1);
2097 /* The rest of these calls *append* to addr_policy. So don't actually
2098 * use the results for anything other than checking if they parse! */
2099 if (config_parse_addr_policy(options->DirPolicy, &addr_policy, -1)) {
2100 log_fn(LOG_WARN, "Error in DirPolicy entry.");
2101 result = -1;
2103 if (config_parse_addr_policy(options->SocksPolicy, &addr_policy, -1)) {
2104 log_fn(LOG_WARN, "Error in SocksPolicy entry.");
2105 result = -1;
2107 if (config_parse_addr_policy(options->ReachableAddresses, &addr_policy,
2108 ADDR_POLICY_ACCEPT)) {
2109 log_fn(LOG_WARN, "Error in ReachableAddresses entry.");
2110 result = -1;
2112 if (config_parse_addr_policy(options->AuthDirReject, &addr_policy,
2113 ADDR_POLICY_REJECT)) {
2114 log_fn(LOG_WARN, "Error in ReachableAddresses entry.");
2115 result = -1;
2117 if (config_parse_addr_policy(options->AuthDirInvalid, &addr_policy,
2118 ADDR_POLICY_REJECT)) {
2119 log_fn(LOG_WARN, "Error in ReachableAddresses entry.");
2120 result = -1;
2122 addr_policy_free(addr_policy);
2124 for (cl = options->RedirectExit; cl; cl = cl->next) {
2125 if (parse_redirect_line(NULL, cl)<0)
2126 result = -1;
2129 if (!options->DirServers) {
2130 add_default_trusted_dirservers(options);
2131 } else {
2132 log_fn(LOG_WARN, "You have used DirServer to specify directory authorities in your configuration. This is potentially dangerous: it can make you look different from all other Tor users, and hurt your anonymity. Even if you've specified the same authorities as Tor uses by default, the defaults could change in the future. Be sure you know what you're doing.");
2133 for (cl = options->DirServers; cl; cl = cl->next) {
2134 if (parse_dir_server_line(cl->value, 1)<0)
2135 result = -1;
2139 if (rend_config_services(options, 1) < 0)
2140 result = -1;
2142 return result;
2145 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
2146 * equal strings. */
2147 static int
2148 opt_streq(const char *s1, const char *s2)
2150 if (!s1 && !s2)
2151 return 1;
2152 else if (s1 && s2 && !strcmp(s1,s2))
2153 return 1;
2154 else
2155 return 0;
2158 /** Check if any of the previous options have changed but aren't allowed to. */
2159 static int
2160 options_transition_allowed(or_options_t *old, or_options_t *new_val)
2162 if (!old)
2163 return 0;
2165 if (!opt_streq(old->PidFile, new_val->PidFile)) {
2166 log_fn(LOG_WARN,"PidFile is not allowed to change. Failing.");
2167 return -1;
2170 if (old->RunAsDaemon != new_val->RunAsDaemon) {
2171 log_fn(LOG_WARN,"While Tor is running, changing RunAsDaemon is not allowed. Failing.");
2172 return -1;
2175 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
2176 log_fn(LOG_WARN,"While Tor is running, changing DataDirectory (\"%s\"->\"%s\") is not allowed. Failing.", old->DataDirectory, new_val->DataDirectory);
2177 return -1;
2180 if (!opt_streq(old->User, new_val->User)) {
2181 log_fn(LOG_WARN,"While Tor is running, changing User is not allowed. Failing.");
2182 return -1;
2185 if (!opt_streq(old->Group, new_val->Group)) {
2186 log_fn(LOG_WARN,"While Tor is running, changing Group is not allowed. Failing.");
2187 return -1;
2190 if (old->HardwareAccel != new_val->HardwareAccel) {
2191 log_fn(LOG_WARN,"While Tor is running, changing HardwareAccel is not allowed. Failing.");
2192 return -1;
2195 return 0;
2198 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2199 * will require us to rotate the cpu and dns workers; else return 0. */
2200 static int
2201 options_transition_affects_workers(or_options_t *old_options,
2202 or_options_t *new_options)
2204 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2205 old_options->NumCpus != new_options->NumCpus ||
2206 old_options->ORPort != new_options->ORPort ||
2207 old_options->SafeLogging != new_options->SafeLogging ||
2208 !config_lines_eq(old_options->Logs, new_options->Logs))
2209 return 1;
2211 /* Check whether log options match. */
2213 /* Nothing that changed matters. */
2214 return 0;
2217 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2218 * will require us to generate a new descriptor; else return 0. */
2219 static int
2220 options_transition_affects_descriptor(or_options_t *old_options,
2221 or_options_t *new_options)
2223 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2224 !opt_streq(old_options->Nickname,new_options->Nickname) ||
2225 !opt_streq(old_options->Address,new_options->Address) ||
2226 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
2227 old_options->ORPort != new_options->ORPort ||
2228 old_options->DirPort != new_options->DirPort ||
2229 old_options->ClientOnly != new_options->ClientOnly ||
2230 old_options->NoPublish != new_options->NoPublish ||
2231 old_options->BandwidthRate != new_options->BandwidthRate ||
2232 old_options->BandwidthBurst != new_options->BandwidthBurst ||
2233 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
2234 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
2235 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
2236 old_options->AccountingMax != new_options->AccountingMax)
2237 return 1;
2239 return 0;
2242 #ifdef MS_WINDOWS
2243 /** Return the directory on windows where we expect to find our application
2244 * data. */
2245 static char *
2246 get_windows_conf_root(void)
2248 static int is_set = 0;
2249 static char path[MAX_PATH+1];
2251 LPITEMIDLIST idl;
2252 IMalloc *m;
2253 HRESULT result;
2255 if (is_set)
2256 return path;
2258 /* Find X:\documents and settings\username\application data\ .
2259 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
2261 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
2262 &idl))) {
2263 GetCurrentDirectory(MAX_PATH, path);
2264 is_set = 1;
2265 log_fn(LOG_WARN, "I couldn't find your application data folder: are you running an ancient version of Windows 95? Defaulting to \"%s\"", path);
2266 return path;
2268 /* Convert the path from an "ID List" (whatever that is!) to a path. */
2269 result = SHGetPathFromIDList(idl, path);
2270 /* Now we need to free the */
2271 SHGetMalloc(&m);
2272 if (m) {
2273 m->lpVtbl->Free(m, idl);
2274 m->lpVtbl->Release(m);
2276 if (!SUCCEEDED(result)) {
2277 return NULL;
2279 strlcat(path,"\\tor",MAX_PATH);
2280 is_set = 1;
2281 return path;
2283 #endif
2285 /** Return the default location for our torrc file. */
2286 static const char *
2287 get_default_conf_file(void)
2289 #ifdef MS_WINDOWS
2290 static char path[MAX_PATH+1];
2291 strlcpy(path, get_windows_conf_root(), MAX_PATH);
2292 strlcat(path,"\\torrc",MAX_PATH);
2293 return path;
2294 #else
2295 return (CONFDIR "/torrc");
2296 #endif
2299 /** Verify whether lst is a string containing valid-looking space-separated
2300 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
2302 static int
2303 check_nickname_list(const char *lst, const char *name)
2305 int r = 0;
2306 smartlist_t *sl;
2308 if (!lst)
2309 return 0;
2310 sl = smartlist_create();
2311 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2312 SMARTLIST_FOREACH(sl, const char *, s,
2314 if (!is_legal_nickname_or_hexdigest(s)) {
2315 log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
2316 r = -1;
2319 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
2320 smartlist_free(sl);
2321 return r;
2324 /** Read a configuration file into <b>options</b>, finding the configuration
2325 * file location based on the command line. After loading the options,
2326 * validate them for consistency, then take actions based on them.
2327 * Return 0 if success, -1 if failure. */
2329 options_init_from_torrc(int argc, char **argv)
2331 or_options_t *oldoptions, *newoptions;
2332 config_line_t *cl;
2333 char *cf=NULL, *fname=NULL;
2334 int i, retval;
2335 int using_default_torrc;
2336 static char **backup_argv;
2337 static int backup_argc;
2339 if (argv) { /* first time we're called. save commandline args */
2340 backup_argv = argv;
2341 backup_argc = argc;
2342 oldoptions = NULL;
2343 } else { /* we're reloading. need to clean up old options first. */
2344 argv = backup_argv;
2345 argc = backup_argc;
2346 oldoptions = get_options();
2348 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
2349 print_usage();
2350 exit(0);
2353 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
2354 printf("Tor version %s.\n",VERSION);
2355 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
2356 print_cvs_version();
2358 exit(0);
2361 newoptions = tor_malloc_zero(sizeof(or_options_t));
2362 newoptions->_magic = OR_OPTIONS_MAGIC;
2363 options_init(newoptions);
2365 /* learn config file name */
2366 fname = NULL;
2367 using_default_torrc = 1;
2368 newoptions->command = CMD_RUN_TOR;
2369 for (i = 1; i < argc; ++i) {
2370 if (i < argc-1 && !strcmp(argv[i],"-f")) {
2371 if (fname) {
2372 log(LOG_WARN, "Duplicate -f options on command line.");
2373 tor_free(fname);
2375 fname = tor_strdup(argv[i+1]);
2376 using_default_torrc = 0;
2377 ++i;
2378 } else if (!strcmp(argv[i],"--list-fingerprint")) {
2379 newoptions->command = CMD_LIST_FINGERPRINT;
2380 } else if (!strcmp(argv[i],"--hash-password")) {
2381 newoptions->command = CMD_HASH_PASSWORD;
2382 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
2383 ++i;
2384 } else if (!strcmp(argv[i],"--verify-config")) {
2385 newoptions->command = CMD_VERIFY_CONFIG;
2388 if (using_default_torrc) {
2389 /* didn't find one, try CONFDIR */
2390 const char *dflt = get_default_conf_file();
2391 char *fn = NULL;
2392 if (dflt && file_status(dflt) == FN_FILE) {
2393 fname = tor_strdup(dflt);
2394 } else {
2395 #ifndef MS_WINDOWS
2396 fn = expand_filename("~/.torrc");
2397 if (fn && file_status(fn) == FN_FILE) {
2398 fname = fn;
2399 } else {
2400 tor_free(fn);
2401 fname = tor_strdup(dflt);
2403 #else
2404 fname = tor_strdup(dflt);
2405 #endif
2408 tor_assert(fname);
2409 log(LOG_DEBUG, "Opening config file \"%s\"", fname);
2411 /* get config lines, assign them */
2412 if (file_status(fname) != FN_FILE ||
2413 !(cf = read_file_to_str(fname,0))) {
2414 if (using_default_torrc == 1) {
2415 log(LOG_NOTICE, "Configuration file \"%s\" not present, "
2416 "using reasonable defaults.", fname);
2417 tor_free(fname); /* sets fname to NULL */
2418 } else {
2419 log(LOG_WARN, "Unable to open configuration file \"%s\".", fname);
2420 tor_free(fname);
2421 goto err;
2423 } else { /* it opened successfully. use it. */
2424 retval = config_get_lines(cf, &cl);
2425 tor_free(cf);
2426 if (retval < 0)
2427 goto err;
2428 retval = config_assign(&options_format, newoptions, cl, 0, 0);
2429 config_free_lines(cl);
2430 if (retval < 0)
2431 goto err;
2434 /* Go through command-line variables too */
2435 if (config_get_commandlines(argc, argv, &cl) < 0)
2436 goto err;
2437 retval = config_assign(&options_format, newoptions, cl, 0, 0);
2438 config_free_lines(cl);
2439 if (retval < 0)
2440 goto err;
2442 /* Validate newoptions */
2443 if (options_validate(newoptions) < 0)
2444 goto err;
2446 if (options_transition_allowed(oldoptions, newoptions) < 0)
2447 goto err;
2449 if (set_options(newoptions))
2450 goto err; /* frees and replaces old options */
2451 tor_free(torrc_fname);
2452 torrc_fname = fname;
2453 return 0;
2454 err:
2455 tor_free(fname);
2456 config_free(&options_format, newoptions);
2457 return -1;
2460 /** Return the location for our configuration file.
2462 const char *
2463 get_torrc_fname(void)
2465 if (torrc_fname)
2466 return torrc_fname;
2467 else
2468 return get_default_conf_file();
2471 /** Adjust the address map mased on the MapAddress elements in the
2472 * configuration <b>options</b>
2474 static void
2475 config_register_addressmaps(or_options_t *options)
2477 smartlist_t *elts;
2478 config_line_t *opt;
2479 char *from, *to;
2481 addressmap_clear_configured();
2482 elts = smartlist_create();
2483 for (opt = options->AddressMap; opt; opt = opt->next) {
2484 smartlist_split_string(elts, opt->value, NULL,
2485 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
2486 if (smartlist_len(elts) >= 2) {
2487 from = smartlist_get(elts,0);
2488 to = smartlist_get(elts,1);
2489 if (!is_plausible_address(from)) {
2490 log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",from);
2491 } else if (!is_plausible_address(to)) {
2492 log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",to);
2493 } else {
2494 addressmap_register(from, tor_strdup(to), 0);
2495 if (smartlist_len(elts)>2) {
2496 log_fn(LOG_WARN,"Ignoring extra arguments to MapAddress.");
2499 } else {
2500 log_fn(LOG_WARN,"MapAddress '%s' has too few arguments. Ignoring.", opt->value);
2502 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
2503 smartlist_clear(elts);
2505 smartlist_free(elts);
2508 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
2509 * recognized log severity levels, set *<b>min_out</b> to MIN and
2510 * *<b>max_out</b> to MAX and return 0. Else, if <b>range</b> is of
2511 * the form MIN, act as if MIN-err had been specified. Else, warn and
2512 * return -1.
2514 static int
2515 parse_log_severity_range(const char *range, int *min_out, int *max_out)
2517 int levelMin, levelMax;
2518 const char *cp;
2519 cp = strchr(range, '-');
2520 if (cp) {
2521 if (cp == range) {
2522 levelMin = LOG_DEBUG;
2523 } else {
2524 char *tmp_sev = tor_strndup(range, cp - range);
2525 levelMin = parse_log_level(tmp_sev);
2526 if (levelMin < 0) {
2527 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
2528 "err|warn|notice|info|debug", tmp_sev);
2529 tor_free(tmp_sev);
2530 return -1;
2532 tor_free(tmp_sev);
2534 if (!*(cp+1)) {
2535 levelMax = LOG_ERR;
2536 } else {
2537 levelMax = parse_log_level(cp+1);
2538 if (levelMax < 0) {
2539 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
2540 "err|warn|notice|info|debug", cp+1);
2541 return -1;
2544 } else {
2545 levelMin = parse_log_level(range);
2546 if (levelMin < 0) {
2547 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
2548 "err|warn|notice|info|debug", range);
2549 return -1;
2551 levelMax = LOG_ERR;
2554 *min_out = levelMin;
2555 *max_out = levelMax;
2557 return 0;
2560 /** Try to convert a pair of old-style logging options [LogLevel, and
2561 * (LogFile/Syslog)] to a new-style option, and add the new option to
2562 * options->Logs. */
2563 static int
2564 convert_log_option(or_options_t *options, config_line_t *level_opt,
2565 config_line_t *file_opt, int isDaemon)
2567 int levelMin = -1, levelMax = -1;
2569 if (level_opt) {
2570 if (parse_log_severity_range(level_opt->value, &levelMin, &levelMax))
2571 return -1;
2573 if (levelMin < 0 && levelMax < 0) {
2574 levelMin = LOG_NOTICE;
2575 levelMax = LOG_ERR;
2576 } else if (levelMin < 0) {
2577 levelMin = levelMax;
2578 } else {
2579 levelMax = LOG_ERR;
2582 if (file_opt && !strcasecmp(file_opt->key, "LogFile")) {
2583 if (add_single_log_option(options, levelMin, levelMax, "file", file_opt->value) < 0) {
2584 log_fn(LOG_WARN, "Cannot write to LogFile \"%s\": %s.", file_opt->value,
2585 strerror(errno));
2586 return -1;
2588 } else if (file_opt && !strcasecmp(file_opt->key, "SysLog")) {
2589 if (add_single_log_option(options, levelMin, levelMax, "syslog", NULL) < 0)
2590 return -1;
2591 } else if (!isDaemon) {
2592 add_single_log_option(options, levelMin, levelMax, "stdout", NULL);
2594 return 0;
2598 * Initialize the logs based on the configuration file.
2601 options_init_logs(or_options_t *options, int validate_only)
2603 config_line_t *opt;
2604 int ok;
2605 smartlist_t *elts;
2607 ok = 1;
2608 elts = smartlist_create();
2609 for (opt = options->Logs; opt; opt = opt->next) {
2610 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
2611 smartlist_split_string(elts, opt->value, NULL,
2612 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
2613 if (smartlist_len(elts) == 0) {
2614 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
2615 ok = 0; goto cleanup;
2617 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin, &levelMax)) {
2618 ok = 0; goto cleanup;
2620 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
2621 if (!validate_only)
2622 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
2623 goto cleanup;
2625 if (!strcasecmp(smartlist_get(elts,1), "file")) {
2626 if (smartlist_len(elts) != 3) {
2627 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
2628 ok = 0; goto cleanup;
2630 if (!validate_only)
2631 add_file_log(levelMin, levelMax, smartlist_get(elts, 2));
2632 goto cleanup;
2634 if (smartlist_len(elts) != 2) {
2635 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
2636 ok = 0; goto cleanup;
2638 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
2639 if (!validate_only) {
2640 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
2641 close_temp_logs();
2643 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
2644 if (!validate_only) {
2645 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
2646 close_temp_logs();
2648 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
2649 #ifdef HAVE_SYSLOG_H
2650 if (!validate_only)
2651 add_syslog_log(levelMin, levelMax);
2652 #else
2653 log_fn(LOG_WARN, "Syslog is not supported in this compilation.");
2654 #endif
2655 } else {
2656 log_fn(LOG_WARN, "Unrecognized log type %s",
2657 (const char*)smartlist_get(elts,1));
2658 if (strchr(smartlist_get(elts,1), '/')) {
2659 log_fn(LOG_WARN, "Did you mean to say 'Log file %s' ?",
2660 (const char *)smartlist_get(elts,1));
2662 ok = 0; goto cleanup;
2664 cleanup:
2665 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
2666 smartlist_clear(elts);
2668 smartlist_free(elts);
2669 if (!validate_only)
2670 close_temp_logs();
2672 return ok?0:-1;
2675 /** Add a single option of the form Log min-max \<type\> [fname] to options. */
2676 static int
2677 add_single_log_option(or_options_t *options, int minSeverity, int maxSeverity,
2678 const char *type, const char *fname)
2680 char buf[512];
2681 int n;
2683 n = tor_snprintf(buf, sizeof(buf), "%s%s%s %s%s%s",
2684 log_level_to_string(minSeverity),
2685 maxSeverity == LOG_ERR ? "" : "-",
2686 maxSeverity == LOG_ERR ? "" : log_level_to_string(maxSeverity),
2687 type, fname?" ":"", fname?fname:"");
2688 if (n<0) {
2689 log_fn(LOG_WARN, "Normalized log option too long.");
2690 return -1;
2693 log(LOG_WARN, "The old LogLevel/LogFile/DebugLogFile/SysLog options are deprecated, and will go away soon. Your new torrc line should be: 'Log %s'", buf);
2694 config_line_append(&options->Logs, "Log", buf);
2695 return 0;
2698 /** Convert all old-style logging options to new-style Log options. Return 0
2699 * on success, -1 on failure. */
2700 static int
2701 normalize_log_options(or_options_t *options)
2703 /* The order of options is: Level? (File Level?)+
2705 config_line_t *opt = options->OldLogOptions;
2707 /* Special case for if first option is LogLevel. */
2708 if (opt && !strcasecmp(opt->key, "LogLevel")) {
2709 if (opt->next && (!strcasecmp(opt->next->key, "LogFile") ||
2710 !strcasecmp(opt->next->key, "SysLog"))) {
2711 if (convert_log_option(options, opt, opt->next, options->RunAsDaemon) < 0)
2712 return -1;
2713 opt = opt->next->next;
2714 } else if (!opt->next) {
2715 if (convert_log_option(options, opt, NULL, options->RunAsDaemon) < 0)
2716 return -1;
2717 opt = opt->next;
2718 } else {
2719 ; /* give warning below */
2723 while (opt) {
2724 if (!strcasecmp(opt->key, "LogLevel")) {
2725 log_fn(LOG_WARN, "Two LogLevel options in a row without intervening LogFile or SysLog");
2726 opt = opt->next;
2727 } else {
2728 tor_assert(!strcasecmp(opt->key, "LogFile") ||
2729 !strcasecmp(opt->key, "SysLog"));
2730 if (opt->next && !strcasecmp(opt->next->key, "LogLevel")) {
2731 /* LogFile/SysLog followed by LogLevel */
2732 if (convert_log_option(options,opt->next,opt, options->RunAsDaemon) < 0)
2733 return -1;
2734 opt = opt->next->next;
2735 } else {
2736 /* LogFile/SysLog followed by LogFile/SysLog or end of list. */
2737 if (convert_log_option(options,NULL, opt, options->RunAsDaemon) < 0)
2738 return -1;
2739 opt = opt->next;
2744 if (options->DebugLogFile) {
2745 if (add_single_log_option(options, LOG_DEBUG, LOG_ERR, "file", options->DebugLogFile) < 0)
2746 return -1;
2749 tor_free(options->DebugLogFile);
2750 config_free_lines(options->OldLogOptions);
2751 options->OldLogOptions = NULL;
2753 return 0;
2756 #define DEFAULT_EXIT_POLICY "reject 0.0.0.0/8,reject 169.254.0.0/16,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:465,reject *:587,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*"
2758 /** Add the default exit policy entries to <b>policy</b>
2760 void
2761 options_append_default_exit_policy(addr_policy_t **policy)
2763 config_line_t tmp;
2764 addr_policy_t *ap;
2766 tmp.key = NULL;
2767 tmp.value = (char*)DEFAULT_EXIT_POLICY;
2768 tmp.next = NULL;
2769 config_parse_addr_policy(&tmp, policy, -1);
2771 /* Remove redundant parts, if any. */
2772 for (ap=*policy; ap; ap=ap->next) {
2773 if (ap->msk == 0 && ap->prt_min <= 1 && ap->prt_max >= 65535) {
2774 if (ap->next) {
2775 addr_policy_free(ap->next);
2776 ap->next = NULL;
2778 return;
2784 * Given a linked list of config lines containing "allow" and "deny" tokens,
2785 * parse them and append the result to <b>dest</b>. Return -1 if any tokens
2786 * are malformed, else return 0.
2789 config_parse_addr_policy(config_line_t *cfg,
2790 addr_policy_t **dest,
2791 int assume_action)
2793 addr_policy_t **nextp;
2794 smartlist_t *entries;
2795 int r = 0;
2797 if (!cfg)
2798 return 0;
2800 nextp = dest;
2802 while (*nextp)
2803 nextp = &((*nextp)->next);
2805 entries = smartlist_create();
2806 for (; cfg; cfg = cfg->next) {
2807 smartlist_split_string(entries, cfg->value, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2808 SMARTLIST_FOREACH(entries, const char *, ent,
2810 log_fn(LOG_DEBUG,"Adding new entry '%s'",ent);
2811 *nextp = router_parse_addr_policy_from_string(ent, assume_action);
2812 if (*nextp) {
2813 nextp = &((*nextp)->next);
2814 } else {
2815 log_fn(LOG_WARN,"Malformed policy '%s'.", ent);
2816 r = -1;
2819 SMARTLIST_FOREACH(entries, char *, ent, tor_free(ent));
2820 smartlist_clear(entries);
2822 smartlist_free(entries);
2823 return r;
2826 /** Compare two provided address policies, and return -1, 0, or 1 if the first
2827 * is less than, equal to, or greater than the second. */
2829 config_cmp_addr_policies(addr_policy_t *a, addr_policy_t *b)
2831 int r;
2832 while (a && b) {
2833 if ((r=((int)a->addr - (int)b->addr)))
2834 return r;
2835 if ((r=((int)a->msk - (int)b->msk)))
2836 return r;
2837 if ((r=((int)a->prt_min - (int)b->prt_min)))
2838 return r;
2839 if ((r=((int)a->prt_max - (int)b->prt_max)))
2840 return r;
2841 a = a->next;
2842 b = b->next;
2844 if (!a && !b)
2845 return 0;
2846 if (a)
2847 return -1;
2848 else
2849 return 1;
2852 /** Release all storage held by <b>p</b> */
2853 void
2854 addr_policy_free(addr_policy_t *p)
2856 addr_policy_t *e;
2858 while (p) {
2859 e = p;
2860 p = p->next;
2861 tor_free(e->string);
2862 tor_free(e);
2866 /** Parse a single RedirectExit line's contents from <b>line</b>. If
2867 * they are valid, and <b>result</b> is not NULL, add an element to
2868 * <b>result</b> and return 0. Else if they are valid, return 0.
2869 * Else return -1. */
2870 static int
2871 parse_redirect_line(smartlist_t *result, config_line_t *line)
2873 smartlist_t *elements = NULL;
2874 exit_redirect_t *r;
2876 tor_assert(line);
2878 r = tor_malloc_zero(sizeof(exit_redirect_t));
2879 elements = smartlist_create();
2880 smartlist_split_string(elements, line->value, NULL,
2881 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2882 if (smartlist_len(elements) != 2) {
2883 log_fn(LOG_WARN, "Wrong number of elements in RedirectExit line");
2884 goto err;
2886 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
2887 &r->port_min,&r->port_max)) {
2888 log_fn(LOG_WARN, "Error parsing source address in RedirectExit line");
2889 goto err;
2891 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
2892 r->is_redirect = 0;
2893 } else {
2894 if (parse_addr_port(smartlist_get(elements,1),NULL,&r->addr_dest,
2895 &r->port_dest)) {
2896 log_fn(LOG_WARN, "Error parsing dest address in RedirectExit line");
2897 goto err;
2899 r->is_redirect = 1;
2902 goto done;
2903 err:
2904 tor_free(r);
2905 done:
2906 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2907 smartlist_free(elements);
2908 if (r) {
2909 if (result)
2910 smartlist_add(result, r);
2911 else
2912 tor_free(r);
2913 return 0;
2914 } else {
2915 return -1;
2919 /** Read the contents of a DirServer line from <b>line</b>. Return 0
2920 * if the line is well-formed, and -1 if it isn't. If
2921 * <b>validate_only</b> is 0, and the line is well-formed, then add
2922 * the dirserver described in the line as a valid server. */
2923 static int
2924 parse_dir_server_line(const char *line, int validate_only)
2926 smartlist_t *items = NULL;
2927 int r, idx;
2928 char *addrport, *address=NULL, *nickname=NULL, *fingerprint=NULL;
2929 uint16_t port;
2930 char digest[DIGEST_LEN];
2931 int supports_v1 = 1; /*XXXX011 change default when clients support v2. */
2933 items = smartlist_create();
2934 smartlist_split_string(items, line, NULL,
2935 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
2936 if (smartlist_len(items) < 2) {
2939 idx = 0;
2940 if (is_legal_nickname(smartlist_get(items, 0))) {
2941 nickname = smartlist_get(items, 0);
2942 smartlist_del_keeporder(items, 0);
2945 if (!strcmp(smartlist_get(items, 0), "v1")) {
2946 char *v1 = smartlist_get(items, 0);
2947 tor_free(v1);
2948 supports_v1 = 1;
2949 smartlist_del_keeporder(items, 0);
2952 if (smartlist_len(items) < 2) {
2953 log_fn(LOG_WARN, "Too few arguments to DirServer line.");
2954 goto err;
2956 addrport = smartlist_get(items, 0);
2957 if (parse_addr_port(addrport, &address, NULL, &port)<0) {
2958 log_fn(LOG_WARN, "Error parsing DirServer address '%s'", addrport);
2959 goto err;
2961 if (!port) {
2962 log_fn(LOG_WARN, "Missing port in DirServer address '%s'",addrport);
2963 goto err;
2965 smartlist_del_keeporder(items, 0);
2967 fingerprint = smartlist_join_strings(items, "", 0, NULL);
2968 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
2969 log_fn(LOG_WARN, "Key digest for DirServer is wrong length.");
2970 goto err;
2972 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
2973 log_fn(LOG_WARN, "Unable to decode DirServer key digest.");
2974 goto err;
2977 if (!validate_only) {
2978 log_fn(LOG_DEBUG, "Trusted dirserver at %s:%d (%s)", address, (int)port,
2979 (char*)smartlist_get(items,1));
2980 add_trusted_dir_server(nickname, address, port, digest, supports_v1);
2983 r = 0;
2984 goto done;
2986 err:
2987 r = -1;
2989 done:
2990 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
2991 smartlist_free(items);
2992 tor_free(address);
2993 tor_free(nickname);
2994 tor_free(fingerprint);
2995 return r;
2998 /** Adjust the value of options->DataDirectory, or fill it in if it's
2999 * absent. Return 0 on success, -1 on failure. */
3000 static int
3001 normalize_data_directory(or_options_t *options)
3003 #ifdef MS_WINDOWS
3004 char *p;
3005 if (options->DataDirectory)
3006 return 0; /* all set */
3007 p = tor_malloc(MAX_PATH);
3008 strlcpy(p,get_windows_conf_root(),MAX_PATH);
3009 options->DataDirectory = p;
3010 return 0;
3011 #else
3012 const char *d = options->DataDirectory;
3013 if (!d)
3014 d = "~/.tor";
3016 if (strncmp(d,"~/",2) == 0) {
3017 char *fn = expand_filename(d);
3018 if (!fn) {
3019 log_fn(LOG_ERR,"Failed to expand filename \"%s\".", d);
3020 return -1;
3022 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
3023 /* If our homedir is /, we probably don't want to use it. */
3024 /* XXXX Default to /var/lib/tor? */
3025 log_fn(LOG_WARN, "Default DataDirectory is \"~/.tor\". This expands to \"%s\", which is probably not what you want. Using \"%s/tor\" instead", fn, LOCALSTATEDIR);
3026 tor_free(fn);
3027 fn = tor_strdup(LOCALSTATEDIR"/tor");
3030 tor_free(options->DataDirectory);
3031 options->DataDirectory = fn;
3033 return 0;
3034 #endif
3037 /** Check and normalize the value of options->DataDirectory; return 0 if it
3038 * sane, -1 otherwise. */
3039 static int
3040 validate_data_directory(or_options_t *options)
3042 if (normalize_data_directory(options) < 0)
3043 return -1;
3044 tor_assert(options->DataDirectory);
3045 if (strlen(options->DataDirectory) > (512-128)) {
3046 log_fn(LOG_ERR, "DataDirectory is too long.");
3047 return -1;
3049 return 0;
3052 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; if you edit it, comments will not be preserved"
3054 /** Save a configuration file for the configuration in <b>options</b>
3055 * into the file <b>fname</b>. If the file already exists, and
3056 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
3057 * replace it. Return 0 on success, -1 on failure. */
3058 static int
3059 write_configuration_file(const char *fname, or_options_t *options)
3061 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
3062 int rename_old = 0, r;
3063 size_t len;
3065 if (fname) {
3066 switch (file_status(fname)) {
3067 case FN_FILE:
3068 old_val = read_file_to_str(fname, 0);
3069 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
3070 rename_old = 1;
3072 tor_free(old_val);
3073 break;
3074 case FN_NOENT:
3075 break;
3076 default:
3077 log_fn(LOG_WARN,"Config file \"%s\" is not a file? Failing.", fname);
3078 return -1;
3082 if (!(new_conf = options_dump(options, 1))) {
3083 log_fn(LOG_WARN, "Couldn't get configuration string");
3084 goto err;
3087 len = strlen(new_conf)+128;
3088 new_val = tor_malloc(len);
3089 tor_snprintf(new_val, len, "%s\n\n%s", GENERATED_FILE_PREFIX, new_conf);
3091 if (rename_old) {
3092 int i = 1;
3093 size_t fn_tmp_len = strlen(fname)+32;
3094 char *fn_tmp;
3095 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
3096 fn_tmp = tor_malloc(fn_tmp_len);
3097 while (1) {
3098 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
3099 log_fn(LOG_WARN, "tor_snprintf failed inexplicably");
3100 tor_free(fn_tmp);
3101 goto err;
3103 if (file_status(fn_tmp) == FN_NOENT)
3104 break;
3105 ++i;
3107 log_fn(LOG_NOTICE, "Renaming old configuration file to \"%s\"", fn_tmp);
3108 rename(fname, fn_tmp);
3109 tor_free(fn_tmp);
3112 write_str_to_file(fname, new_val, 0);
3114 r = 0;
3115 goto done;
3116 err:
3117 r = -1;
3118 done:
3119 tor_free(new_val);
3120 tor_free(new_conf);
3121 return r;
3125 * Save the current configuration file value to disk. Return 0 on
3126 * success, -1 on failure.
3129 options_save_current(void)
3131 if (torrc_fname) {
3132 /* XXX This fails if we can't write to our configuration file.
3133 * Arguably, we should try falling back to datadirectory or something.
3134 * But just as arguably, we shouldn't. */
3135 return write_configuration_file(torrc_fname, get_options());
3137 return write_configuration_file(get_default_conf_file(), get_options());
3140 /** Mapping from a unit name to a multiplier for converting that unit into a
3141 * base unit. */
3142 struct unit_table_t {
3143 const char *unit;
3144 uint64_t multiplier;
3147 static struct unit_table_t memory_units[] = {
3148 { "", 1 },
3149 { "b", 1<< 0 },
3150 { "byte", 1<< 0 },
3151 { "bytes", 1<< 0 },
3152 { "kb", 1<<10 },
3153 { "kilobyte", 1<<10 },
3154 { "kilobytes", 1<<10 },
3155 { "m", 1<<20 },
3156 { "mb", 1<<20 },
3157 { "megabyte", 1<<20 },
3158 { "megabytes", 1<<20 },
3159 { "gb", 1<<30 },
3160 { "gigabyte", 1<<30 },
3161 { "gigabytes", 1<<30 },
3162 { "tb", U64_LITERAL(1)<<40 },
3163 { "terabyte", U64_LITERAL(1)<<40 },
3164 { "terabytes", U64_LITERAL(1)<<40 },
3165 { NULL, 0 },
3168 static struct unit_table_t time_units[] = {
3169 { "", 1 },
3170 { "second", 1 },
3171 { "seconds", 1 },
3172 { "minute", 60 },
3173 { "minutes", 60 },
3174 { "hour", 60*60 },
3175 { "hours", 60*60 },
3176 { "day", 24*60*60 },
3177 { "days", 24*60*60 },
3178 { "week", 7*24*60*60 },
3179 { "weeks", 7*24*60*60 },
3180 { NULL, 0 },
3183 /** Parse a string <b>val</b> containing a number, zero or more
3184 * spaces, and an optional unit string. If the unit appears in the
3185 * table <b>u</b>, then multiply the number by the unit multiplier.
3186 * On success, set *<b>ok</b> to 1 and return this product.
3187 * Otherwise, set *<b>ok</b> to 0.
3189 static uint64_t
3190 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
3192 uint64_t v;
3193 char *cp;
3195 tor_assert(ok);
3197 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
3198 if (!*ok)
3199 return 0;
3200 if (!cp) {
3201 *ok = 1;
3202 return v;
3204 while (TOR_ISSPACE(*cp))
3205 ++cp;
3206 for ( ;u->unit;++u) {
3207 if (!strcasecmp(u->unit, cp)) {
3208 v *= u->multiplier;
3209 *ok = 1;
3210 return v;
3213 log_fn(LOG_WARN, "Unknown unit '%s'.", cp);
3214 *ok = 0;
3215 return 0;
3218 /** Parse a string in the format "number unit", where unit is a unit of
3219 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
3220 * and return the number of bytes specified. Otherwise, set
3221 * *<b>ok</b> to false and return 0. */
3222 static uint64_t
3223 config_parse_memunit(const char *s, int *ok)
3225 return config_parse_units(s, memory_units, ok);
3228 /** Parse a string in the format "number unit", where unit is a unit of time.
3229 * On success, set *<b>ok</b> to true and return the number of seconds in
3230 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
3232 static int
3233 config_parse_interval(const char *s, int *ok)
3235 uint64_t r;
3236 r = config_parse_units(s, time_units, ok);
3237 if (!ok)
3238 return -1;
3239 if (r > INT_MAX) {
3240 log_fn(LOG_WARN, "Interval '%s' is too long", s);
3241 *ok = 0;
3242 return -1;
3244 return (int)r;
3248 * Initialize the libevent library.
3250 static int
3251 init_libevent(void)
3253 configure_libevent_logging();
3254 /* If the kernel complains that some method (say, epoll) doesn't
3255 * exist, we don't care about it, since libevent will cope.
3257 suppress_libevent_log_msg("Function not implemented");
3258 #ifdef __APPLE__
3259 setenv("EVENT_NOKQUEUE","1",1);
3260 #endif
3261 event_init();
3262 suppress_libevent_log_msg(NULL);
3263 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3264 /* Making this a NOTICE for now so we can link bugs to a libevent versions
3265 * or methods better. */
3266 log(LOG_NOTICE, "Initialized libevent version %s using method %s. Good.",
3267 event_get_version(), event_get_method());
3268 check_libevent_version(event_get_method(), event_get_version(),
3269 get_options()->ORPort != 0);
3270 #else
3271 log(LOG_NOTICE, "Initialized old libevent (version 1.0b or earlier).");
3272 log(LOG_WARN, "You have a very old version of libevent. It is likely to be buggy; please consider building Tor with a more recent version.");
3273 #endif
3275 return 0;
3278 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3280 * Compare the given libevent method and version to a list of versions
3281 * which are known not to work. Warn the user as appropriate.
3284 static void
3285 check_libevent_version(const char *m, const char *v, int server)
3287 int buggy = 0, iffy = 0, slow = 0;
3289 tor_assert(m && v);
3291 if (!strcmp(m, "kqueue")) {
3292 if (!strcmp(v, "1.0c") || !strcmp(v, "1.0d") || !strcmp(v, "1.0e") ||
3293 !strcmp(v, "1.1")) {
3294 buggy = 1;
3296 } else if (!strcmp(m, "epoll")) {
3297 if (!strcmp(v, "1.0c") || !strcmp(v, "1.0d") || !strcmp(v, "1.0e"))
3298 iffy = 1;
3299 } else if (!strcmp(m, "poll")) {
3300 if (!strcmp(v, "1.0c") || !strcmp(v, "1.0d"))
3301 buggy = 1;
3302 else if (!strcmp(v, "1.0e"))
3303 slow = 1;
3304 } else if (!strcmp(m, "poll")) {
3305 if (!strcmp(v, "1.0c") || !strcmp(v, "1.0d") || !strcmp(v, "1.0e"))
3306 slow = 1;
3309 if (buggy) {
3310 log(LOG_WARN,
3311 "There are known bugs in using %s with libevent %s. "
3312 "Please use the latest version of libevent.", m, v);
3313 } else if (iffy) {
3314 log(LOG_WARN,
3315 "There are minor bugs in using %s with libevent %s. "
3316 "You may want to use the latest version of libevent.", m, v);
3317 } else if (slow && server) {
3318 log(LOG_WARN,
3319 "libevent %s can be very slow with %s. "
3320 "When running a server, please use the latest version of libevent.",v,m);
3324 #endif
3326 /* Versioning issues and state: we want to be able to understand old state
3327 * files, and not choke on new ones.
3329 * We could preserve all unrecognized variables across invocations, but we could
3330 * screw up order, if their order is significant with respect to existing
3331 * options.
3333 * We could just dump unrecognized variables if you downgrade.
3335 * This needs thought. XXXX NM
3338 /** DOCDOC */
3339 or_state_t *
3340 get_or_state(void)
3342 return global_state;
3345 /** DOCDOC */
3346 static char *
3347 get_or_state_fname(void)
3349 char *fname = NULL;
3350 or_options_t *options = get_options();
3351 size_t len = strlen(options->DataDirectory) + 16;
3352 fname = tor_malloc(len);
3353 tor_snprintf(fname, len, "%s/state", options->DataDirectory);
3354 return fname;
3357 /** DOCDOC */
3358 static int
3359 or_state_validate(or_state_t *state)
3361 const char *err;
3362 if (helper_nodes_parse_state(state, 0, &err)<0) {
3363 log_fn(LOG_WARN, "Unable to parse helper nodes: %s", err);
3364 return -1;
3366 return 0;
3369 /** DOCDOC */
3370 static void
3371 or_state_set(or_state_t *new_state)
3373 const char *err;
3374 tor_assert(new_state);
3375 if (global_state)
3376 config_free(&state_format, global_state);
3377 global_state = new_state;
3378 if (helper_nodes_parse_state(global_state, 1, &err)<0)
3379 log_fn(LOG_WARN,"Unparseable helper nodes state: %s",err);
3383 /* DOCDOC */
3385 or_state_load(void)
3387 or_state_t *new_state = NULL;
3388 char *contents = NULL, *fname;
3389 int r = -1;
3391 fname = get_or_state_fname();
3392 switch (file_status(fname)) {
3393 case FN_FILE:
3394 if (!(contents = read_file_to_str(fname, 0))) {
3395 log_fn(LOG_WARN, "Unable to read state file \"%s\"", fname);
3396 goto done;
3398 break;
3399 case FN_NOENT:
3400 break;
3401 default:
3402 log_fn(LOG_WARN,"State file \"%s\" is not a file? Failing.", fname);
3403 goto done;
3405 new_state = tor_malloc_zero(sizeof(or_state_t));
3406 new_state->_magic = OR_STATE_MAGIC;
3407 config_init(&state_format, new_state);
3408 if (contents) {
3409 config_line_t *lines=NULL;
3410 int assign_retval;
3411 if (config_get_lines(contents, &lines)<0)
3412 goto done;
3413 assign_retval = config_assign(&state_format, new_state, lines, 0, 0);
3414 config_free_lines(lines);
3415 if (assign_retval<0)
3416 goto done;
3419 if (or_state_validate(new_state) < 0)
3420 goto done;
3422 if (contents)
3423 log_fn(LOG_INFO, "Loaded state from \"%s\"", fname);
3424 else
3425 log_fn(LOG_INFO, "Initialized state");
3426 or_state_set(new_state);
3427 new_state = NULL;
3428 if (!contents) {
3429 global_state->dirty = 1;
3430 or_state_save();
3433 r = 0;
3434 done:
3435 tor_free(fname);
3436 tor_free(contents);
3437 if (new_state)
3438 config_free(&state_format, new_state);
3440 return r;
3443 /** DOCDOC */
3445 or_state_save(void)
3447 char *state, *contents;
3448 char tbuf[ISO_TIME_LEN+1];
3449 size_t len;
3450 char *fname;
3452 helper_nodes_update_state(global_state);
3454 if (!global_state->dirty)
3455 return 0;
3457 global_state->LastWritten = time(NULL);
3458 state = config_dump(&state_format, global_state, 0);
3459 len = strlen(state)+128;
3460 contents = tor_malloc(len);
3461 format_local_iso_time(tbuf, time(NULL));
3462 tor_snprintf(contents, len,
3463 "# Tor state file last generated on %s\n"
3464 "# You *do not* need to edit this file.\n\n%s",
3465 tbuf, state);
3466 tor_free(state);
3467 fname = get_or_state_fname();
3468 if (write_str_to_file(fname, contents, 0)<0) {
3469 log_fn(LOG_WARN, "Unable to write state to file \"%s\"", fname);
3470 tor_free(fname);
3471 tor_free(contents);
3472 return -1;
3474 log_fn(LOG_INFO, "Saved state to \"%s\"", fname);
3475 tor_free(fname);
3476 tor_free(contents);
3478 global_state->dirty = 0;
3479 return 0;
3482 /** DOCDOC */
3484 config_getinfo_helper(const char *question, char **answer)
3486 if (!strcmp(question, "config/names")) {
3487 smartlist_t *sl = smartlist_create();
3488 int i;
3489 for (i = 0; _option_vars[i].name; ++i) {
3490 config_var_t *var = &_option_vars[i];
3491 const char *type, *desc;
3492 char *line;
3493 size_t len;
3494 desc = config_find_description(&options_format, var->name);
3495 switch (var->type) {
3496 case CONFIG_TYPE_STRING: type = "String"; break;
3497 case CONFIG_TYPE_UINT: type = "Integer"; break;
3498 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
3499 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
3500 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
3501 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
3502 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
3503 case CONFIG_TYPE_CSV: type = "CommaList"; break;
3504 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
3505 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
3506 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
3507 default:
3508 case CONFIG_TYPE_OBSOLETE:
3509 type = NULL; break;
3511 if (!type)
3512 continue;
3513 len = strlen(var->name)+strlen(type)+16;
3514 if (desc)
3515 len += strlen(desc);
3516 line = tor_malloc(len);
3517 if (desc)
3518 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
3519 else
3520 tor_snprintf(line, len, "%s %s\n",var->name,type);
3521 smartlist_add(sl, line);
3523 *answer = smartlist_join_strings(sl, "", 0, NULL);
3524 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
3525 smartlist_free(sl);
3527 return 0;
3530 /** Dump the version of every file to the log. */
3531 static void
3532 print_cvs_version(void)
3534 extern const char aes_c_id[];
3535 extern const char compat_c_id[];
3536 extern const char container_c_id[];
3537 extern const char crypto_c_id[];
3538 extern const char log_c_id[];
3539 extern const char torgzip_c_id[];
3540 extern const char tortls_c_id[];
3541 extern const char util_c_id[];
3543 extern const char buffers_c_id[];
3544 extern const char circuitbuild_c_id[];
3545 extern const char circuitlist_c_id[];
3546 extern const char circuituse_c_id[];
3547 extern const char command_c_id[];
3548 // extern const char config_c_id[];
3549 extern const char connection_c_id[];
3550 extern const char connection_edge_c_id[];
3551 extern const char connection_or_c_id[];
3552 extern const char control_c_id[];
3553 extern const char cpuworker_c_id[];
3554 extern const char directory_c_id[];
3555 extern const char dirserv_c_id[];
3556 extern const char dns_c_id[];
3557 extern const char hibernate_c_id[];
3558 extern const char main_c_id[];
3559 extern const char onion_c_id[];
3560 extern const char relay_c_id[];
3561 extern const char rendclient_c_id[];
3562 extern const char rendcommon_c_id[];
3563 extern const char rendmid_c_id[];
3564 extern const char rendservice_c_id[];
3565 extern const char rephist_c_id[];
3566 extern const char router_c_id[];
3567 extern const char routerlist_c_id[];
3568 extern const char routerparse_c_id[];
3570 puts(AES_H_ID);
3571 puts(COMPAT_H_ID);
3572 puts(CONTAINER_H_ID);
3573 puts(CRYPTO_H_ID);
3574 puts(LOG_H_ID);
3575 puts(TORGZIP_H_ID);
3576 puts(TORINT_H_ID);
3577 puts(TORTLS_H_ID);
3578 puts(UTIL_H_ID);
3579 puts(aes_c_id);
3580 puts(compat_c_id);
3581 puts(container_c_id);
3582 puts(crypto_c_id);
3583 puts(log_c_id);
3584 puts(torgzip_c_id);
3585 puts(tortls_c_id);
3586 puts(util_c_id);
3588 puts(OR_H_ID);
3589 puts(buffers_c_id);
3590 puts(circuitbuild_c_id);
3591 puts(circuitlist_c_id);
3592 puts(circuituse_c_id);
3593 puts(command_c_id);
3594 puts(config_c_id);
3595 puts(connection_c_id);
3596 puts(connection_edge_c_id);
3597 puts(connection_or_c_id);
3598 puts(control_c_id);
3599 puts(cpuworker_c_id);
3600 puts(directory_c_id);
3601 puts(dirserv_c_id);
3602 puts(dns_c_id);
3603 puts(hibernate_c_id);
3604 puts(main_c_id);
3605 puts(onion_c_id);
3606 puts(relay_c_id);
3607 puts(rendclient_c_id);
3608 puts(rendcommon_c_id);
3609 puts(rendmid_c_id);
3610 puts(rendservice_c_id);
3611 puts(rephist_c_id);
3612 puts(router_c_id);
3613 puts(routerlist_c_id);
3614 puts(routerparse_c_id);