add geoff's NoPublish patch
[tor.git] / src / or / config.c
blob48f08e5b5fd6d144b87dd0c30932543c4cd78b6c
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
11 * \brief Code to parse and interpret configuration files.
12 **/
14 #include "or.h"
15 #ifdef MS_WINDOWS
16 #include <shlobj.h>
17 #endif
18 #include "../common/aes.h"
20 /** Enumeration of types which option values can take */
21 typedef enum config_type_t {
22 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
23 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
24 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
25 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
26 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
27 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
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 } config_abbrev_t;
46 /* Handy macro for declaring "In the config file or on the command line,
47 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
48 #define PLURAL(tok) { #tok, #tok "s", 0 }
50 /* A list of command-line abbreviations. */
51 static config_abbrev_t config_abbrevs[] = {
52 PLURAL(ExitNode),
53 PLURAL(EntryNode),
54 PLURAL(ExcludeNode),
55 PLURAL(FirewallPort),
56 PLURAL(LongLivedPort),
57 PLURAL(HiddenServiceNode),
58 PLURAL(HiddenServiceExcludeNode),
59 PLURAL(RendNode),
60 PLURAL(RendExcludeNode),
61 PLURAL(StrictEntryNode),
62 PLURAL(StrictExitNode),
63 { "l", "Log", 1},
64 { "BandwidthRateBytes", "BandwidthRate", 0},
65 { "BandwidthBurstBytes", "BandwidthBurst", 0},
66 { "DirFetchPostPeriod", "StatusFetchPeriod", 0},
67 { "MaxConn", "ConnLimit", 0},
68 { NULL, NULL , 0},
70 #undef PLURAL
72 /** A variable allowed in the configuration file or on the command line. */
73 typedef struct config_var_t {
74 const char *name; /**< The full keyword (case insensitive). */
75 config_type_t type; /**< How to interpret the type and turn it into a value. */
76 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
77 const char *initvalue; /**< String (or null) describing initial value. */
78 } config_var_t;
80 /** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */
81 #define STRUCT_OFFSET(tp, member) ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
82 /** An entry for config_vars: "The option <b>name</b> has type
83 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
84 * or_options_t.<b>member</b>"
86 #define VAR(name,conftype,member,initvalue) \
87 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), initvalue }
88 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
89 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
91 /** Array of configuration options. Until we disallow nonstandard
92 * abbreviations, order is significant, since the first matching option will
93 * be chosen first.
95 static config_var_t config_vars[] = {
96 VAR("Address", STRING, Address, NULL),
97 VAR("AccountingStart", STRING, AccountingStart, NULL),
98 VAR("AllowUnverifiedNodes",CSV, AllowUnverifiedNodes, "middle,rendezvous"),
99 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
100 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "1 MB"),
101 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "5 MB"),
102 VAR("MaxAdvertisedBandwidth",MEMUNIT,MaxAdvertisedBandwidth,"128 TB"),
103 VAR("ClientOnly", BOOL, ClientOnly, "0"),
104 VAR("ContactInfo", STRING, ContactInfo, NULL),
105 VAR("ControlPort", UINT, ControlPort, "0"),
106 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
107 VAR("DebugLogFile", STRING, DebugLogFile, NULL),
108 VAR("DataDirectory", STRING, DataDirectory, NULL),
109 VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL),
110 VAR("DirPort", UINT, DirPort, "0"),
111 VAR("DirBindAddress", LINELIST, DirBindAddress, NULL),
112 /** DOCDOC **/
113 VAR("DirFetchPeriod", INTERVAL, DirFetchPeriod, "0 seconds"),
114 VAR("DirPostPeriod", INTERVAL, DirPostPeriod, "20 minutes"),
115 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "20 minutes"),
116 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
117 VAR("DirServer", LINELIST, DirServers, NULL),
118 VAR("ExitNodes", STRING, ExitNodes, NULL),
119 VAR("EntryNodes", STRING, EntryNodes, NULL),
120 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
121 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
122 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
123 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
124 VAR("TrackHostExits", CSV, TrackHostExits, NULL),
125 VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
126 VAR("MapAddress", LINELIST, AddressMap, NULL),
127 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
128 VAR("FirewallPorts", CSV, FirewallPorts, "80,443"),
129 VAR("MyFamily", STRING, MyFamily, NULL),
130 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
131 VAR("NoPublish", BOOL, NoPublish, "0"),
132 VAR("Group", STRING, Group, NULL),
133 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
134 VAR("HttpProxy", STRING, HttpProxy, NULL),
135 VAR("HttpsProxy", STRING, HttpsProxy, NULL),
136 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
137 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
138 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
139 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
140 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
141 VAR("IgnoreVersion", BOOL, IgnoreVersion, "0"),
142 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
143 VAR("Log", LINELIST, Logs, NULL),
144 VAR("LogLevel", LINELIST_S, OldLogOptions, NULL),
145 VAR("LogFile", LINELIST_S, OldLogOptions, NULL),
146 OBSOLETE("LinkPadding"),
147 VAR("ConnLimit", UINT, ConnLimit, "1024"),
148 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
149 VAR("MonthlyAccountingStart",UINT, _MonthlyAccountingStart,"0"),
150 VAR("AccountingMaxKB", UINT, _AccountingMaxKB, "0"),
151 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
152 VAR("Nickname", STRING, Nickname, NULL),
153 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
154 VAR("MaxCircuitDirtiness", INTERVAL, MaxCircuitDirtiness, "10 minutes"),
155 VAR("NumCpus", UINT, NumCpus, "1"),
156 VAR("ORPort", UINT, ORPort, "0"),
157 VAR("ORBindAddress", LINELIST, ORBindAddress, NULL),
158 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
159 VAR("PidFile", STRING, PidFile, NULL),
160 VAR("LongLivedPorts", CSV, LongLivedPorts, "21,22,706,1863,5050,5190,5222,5223,6667,8300,8888"),
161 VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"),
162 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
163 OBSOLETE("RouterFile"),
164 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
165 VAR("RunTesting", BOOL, RunTesting, "0"),
166 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
167 VAR("RendNodes", STRING, RendNodes, NULL),
168 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
169 VAR("ShutdownWaitLength", INTERVAL, ShutdownWaitLength, "30 seconds"),
170 VAR("SocksPort", UINT, SocksPort, "9050"),
171 VAR("SocksBindAddress", LINELIST, SocksBindAddress, NULL),
172 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
173 /** DOCDOC */
174 VAR("StatusFetchPeriod", INTERVAL, StatusFetchPeriod, "0 seconds"),
175 VAR("SysLog", LINELIST_S, OldLogOptions, NULL),
176 OBSOLETE("TrafficShaping"),
177 VAR("User", STRING, User, NULL),
178 VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
179 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
181 #undef VAR
182 #undef OBSOLETE
184 /** Largest allowed config line */
185 #define CONFIG_LINE_T_MAXLEN 4096
187 static void config_line_append(struct config_line_t **lst,
188 const char *key, const char *val);
189 static void option_reset(or_options_t *options, config_var_t *var);
190 static void options_free(or_options_t *options);
191 static int option_is_same(or_options_t *o1, or_options_t *o2,const char *name);
192 static or_options_t *options_dup(or_options_t *old);
193 static int options_validate(or_options_t *options);
194 static int options_transition_allowed(or_options_t *old, or_options_t *new);
195 static int check_nickname_list(const char *lst, const char *name);
196 static void config_register_addressmaps(or_options_t *options);
198 static int parse_dir_server_line(const char *line, int validate_only);
199 static int parse_redirect_line(smartlist_t *result,
200 struct config_line_t *line);
201 static int parse_log_severity_range(const char *range, int *min_out,
202 int *max_out);
203 static int convert_log_option(or_options_t *options,
204 struct config_line_t *level_opt,
205 struct config_line_t *file_opt, int isDaemon);
206 static int add_single_log_option(or_options_t *options, int minSeverity,
207 int maxSeverity,
208 const char *type, const char *fname);
209 static int normalize_log_options(or_options_t *options);
210 static int validate_data_directory(or_options_t *options);
211 static int write_configuration_file(const char *fname, or_options_t *options);
213 static uint64_t config_parse_memunit(const char *s, int *ok);
214 static int config_parse_interval(const char *s, int *ok);
215 static void print_cvs_version(void);
218 * Functions to read and write the global options pointer.
221 /** Command-line and config-file options. */
222 static or_options_t *global_options=NULL;
223 /** Name of most recently read torrc file. */
224 static char *config_fname = NULL;
226 /** Return the currently configured options. */
227 or_options_t *
228 get_options(void) {
229 tor_assert(global_options);
230 return global_options;
233 /** Change the current global options to contain <b>new_val</b> instead
234 * of their current value; free the old value as necessary.
236 void
237 set_options(or_options_t *new_val) {
238 if (global_options)
239 options_free(global_options);
240 global_options = new_val;
243 void
244 config_free_all(void)
246 options_free(global_options);
247 tor_free(config_fname);
250 /** Fetch the active option list, and take actions based on it. All
251 * of the things we do should survive being done repeatedly.
252 * Return 0 if all goes well, return -1 if it's time to die.
254 * Note 1: <b>new_val</b> must have previously been validated with
255 * options_validate(), or Tor may freak out and exit.
257 * Note 2: We haven't moved all the "act on new configuration" logic
258 * here yet. Some is still in do_hup() and other places.
261 options_act(void) {
262 struct config_line_t *cl;
263 or_options_t *options = get_options();
264 static int libevent_initialized = 0;
266 /* XXXX009 We once had a reason to separate start_daemon and finish_daemon:
267 * It let us have the parent process stick around until we were sure Tor
268 * was started. Should we make start_daemon get called earlier? -NM */
269 if (options->RunAsDaemon) {
270 start_daemon();
272 if (!libevent_initialized) {
273 configure_libevent_logging();
274 suppress_libevent_log_msg("function not implemented");
275 event_init();
276 suppress_libevent_log_msg(NULL);
277 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
278 /* Making this a NOTICE for now so we can link bugs to a libevent versions
279 * or methods better. */
280 log_fn(LOG_NOTICE, "Initialized libevent version %s using method %s",
281 event_get_version(), event_get_method());
282 #else
283 log_fn(LOG_NOTICE, "Initialized old libevent (version 1.0b or earlier)");
284 #endif
285 libevent_initialized = 1;
288 clear_trusted_dir_servers();
289 for (cl = options->DirServers; cl; cl = cl->next) {
290 if (parse_dir_server_line(cl->value, 0)<0) {
291 log_fn(LOG_ERR,
292 "Bug: Previously validated DirServer line could not be added!");
293 return -1;
297 if (rend_config_services(options, 0)<0) {
298 log_fn(LOG_ERR,
299 "Bug: Previously validated hidden services line could not be added!");
300 return -1;
303 /* Setuid/setgid as appropriate */
304 if (options->User || options->Group) {
305 if (switch_id(options->User, options->Group) != 0) {
306 return -1;
310 /* Ensure data directory is private; create if possible. */
311 if (check_private_dir(options->DataDirectory, CPD_CREATE) != 0) {
312 log_fn(LOG_ERR, "Couldn't access/create private data directory %s",
313 options->DataDirectory);
314 return -1;
317 /* Bail out at this point if we're not going to be a server: we want
318 * to not fork, and to log stuff to stderr. */
319 if (options->command != CMD_RUN_TOR)
320 return 0;
322 mark_logs_temp(); /* Close current logs once new logs are open. */
323 if (config_init_logs(options, 0)<0) /* Configure the log(s) */
324 return -1;
325 /* Close the temporary log we used while starting up, if it isn't already
326 * gone. */
327 close_temp_logs();
328 add_callback_log(LOG_ERR, LOG_ERR, control_event_logmsg);
329 adjust_event_log_severity();
331 options->_ConnLimit =
332 set_max_file_descriptors((unsigned)options->ConnLimit, MAXCONNECTIONS);
333 if (options->_ConnLimit < 0)
334 return -1;
337 smartlist_t *sl = smartlist_create();
338 for (cl = options->RedirectExit; cl; cl = cl->next) {
339 if (parse_redirect_line(sl, cl)<0)
340 return -1;
342 set_exit_redirects(sl);
345 /* Start backgrounding the process, if requested. */
347 /* Finish backgrounding the process */
348 if (options->RunAsDaemon) {
349 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
350 finish_daemon(options->DataDirectory);
353 /* Write our pid to the pid file. If we do not have write permissions we
354 * will log a warning */
355 if (options->PidFile)
356 write_pidfile(options->PidFile);
358 /* Register addressmap directives */
359 config_register_addressmaps(options);
361 /* Update address policies. */
362 parse_socks_policy();
363 parse_dir_policy();
365 init_cookie_authentication(options->CookieAuthentication);
367 /* reload keys as needed for rendezvous services. */
368 if (rend_service_load_keys()<0) {
369 log_fn(LOG_ERR,"Error loading rendezvous service keys");
370 return -1;
373 /* Set up accounting */
374 if (accounting_parse_options(options, 0)<0) {
375 log_fn(LOG_ERR,"Error in accounting options");
376 return -1;
378 if (accounting_is_enabled(options))
379 configure_accounting(time(NULL));
381 if (!we_are_hibernating() && retry_all_listeners(1) < 0) {
382 log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
383 return -1;
386 #if 0
388 char *smin, *smax;
389 smin = config_dump_options(options, 1);
390 smax = config_dump_options(options, 0);
391 log_fn(LOG_DEBUG, "These are our options:\n%s",smax);
392 log_fn(LOG_DEBUG, "We changed these options:\n%s",smin);
393 tor_free(smin);
394 tor_free(smax);
396 #endif
398 /* Since our options changed, we might need to regenerate and upload our
399 * server descriptor. (We could probably be more clever about only calling
400 * this when something significant changed.)
402 mark_my_descriptor_dirty();
404 return 0;
408 * Functions to parse config options
411 /** If <b>option</b> is an official abbreviation for a longer option,
412 * return the longer option. Otherwise return <b>option</b>.
413 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
414 * apply abbreviations that work for the config file and the command line. */
415 static const char *
416 expand_abbrev(const char *option, int command_line)
418 int i;
419 for (i=0; config_abbrevs[i].abbreviated; ++i) {
420 /* Abbreviations aren't casei. */
421 if (!strcasecmp(option,config_abbrevs[i].abbreviated) &&
422 (command_line || !config_abbrevs[i].commandline_only)) {
423 return config_abbrevs[i].full;
426 return option;
429 /** Helper: Read a list of configuration options from the command line. */
430 static struct config_line_t *
431 config_get_commandlines(int argc, char **argv)
433 struct config_line_t *new;
434 struct config_line_t *front = NULL;
435 char *s;
436 int i = 1;
438 while (i < argc-1) {
439 if (!strcmp(argv[i],"-f") ||
440 !strcmp(argv[i],"--hash-password")) {
441 i += 2; /* command-line option with argument. ignore them. */
442 continue;
443 } else if (!strcmp(argv[i],"--list-fingerprint")) {
444 i += 1; /* command-line option. ignore it. */
445 continue;
446 } else if (!strcmp(argv[i],"--nt-service")) {
447 i += 1;
448 continue;
451 new = tor_malloc(sizeof(struct config_line_t));
452 s = argv[i];
454 while (*s == '-')
455 s++;
457 new->key = tor_strdup(expand_abbrev(s, 1));
458 new->value = tor_strdup(argv[i+1]);
460 log(LOG_DEBUG,"Commandline: parsed keyword '%s', value '%s'",
461 new->key, new->value);
462 new->next = front;
463 front = new;
464 i += 2;
466 return front;
469 /** Helper: allocate a new configuration option mapping 'key' to 'val',
470 * append it to *<b>lst</b>. */
471 static void
472 config_line_append(struct config_line_t **lst,
473 const char *key,
474 const char *val)
476 struct config_line_t *newline;
478 newline = tor_malloc(sizeof(struct config_line_t));
479 newline->key = tor_strdup(key);
480 newline->value = tor_strdup(val);
481 newline->next = NULL;
482 while (*lst)
483 lst = &((*lst)->next);
485 (*lst) = newline;
488 /** Helper: parse the config string and strdup into key/value
489 * strings. Set *result to the list, or NULL if parsing the string
490 * failed. Return 0 on success, -1 on failure. Warn and ignore any
491 * misformatted lines. */
493 config_get_lines(char *string, struct config_line_t **result)
495 struct config_line_t *list = NULL, **next;
496 char *k, *v;
498 next = &list;
499 do {
500 string = parse_line_from_str(string, &k, &v);
501 if (!string) {
502 config_free_lines(list);
503 return -1;
505 if (k && v) {
506 /* This list can get long, so we keep a pointer to the end of it
507 * rather than using config_line_append over and over and getting n^2
508 * performance. This is the only really long list. */
509 *next = tor_malloc(sizeof(struct config_line_t));
510 (*next)->key = tor_strdup(k);
511 (*next)->value = tor_strdup(v);
512 (*next)->next = NULL;
513 next = &((*next)->next);
515 } while (*string);
517 *result = list;
518 return 0;
522 * Free all the configuration lines on the linked list <b>front</b>.
524 void
525 config_free_lines(struct config_line_t *front)
527 struct config_line_t *tmp;
529 while (front) {
530 tmp = front;
531 front = tmp->next;
533 tor_free(tmp->key);
534 tor_free(tmp->value);
535 tor_free(tmp);
539 /** If <b>key</b> is a configuration option, return the corresponding
540 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
541 * warn, and return the corresponding config_var_t. Otherwise return NULL.
543 static config_var_t *config_find_option(const char *key)
545 int i;
546 size_t keylen = strlen(key);
547 if (!keylen)
548 return NULL; /* if they say "--" on the commandline, it's not an option */
549 /* First, check for an exact (case-insensitive) match */
550 for (i=0; config_vars[i].name; ++i) {
551 if (!strcasecmp(key, config_vars[i].name))
552 return &config_vars[i];
554 /* If none, check for an abbreviated match */
555 for (i=0; config_vars[i].name; ++i) {
556 if (!strncasecmp(key, config_vars[i].name, keylen)) {
557 log_fn(LOG_WARN, "The abbreviation '%s' is deprecated. "
558 "Tell Nick and Roger to make it official, or just use '%s' instead",
559 key, config_vars[i].name);
560 return &config_vars[i];
563 /* Okay, unrecognized options */
564 return NULL;
567 /** If <b>c</b> is a syntactically valid configuration line, update
568 * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
569 * -2 for bad value.
571 * If 'reset' is set, and we get a line containing no value, restore the
572 * option to its default value.
574 static int
575 config_assign_line(or_options_t *options, struct config_line_t *c, int reset)
577 int i, ok;
578 config_var_t *var;
579 void *lvalue;
581 var = config_find_option(c->key);
582 if (!var) {
583 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
584 return -1;
586 /* Put keyword into canonical case. */
587 if (strcmp(var->name, c->key)) {
588 tor_free(c->key);
589 c->key = tor_strdup(var->name);
592 if (reset && !strlen(c->value)) {
593 option_reset(options, var);
594 return 0;
597 lvalue = ((char*)options) + var->var_offset;
598 switch (var->type) {
600 case CONFIG_TYPE_UINT:
601 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
602 if (!ok) {
603 log(LOG_WARN, "Int keyword '%s %s' is malformed or out of bounds.",
604 c->key,c->value);
605 return -2;
607 *(int *)lvalue = i;
608 break;
610 case CONFIG_TYPE_INTERVAL: {
611 i = config_parse_interval(c->value, &ok);
612 if (!ok) {
613 return -2;
615 *(int *)lvalue = i;
616 break;
619 case CONFIG_TYPE_MEMUNIT: {
620 uint64_t u64 = config_parse_memunit(c->value, &ok);
621 if (!ok) {
622 return -2;
624 *(uint64_t *)lvalue = u64;
625 break;
628 case CONFIG_TYPE_BOOL:
629 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
630 if (!ok) {
631 log(LOG_WARN, "Boolean keyword '%s' expects 0 or 1.", c->key);
632 return -2;
634 *(int *)lvalue = i;
635 break;
637 case CONFIG_TYPE_STRING:
638 tor_free(*(char **)lvalue);
639 *(char **)lvalue = tor_strdup(c->value);
640 break;
642 case CONFIG_TYPE_DOUBLE:
643 *(double *)lvalue = atof(c->value);
644 break;
646 case CONFIG_TYPE_CSV:
647 if (*(smartlist_t**)lvalue) {
648 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
649 smartlist_clear(*(smartlist_t**)lvalue);
650 } else {
651 *(smartlist_t**)lvalue = smartlist_create();
654 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
655 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
656 break;
658 case CONFIG_TYPE_LINELIST:
659 case CONFIG_TYPE_LINELIST_S:
660 config_line_append((struct config_line_t**)lvalue, c->key, c->value);
661 break;
663 case CONFIG_TYPE_OBSOLETE:
664 log_fn(LOG_WARN, "Skipping obsolete configuration option '%s'", c->key);
665 break;
666 case CONFIG_TYPE_LINELIST_V:
667 log_fn(LOG_WARN, "Can't provide value for virtual option '%s'", c->key);
668 return -2;
669 default:
670 tor_assert(0);
671 break;
673 return 0;
676 /** restore the option named <b>key</b> in options to its default value. */
677 static void
678 config_reset_line(or_options_t *options, const char *key)
680 config_var_t *var;
682 var = config_find_option(key);
683 if (!var)
684 return; /* give error on next pass. */
686 option_reset(options, var);
689 /** Return true iff key is a valid configuration option. */
691 config_option_is_recognized(const char *key)
693 config_var_t *var = config_find_option(key);
694 return (var != NULL);
697 /** Return a canonicalized list of the options assigned for key.
699 struct config_line_t *
700 config_get_assigned_option(or_options_t *options, const char *key)
702 config_var_t *var;
703 const void *value;
704 char buf[32];
705 struct config_line_t *result;
706 tor_assert(options && key);
708 var = config_find_option(key);
709 if (!var) {
710 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", key);
711 return NULL;
712 } else if (var->type == CONFIG_TYPE_LINELIST_S) {
713 log_fn(LOG_WARN, "Can't return context-sensitive '%s' on its own", key);
714 return NULL;
716 value = ((char*)options) + var->var_offset;
718 if (var->type == CONFIG_TYPE_LINELIST ||
719 var->type == CONFIG_TYPE_LINELIST_V) {
720 /* Linelist requires special handling: we just copy and return it. */
721 const struct config_line_t *next_in = *(const struct config_line_t**)value;
722 struct config_line_t **next_out = &result;
723 while (next_in) {
724 *next_out = tor_malloc(sizeof(struct config_line_t));
725 (*next_out)->key = tor_strdup(next_in->key);
726 (*next_out)->value = tor_strdup(next_in->value);
727 next_in = next_in->next;
728 next_out = &((*next_out)->next);
730 (*next_out) = NULL;
731 return result;
734 result = tor_malloc_zero(sizeof(struct config_line_t));
735 result->key = tor_strdup(var->name);
736 switch (var->type)
738 case CONFIG_TYPE_STRING:
739 if (*(char**)value) {
740 result->value = tor_strdup(*(char**)value);
741 } else {
742 tor_free(result->key);
743 tor_free(result);
744 return NULL;
746 break;
747 case CONFIG_TYPE_INTERVAL:
748 case CONFIG_TYPE_UINT:
749 /* This means every or_options_t uint or bool element
750 * needs to be an int. Not, say, a uint16_t or char. */
751 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
752 result->value = tor_strdup(buf);
753 break;
754 case CONFIG_TYPE_MEMUNIT:
755 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
756 U64_PRINTF_ARG(*(uint64_t*)value));
757 result->value = tor_strdup(buf);
758 break;
759 case CONFIG_TYPE_DOUBLE:
760 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
761 result->value = tor_strdup(buf);
762 break;
763 case CONFIG_TYPE_BOOL:
764 result->value = tor_strdup(*(int*)value ? "1" : "0");
765 break;
766 case CONFIG_TYPE_CSV:
767 if (*(smartlist_t**)value)
768 result->value = smartlist_join_strings(*(smartlist_t**)value,",",0,NULL);
769 else
770 result->value = tor_strdup("");
771 break;
772 case CONFIG_TYPE_OBSOLETE:
773 log_fn(LOG_WARN,"You asked me for the value of an obsolete config option %s.", key);
774 tor_free(result->key);
775 tor_free(result);
776 return NULL;
777 default:
778 tor_free(result->key);
779 tor_free(result);
780 log_fn(LOG_WARN,"Bug: unknown type %d for known key %s", var->type, key);
781 return NULL;
784 return result;
787 /** Iterate through the linked list of requested options <b>list</b>.
788 * For each item, convert as appropriate and assign to <b>options</b>.
789 * If an item is unrecognized, return -1 immediately,
790 * else return 0 for success.
792 * If <b>reset</b>, then interpret empty lines as meaning "restore to
793 * default value", and interpret LINELIST* options as replacing (not
794 * extending) their previous values. Return 0 on success, -1 on bad key,
795 * -2 on bad value.
797 static int
798 config_assign(or_options_t *options, struct config_line_t *list, int reset)
800 struct config_line_t *p;
801 tor_assert(options);
803 /* pass 1: normalize keys */
804 for (p = list; p; p = p->next) {
805 const char *full = expand_abbrev(p->key, 0);
806 if (strcmp(full,p->key)) {
807 tor_free(p->key);
808 p->key = tor_strdup(full);
812 /* pass 2: if we're reading from a resetting source, clear all mentioned
813 * linelists. */
814 if (reset) {
815 for (p = list; p; p = p->next)
816 config_reset_line(options, p->key);
819 /* pass 3: assign. */
820 while (list) {
821 int r;
822 if ((r=config_assign_line(options, list, reset)))
823 return r;
824 list = list->next;
826 return 0;
829 /** Try assigning <b>list</b> to the global options. You do this by duping
830 * options, assigning list to the new one, then validating it. If it's
831 * ok, then throw out the old one and stick with the new one. Else,
832 * revert to old and return failure. Return 0 on success, -1 on bad
833 * keys, -2 on bad values, -3 on bad transition.
836 config_trial_assign(struct config_line_t *list, int reset)
838 int r;
839 or_options_t *trial_options = options_dup(get_options());
841 if ((r=config_assign(trial_options, list, reset)) < 0) {
842 options_free(trial_options);
843 return r;
846 if (options_validate(trial_options) < 0) {
847 options_free(trial_options);
848 return -2;
851 if (options_transition_allowed(get_options(), trial_options) < 0) {
852 options_free(trial_options);
853 return -3;
856 set_options(trial_options); /* we liked it. put it in place. */
857 return 0;
860 /** Replace the option indexed by <b>var</b> in <b>options</b> with its
861 * default value. */
862 static void
863 option_reset(or_options_t *options, config_var_t *var)
865 struct config_line_t *c;
866 void *lvalue;
868 lvalue = ((char*)options) + var->var_offset;
869 switch (var->type) {
870 case CONFIG_TYPE_STRING:
871 tor_free(*(char**)lvalue);
872 break;
873 case CONFIG_TYPE_DOUBLE:
874 *(double*)lvalue = 0.0;
875 break;
876 case CONFIG_TYPE_INTERVAL:
877 case CONFIG_TYPE_UINT:
878 case CONFIG_TYPE_BOOL:
879 *(int*)lvalue = 0;
880 break;
881 case CONFIG_TYPE_MEMUNIT:
882 *(uint64_t*)lvalue = 0;
883 break;
884 case CONFIG_TYPE_CSV:
885 if (*(smartlist_t**)lvalue) {
886 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
887 smartlist_free(*(smartlist_t **)lvalue);
888 *(smartlist_t **)lvalue = NULL;
890 break;
891 case CONFIG_TYPE_LINELIST:
892 case CONFIG_TYPE_LINELIST_S:
893 config_free_lines(*(struct config_line_t **)lvalue);
894 *(struct config_line_t **)lvalue = NULL;
895 break;
896 case CONFIG_TYPE_LINELIST_V:
897 /* handled by linelist_s. */
898 break;
899 case CONFIG_TYPE_OBSOLETE:
900 break;
902 if (var->initvalue) {
903 c = tor_malloc_zero(sizeof(struct config_line_t));
904 c->key = tor_strdup(var->name);
905 c->value = tor_strdup(var->initvalue);
906 config_assign_line(options,c,0);
907 config_free_lines(c);
911 /** Set <b>options</b>-&gt;DirServers to contain the default directory
912 * servers. */
913 static void
914 add_default_trusted_dirservers(or_options_t *options)
916 /* moria1 */
917 config_line_append(&options->DirServers, "DirServer",
918 "18.244.0.188:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441");
919 /* moria2 */
920 config_line_append(&options->DirServers, "DirServer",
921 "18.244.0.114:80 719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF");
922 /* tor26 */
923 config_line_append(&options->DirServers, "DirServer",
924 "62.116.124.106:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
925 // "tor.noreply.org:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
928 /** Print a usage message for tor. */
929 static void
930 print_usage(void)
932 printf(
933 "Copyright 2001-2004 Roger Dingledine, Nick Mathewson, Matej Pfajfar.\n\n"
934 "tor -f <torrc> [args]\n"
935 "See man page for options, or http://tor.eff.org/ for documentation.\n");
939 * Based on <b>address</b>, guess our public IP address and put it
940 * in <b>addr</b>.
943 resolve_my_address(const char *address, uint32_t *addr)
945 struct in_addr in;
946 struct hostent *rent;
947 char hostname[256];
948 int explicit_ip=1;
949 char tmpbuf[INET_NTOA_BUF_LEN];
950 static uint32_t old_addr=0;
952 tor_assert(addr);
954 if (address) {
955 strlcpy(hostname, address, sizeof(hostname));
956 } else { /* then we need to guess our address */
957 explicit_ip = 0; /* it's implicit */
959 if (gethostname(hostname, sizeof(hostname)) < 0) {
960 log_fn(LOG_WARN,"Error obtaining local hostname");
961 return -1;
963 log_fn(LOG_DEBUG,"Guessed local host name as '%s'",hostname);
966 /* now we know hostname. resolve it and keep only the IP */
968 if (tor_inet_aton(hostname, &in) == 0) {
969 /* then we have to resolve it */
970 explicit_ip = 0;
971 rent = (struct hostent *)gethostbyname(hostname);
972 if (!rent) {
973 log_fn(LOG_WARN,"Could not resolve local Address %s. Failing.", hostname);
974 return -1;
976 tor_assert(rent->h_length == 4);
977 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
980 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
981 if (!explicit_ip && is_internal_IP(htonl(in.s_addr))) {
982 log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
983 "Please set the Address config option to be the IP you want to use.",
984 hostname, tmpbuf);
985 return -1;
988 log_fn(LOG_DEBUG, "Resolved Address to %s.", tmpbuf);
989 *addr = ntohl(in.s_addr);
990 if (old_addr && old_addr != *addr) {
991 log_fn(LOG_NOTICE,"Your IP seems to have changed. Updating.");
992 server_has_changed_ip();
994 old_addr = *addr;
995 return 0;
998 /** Called when we don't have a nickname set. Try to guess a good
999 * nickname based on the hostname, and return it in a newly allocated string. */
1000 static char *
1001 get_default_nickname(void)
1003 char localhostname[256];
1004 char *cp, *out, *outp;
1006 if (gethostname(localhostname, sizeof(localhostname)) < 0) {
1007 log_fn(LOG_WARN,"Error obtaining local hostname");
1008 return NULL;
1011 /* Put it in lowercase; stop at the first dot. */
1012 for (cp = localhostname; *cp; ++cp) {
1013 if (*cp == '.') {
1014 *cp = '\0';
1015 break;
1017 *cp = tolower(*cp);
1020 /* Strip invalid characters. */
1021 cp = localhostname;
1022 out = outp = tor_malloc(strlen(localhostname) + 1);
1023 while (*cp) {
1024 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
1025 *outp++ = *cp++;
1026 else
1027 cp++;
1029 *outp = '\0';
1031 /* Enforce length. */
1032 if (strlen(out) > MAX_NICKNAME_LEN)
1033 out[MAX_NICKNAME_LEN]='\0';
1035 return out;
1038 /** Release storage held by <b>options</b> */
1039 static void
1040 options_free(or_options_t *options)
1042 int i;
1043 void *lvalue;
1045 tor_assert(options);
1047 for (i=0; config_vars[i].name; ++i) {
1048 lvalue = ((char*)options) + config_vars[i].var_offset;
1049 switch (config_vars[i].type) {
1050 case CONFIG_TYPE_MEMUNIT:
1051 case CONFIG_TYPE_INTERVAL:
1052 case CONFIG_TYPE_UINT:
1053 case CONFIG_TYPE_BOOL:
1054 case CONFIG_TYPE_DOUBLE:
1055 case CONFIG_TYPE_OBSOLETE:
1056 break; /* nothing to free for these config types */
1057 case CONFIG_TYPE_STRING:
1058 tor_free(*(char **)lvalue);
1059 break;
1060 case CONFIG_TYPE_LINELIST:
1061 case CONFIG_TYPE_LINELIST_V:
1062 config_free_lines(*(struct config_line_t**)lvalue);
1063 *(struct config_line_t**)lvalue = NULL;
1064 break;
1065 case CONFIG_TYPE_CSV:
1066 if (*(smartlist_t**)lvalue) {
1067 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1068 smartlist_free(*(smartlist_t**)lvalue);
1069 *(smartlist_t**)lvalue = NULL;
1071 break;
1072 case CONFIG_TYPE_LINELIST_S:
1073 /* will be freed by corresponding LINELIST_V. */
1074 break;
1077 tor_free(options);
1080 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
1081 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1083 static int
1084 option_is_same(or_options_t *o1, or_options_t *o2, const char *name)
1086 struct config_line_t *c1, *c2;
1087 int r = 1;
1088 c1 = config_get_assigned_option(o1, name);
1089 c2 = config_get_assigned_option(o2, name);
1090 while (c1 && c2) {
1091 if (strcasecmp(c1->key, c2->key) ||
1092 strcmp(c1->value, c2->value)) {
1093 r = 0;
1094 break;
1096 c1 = c1->next;
1097 c2 = c2->next;
1099 if (r && (c1 || c2)) {
1100 r = 0;
1102 config_free_lines(c1);
1103 config_free_lines(c2);
1104 return r;
1107 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1108 static or_options_t *
1109 options_dup(or_options_t *old)
1111 or_options_t *newopts;
1112 int i;
1113 struct config_line_t *line;
1115 newopts = tor_malloc_zero(sizeof(or_options_t));
1116 for (i=0; config_vars[i].name; ++i) {
1117 if (config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1118 continue;
1119 if (config_vars[i].type == CONFIG_TYPE_OBSOLETE)
1120 continue;
1121 line = config_get_assigned_option(old, config_vars[i].name);
1122 if (line) {
1123 if (config_assign(newopts, line, 0) < 0) {
1124 log_fn(LOG_WARN,"Bug: config_get_assigned_option() generated "
1125 "something we couldn't config_assign().");
1126 tor_assert(0);
1129 config_free_lines(line);
1131 return newopts;
1134 /** Set <b>options</b> to hold reasonable defaults for most options.
1135 * Each option defaults to zero. */
1136 void
1137 options_init(or_options_t *options)
1139 int i;
1140 config_var_t *var;
1142 for (i=0; config_vars[i].name; ++i) {
1143 var = &config_vars[i];
1144 if (!var->initvalue)
1145 continue; /* defaults to NULL or 0 */
1146 option_reset(options, var);
1150 /** Return a string containing a possible configuration file that would give
1151 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
1152 * include options that are the same as Tor's defaults.
1154 char *
1155 config_dump_options(or_options_t *options, int minimal)
1157 smartlist_t *elements;
1158 or_options_t *defaults;
1159 struct config_line_t *line;
1160 char *result;
1161 int i;
1163 defaults = tor_malloc_zero(sizeof(or_options_t));
1164 options_init(defaults);
1165 options_validate(defaults); /* ??? will this work? */
1167 elements = smartlist_create();
1168 for (i=0; config_vars[i].name; ++i) {
1169 if (config_vars[i].type == CONFIG_TYPE_OBSOLETE ||
1170 config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1171 continue;
1172 /* Don't save 'hidden' control variables. */
1173 if (!strcmpstart(config_vars[i].name, "__"))
1174 continue;
1175 if (minimal && option_is_same(options, defaults, config_vars[i].name))
1176 continue;
1177 line = config_get_assigned_option(options, config_vars[i].name);
1178 for (; line; line = line->next) {
1179 size_t len = strlen(line->key) + strlen(line->value) + 3;
1180 char *tmp;
1181 tmp = tor_malloc(len);
1182 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
1183 log_fn(LOG_ERR, "Internal error writing log option");
1184 tor_assert(0);
1186 smartlist_add(elements, tmp);
1188 config_free_lines(line);
1191 result = smartlist_join_strings(elements, "", 0, NULL);
1192 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
1193 smartlist_free(elements);
1194 return result;
1197 static int
1198 validate_ports_csv(smartlist_t *sl, const char *name) {
1199 int i;
1200 int result = 0;
1201 tor_assert(name);
1203 if (!sl)
1204 return 0;
1206 SMARTLIST_FOREACH(sl, const char *, cp,
1208 i = atoi(cp);
1209 if (i < 1 || i > 65535) {
1210 log(LOG_WARN, "Port '%s' out of range in %s", cp, name);
1211 result=-1;
1214 return result;
1217 /** Return 0 if every setting in <b>options</b> is reasonable. Else
1218 * warn and return -1. Should have no side effects, except for
1219 * normalizing the contents of <b>options</b>. */
1220 static int
1221 options_validate(or_options_t *options)
1223 int result = 0;
1224 struct config_line_t *cl;
1225 addr_policy_t *addr_policy=NULL;
1227 if (options->ORPort < 0 || options->ORPort > 65535) {
1228 log(LOG_WARN, "ORPort option out of bounds.");
1229 result = -1;
1232 /* XXX might similarly want to check the other *BindAddress options */
1233 if (options->ORPort == 0 && options->ORBindAddress != NULL) {
1234 log(LOG_WARN, "ORPort must be defined if ORBindAddress is defined.");
1235 result = -1;
1238 if (validate_data_directory(options)<0) {
1239 log(LOG_WARN, "Invalid DataDirectory");
1240 result = -1;
1243 if (options->Nickname == NULL) {
1244 if (server_mode(options)) {
1245 if (!(options->Nickname = get_default_nickname()))
1246 return -1;
1247 log_fn(LOG_NOTICE, "Choosing default nickname %s", options->Nickname);
1249 } else {
1250 if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) !=
1251 strlen(options->Nickname)) {
1252 log_fn(LOG_WARN, "Nickname '%s' contains illegal characters.", options->Nickname);
1253 result = -1;
1255 if (strlen(options->Nickname) == 0) {
1256 log_fn(LOG_WARN, "Nickname must have at least one character");
1257 result = -1;
1259 if (strlen(options->Nickname) > MAX_NICKNAME_LEN) {
1260 log_fn(LOG_WARN, "Nickname '%s' has more than %d characters.",
1261 options->Nickname, MAX_NICKNAME_LEN);
1262 result = -1;
1266 if (normalize_log_options(options))
1267 return -1;
1269 /* Special case if no options are given. */
1270 if (!options->Logs) {
1271 config_line_append(&options->Logs, "Log", "notice stdout");
1274 if (config_init_logs(options, 1)<0) /* Validate the log(s) */
1275 return -1;
1277 if (server_mode(options)) {
1278 /* confirm that our address isn't broken, so we can complain now */
1279 uint32_t tmp;
1280 if (resolve_my_address(options->Address, &tmp) < 0)
1281 result = -1;
1284 if (options->SocksPort < 0 || options->SocksPort > 65535) {
1285 log(LOG_WARN, "SocksPort option out of bounds.");
1286 result = -1;
1289 if (options->SocksPort == 0 && options->ORPort == 0) {
1290 log(LOG_WARN, "SocksPort and ORPort are both undefined? Quitting.");
1291 result = -1;
1294 if (options->ControlPort < 0 || options->ControlPort > 65535) {
1295 log(LOG_WARN, "ControlPort option out of bounds.");
1296 result = -1;
1299 if (options->DirPort < 0 || options->DirPort > 65535) {
1300 log(LOG_WARN, "DirPort option out of bounds.");
1301 result = -1;
1304 if (options->StrictExitNodes &&
1305 (!options->ExitNodes || !strlen(options->ExitNodes))) {
1306 log(LOG_WARN, "StrictExitNodes set, but no ExitNodes listed.");
1309 if (options->StrictEntryNodes &&
1310 (!options->EntryNodes || !strlen(options->EntryNodes))) {
1311 log(LOG_WARN, "StrictEntryNodes set, but no EntryNodes listed.");
1314 if (options->AuthoritativeDir && options->RecommendedVersions == NULL) {
1315 log(LOG_WARN, "Directory servers must configure RecommendedVersions.");
1316 result = -1;
1319 if (options->AuthoritativeDir && !options->DirPort) {
1320 log(LOG_WARN, "Running as authoritative directory, but no DirPort set.");
1321 result = -1;
1324 if (options->AuthoritativeDir && !options->ORPort) {
1325 log(LOG_WARN, "Running as authoritative directory, but no ORPort set.");
1326 result = -1;
1329 if (options->AuthoritativeDir && options->ClientOnly) {
1330 log(LOG_WARN, "Running as authoritative directory, but ClientOnly also set.");
1331 result = -1;
1334 if (options->AuthoritativeDir && options->NoPublish) {
1335 log(LOG_WARN, "You cannot set both AuthoritativeDir and NoPublish.");
1336 result = -1;
1339 if (options->ConnLimit <= 0) {
1340 log(LOG_WARN, "ConnLimit must be greater than 0, but was set to %d",
1341 options->ConnLimit);
1342 result = -1;
1345 if (options->_AccountingMaxKB) {
1346 log(LOG_WARN, "AccountingMaxKB is deprecated. Say 'AccountingMax %d KB' instead.", options->_AccountingMaxKB);
1347 options->AccountingMax = U64_LITERAL(1024)*options->_AccountingMaxKB;
1348 options->_AccountingMaxKB = 0;
1351 if (validate_ports_csv(options->FirewallPorts,
1352 "FirewallPorts") < 0)
1353 result = -1;
1355 if (validate_ports_csv(options->LongLivedPorts,
1356 "LongLivedPorts") < 0)
1357 result = -1;
1359 options->_AllowUnverified = 0;
1360 if (options->AllowUnverifiedNodes) {
1361 SMARTLIST_FOREACH(options->AllowUnverifiedNodes, const char *, cp, {
1362 if (!strcasecmp(cp, "entry"))
1363 options->_AllowUnverified |= ALLOW_UNVERIFIED_ENTRY;
1364 else if (!strcasecmp(cp, "exit"))
1365 options->_AllowUnverified |= ALLOW_UNVERIFIED_EXIT;
1366 else if (!strcasecmp(cp, "middle"))
1367 options->_AllowUnverified |= ALLOW_UNVERIFIED_MIDDLE;
1368 else if (!strcasecmp(cp, "introduction"))
1369 options->_AllowUnverified |= ALLOW_UNVERIFIED_INTRODUCTION;
1370 else if (!strcasecmp(cp, "rendezvous"))
1371 options->_AllowUnverified |= ALLOW_UNVERIFIED_RENDEZVOUS;
1372 else {
1373 log(LOG_WARN, "Unrecognized value '%s' in AllowUnverifiedNodes",
1374 cp);
1375 result = -1;
1380 if (options->SocksPort >= 1 &&
1381 (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) {
1382 log(LOG_WARN, "PathlenCoinWeight option must be >=0.0 and <1.0.");
1383 result = -1;
1386 #define MIN_DIR_FETCH_PERIOD 600
1387 #define MIN_DIR_POST_PERIOD 300
1388 #define MIN_REND_POST_PERIOD 300
1389 #define MIN_STATUS_FETCH_PERIOD 60
1391 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
1392 #define MAX_CACHE_DIR_FETCH_PERIOD 3600
1393 #define MAX_CACHE_STATUS_FETCH_PERIOD 900
1395 if (options->DirFetchPeriod &&
1396 options->DirFetchPeriod < MIN_DIR_FETCH_PERIOD) {
1397 log(LOG_WARN, "DirFetchPeriod option must be at least %d seconds. Clipping.", MIN_DIR_FETCH_PERIOD);
1398 options->DirFetchPeriod = MIN_DIR_FETCH_PERIOD;
1400 if (options->StatusFetchPeriod &&
1401 options->StatusFetchPeriod < MIN_STATUS_FETCH_PERIOD) {
1402 log(LOG_WARN, "StatusFetchPeriod option must be at least %d seconds. Clipping.", MIN_STATUS_FETCH_PERIOD);
1403 options->StatusFetchPeriod = MIN_STATUS_FETCH_PERIOD;
1405 if (options->DirPostPeriod < MIN_DIR_POST_PERIOD) {
1406 log(LOG_WARN, "DirPostPeriod option must be at least %d seconds. Clipping.",
1407 MIN_DIR_POST_PERIOD);
1408 options->DirPostPeriod = MIN_DIR_POST_PERIOD;
1410 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
1411 log(LOG_WARN,"RendPostPeriod option must be at least %d seconds. Clipping.",
1412 MIN_REND_POST_PERIOD);
1413 options->RendPostPeriod = MIN_REND_POST_PERIOD;
1416 if (options->DirPort && ! options->AuthoritativeDir) {
1417 if (options->DirFetchPeriod > MAX_CACHE_DIR_FETCH_PERIOD) {
1418 log(LOG_WARN, "Caching directory servers must have DirFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_DIR_FETCH_PERIOD);
1419 options->DirFetchPeriod = MAX_CACHE_DIR_FETCH_PERIOD;
1421 if (options->StatusFetchPeriod > MAX_CACHE_STATUS_FETCH_PERIOD) {
1422 log(LOG_WARN, "Caching directory servers must have StatusFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_STATUS_FETCH_PERIOD);
1423 options->StatusFetchPeriod = MAX_CACHE_STATUS_FETCH_PERIOD;
1427 if (options->DirFetchPeriod > MAX_DIR_PERIOD) {
1428 log(LOG_WARN, "DirFetchPeriod is too large; clipping.");
1429 options->DirFetchPeriod = MAX_DIR_PERIOD;
1431 if (options->DirPostPeriod > MAX_DIR_PERIOD) {
1432 log(LOG_WARN, "DirPostPeriod is too large; clipping.");
1433 options->DirPostPeriod = MAX_DIR_PERIOD;
1435 if (options->StatusFetchPeriod > MAX_DIR_PERIOD) {
1436 log(LOG_WARN, "StatusFetchPeriod is too large; clipping.");
1437 options->StatusFetchPeriod = MAX_DIR_PERIOD;
1439 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
1440 log(LOG_WARN, "RendPostPeriod is too large; clipping.");
1441 options->RendPostPeriod = MAX_DIR_PERIOD;
1444 if (options->KeepalivePeriod < 1) {
1445 log(LOG_WARN,"KeepalivePeriod option must be positive.");
1446 result = -1;
1449 if (options->BandwidthRate > INT_MAX) {
1450 log(LOG_WARN,"BandwidthRate must be less than %d",INT_MAX);
1451 result = -1;
1453 if (options->BandwidthBurst > INT_MAX) {
1454 log(LOG_WARN,"BandwidthBurst must be less than %d",INT_MAX);
1455 result = -1;
1457 if (server_mode(options) &&
1458 options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
1459 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);
1460 result = -1;
1462 if (options->BandwidthRate > options->BandwidthBurst) {
1463 log(LOG_WARN,"BandwidthBurst must be at least equal to BandwidthRate.");
1464 result = -1;
1466 #if 0
1467 if (2*options->BandwidthRate > options->BandwidthBurst) {
1468 log(LOG_NOTICE,"You have chosen a BandwidthBurst less than twice BandwidthRate. Please consider setting your BandwidthBurst higher (at least %d), to provide better service to the Tor network.", (int)(2*options->BandwidthRate));
1470 #endif
1472 if (options->_MonthlyAccountingStart) {
1473 if (options->AccountingStart) {
1474 log(LOG_WARN,"Can't specify AccountingStart and MonthlyAccountingStart");
1475 result = -1;
1476 } else {
1477 options->AccountingStart = tor_malloc(32);
1478 if (tor_snprintf(options->AccountingStart, 32, "month %d 0:00",
1479 options->_MonthlyAccountingStart)<0) {
1480 log_fn(LOG_WARN,"Error translating MonthlyAccountingStart");
1481 result = -1;
1482 } else {
1483 log_fn(LOG_WARN,"MonthlyAccountingStart is deprecated. Use 'AccountingStart %s' instead.", options->AccountingStart);
1488 if (accounting_parse_options(options, 1)<0) {
1489 result = -1;
1492 if (options->HttpProxy) { /* parse it now */
1493 if (parse_addr_port(options->HttpProxy, NULL,
1494 &options->HttpProxyAddr, &options->HttpProxyPort) < 0) {
1495 log(LOG_WARN,"HttpProxy failed to parse or resolve. Please fix.");
1496 result = -1;
1498 if (options->HttpProxyPort == 0) { /* give it a default */
1499 options->HttpProxyPort = 80;
1503 if (options->HttpsProxy) { /* parse it now */
1504 if (parse_addr_port(options->HttpsProxy, NULL,
1505 &options->HttpsProxyAddr, &options->HttpsProxyPort) < 0) {
1506 log(LOG_WARN,"HttpsProxy failed to parse or resolve. Please fix.");
1507 result = -1;
1509 if (options->HttpsProxyPort == 0) { /* give it a default */
1510 options->HttpsProxyPort = 443;
1514 if (options->HashedControlPassword) {
1515 if (decode_hashed_password(NULL, options->HashedControlPassword)<0) {
1516 log_fn(LOG_WARN,"Bad HashedControlPassword: wrong length or bad base64");
1517 result = -1;
1520 if (options->HashedControlPassword && options->CookieAuthentication) {
1521 log_fn(LOG_WARN,"Cannot enable both HashedControlPassword and CookieAuthentication");
1522 result = -1;
1525 if (check_nickname_list(options->ExitNodes, "ExitNodes"))
1526 result = -1;
1527 if (check_nickname_list(options->EntryNodes, "EntryNodes"))
1528 result = -1;
1529 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
1530 result = -1;
1531 if (check_nickname_list(options->RendNodes, "RendNodes"))
1532 result = -1;
1533 if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
1534 result = -1;
1535 if (check_nickname_list(options->MyFamily, "MyFamily"))
1536 result = -1;
1537 for (cl = options->NodeFamilies; cl; cl = cl->next) {
1538 if (check_nickname_list(cl->value, "NodeFamily"))
1539 result = -1;
1542 if (config_parse_addr_policy(options->ExitPolicy, &addr_policy)) {
1543 log_fn(LOG_WARN, "Error in Exit Policy entry.");
1544 result = -1;
1546 if (server_mode(options)) {
1547 exit_policy_implicitly_allows_local_networks(addr_policy, 1);
1549 /* The rest of these calls *append* to addr_policy. So don't actually
1550 * use the results for anything other than checking if they parse! */
1551 if (config_parse_addr_policy(options->DirPolicy, &addr_policy)) {
1552 log_fn(LOG_WARN, "Error in DirPolicy entry.");
1553 result = -1;
1555 if (config_parse_addr_policy(options->SocksPolicy, &addr_policy)) {
1556 log_fn(LOG_WARN, "Error in SocksPolicy entry.");
1557 result = -1;
1559 addr_policy_free(addr_policy);
1561 for (cl = options->RedirectExit; cl; cl = cl->next) {
1562 if (parse_redirect_line(NULL, cl)<0)
1563 result = -1;
1566 if (!options->DirServers) {
1567 add_default_trusted_dirservers(options);
1568 } else {
1569 for (cl = options->DirServers; cl; cl = cl->next) {
1570 if (parse_dir_server_line(cl->value, 1)<0)
1571 result = -1;
1575 if (rend_config_services(options, 1) < 0)
1576 result = -1;
1578 return result;
1581 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
1582 * equal strings. */
1583 static int
1584 opt_streq(const char *s1, const char *s2)
1586 if (!s1 && !s2)
1587 return 1;
1588 else if (s1 && s2 && !strcmp(s1,s2))
1589 return 1;
1590 else
1591 return 0;
1594 /** Check if any of the previous options have changed but aren't allowed to. */
1595 static int
1596 options_transition_allowed(or_options_t *old, or_options_t *new_val) {
1598 if (!old)
1599 return 0;
1601 if (!opt_streq(old->PidFile, new_val->PidFile)) {
1602 log_fn(LOG_WARN,"PidFile is not allowed to change. Failing.");
1603 return -1;
1606 if (old->RunAsDaemon && !new_val->RunAsDaemon) {
1607 log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing.");
1608 return -1;
1611 if (old->ORPort != new_val->ORPort) {
1612 log_fn(LOG_WARN,"During reload, changing ORPort is not allowed. Failing.");
1613 return -1;
1616 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
1617 log_fn(LOG_WARN,"During reload, changing DataDirectory (%s->%s) is not allowed. Failing.", old->DataDirectory, new_val->DataDirectory);
1618 return -1;
1621 if (!opt_streq(old->User, new_val->User)) {
1622 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1623 return -1;
1626 if (!opt_streq(old->Group, new_val->Group)) {
1627 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1628 return -1;
1631 return 0;
1634 #ifdef MS_WINDOWS
1635 /** Return the directory on windows where we expect to find our application
1636 * data. */
1637 static char *get_windows_conf_root(void)
1639 static int is_set = 0;
1640 static char path[MAX_PATH+1];
1642 LPITEMIDLIST idl;
1643 IMalloc *m;
1644 HRESULT result;
1646 if (is_set)
1647 return path;
1649 /* Find X:\documents and settings\username\application data\ .
1650 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
1652 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
1653 &idl))) {
1654 GetCurrentDirectory(MAX_PATH, path);
1655 is_set = 1;
1656 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);
1657 return path;
1659 /* Convert the path from an "ID List" (whatever that is!) to a path. */
1660 result = SHGetPathFromIDList(idl, path);
1661 /* Now we need to free the */
1662 SHGetMalloc(&m);
1663 if (m) {
1664 m->lpVtbl->Free(m, idl);
1665 m->lpVtbl->Release(m);
1667 if (!SUCCEEDED(result)) {
1668 return NULL;
1670 strlcat(path,"\\tor",MAX_PATH);
1671 is_set = 1;
1672 return path;
1674 #endif
1676 /** Return the default location for our torrc file. */
1677 static char *
1678 get_default_conf_file(void)
1680 #ifdef MS_WINDOWS
1681 char *path = tor_malloc(MAX_PATH);
1682 strlcpy(path, get_windows_conf_root(), MAX_PATH);
1683 strlcat(path,"\\torrc",MAX_PATH);
1684 return path;
1685 #else
1686 return tor_strdup(CONFDIR "/torrc");
1687 #endif
1690 /** Verify whether lst is a string containing valid-looking space-separated
1691 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
1693 static int check_nickname_list(const char *lst, const char *name)
1695 int r = 0;
1696 smartlist_t *sl;
1698 if (!lst)
1699 return 0;
1700 sl = smartlist_create();
1701 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1702 SMARTLIST_FOREACH(sl, const char *, s,
1704 if (!is_legal_nickname_or_hexdigest(s)) {
1705 log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
1706 r = -1;
1709 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
1710 smartlist_free(sl);
1711 return r;
1714 /** Read a configuration file into <b>options</b>, finding the configuration
1715 * file location based on the command line. After loading the options,
1716 * validate them for consistency, then take actions based on them.
1717 * Return 0 if success, -1 if failure. */
1719 init_from_config(int argc, char **argv)
1721 or_options_t *oldoptions, *newoptions;
1722 struct config_line_t *cl;
1723 char *cf=NULL, *fname=NULL;
1724 int i, retval;
1725 int using_default_torrc;
1726 static char **backup_argv;
1727 static int backup_argc;
1729 if (argv) { /* first time we're called. save commandline args */
1730 backup_argv = argv;
1731 backup_argc = argc;
1732 oldoptions = NULL;
1733 } else { /* we're reloading. need to clean up old options first. */
1734 argv = backup_argv;
1735 argc = backup_argc;
1736 oldoptions = get_options();
1738 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
1739 print_usage();
1740 exit(0);
1743 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
1744 printf("Tor version %s.\n",VERSION);
1745 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
1746 print_cvs_version();
1748 exit(0);
1751 newoptions = tor_malloc_zero(sizeof(or_options_t));
1752 options_init(newoptions);
1754 /* learn config file name, get config lines, assign them */
1755 fname = NULL;
1756 using_default_torrc = 1;
1757 newoptions->command = CMD_RUN_TOR;
1758 for (i = 1; i < argc; ++i) {
1759 if (i < argc-1 && !strcmp(argv[i],"-f")) {
1760 if (fname) {
1761 log(LOG_WARN, "Duplicate -f options on command line.");
1762 tor_free(fname);
1764 fname = tor_strdup(argv[i+1]);
1765 using_default_torrc = 0;
1766 ++i;
1767 } else if (!strcmp(argv[i],"--list-fingerprint")) {
1768 newoptions->command = CMD_LIST_FINGERPRINT;
1769 } else if (!strcmp(argv[i],"--hash-password")) {
1770 newoptions->command = CMD_HASH_PASSWORD;
1771 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
1772 ++i;
1776 if (using_default_torrc) {
1777 /* didn't find one, try CONFDIR */
1778 char *fn;
1779 fn = get_default_conf_file();
1780 if (fn && file_status(fn) == FN_FILE) {
1781 fname = fn;
1782 } else {
1783 tor_free(fn);
1784 #ifndef MS_WINDOWS
1785 fn = expand_filename("~/.torrc");
1786 if (fn && file_status(fn) == FN_FILE) {
1787 fname = fn;
1788 } else {
1789 tor_free(fn);
1790 fname = get_default_conf_file();
1792 #else
1793 fname = get_default_conf_file();
1794 #endif
1797 tor_assert(fname);
1798 log(LOG_DEBUG, "Opening config file '%s'", fname);
1800 if (file_status(fname) != FN_FILE ||
1801 !(cf = read_file_to_str(fname,0))) {
1802 if (using_default_torrc == 1) {
1803 log(LOG_NOTICE, "Configuration file '%s' not present, "
1804 "using reasonable defaults.", fname);
1805 tor_free(fname); /* sets fname to NULL */
1806 } else {
1807 log(LOG_WARN, "Unable to open configuration file '%s'.", fname);
1808 tor_free(fname);
1809 goto err;
1811 } else { /* it opened successfully. use it. */
1812 retval = config_get_lines(cf, &cl);
1813 tor_free(cf);
1814 if (retval < 0)
1815 goto err;
1816 retval = config_assign(newoptions, cl, 0);
1817 config_free_lines(cl);
1818 if (retval < 0)
1819 goto err;
1822 /* Go through command-line variables too */
1823 cl = config_get_commandlines(argc,argv);
1824 retval = config_assign(newoptions,cl,0);
1825 config_free_lines(cl);
1826 if (retval < 0)
1827 goto err;
1829 /* Validate newoptions */
1830 if (options_validate(newoptions) < 0)
1831 goto err;
1833 if (options_transition_allowed(oldoptions, newoptions) < 0)
1834 goto err;
1836 set_options(newoptions); /* frees and replaces old options */
1837 if (options_act() < 0) { /* acting on them failed. die. */
1838 log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying.");
1839 exit(1);
1841 tor_free(config_fname);
1842 config_fname = fname;
1843 return 0;
1844 err:
1845 tor_free(fname);
1846 options_free(newoptions);
1847 return -1;
1850 static void
1851 config_register_addressmaps(or_options_t *options) {
1852 smartlist_t *elts;
1853 struct config_line_t *opt;
1854 char *from, *to;
1856 addressmap_clear_configured();
1857 elts = smartlist_create();
1858 for (opt = options->AddressMap; opt; opt = opt->next) {
1859 smartlist_split_string(elts, opt->value, NULL,
1860 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
1861 if (smartlist_len(elts) >= 2) {
1862 from = smartlist_get(elts,0);
1863 to = smartlist_get(elts,1);
1864 if (!is_plausible_address(from)) {
1865 log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",from);
1866 } else if (!is_plausible_address(to)) {
1867 log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",to);
1868 } else {
1869 addressmap_register(from, tor_strdup(to), 0);
1870 if (smartlist_len(elts)>2) {
1871 log_fn(LOG_WARN,"Ignoring extra arguments to MapAddress.");
1874 } else {
1875 log_fn(LOG_WARN,"MapAddress '%s' has too few arguments. Ignoring.", opt->value);
1877 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
1878 smartlist_clear(elts);
1880 smartlist_free(elts);
1883 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
1884 * recognized log severity levels, set *<b>min_out</b> to MIN and
1885 * *<b>max_out</b> to MAX and return 0. Else, if <b>range<b> is of
1886 * the form MIN, act as if MIN-err had been specified. Else, warn and
1887 * return -1.
1889 static int
1890 parse_log_severity_range(const char *range, int *min_out, int *max_out)
1892 int levelMin, levelMax;
1893 const char *cp;
1894 cp = strchr(range, '-');
1895 if (cp) {
1896 if (cp == range) {
1897 levelMin = LOG_DEBUG;
1898 } else {
1899 char *tmp_sev = tor_strndup(range, cp - range);
1900 levelMin = parse_log_level(tmp_sev);
1901 if (levelMin < 0) {
1902 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1903 "err|warn|notice|info|debug", tmp_sev);
1904 tor_free(tmp_sev);
1905 return -1;
1907 tor_free(tmp_sev);
1909 if (!*(cp+1)) {
1910 levelMax = LOG_ERR;
1911 } else {
1912 levelMax = parse_log_level(cp+1);
1913 if (levelMax < 0) {
1914 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1915 "err|warn|notice|info|debug", cp+1);
1916 return -1;
1919 } else {
1920 levelMin = parse_log_level(range);
1921 if (levelMin < 0) {
1922 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1923 "err|warn|notice|info|debug", range);
1924 return -1;
1926 levelMax = LOG_ERR;
1929 *min_out = levelMin;
1930 *max_out = levelMax;
1932 return 0;
1935 /** Try to convert a pair of old-style logging options [LogLevel, and
1936 * (LogFile/Syslog)] to a new-style option, and add the new option to
1937 * options->Logs. */
1938 static int
1939 convert_log_option(or_options_t *options, struct config_line_t *level_opt,
1940 struct config_line_t *file_opt, int isDaemon)
1942 int levelMin = -1, levelMax = -1;
1944 if (level_opt) {
1945 if (parse_log_severity_range(level_opt->value, &levelMin, &levelMax))
1946 return -1;
1948 if (levelMin < 0 && levelMax < 0) {
1949 levelMin = LOG_NOTICE;
1950 levelMax = LOG_ERR;
1951 } else if (levelMin < 0) {
1952 levelMin = levelMax;
1953 } else {
1954 levelMax = LOG_ERR;
1957 if (file_opt && !strcasecmp(file_opt->key, "LogFile")) {
1958 if (add_single_log_option(options, levelMin, levelMax, "file", file_opt->value) < 0) {
1959 log_fn(LOG_WARN, "Cannot write to LogFile '%s': %s.", file_opt->value,
1960 strerror(errno));
1961 return -1;
1963 } else if (file_opt && !strcasecmp(file_opt->key, "SysLog")) {
1964 if (add_single_log_option(options, levelMin, levelMax, "syslog", NULL) < 0)
1965 return -1;
1966 } else if (!isDaemon) {
1967 add_single_log_option(options, levelMin, levelMax, "stdout", NULL);
1969 return 0;
1973 * Initialize the logs based on the configuration file.
1976 config_init_logs(or_options_t *options, int validate_only)
1978 struct config_line_t *opt;
1979 int ok;
1980 smartlist_t *elts;
1982 ok = 1;
1983 elts = smartlist_create();
1984 for (opt = options->Logs; opt; opt = opt->next) {
1985 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
1986 smartlist_split_string(elts, opt->value, NULL,
1987 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
1988 if (smartlist_len(elts) == 0) {
1989 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1990 ok = 0; goto cleanup;
1992 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin, &levelMax)) {
1993 ok = 0; goto cleanup;
1995 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
1996 if (!validate_only)
1997 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
1998 goto cleanup;
2000 if (!strcasecmp(smartlist_get(elts,1), "file")) {
2001 if (smartlist_len(elts) != 3) {
2002 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
2003 ok = 0; goto cleanup;
2005 if (!validate_only)
2006 add_file_log(levelMin, levelMax, smartlist_get(elts, 2));
2007 goto cleanup;
2009 if (smartlist_len(elts) != 2) {
2010 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
2011 ok = 0; goto cleanup;
2013 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
2014 if (!validate_only) {
2015 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
2016 close_temp_logs();
2018 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
2019 if (!validate_only) {
2020 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
2021 close_temp_logs();
2023 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
2024 #ifdef HAVE_SYSLOG_H
2025 if (!validate_only)
2026 add_syslog_log(levelMin, levelMax);
2027 #else
2028 log_fn(LOG_WARN, "Syslog is not supported in this compilation.");
2029 #endif
2030 } else {
2031 log_fn(LOG_WARN, "Unrecognized log type %s",
2032 (const char*)smartlist_get(elts,1));
2033 if (strchr(smartlist_get(elts,1), '/')) {
2034 log_fn(LOG_WARN, "Did you mean to say 'Log file %s' ?",
2035 (const char *)smartlist_get(elts,1));
2037 ok = 0; goto cleanup;
2039 cleanup:
2040 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
2041 smartlist_clear(elts);
2043 smartlist_free(elts);
2044 if (!validate_only)
2045 close_temp_logs();
2047 return ok?0:-1;
2050 /** Add a single option of the form Log min-max <type> [fname] to options. */
2051 static int
2052 add_single_log_option(or_options_t *options, int minSeverity, int maxSeverity,
2053 const char *type, const char *fname)
2055 char buf[512];
2056 int n;
2058 n = tor_snprintf(buf, sizeof(buf), "%s%s%s %s%s%s",
2059 log_level_to_string(minSeverity),
2060 maxSeverity == LOG_ERR ? "" : "-",
2061 maxSeverity == LOG_ERR ? "" : log_level_to_string(maxSeverity),
2062 type, fname?" ":"", fname?fname:"");
2063 if (n<0) {
2064 log_fn(LOG_WARN, "Normalized log option too long.");
2065 return -1;
2068 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);
2069 config_line_append(&options->Logs, "Log", buf);
2070 return 0;
2073 /** Convert all old-style logging options to new-style Log options. Return 0
2074 * on success, -1 on failure. */
2075 static int
2076 normalize_log_options(or_options_t *options)
2078 /* The order of options is: Level? (File Level?)+
2080 struct config_line_t *opt = options->OldLogOptions;
2082 /* Special case for if first option is LogLevel. */
2083 if (opt && !strcasecmp(opt->key, "LogLevel")) {
2084 if (opt->next && (!strcasecmp(opt->next->key, "LogFile") ||
2085 !strcasecmp(opt->next->key, "SysLog"))) {
2086 if (convert_log_option(options, opt, opt->next, options->RunAsDaemon) < 0)
2087 return -1;
2088 opt = opt->next->next;
2089 } else if (!opt->next) {
2090 if (convert_log_option(options, opt, NULL, options->RunAsDaemon) < 0)
2091 return -1;
2092 opt = opt->next;
2093 } else {
2094 ; /* give warning below */
2098 while (opt) {
2099 if (!strcasecmp(opt->key, "LogLevel")) {
2100 log_fn(LOG_WARN, "Two LogLevel options in a row without intervening LogFile or SysLog");
2101 opt = opt->next;
2102 } else {
2103 tor_assert(!strcasecmp(opt->key, "LogFile") ||
2104 !strcasecmp(opt->key, "SysLog"));
2105 if (opt->next && !strcasecmp(opt->next->key, "LogLevel")) {
2106 /* LogFile/SysLog followed by LogLevel */
2107 if (convert_log_option(options,opt->next,opt, options->RunAsDaemon) < 0)
2108 return -1;
2109 opt = opt->next->next;
2110 } else {
2111 /* LogFile/SysLog followed by LogFile/SysLog or end of list. */
2112 if (convert_log_option(options,NULL, opt, options->RunAsDaemon) < 0)
2113 return -1;
2114 opt = opt->next;
2119 if (options->DebugLogFile) {
2120 if (add_single_log_option(options, LOG_DEBUG, LOG_ERR, "file", options->DebugLogFile) < 0)
2121 return -1;
2124 tor_free(options->DebugLogFile);
2125 config_free_lines(options->OldLogOptions);
2126 options->OldLogOptions = NULL;
2128 return 0;
2132 * Given a linked list of config lines containing "allow" and "deny" tokens,
2133 * parse them and append the result to <b>dest</b>. Return -1 if any tokens
2134 * are malformed, else return 0.
2137 config_parse_addr_policy(struct config_line_t *cfg,
2138 addr_policy_t **dest)
2140 addr_policy_t **nextp;
2141 smartlist_t *entries;
2142 int r = 0;
2144 if (!cfg)
2145 return 0;
2147 nextp = dest;
2149 while (*nextp)
2150 nextp = &((*nextp)->next);
2152 entries = smartlist_create();
2153 for (; cfg; cfg = cfg->next) {
2154 smartlist_split_string(entries, cfg->value, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2155 SMARTLIST_FOREACH(entries, const char *, ent,
2157 log_fn(LOG_DEBUG,"Adding new entry '%s'",ent);
2158 *nextp = router_parse_addr_policy_from_string(ent);
2159 if (*nextp) {
2160 nextp = &((*nextp)->next);
2161 } else {
2162 log_fn(LOG_WARN,"Malformed policy %s.", ent);
2163 r = -1;
2166 SMARTLIST_FOREACH(entries, char *, ent, tor_free(ent));
2167 smartlist_clear(entries);
2169 smartlist_free(entries);
2170 return r;
2173 /** Release all storage held by <b>p</b> */
2174 void
2175 addr_policy_free(addr_policy_t *p) {
2176 addr_policy_t *e;
2178 while (p) {
2179 e = p;
2180 p = p->next;
2181 tor_free(e->string);
2182 tor_free(e);
2186 /** Parse a single RedirectExit line's contents from <b>line</b>. If
2187 * they are valid, and <b>result</b> is not NULL, add an element to
2188 * <b>result</b> and return 0. Else if they are valid, return 0.
2189 * Else return -1. */
2190 static int
2191 parse_redirect_line(smartlist_t *result, struct config_line_t *line)
2193 smartlist_t *elements = NULL;
2194 exit_redirect_t *r;
2196 tor_assert(line);
2198 r = tor_malloc_zero(sizeof(exit_redirect_t));
2199 elements = smartlist_create();
2200 smartlist_split_string(elements, line->value, NULL,
2201 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2202 if (smartlist_len(elements) != 2) {
2203 log_fn(LOG_WARN, "Wrong number of elements in RedirectExit line");
2204 goto err;
2206 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
2207 &r->port_min,&r->port_max)) {
2208 log_fn(LOG_WARN, "Error parsing source address in RedirectExit line");
2209 goto err;
2211 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
2212 r->is_redirect = 0;
2213 } else {
2214 if (parse_addr_port(smartlist_get(elements,1),NULL,&r->addr_dest,
2215 &r->port_dest)) {
2216 log_fn(LOG_WARN, "Error parsing dest address in RedirectExit line");
2217 goto err;
2219 r->is_redirect = 1;
2222 goto done;
2223 err:
2224 tor_free(r);
2225 done:
2226 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2227 smartlist_free(elements);
2228 if (r) {
2229 if (result)
2230 smartlist_add(result, r);
2231 else
2232 tor_free(r);
2233 return 0;
2234 } else {
2235 return -1;
2239 /** Read the contents of a DirServer line from <b>line</b>. Return 0
2240 * if the line is well-formed, and 0 if it isn't. If
2241 * <b>validate_only</b> is 0, and the line is well-formed, then add
2242 * the dirserver described in the line as a valid server. */
2243 static int
2244 parse_dir_server_line(const char *line, int validate_only)
2246 smartlist_t *items = NULL;
2247 int r;
2248 char *addrport, *address=NULL;
2249 uint16_t port;
2250 char digest[DIGEST_LEN];
2252 items = smartlist_create();
2253 smartlist_split_string(items, line, NULL,
2254 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
2255 if (smartlist_len(items) < 2) {
2256 log_fn(LOG_WARN, "Too few arguments to DirServer line.");
2257 goto err;
2259 addrport = smartlist_get(items, 0);
2260 if (parse_addr_port(addrport, &address, NULL, &port)<0) {
2261 log_fn(LOG_WARN, "Error parsing DirServer address '%s'", addrport);
2262 goto err;
2264 if (!port) {
2265 log_fn(LOG_WARN, "Missing port in DirServer address '%s'",addrport);
2266 goto err;
2269 tor_strstrip(smartlist_get(items, 1), " ");
2270 if (strlen(smartlist_get(items, 1)) != HEX_DIGEST_LEN) {
2271 log_fn(LOG_WARN, "Key digest for DirServer is wrong length.");
2272 goto err;
2274 if (base16_decode(digest, DIGEST_LEN,
2275 smartlist_get(items,1), HEX_DIGEST_LEN)<0) {
2276 log_fn(LOG_WARN, "Unable to decode DirServer key digest.");
2277 goto err;
2280 if (!validate_only) {
2281 log_fn(LOG_DEBUG, "Trusted dirserver at %s:%d (%s)", address, (int)port,
2282 (char*)smartlist_get(items,1));
2283 add_trusted_dir_server(address, port, digest);
2286 r = 0;
2287 goto done;
2289 err:
2290 r = -1;
2292 done:
2293 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
2294 smartlist_free(items);
2295 tor_free(address);
2296 return r;
2299 /** Adjust the value of options->DataDirectory, or fill it in if it's
2300 * absent. Return 0 on success, -1 on failure. */
2301 static int
2302 normalize_data_directory(or_options_t *options) {
2303 #ifdef MS_WINDOWS
2304 char *p;
2305 if (options->DataDirectory)
2306 return 0; /* all set */
2307 p = tor_malloc(MAX_PATH);
2308 strlcpy(p,get_windows_conf_root(),MAX_PATH);
2309 options->DataDirectory = p;
2310 return 0;
2311 #else
2312 const char *d = options->DataDirectory;
2313 if (!d)
2314 d = "~/.tor";
2316 if (strncmp(d,"~/",2) == 0) {
2317 char *fn = expand_filename(d);
2318 if (!fn) {
2319 log_fn(LOG_ERR,"Failed to expand filename '%s'.", d);
2320 return -1;
2322 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
2323 /* If our homedir is /, we probably don't want to use it. */
2324 /* XXXX Default to /var/lib/tor? */
2325 log_fn(LOG_WARN, "Defaulting to 'DataDirectory %s', which may not be what you want", fn);
2327 tor_free(options->DataDirectory);
2328 options->DataDirectory = fn;
2330 return 0;
2331 #endif
2334 /** Check and normalize the value of options->DataDirectory; return 0 if it
2335 * sane, -1 otherwise. */
2336 static int
2337 validate_data_directory(or_options_t *options) {
2338 if (normalize_data_directory(options) < 0)
2339 return -1;
2340 tor_assert(options->DataDirectory);
2341 if (strlen(options->DataDirectory) > (512-128)) {
2342 log_fn(LOG_ERR, "DataDirectory is too long.");
2343 return -1;
2345 #if 0
2346 if (check_private_dir(options->DataDirectory, CPD_CHECK != 0)) {
2347 log_fn(LOG_WARN, "Can't create directory %s", options->DataDirectory);
2348 return -1;
2350 #endif
2351 return 0;
2354 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; if you edit it, comments will not be preserved"
2356 /** Save a configuration file for the configuration in <b>options</b>
2357 * into the file <b>fname</b>. If the file already exists, and
2358 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
2359 * replace it. Return 0 on success, -1 on failure. */
2360 static int
2361 write_configuration_file(const char *fname, or_options_t *options)
2363 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
2364 int rename_old = 0, r;
2365 size_t len;
2367 if (fname) {
2368 switch (file_status(fname)) {
2369 case FN_FILE:
2370 old_val = read_file_to_str(fname, 0);
2371 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
2372 rename_old = 1;
2374 tor_free(old_val);
2375 break;
2376 case FN_NOENT:
2377 break;
2378 default:
2379 log_fn(LOG_WARN,"Config file %s is not a file? Failing.", fname);
2380 return -1;
2384 if (!(new_conf = config_dump_options(options, 1))) {
2385 log_fn(LOG_WARN, "Couldn't get configuration string");
2386 goto err;
2389 len = strlen(new_conf)+128;
2390 new_val = tor_malloc(len);
2391 tor_snprintf(new_val, len, "%s\n\n%s", GENERATED_FILE_PREFIX, new_conf);
2393 if (rename_old) {
2394 int i = 1;
2395 size_t fn_tmp_len = strlen(fname)+32;
2396 char *fn_tmp;
2397 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
2398 fn_tmp = tor_malloc(fn_tmp_len);
2399 while (1) {
2400 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
2401 log_fn(LOG_WARN, "tor_snprintf failed inexplicably");
2402 tor_free(fn_tmp);
2403 goto err;
2405 if (file_status(fn_tmp) == FN_NOENT)
2406 break;
2407 ++i;
2409 log_fn(LOG_NOTICE, "Renaming old configuration file to %s", fn_tmp);
2410 rename(fname, fn_tmp);
2411 tor_free(fn_tmp);
2414 write_str_to_file(fname, new_val, 0);
2416 r = 0;
2417 goto done;
2418 err:
2419 r = -1;
2420 done:
2421 tor_free(new_val);
2422 tor_free(new_conf);
2423 return r;
2427 * Save the current configuration file value to disk. Return 0 on
2428 * success, -1 on failure.
2431 save_current_config(void)
2433 char *fn;
2434 if (config_fname) {
2435 /* XXX This fails if we can't write to our configuration file.
2436 * Arguably, we should try falling back to datadirectory or something.
2437 * But just as arguably, we shouldn't. */
2438 return write_configuration_file(config_fname, get_options());
2440 fn = get_default_conf_file();
2441 return write_configuration_file(fn, get_options());
2444 struct unit_table_t {
2445 const char *unit;
2446 uint64_t multiplier;
2449 static struct unit_table_t memory_units[] = {
2450 { "", 1 },
2451 { "b", 1<< 0 },
2452 { "byte", 1<< 0 },
2453 { "bytes", 1<< 0 },
2454 { "kb", 1<<10 },
2455 { "kilobyte", 1<<10 },
2456 { "kilobytes", 1<<10 },
2457 { "m", 1<<20 },
2458 { "mb", 1<<20 },
2459 { "megabyte", 1<<20 },
2460 { "megabytes", 1<<20 },
2461 { "gb", 1<<30 },
2462 { "gigabyte", 1<<30 },
2463 { "gigabytes", 1<<30 },
2464 { "tb", U64_LITERAL(1)<<40 },
2465 { "terabyte", U64_LITERAL(1)<<40 },
2466 { "terabytes", U64_LITERAL(1)<<40 },
2467 { NULL, 0 },
2470 static struct unit_table_t time_units[] = {
2471 { "", 1 },
2472 { "second", 1 },
2473 { "seconds", 1 },
2474 { "minute", 60 },
2475 { "minutes", 60 },
2476 { "hour", 60*60 },
2477 { "hours", 60*60 },
2478 { "day", 24*60*60 },
2479 { "days", 24*60*60 },
2480 { "week", 7*24*60*60 },
2481 { "weeks", 7*24*60*60 },
2482 { NULL, 0 },
2485 /** Parse a string <b>val</b> containing a number, zero or more
2486 * spaces, and an optional unit string. If the unit appears in the
2487 * table <b>u</b>, then multiply the number by the unit multiplier.
2488 * On success, set *<b>ok</b> to 1 and return this product.
2489 * Otherwise, set *<b>ok</b> to 0.
2491 static uint64_t
2492 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
2494 uint64_t v;
2495 char *cp;
2497 tor_assert(ok);
2499 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
2500 if (!*ok)
2501 return 0;
2502 if (!cp) {
2503 *ok = 1;
2504 return v;
2506 while (TOR_ISSPACE(*cp))
2507 ++cp;
2508 for ( ;u->unit;++u) {
2509 if (!strcasecmp(u->unit, cp)) {
2510 v *= u->multiplier;
2511 *ok = 1;
2512 return v;
2515 log_fn(LOG_WARN, "Unknown unit '%s'.", cp);
2516 *ok = 0;
2517 return 0;
2520 /** Parse a string in the format "number unit", where unit is a unit of
2521 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
2522 * and return the number of bytes specified. Otherwise, set
2523 * *<b>ok</b> to false and return 0. */
2524 static uint64_t
2525 config_parse_memunit(const char *s, int *ok) {
2526 return config_parse_units(s, memory_units, ok);
2529 /** Parse a string in the format "number unit", where unit is a unit of time.
2530 * On success, set *<b>ok</b> to true and return the number of seconds in
2531 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
2533 static int
2534 config_parse_interval(const char *s, int *ok) {
2535 uint64_t r;
2536 r = config_parse_units(s, time_units, ok);
2537 if (!ok)
2538 return -1;
2539 if (r > INT_MAX) {
2540 log_fn(LOG_WARN, "Interval '%s' is too long", s);
2541 *ok = 0;
2542 return -1;
2544 return (int)r;
2547 static void
2548 print_cvs_version(void)
2550 extern const char aes_c_id[];
2551 extern const char compat_c_id[];
2552 extern const char container_c_id[];
2553 extern const char crypto_c_id[];
2554 extern const char log_c_id[];
2555 extern const char torgzip_c_id[];
2556 extern const char tortls_c_id[];
2557 extern const char util_c_id[];
2559 extern const char buffers_c_id[];
2560 extern const char circuitbuild_c_id[];
2561 extern const char circuitlist_c_id[];
2562 extern const char circuituse_c_id[];
2563 extern const char command_c_id[];
2564 // extern const char config_c_id[];
2565 extern const char connection_c_id[];
2566 extern const char connection_edge_c_id[];
2567 extern const char connection_or_c_id[];
2568 extern const char control_c_id[];
2569 extern const char cpuworker_c_id[];
2570 extern const char directory_c_id[];
2571 extern const char dirserv_c_id[];
2572 extern const char dns_c_id[];
2573 extern const char hibernate_c_id[];
2574 extern const char main_c_id[];
2575 extern const char onion_c_id[];
2576 extern const char relay_c_id[];
2577 extern const char rendclient_c_id[];
2578 extern const char rendcommon_c_id[];
2579 extern const char rendmid_c_id[];
2580 extern const char rendservice_c_id[];
2581 extern const char rephist_c_id[];
2582 extern const char router_c_id[];
2583 extern const char routerlist_c_id[];
2584 extern const char routerparse_c_id[];
2586 puts(AES_H_ID);
2587 puts(COMPAT_H_ID);
2588 puts(CONTAINER_H_ID);
2589 puts(CRYPTO_H_ID);
2590 puts(LOG_H_ID);
2591 puts(TORGZIP_H_ID);
2592 puts(TORINT_H_ID);
2593 puts(TORTLS_H_ID);
2594 puts(UTIL_H_ID);
2595 puts(aes_c_id);
2596 puts(compat_c_id);
2597 puts(container_c_id);
2598 puts(crypto_c_id);
2599 puts(log_c_id);
2600 puts(torgzip_c_id);
2601 puts(tortls_c_id);
2602 puts(util_c_id);
2604 puts(OR_H_ID);
2605 puts(buffers_c_id);
2606 puts(circuitbuild_c_id);
2607 puts(circuitlist_c_id);
2608 puts(circuituse_c_id);
2609 puts(command_c_id);
2610 puts(config_c_id);
2611 puts(connection_c_id);
2612 puts(connection_edge_c_id);
2613 puts(connection_or_c_id);
2614 puts(control_c_id);
2615 puts(cpuworker_c_id);
2616 puts(directory_c_id);
2617 puts(dirserv_c_id);
2618 puts(dns_c_id);
2619 puts(hibernate_c_id);
2620 puts(main_c_id);
2621 puts(onion_c_id);
2622 puts(relay_c_id);
2623 puts(rendclient_c_id);
2624 puts(rendcommon_c_id);
2625 puts(rendmid_c_id);
2626 puts(rendservice_c_id);
2627 puts(rephist_c_id);
2628 puts(router_c_id);
2629 puts(routerlist_c_id);
2630 puts(routerparse_c_id);