forward-port the dns and maxconn fixes
[tor.git] / src / or / config.c
blob33f0e023d39a61b38e8439b74ca50419f23158a3
1 /* Copyright 2001 Matej Pfajfar.
2 * Copyright 2001-2004 Roger Dingledine.
3 * Copyright 2004 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 { NULL, NULL , 0},
69 #undef PLURAL
71 /** A variable allowed in the configuration file or on the command line. */
72 typedef struct config_var_t {
73 const char *name; /**< The full keyword (case insensitive). */
74 config_type_t type; /**< How to interpret the type and turn it into a value. */
75 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
76 const char *initvalue; /**< String (or null) describing initial value. */
77 } config_var_t;
79 /** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */
80 #define STRUCT_OFFSET(tp, member) ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
81 /** An entry for config_vars: "The option <b>name</b> has type
82 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
83 * or_options_t.<b>member</b>"
85 #define VAR(name,conftype,member,initvalue) \
86 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), initvalue }
87 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
88 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
90 /** Array of configuration options. Until we disallow nonstandard
91 * abbreviations, order is significant, since the first matching option will
92 * be chosen first.
94 static config_var_t config_vars[] = {
95 VAR("Address", STRING, Address, NULL),
96 VAR("AccountingStart", STRING, AccountingStart, NULL),
97 VAR("AllowUnverifiedNodes",CSV, AllowUnverifiedNodes, "middle,rendezvous"),
98 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
99 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "780 KB"),
100 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "48 MB"),
101 VAR("ClientOnly", BOOL, ClientOnly, "0"),
102 VAR("ContactInfo", STRING, ContactInfo, NULL),
103 VAR("ControlPort", UINT, ControlPort, "0"),
104 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
105 VAR("DebugLogFile", STRING, DebugLogFile, NULL),
106 VAR("DataDirectory", STRING, DataDirectory, NULL),
107 VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL),
108 VAR("DirPort", UINT, DirPort, "0"),
109 VAR("DirBindAddress", LINELIST, DirBindAddress, NULL),
110 /* XXX we'd like dirfetchperiod to be higher for people with dirport not
111 * set, but low for people with dirport set. how to have two defaults? */
112 VAR("DirFetchPeriod", INTERVAL, DirFetchPeriod, "1 hour"),
113 VAR("DirPostPeriod", INTERVAL, DirPostPeriod, "20 minutes"),
114 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "20 minutes"),
115 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
116 VAR("DirServer", LINELIST, DirServers, NULL),
117 VAR("ExitNodes", STRING, ExitNodes, NULL),
118 VAR("EntryNodes", STRING, EntryNodes, NULL),
119 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
120 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
121 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
122 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
123 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
124 VAR("FirewallPorts", CSV, FirewallPorts, "80,443"),
125 VAR("MyFamily", STRING, MyFamily, NULL),
126 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
127 VAR("Group", STRING, Group, NULL),
128 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
129 VAR("HttpProxy", STRING, HttpProxy, NULL),
130 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
131 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
132 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
133 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
134 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
135 VAR("IgnoreVersion", BOOL, IgnoreVersion, "0"),
136 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
137 VAR("Log", LINELIST, Logs, NULL),
138 VAR("LogLevel", LINELIST_S, OldLogOptions, NULL),
139 VAR("LogFile", LINELIST_S, OldLogOptions, NULL),
140 OBSOLETE("LinkPadding"),
141 VAR("MaxConn", UINT, MaxConn, "1024"),
142 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
143 VAR("MonthlyAccountingStart",UINT, _MonthlyAccountingStart,"0"),
144 VAR("AccountingMaxKB", UINT, _AccountingMaxKB, "0"),
145 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
146 VAR("Nickname", STRING, Nickname, NULL),
147 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
148 VAR("MaxCircuitDirtiness", INTERVAL, MaxCircuitDirtiness, "10 minutes"),
149 VAR("NumCpus", UINT, NumCpus, "1"),
150 VAR("ORPort", UINT, ORPort, "0"),
151 VAR("ORBindAddress", LINELIST, ORBindAddress, NULL),
152 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
153 VAR("PidFile", STRING, PidFile, NULL),
154 VAR("LongLivedPorts", CSV, LongLivedPorts, "21,22,706,1863,5050,5190,5222,5223,6667,8300,8888"),
155 VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"),
156 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
157 OBSOLETE("RouterFile"),
158 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
159 VAR("RunTesting", BOOL, RunTesting, "0"),
160 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
161 VAR("RendNodes", STRING, RendNodes, NULL),
162 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
163 VAR("SocksPort", UINT, SocksPort, "9050"),
164 VAR("SocksBindAddress", LINELIST, SocksBindAddress, NULL),
165 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
166 /* XXX as with dirfetchperiod, we want this to be 15 minutes for people
167 * with a dirport open, but higher for people without a dirport open. */
168 VAR("StatusFetchPeriod", INTERVAL, StatusFetchPeriod, "15 minutes"),
169 VAR("SysLog", LINELIST_S, OldLogOptions, NULL),
170 OBSOLETE("TrafficShaping"),
171 VAR("User", STRING, User, NULL),
172 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
174 #undef VAR
175 #undef OBSOLETE
177 /** Largest allowed config line */
178 #define CONFIG_LINE_T_MAXLEN 4096
180 static void config_line_append(struct config_line_t **lst,
181 const char *key, const char *val);
182 static void option_reset(or_options_t *options, config_var_t *var);
183 static void options_free(or_options_t *options);
184 static int option_is_same(or_options_t *o1, or_options_t *o2,const char *name);
185 static or_options_t *options_dup(or_options_t *old);
186 static int options_validate(or_options_t *options);
187 static int options_transition_allowed(or_options_t *old, or_options_t *new);
188 static int check_nickname_list(const char *lst, const char *name);
190 static int parse_dir_server_line(const char *line, int validate_only);
191 static int parse_redirect_line(smartlist_t *result,
192 struct config_line_t *line);
193 static int parse_log_severity_range(const char *range, int *min_out,
194 int *max_out);
195 static int convert_log_option(or_options_t *options,
196 struct config_line_t *level_opt,
197 struct config_line_t *file_opt, int isDaemon);
198 static int add_single_log_option(or_options_t *options, int minSeverity,
199 int maxSeverity,
200 const char *type, const char *fname);
201 static int normalize_log_options(or_options_t *options);
202 static int validate_data_directory(or_options_t *options);
203 static int write_configuration_file(const char *fname, or_options_t *options);
205 static uint64_t config_parse_memunit(const char *s, int *ok);
206 static int config_parse_interval(const char *s, int *ok);
207 static void print_cvs_version(void);
210 * Functions to read and write the global options pointer.
213 /** Command-line and config-file options. */
214 static or_options_t *global_options=NULL;
215 /** Name of most recently read torrc file. */
216 static char *config_fname = NULL;
218 /** Return the currently configured options. */
219 or_options_t *
220 get_options(void) {
221 tor_assert(global_options);
222 return global_options;
225 /** Change the current global options to contain <b>new_val</b> instead
226 * of their current value; free the old value as necessary.
228 void
229 set_options(or_options_t *new_val) {
230 if (global_options)
231 options_free(global_options);
232 global_options = new_val;
235 /** Fetch the active option list, and take actions based on it. All
236 * of the things we do should survive being done repeatedly.
237 * Return 0 if all goes well, return -1 if it's time to die.
239 * Note 1: <b>new_val</b> must have previously been validated with
240 * options_validate(), or Tor may freak out and exit.
242 * Note 2: We haven't moved all the "act on new configuration" logic
243 * here yet. Some is still in do_hup() and other places.
246 options_act(void) {
247 struct config_line_t *cl;
248 or_options_t *options = get_options();
249 static int libevent_initialized = 0;
251 /* XXXX009 We once had a reason to separate start_daemon and finish_daemon:
252 * It let us have the parent process stick around until we were sure Tor
253 * was started. Should we make start_daemon get called earlier? -NM */
254 if (options->RunAsDaemon) {
255 start_daemon(options->DataDirectory);
257 if (!libevent_initialized) {
258 event_init();
259 libevent_initialized = 1;
262 clear_trusted_dir_servers();
263 for (cl = options->DirServers; cl; cl = cl->next) {
264 if (parse_dir_server_line(cl->value, 0)<0) {
265 log_fn(LOG_ERR,
266 "Bug: Previously validated DirServer line could not be added!");
267 return -1;
271 if (rend_config_services(options, 0)<0) {
272 log_fn(LOG_ERR,
273 "Bug: Previously validated hidden services line could not be added!");
274 return -1;
277 /* Setuid/setgid as appropriate */
278 if (options->User || options->Group) {
279 if (switch_id(options->User, options->Group) != 0) {
280 return -1;
284 /* Ensure data directory is private; create if possible. */
285 if (check_private_dir(options->DataDirectory, CPD_CREATE) != 0) {
286 log_fn(LOG_ERR, "Couldn't access/create private data directory %s",
287 options->DataDirectory);
288 return -1;
291 /* Bail out at this point if we're not going to be a server: we want
292 * to not fork, and to log stuff to stderr. */
293 if (options->command != CMD_RUN_TOR)
294 return 0;
296 mark_logs_temp(); /* Close current logs once new logs are open. */
297 if (config_init_logs(options, 0)<0) /* Configure the log(s) */
298 return -1;
299 /* Close the temporary log we used while starting up, if it isn't already
300 * gone. */
301 close_temp_logs();
302 add_callback_log(LOG_NOTICE, LOG_ERR, control_event_logmsg);
304 if (set_max_file_descriptors(options->MaxConn) < 0)
305 return -1;
308 smartlist_t *sl = smartlist_create();
309 for (cl = options->RedirectExit; cl; cl = cl->next) {
310 if (parse_redirect_line(sl, cl)<0)
311 return -1;
313 set_exit_redirects(sl);
316 /* Start backgrounding the process, if requested. */
318 /* Finish backgrounding the process */
319 if (options->RunAsDaemon) {
320 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
321 finish_daemon();
324 /* Write our pid to the pid file. If we do not have write permissions we
325 * will log a warning */
326 if (options->PidFile)
327 write_pidfile(options->PidFile);
329 /* Update address policies. */
330 parse_socks_policy();
331 parse_dir_policy();
333 init_cookie_authentication(options->CookieAuthentication);
335 /* reload keys as needed for rendezvous services. */
336 if (rend_service_load_keys()<0) {
337 log_fn(LOG_ERR,"Error loading rendezvous service keys");
338 return -1;
341 /* Set up accounting */
342 if (accounting_parse_options(options, 0)<0) {
343 log_fn(LOG_ERR,"Error in accounting options");
344 return -1;
346 if (accounting_is_enabled(options))
347 configure_accounting(time(NULL));
349 if (!we_are_hibernating() && retry_all_listeners(1) < 0) {
350 log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
351 return -1;
354 #if 0
356 char *smin, *smax;
357 smin = config_dump_options(options, 1);
358 smax = config_dump_options(options, 0);
359 log_fn(LOG_DEBUG, "These are our options:\n%s",smax);
360 log_fn(LOG_DEBUG, "We changed these options:\n%s",smin);
361 tor_free(smin);
362 tor_free(smax);
364 #endif
366 /* Since our options changed, we might need to regenerate and upload our
367 * server descriptor. (We could probably be more clever about only calling
368 * this when something significant changed.)
370 mark_my_descriptor_dirty();
372 return 0;
376 * Functions to parse config options
379 /** If <b>option</b> is an official abbreviation for a longer option,
380 * return the longer option. Otherwise return <b>option</b>.
381 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
382 * apply abbreviations that work for the config file and the command line. */
383 static const char *
384 expand_abbrev(const char *option, int command_line)
386 int i;
387 for (i=0; config_abbrevs[i].abbreviated; ++i) {
388 /* Abbreviations aren't casei. */
389 if (!strcasecmp(option,config_abbrevs[i].abbreviated) &&
390 (command_line || !config_abbrevs[i].commandline_only)) {
391 return config_abbrevs[i].full;
394 return option;
397 /** Helper: Read a list of configuration options from the command line. */
398 static struct config_line_t *
399 config_get_commandlines(int argc, char **argv)
401 struct config_line_t *new;
402 struct config_line_t *front = NULL;
403 char *s;
404 int i = 1;
406 while (i < argc-1) {
407 if (!strcmp(argv[i],"-f") ||
408 !strcmp(argv[i],"--hash-password")) {
409 i += 2; /* command-line option with argument. ignore them. */
410 continue;
411 } else if (!strcmp(argv[i],"--list-fingerprint")) {
412 i += 1; /* command-line option. ignore it. */
413 continue;
416 new = tor_malloc(sizeof(struct config_line_t));
417 s = argv[i];
419 while (*s == '-')
420 s++;
422 new->key = tor_strdup(expand_abbrev(s, 1));
423 new->value = tor_strdup(argv[i+1]);
425 log(LOG_DEBUG,"Commandline: parsed keyword '%s', value '%s'",
426 new->key, new->value);
427 new->next = front;
428 front = new;
429 i += 2;
431 return front;
434 /** Helper: allocate a new configuration option mapping 'key' to 'val',
435 * append it to *<b>lst</b>. */
436 static void
437 config_line_append(struct config_line_t **lst,
438 const char *key,
439 const char *val)
441 struct config_line_t *newline;
443 newline = tor_malloc(sizeof(struct config_line_t));
444 newline->key = tor_strdup(key);
445 newline->value = tor_strdup(val);
446 newline->next = NULL;
447 while (*lst)
448 lst = &((*lst)->next);
450 (*lst) = newline;
453 /** Helper: parse the config string and strdup into key/value
454 * strings. Set *result to the list, or NULL if parsing the string
455 * failed. Return 0 on success, -1 on failure. Warn and ignore any
456 * misformatted lines. */
458 config_get_lines(char *string, struct config_line_t **result)
460 struct config_line_t *list = NULL, **next;
461 char *k, *v;
463 next = &list;
464 do {
465 string = parse_line_from_str(string, &k, &v);
466 if (!string) {
467 config_free_lines(list);
468 return -1;
470 if (k && v) {
471 /* This list can get long, so we keep a pointer to the end of it
472 * rather than using config_line_append over and over and getting n^2
473 * performance. This is the only really long list. */
474 *next = tor_malloc(sizeof(struct config_line_t));
475 (*next)->key = tor_strdup(k);
476 (*next)->value = tor_strdup(v);
477 (*next)->next = NULL;
478 next = &((*next)->next);
480 } while (*string);
482 *result = list;
483 return 0;
487 * Free all the configuration lines on the linked list <b>front</b>.
489 void
490 config_free_lines(struct config_line_t *front)
492 struct config_line_t *tmp;
494 while (front) {
495 tmp = front;
496 front = tmp->next;
498 tor_free(tmp->key);
499 tor_free(tmp->value);
500 tor_free(tmp);
504 /** If <b>key</b> is a configuration option, return the corresponding
505 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
506 * warn, and return the corresponding config_var_t. Otherwise return NULL.
508 static config_var_t *config_find_option(const char *key)
510 int i;
511 /* First, check for an exact (case-insensitive) match */
512 for (i=0; config_vars[i].name; ++i) {
513 if (!strcasecmp(key, config_vars[i].name))
514 return &config_vars[i];
516 /* If none, check for an abbreviated match */
517 for (i=0; config_vars[i].name; ++i) {
518 if (!strncasecmp(key, config_vars[i].name, strlen(key))) {
519 log_fn(LOG_WARN, "The abbreviation '%s' is deprecated. "
520 "Tell Nick and Roger to make it official, or just use '%s' instead",
521 key, config_vars[i].name);
522 return &config_vars[i];
525 /* Okay, unrecognized options */
526 return NULL;
529 /** If <b>c</b> is a syntactically valid configuration line, update
530 * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
531 * -2 for bad value.
533 * If 'reset' is set, and we get a line containing no value, restore the
534 * option to its default value.
536 static int
537 config_assign_line(or_options_t *options, struct config_line_t *c, int reset)
539 int i, ok;
540 config_var_t *var;
541 void *lvalue;
543 var = config_find_option(c->key);
544 if (!var) {
545 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
546 return -1;
548 /* Put keyword into canonical case. */
549 if (strcmp(var->name, c->key)) {
550 tor_free(c->key);
551 c->key = tor_strdup(var->name);
554 if (reset && !strlen(c->value)) {
555 option_reset(options, var);
556 return 0;
559 lvalue = ((char*)options) + var->var_offset;
560 switch (var->type) {
562 case CONFIG_TYPE_UINT:
563 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
564 if (!ok) {
565 log(LOG_WARN, "Int keyword '%s %s' is malformed or out of bounds.",
566 c->key,c->value);
567 return -2;
569 *(int *)lvalue = i;
570 break;
572 case CONFIG_TYPE_INTERVAL: {
573 i = config_parse_interval(c->value, &ok);
574 if (!ok) {
575 return -2;
577 *(int *)lvalue = i;
578 break;
581 case CONFIG_TYPE_MEMUNIT: {
582 uint64_t u64 = config_parse_memunit(c->value, &ok);
583 if (!ok) {
584 return -2;
586 *(uint64_t *)lvalue = u64;
587 break;
590 case CONFIG_TYPE_BOOL:
591 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
592 if (!ok) {
593 log(LOG_WARN, "Boolean keyword '%s' expects 0 or 1.", c->key);
594 return -2;
596 *(int *)lvalue = i;
597 break;
599 case CONFIG_TYPE_STRING:
600 tor_free(*(char **)lvalue);
601 *(char **)lvalue = tor_strdup(c->value);
602 break;
604 case CONFIG_TYPE_DOUBLE:
605 *(double *)lvalue = atof(c->value);
606 break;
608 case CONFIG_TYPE_CSV:
609 if (*(smartlist_t**)lvalue) {
610 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
611 smartlist_clear(*(smartlist_t**)lvalue);
612 } else {
613 *(smartlist_t**)lvalue = smartlist_create();
616 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
617 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
618 break;
620 case CONFIG_TYPE_LINELIST:
621 case CONFIG_TYPE_LINELIST_S:
622 config_line_append((struct config_line_t**)lvalue, c->key, c->value);
623 break;
625 case CONFIG_TYPE_OBSOLETE:
626 log_fn(LOG_WARN, "Skipping obsolete configuration option '%s'", c->key);
627 break;
628 case CONFIG_TYPE_LINELIST_V:
629 log_fn(LOG_WARN, "Can't provide value for virtual option '%s'", c->key);
630 return -2;
631 default:
632 tor_assert(0);
633 break;
635 return 0;
638 /** restore the option named <b>key</b> in options to its default value. */
639 static void
640 config_reset_line(or_options_t *options, const char *key)
642 config_var_t *var;
644 var = config_find_option(key);
645 if (!var)
646 return; /* give error on next pass. */
648 option_reset(options, var);
651 /** Return true iff key is a valid configuration option. */
653 config_option_is_recognized(const char *key)
655 config_var_t *var = config_find_option(key);
656 return (var != NULL);
659 /** Return a canonicalized list of the options assigned for key.
661 struct config_line_t *
662 config_get_assigned_option(or_options_t *options, const char *key)
664 config_var_t *var;
665 const void *value;
666 char buf[32];
667 struct config_line_t *result;
668 tor_assert(options && key);
670 var = config_find_option(key);
671 if (!var) {
672 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", key);
673 return NULL;
674 } else if (var->type == CONFIG_TYPE_LINELIST_S) {
675 log_fn(LOG_WARN, "Can't return context-sensitive '%s' on its own", key);
676 return NULL;
678 value = ((char*)options) + var->var_offset;
680 if (var->type == CONFIG_TYPE_LINELIST ||
681 var->type == CONFIG_TYPE_LINELIST_V) {
682 /* Linelist requires special handling: we just copy and return it. */
683 const struct config_line_t *next_in = *(const struct config_line_t**)value;
684 struct config_line_t **next_out = &result;
685 while (next_in) {
686 *next_out = tor_malloc(sizeof(struct config_line_t));
687 (*next_out)->key = tor_strdup(next_in->key);
688 (*next_out)->value = tor_strdup(next_in->value);
689 next_in = next_in->next;
690 next_out = &((*next_out)->next);
692 (*next_out) = NULL;
693 return result;
696 result = tor_malloc_zero(sizeof(struct config_line_t));
697 result->key = tor_strdup(var->name);
698 switch (var->type)
700 case CONFIG_TYPE_STRING:
701 if (*(char**)value) {
702 result->value = tor_strdup(*(char**)value);
703 } else {
704 tor_free(result->key);
705 tor_free(result);
706 return NULL;
708 break;
709 case CONFIG_TYPE_INTERVAL:
710 case CONFIG_TYPE_UINT:
711 /* This means every or_options_t uint or bool element
712 * needs to be an int. Not, say, a uint16_t or char. */
713 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
714 result->value = tor_strdup(buf);
715 break;
716 case CONFIG_TYPE_MEMUNIT:
717 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
718 U64_PRINTF_ARG(*(uint64_t*)value));
719 result->value = tor_strdup(buf);
720 break;
721 case CONFIG_TYPE_DOUBLE:
722 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
723 result->value = tor_strdup(buf);
724 break;
725 case CONFIG_TYPE_BOOL:
726 result->value = tor_strdup(*(int*)value ? "1" : "0");
727 break;
728 case CONFIG_TYPE_CSV:
729 if (*(smartlist_t**)value)
730 result->value = smartlist_join_strings(*(smartlist_t**)value,",",0,NULL);
731 else
732 result->value = tor_strdup("");
733 break;
734 case CONFIG_TYPE_OBSOLETE:
735 log_fn(LOG_WARN,"You asked me for the value of an obsolete config option %s.", key);
736 tor_free(result->key);
737 tor_free(result);
738 return NULL;
739 default:
740 tor_free(result->key);
741 tor_free(result);
742 log_fn(LOG_WARN,"Bug: unknown type %d for known key %s", var->type, key);
743 return NULL;
746 return result;
749 /** Iterate through the linked list of requested options <b>list</b>.
750 * For each item, convert as appropriate and assign to <b>options</b>.
751 * If an item is unrecognized, return -1 immediately,
752 * else return 0 for success.
754 * If <b>reset</b>, then interpret empty lines as meaning "restore to
755 * default value", and interpret LINELIST* options as replacing (not
756 * extending) their previous values. Return 0 on success, -1 on bad key,
757 * -2 on bad value.
759 static int
760 config_assign(or_options_t *options, struct config_line_t *list, int reset)
762 struct config_line_t *p;
763 tor_assert(options);
765 /* pass 1: normalize keys */
766 for (p = list; p; p = p->next) {
767 const char *full = expand_abbrev(p->key, 0);
768 if (strcmp(full,p->key)) {
769 tor_free(p->key);
770 p->key = tor_strdup(full);
774 /* pass 2: if we're reading from a resetting source, clear all mentioned
775 * linelists. */
776 if (reset) {
777 for (p = list; p; p = p->next)
778 config_reset_line(options, p->key);
781 /* pass 3: assign. */
782 while (list) {
783 int r;
784 if ((r=config_assign_line(options, list, reset)))
785 return r;
786 list = list->next;
788 return 0;
791 /** Try assigning <b>list</b> to the global options. You do this by duping
792 * options, assigning list to the new one, then validating it. If it's
793 * ok, then throw out the old one and stick with the new one. Else,
794 * revert to old and return failure. Return 0 on success, -1 on bad
795 * keys, -2 on bad values, -3 on bad transition.
798 config_trial_assign(struct config_line_t *list, int reset)
800 int r;
801 or_options_t *trial_options = options_dup(get_options());
803 if ((r=config_assign(trial_options, list, reset)) < 0) {
804 options_free(trial_options);
805 return r;
808 if (options_validate(trial_options) < 0) {
809 options_free(trial_options);
810 return -2;
813 if (options_transition_allowed(get_options(), trial_options) < 0) {
814 options_free(trial_options);
815 return -3;
818 set_options(trial_options); /* we liked it. put it in place. */
819 return 0;
822 /** Replace the option indexed by <b>var</b> in <b>options</b> with its
823 * default value. */
824 static void
825 option_reset(or_options_t *options, config_var_t *var)
827 struct config_line_t *c;
828 void *lvalue;
830 lvalue = ((char*)options) + var->var_offset;
831 switch (var->type) {
832 case CONFIG_TYPE_STRING:
833 tor_free(*(char**)lvalue);
834 break;
835 case CONFIG_TYPE_DOUBLE:
836 *(double*)lvalue = 0.0;
837 break;
838 case CONFIG_TYPE_INTERVAL:
839 case CONFIG_TYPE_UINT:
840 case CONFIG_TYPE_BOOL:
841 *(int*)lvalue = 0;
842 break;
843 case CONFIG_TYPE_MEMUNIT:
844 *(uint64_t*)lvalue = 0;
845 break;
846 case CONFIG_TYPE_CSV:
847 if (*(smartlist_t**)lvalue) {
848 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
849 smartlist_free(*(smartlist_t **)lvalue);
850 *(smartlist_t **)lvalue = NULL;
852 break;
853 case CONFIG_TYPE_LINELIST:
854 case CONFIG_TYPE_LINELIST_S:
855 config_free_lines(*(struct config_line_t **)lvalue);
856 *(struct config_line_t **)lvalue = NULL;
857 break;
858 case CONFIG_TYPE_LINELIST_V:
859 /* handled by linelist_s. */
860 break;
861 case CONFIG_TYPE_OBSOLETE:
862 break;
864 if (var->initvalue) {
865 c = tor_malloc_zero(sizeof(struct config_line_t));
866 c->key = tor_strdup(var->name);
867 c->value = tor_strdup(var->initvalue);
868 config_assign_line(options,c,0);
869 config_free_lines(c);
873 /** Set <b>options</b>-&gt;DirServers to contain the default directory
874 * servers. */
875 static void
876 add_default_trusted_dirservers(or_options_t *options)
878 /* moria1 */
879 config_line_append(&options->DirServers, "DirServer",
880 "18.244.0.188:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441");
881 /* moria2 */
882 config_line_append(&options->DirServers, "DirServer",
883 "18.244.0.114:80 719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF");
884 /* tor26 */
885 config_line_append(&options->DirServers, "DirServer",
886 "62.116.124.106:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
887 // "tor.noreply.org:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
890 /** Print a usage message for tor. */
891 static void
892 print_usage(void)
894 printf(
895 "Copyright 2001-2004 Roger Dingledine, Nick Mathewson, Matej Pfajfar.\n\n"
896 "tor -f <torrc> [args]\n"
897 "See man page for options, or http://tor.eff.org/ for documentation.\n");
901 * Based on <b>address</b>, guess our public IP address and put it
902 * in <b>addr</b>.
905 resolve_my_address(const char *address, uint32_t *addr)
907 struct in_addr in;
908 struct hostent *rent;
909 char hostname[256];
910 int explicit_ip=1;
912 tor_assert(addr);
914 if (address) {
915 strlcpy(hostname, address, sizeof(hostname));
916 } else { /* then we need to guess our address */
917 explicit_ip = 0; /* it's implicit */
919 if (gethostname(hostname, sizeof(hostname)) < 0) {
920 log_fn(LOG_WARN,"Error obtaining local hostname");
921 return -1;
923 log_fn(LOG_DEBUG,"Guessed local host name as '%s'",hostname);
926 /* now we know hostname. resolve it and keep only the IP */
928 if (tor_inet_aton(hostname, &in) == 0) {
929 /* then we have to resolve it */
930 explicit_ip = 0;
931 rent = (struct hostent *)gethostbyname(hostname);
932 if (!rent) {
933 log_fn(LOG_WARN,"Could not resolve local Address %s. Failing.", hostname);
934 return -1;
936 tor_assert(rent->h_length == 4);
937 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
940 if (!explicit_ip && is_internal_IP(htonl(in.s_addr))) {
941 log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
942 "Please set the Address config option to be the IP you want to use.",
943 hostname, inet_ntoa(in));
944 return -1;
947 log_fn(LOG_DEBUG, "Resolved Address to %s.", inet_ntoa(in));
948 *addr = ntohl(in.s_addr);
949 return 0;
952 /** Called when we don't have a nickname set. Try to guess a good
953 * nickname based on the hostname, and return it in a newly allocated string. */
954 static char *
955 get_default_nickname(void)
957 char localhostname[256];
958 char *cp, *out, *outp;
960 if (gethostname(localhostname, sizeof(localhostname)) < 0) {
961 log_fn(LOG_WARN,"Error obtaining local hostname");
962 return NULL;
965 /* Put it in lowercase; stop at the first dot. */
966 for (cp = localhostname; *cp; ++cp) {
967 if (*cp == '.') {
968 *cp = '\0';
969 break;
971 *cp = tolower(*cp);
974 /* Strip invalid characters. */
975 cp = localhostname;
976 out = outp = tor_malloc(strlen(localhostname) + 1);
977 while (*cp) {
978 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
979 *outp++ = *cp++;
980 else
981 cp++;
983 *outp = '\0';
985 /* Enforce length. */
986 if (strlen(out) > MAX_NICKNAME_LEN)
987 out[MAX_NICKNAME_LEN]='\0';
989 return out;
992 /** Release storage held by <b>options</b> */
993 static void
994 options_free(or_options_t *options)
996 int i;
997 void *lvalue;
999 tor_assert(options);
1001 for (i=0; config_vars[i].name; ++i) {
1002 lvalue = ((char*)options) + config_vars[i].var_offset;
1003 switch (config_vars[i].type) {
1004 case CONFIG_TYPE_MEMUNIT:
1005 case CONFIG_TYPE_INTERVAL:
1006 case CONFIG_TYPE_UINT:
1007 case CONFIG_TYPE_BOOL:
1008 case CONFIG_TYPE_DOUBLE:
1009 case CONFIG_TYPE_OBSOLETE:
1010 break; /* nothing to free for these config types */
1011 case CONFIG_TYPE_STRING:
1012 tor_free(*(char **)lvalue);
1013 break;
1014 case CONFIG_TYPE_LINELIST:
1015 case CONFIG_TYPE_LINELIST_V:
1016 config_free_lines(*(struct config_line_t**)lvalue);
1017 *(struct config_line_t**)lvalue = NULL;
1018 break;
1019 case CONFIG_TYPE_CSV:
1020 if (*(smartlist_t**)lvalue) {
1021 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1022 smartlist_free(*(smartlist_t**)lvalue);
1023 *(smartlist_t**)lvalue = NULL;
1025 break;
1026 case CONFIG_TYPE_LINELIST_S:
1027 /* will be freed by corresponding LINELIST_V. */
1028 break;
1031 tor_free(options);
1034 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
1035 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1037 static int
1038 option_is_same(or_options_t *o1, or_options_t *o2, const char *name)
1040 struct config_line_t *c1, *c2;
1041 int r = 1;
1042 c1 = config_get_assigned_option(o1, name);
1043 c2 = config_get_assigned_option(o2, name);
1044 while (c1 && c2) {
1045 if (strcasecmp(c1->key, c2->key) ||
1046 strcmp(c1->value, c2->value)) {
1047 r = 0;
1048 break;
1050 c1 = c1->next;
1051 c2 = c2->next;
1053 if (r && (c1 || c2)) {
1054 r = 0;
1056 config_free_lines(c1);
1057 config_free_lines(c2);
1058 return r;
1061 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1062 static or_options_t *
1063 options_dup(or_options_t *old)
1065 or_options_t *newopts;
1066 int i;
1067 struct config_line_t *line;
1069 newopts = tor_malloc_zero(sizeof(or_options_t));
1070 for (i=0; config_vars[i].name; ++i) {
1071 if (config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1072 continue;
1073 if (config_vars[i].type == CONFIG_TYPE_OBSOLETE)
1074 continue;
1075 line = config_get_assigned_option(old, config_vars[i].name);
1076 if (line) {
1077 if (config_assign(newopts, line, 0) < 0) {
1078 log_fn(LOG_WARN,"Bug: config_get_assigned_option() generated "
1079 "something we couldn't config_assign().");
1080 tor_assert(0);
1083 config_free_lines(line);
1085 return newopts;
1088 /** Set <b>options</b> to hold reasonable defaults for most options.
1089 * Each option defaults to zero. */
1090 void
1091 options_init(or_options_t *options)
1093 int i;
1094 config_var_t *var;
1096 for (i=0; config_vars[i].name; ++i) {
1097 var = &config_vars[i];
1098 if (!var->initvalue)
1099 continue; /* defaults to NULL or 0 */
1100 option_reset(options, var);
1104 /** Return a string containing a possible configuration file that would give
1105 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
1106 * include options that are the same as Tor's defaults.
1108 char *
1109 config_dump_options(or_options_t *options, int minimal)
1111 smartlist_t *elements;
1112 or_options_t *defaults;
1113 struct config_line_t *line;
1114 char *result;
1115 int i;
1117 defaults = tor_malloc_zero(sizeof(or_options_t));
1118 options_init(defaults);
1119 options_validate(defaults); /* ??? will this work? */
1121 elements = smartlist_create();
1122 for (i=0; config_vars[i].name; ++i) {
1123 if (config_vars[i].type == CONFIG_TYPE_OBSOLETE ||
1124 config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1125 continue;
1126 if (minimal && option_is_same(options, defaults, config_vars[i].name))
1127 continue;
1128 line = config_get_assigned_option(options, config_vars[i].name);
1129 for (; line; line = line->next) {
1130 size_t len = strlen(line->key) + strlen(line->value) + 3;
1131 char *tmp;
1132 tmp = tor_malloc(len);
1133 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
1134 log_fn(LOG_ERR, "Internal error writing log option");
1135 tor_assert(0);
1137 smartlist_add(elements, tmp);
1139 config_free_lines(line);
1142 result = smartlist_join_strings(elements, "", 0, NULL);
1143 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
1144 smartlist_free(elements);
1145 return result;
1148 static int
1149 validate_ports_csv(smartlist_t *sl, char *name) {
1150 int i;
1151 int result = 0;
1152 tor_assert(name);
1154 if(!sl)
1155 return 0;
1157 SMARTLIST_FOREACH(sl, const char *, cp,
1159 i = atoi(cp);
1160 if (i < 1 || i > 65535) {
1161 log(LOG_WARN, "Port '%s' out of range in %s", cp, name);
1162 result=-1;
1165 return result;
1168 /** Return 0 if every setting in <b>options</b> is reasonable. Else
1169 * warn and return -1. Should have no side effects, except for
1170 * normalizing the contents of <b>options</b>. */
1171 static int
1172 options_validate(or_options_t *options)
1174 int result = 0;
1175 struct config_line_t *cl;
1176 addr_policy_t *addr_policy=NULL;
1178 if (options->ORPort < 0 || options->ORPort > 65535) {
1179 log(LOG_WARN, "ORPort option out of bounds.");
1180 result = -1;
1183 /* XXX might similarly want to check the other *BindAddress options */
1184 if (options->ORPort == 0 && options->ORBindAddress != NULL) {
1185 log(LOG_WARN, "ORPort must be defined if ORBindAddress is defined.");
1186 result = -1;
1189 if (validate_data_directory(options)<0) {
1190 log(LOG_WARN, "Invalid DataDirectory");
1191 result = -1;
1194 if (options->Nickname == NULL) {
1195 if (server_mode(options)) {
1196 if (!(options->Nickname = get_default_nickname()))
1197 return -1;
1198 log_fn(LOG_NOTICE, "Choosing default nickname %s", options->Nickname);
1200 } else {
1201 if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) !=
1202 strlen(options->Nickname)) {
1203 log_fn(LOG_WARN, "Nickname '%s' contains illegal characters.", options->Nickname);
1204 result = -1;
1206 if (strlen(options->Nickname) == 0) {
1207 log_fn(LOG_WARN, "Nickname must have at least one character");
1208 result = -1;
1210 if (strlen(options->Nickname) > MAX_NICKNAME_LEN) {
1211 log_fn(LOG_WARN, "Nickname '%s' has more than %d characters.",
1212 options->Nickname, MAX_NICKNAME_LEN);
1213 result = -1;
1217 if (normalize_log_options(options))
1218 return -1;
1220 /* Special case if no options are given. */
1221 if (!options->Logs) {
1222 config_line_append(&options->Logs, "Log", "notice stdout");
1225 if (config_init_logs(options, 1)<0) /* Validate the log(s) */
1226 return -1;
1228 if (server_mode(options)) {
1229 /* confirm that our address isn't broken, so we can complain now */
1230 uint32_t tmp;
1231 if (resolve_my_address(options->Address, &tmp) < 0)
1232 result = -1;
1235 if (options->SocksPort < 0 || options->SocksPort > 65535) {
1236 log(LOG_WARN, "SocksPort option out of bounds.");
1237 result = -1;
1240 if (options->SocksPort == 0 && options->ORPort == 0) {
1241 log(LOG_WARN, "SocksPort and ORPort are both undefined? Quitting.");
1242 result = -1;
1245 if (options->ControlPort < 0 || options->ControlPort > 65535) {
1246 log(LOG_WARN, "ControlPort option out of bounds.");
1247 result = -1;
1250 if (options->DirPort < 0 || options->DirPort > 65535) {
1251 log(LOG_WARN, "DirPort option out of bounds.");
1252 result = -1;
1255 if (options->StrictExitNodes &&
1256 (!options->ExitNodes || !strlen(options->ExitNodes))) {
1257 log(LOG_WARN, "StrictExitNodes set, but no ExitNodes listed.");
1260 if (options->StrictEntryNodes &&
1261 (!options->EntryNodes || !strlen(options->EntryNodes))) {
1262 log(LOG_WARN, "StrictEntryNodes set, but no EntryNodes listed.");
1265 if (options->AuthoritativeDir && options->RecommendedVersions == NULL) {
1266 log(LOG_WARN, "Directory servers must configure RecommendedVersions.");
1267 result = -1;
1270 if (options->AuthoritativeDir && !options->DirPort) {
1271 log(LOG_WARN, "Running as authoritative directory, but no DirPort set.");
1272 result = -1;
1275 if (options->AuthoritativeDir && !options->ORPort) {
1276 log(LOG_WARN, "Running as authoritative directory, but no ORPort set.");
1277 result = -1;
1280 if (options->AuthoritativeDir && options->ClientOnly) {
1281 log(LOG_WARN, "Running as authoritative directory, but ClientOnly also set.");
1282 result = -1;
1285 if (options->_AccountingMaxKB) {
1286 log(LOG_WARN, "AccountingMaxKB is deprecated. Say 'AccountingMax %d KB' instead.", options->_AccountingMaxKB);
1287 options->AccountingMax = U64_LITERAL(1024)*options->_AccountingMaxKB;
1288 options->_AccountingMaxKB = 0;
1291 if (validate_ports_csv(options->FirewallPorts,
1292 "FirewallPorts") < 0)
1293 result = -1;
1295 if (validate_ports_csv(options->LongLivedPorts,
1296 "LongLivedPorts") < 0)
1297 result = -1;
1299 options->_AllowUnverified = 0;
1300 if (options->AllowUnverifiedNodes) {
1301 SMARTLIST_FOREACH(options->AllowUnverifiedNodes, const char *, cp, {
1302 if (!strcasecmp(cp, "entry"))
1303 options->_AllowUnverified |= ALLOW_UNVERIFIED_ENTRY;
1304 else if (!strcasecmp(cp, "exit"))
1305 options->_AllowUnverified |= ALLOW_UNVERIFIED_EXIT;
1306 else if (!strcasecmp(cp, "middle"))
1307 options->_AllowUnverified |= ALLOW_UNVERIFIED_MIDDLE;
1308 else if (!strcasecmp(cp, "introduction"))
1309 options->_AllowUnverified |= ALLOW_UNVERIFIED_INTRODUCTION;
1310 else if (!strcasecmp(cp, "rendezvous"))
1311 options->_AllowUnverified |= ALLOW_UNVERIFIED_RENDEZVOUS;
1312 else {
1313 log(LOG_WARN, "Unrecognized value '%s' in AllowUnverifiedNodes",
1314 cp);
1315 result = -1;
1320 if (options->SocksPort >= 1 &&
1321 (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) {
1322 log(LOG_WARN, "PathlenCoinWeight option must be >=0.0 and <1.0.");
1323 result = -1;
1326 if (options->MaxConn < 1) {
1327 log(LOG_WARN, "MaxConn option must be a non-zero positive integer.");
1328 result = -1;
1331 if (options->MaxConn > MAXCONNECTIONS) {
1332 log(LOG_WARN, "MaxConn option must be at most %d.", MAXCONNECTIONS);
1333 result = -1;
1336 #define MIN_DIR_FETCH_PERIOD 600
1337 #define MIN_DIR_POST_PERIOD 300
1338 #define MIN_REND_POST_PERIOD 300
1339 #define MIN_STATUS_FETCH_PERIOD 60
1341 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
1342 #define MAX_CACHE_DIR_FETCH_PERIOD 3600
1343 #define MAX_CACHE_STATUS_FETCH_PERIOD 900
1345 if (options->DirFetchPeriod < MIN_DIR_FETCH_PERIOD) {
1346 log(LOG_WARN, "DirFetchPeriod option must be at least %d seconds. Clipping.", MIN_DIR_FETCH_PERIOD);
1347 options->DirFetchPeriod = MIN_DIR_FETCH_PERIOD;
1349 if (options->StatusFetchPeriod < MIN_STATUS_FETCH_PERIOD) {
1350 log(LOG_WARN, "StatusFetchPeriod option must be at least %d seconds. Clipping.", MIN_STATUS_FETCH_PERIOD);
1351 options->StatusFetchPeriod = MIN_STATUS_FETCH_PERIOD;
1353 if (options->DirPostPeriod < MIN_DIR_POST_PERIOD) {
1354 log(LOG_WARN, "DirPostPeriod option must be at least %d seconds. Clipping.",
1355 MIN_DIR_POST_PERIOD);
1356 options->DirPostPeriod = MIN_DIR_POST_PERIOD;
1358 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
1359 log(LOG_WARN,"RendPostPeriod option must be at least %d seconds. Clipping.",
1360 MIN_REND_POST_PERIOD);
1361 options->RendPostPeriod = MIN_REND_POST_PERIOD;
1364 if (options->DirPort && ! options->AuthoritativeDir) {
1365 if (options->DirFetchPeriod > MAX_CACHE_DIR_FETCH_PERIOD) {
1366 log(LOG_WARN, "Caching directory servers must have DirFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_DIR_FETCH_PERIOD);
1367 options->DirFetchPeriod = MAX_CACHE_DIR_FETCH_PERIOD;
1369 if (options->StatusFetchPeriod > MAX_CACHE_STATUS_FETCH_PERIOD) {
1370 log(LOG_WARN, "Caching directory servers must have StatusFetchPeriod less than %d seconds. Clipping.", MAX_CACHE_STATUS_FETCH_PERIOD);
1371 options->StatusFetchPeriod = MAX_CACHE_STATUS_FETCH_PERIOD;
1375 if (options->DirFetchPeriod > MAX_DIR_PERIOD) {
1376 log(LOG_WARN, "DirFetchPeriod is too large; clipping.");
1377 options->DirFetchPeriod = MAX_DIR_PERIOD;
1379 if (options->DirPostPeriod > MAX_DIR_PERIOD) {
1380 log(LOG_WARN, "DirPostPeriod is too large; clipping.");
1381 options->DirPostPeriod = MAX_DIR_PERIOD;
1383 if (options->StatusFetchPeriod > MAX_DIR_PERIOD) {
1384 log(LOG_WARN, "StatusFetchPeriod is too large; clipping.");
1385 options->StatusFetchPeriod = MAX_DIR_PERIOD;
1387 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
1388 log(LOG_WARN, "RendPostPeriod is too large; clipping.");
1389 options->RendPostPeriod = MAX_DIR_PERIOD;
1392 if (options->KeepalivePeriod < 1) {
1393 log(LOG_WARN,"KeepalivePeriod option must be positive.");
1394 result = -1;
1397 if (options->BandwidthRate > INT_MAX) {
1398 log(LOG_WARN,"BandwidthRate must be less than %d",INT_MAX);
1399 result = -1;
1401 if (options->BandwidthBurst > INT_MAX) {
1402 log(LOG_WARN,"BandwidthBurst must be less than %d",INT_MAX);
1403 result = -1;
1405 if (server_mode(options) &&
1406 options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
1407 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);
1408 result = -1;
1410 if (options->BandwidthRate > options->BandwidthBurst) {
1411 log(LOG_WARN,"BandwidthBurst must be at least equal to BandwidthRate.");
1412 result = -1;
1414 if (2*options->BandwidthRate > options->BandwidthBurst) {
1415 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));
1416 result = -1;
1420 if (options->_MonthlyAccountingStart) {
1421 if (options->AccountingStart) {
1422 log(LOG_WARN,"Can't specify AccountingStart and MonthlyAccountingStart");
1423 result = -1;
1424 } else {
1425 options->AccountingStart = tor_malloc(32);
1426 if (tor_snprintf(options->AccountingStart, 32, "month %d 0:00",
1427 options->_MonthlyAccountingStart)<0) {
1428 log_fn(LOG_WARN,"Error translating MonthlyAccountingStart");
1429 result = -1;
1430 } else {
1431 log_fn(LOG_WARN,"MonthlyAccountingStart is deprecated. Use 'AccountingStart %s' instead.", options->AccountingStart);
1436 if (accounting_parse_options(options, 1)<0) {
1437 result = -1;
1440 if (options->HttpProxy) { /* parse it now */
1441 if (parse_addr_port(options->HttpProxy, NULL,
1442 &options->HttpProxyAddr, &options->HttpProxyPort) < 0) {
1443 log(LOG_WARN,"HttpProxy failed to parse or resolve. Please fix.");
1444 result = -1;
1446 if (options->HttpProxyPort == 0) { /* give it a default */
1447 options->HttpProxyPort = 80;
1451 if (options->HashedControlPassword) {
1452 if (decode_hashed_password(NULL, options->HashedControlPassword)<0) {
1453 log_fn(LOG_WARN,"Bad HashedControlPassword: wrong length or bad base64");
1454 result = -1;
1457 if (options->HashedControlPassword && options->CookieAuthentication) {
1458 log_fn(LOG_WARN,"Cannot enable both HashedControlPassword and CookieAuthentication");
1459 result = -1;
1462 if (check_nickname_list(options->ExitNodes, "ExitNodes"))
1463 result = -1;
1464 if (check_nickname_list(options->EntryNodes, "EntryNodes"))
1465 result = -1;
1466 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
1467 result = -1;
1468 if (check_nickname_list(options->RendNodes, "RendNodes"))
1469 result = -1;
1470 if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
1471 result = -1;
1472 if (check_nickname_list(options->MyFamily, "MyFamily"))
1473 result = -1;
1474 for (cl = options->NodeFamilies; cl; cl = cl->next) {
1475 if (check_nickname_list(cl->value, "NodeFamily"))
1476 result = -1;
1479 if (config_parse_addr_policy(options->ExitPolicy, &addr_policy)) {
1480 log_fn(LOG_WARN, "Error in Exit Policy entry.");
1481 result = -1;
1483 exit_policy_implicitly_allows_local_networks(addr_policy, 1);
1484 if (config_parse_addr_policy(options->DirPolicy, &addr_policy)) {
1485 log_fn(LOG_WARN, "Error in DirPolicy entry.");
1486 result = -1;
1488 if (config_parse_addr_policy(options->SocksPolicy, &addr_policy)) {
1489 log_fn(LOG_WARN, "Error in SocksPolicy entry.");
1490 result = -1;
1492 addr_policy_free(addr_policy);
1494 for (cl = options->RedirectExit; cl; cl = cl->next) {
1495 if (parse_redirect_line(NULL, cl)<0)
1496 result = -1;
1499 if (!options->DirServers) {
1500 add_default_trusted_dirservers(options);
1501 } else {
1502 for (cl = options->DirServers; cl; cl = cl->next) {
1503 if (parse_dir_server_line(cl->value, 1)<0)
1504 result = -1;
1508 if (rend_config_services(options, 1) < 0)
1509 result = -1;
1511 return result;
1514 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
1515 * equal strings. */
1516 static int
1517 opt_streq(const char *s1, const char *s2)
1519 if (!s1 && !s2)
1520 return 1;
1521 else if (s1 && s2 && !strcmp(s1,s2))
1522 return 1;
1523 else
1524 return 0;
1527 /** Check if any of the previous options have changed but aren't allowed to. */
1528 static int
1529 options_transition_allowed(or_options_t *old, or_options_t *new_val) {
1531 if (!old)
1532 return 0;
1534 if (!opt_streq(old->PidFile, new_val->PidFile)) {
1535 log_fn(LOG_WARN,"PidFile is not allowed to change. Failing.");
1536 return -1;
1539 if (old->RunAsDaemon && !new_val->RunAsDaemon) {
1540 log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing.");
1541 return -1;
1544 if (old->ORPort != new_val->ORPort) {
1545 log_fn(LOG_WARN,"During reload, changing ORPort is not allowed. Failing.");
1546 return -1;
1549 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
1550 log_fn(LOG_WARN,"During reload, changing DataDirectory (%s->%s) is not allowed. Failing.", old->DataDirectory, new_val->DataDirectory);
1551 return -1;
1554 if (!opt_streq(old->User, new_val->User)) {
1555 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1556 return -1;
1559 if (!opt_streq(old->Group, new_val->Group)) {
1560 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1561 return -1;
1564 return 0;
1567 #ifdef MS_WINDOWS
1568 /** Return the directory on windows where we expect to find our application
1569 * data. */
1570 static char *get_windows_conf_root(void)
1572 static int is_set = 0;
1573 static char path[MAX_PATH+1];
1575 LPITEMIDLIST idl;
1576 IMalloc *m;
1577 HRESULT result;
1579 if (is_set)
1580 return path;
1582 /* Find X:\documents and settings\username\application data\ .
1583 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
1585 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
1586 &idl))) {
1587 GetCurrentDirectory(MAX_PATH, path);
1588 is_set = 1;
1589 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);
1590 return path;
1592 /* Convert the path from an "ID List" (whatever that is!) to a path. */
1593 result = SHGetPathFromIDList(idl, path);
1594 /* Now we need to free the */
1595 SHGetMalloc(&m);
1596 if (m) {
1597 m->lpVtbl->Free(m, idl);
1598 m->lpVtbl->Release(m);
1600 if (!SUCCEEDED(result)) {
1601 return NULL;
1603 strlcat(path,"\\tor",MAX_PATH);
1604 is_set = 1;
1605 return path;
1607 #endif
1609 /** Return the default location for our torrc file. */
1610 static char *
1611 get_default_conf_file(void)
1613 #ifdef MS_WINDOWS
1614 char *path = tor_malloc(MAX_PATH);
1615 strlcpy(path, get_windows_conf_root(), MAX_PATH);
1616 strlcat(path,"\\torrc",MAX_PATH);
1617 return path;
1618 #else
1619 return tor_strdup(CONFDIR "/torrc");
1620 #endif
1623 /** Verify whether lst is a string containing valid-looking space-separated
1624 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
1626 static int check_nickname_list(const char *lst, const char *name)
1628 int r = 0;
1629 smartlist_t *sl;
1631 if (!lst)
1632 return 0;
1633 sl = smartlist_create();
1634 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1635 SMARTLIST_FOREACH(sl, const char *, s,
1637 if (!is_legal_nickname_or_hexdigest(s)) {
1638 log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
1639 r = -1;
1642 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
1643 smartlist_free(sl);
1644 return r;
1647 /** Read a configuration file into <b>options</b>, finding the configuration
1648 * file location based on the command line. After loading the options,
1649 * validate them for consistency, then take actions based on them.
1650 * Return 0 if success, -1 if failure. */
1652 init_from_config(int argc, char **argv)
1654 or_options_t *oldoptions, *newoptions;
1655 struct config_line_t *cl;
1656 char *cf=NULL, *fname=NULL;
1657 int i, retval;
1658 int using_default_torrc;
1659 static char **backup_argv;
1660 static int backup_argc;
1662 if (argv) { /* first time we're called. save commandline args */
1663 backup_argv = argv;
1664 backup_argc = argc;
1665 oldoptions = NULL;
1666 } else { /* we're reloading. need to clean up old options first. */
1667 argv = backup_argv;
1668 argc = backup_argc;
1669 oldoptions = get_options();
1671 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
1672 print_usage();
1673 exit(0);
1676 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
1677 printf("Tor version %s.\n",VERSION);
1678 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
1679 print_cvs_version();
1681 exit(0);
1684 newoptions = tor_malloc_zero(sizeof(or_options_t));
1685 options_init(newoptions);
1687 /* learn config file name, get config lines, assign them */
1688 fname = NULL;
1689 using_default_torrc = 1;
1690 newoptions->command = CMD_RUN_TOR;
1691 for (i = 1; i < argc; ++i) {
1692 if (i < argc-1 && !strcmp(argv[i],"-f")) {
1693 if (fname) {
1694 log(LOG_WARN, "Duplicate -f options on command line.");
1695 tor_free(fname);
1697 fname = tor_strdup(argv[i+1]);
1698 using_default_torrc = 0;
1699 ++i;
1700 } else if (!strcmp(argv[i],"--list-fingerprint")) {
1701 newoptions->command = CMD_LIST_FINGERPRINT;
1702 } else if (!strcmp(argv[i],"--hash-password")) {
1703 newoptions->command = CMD_HASH_PASSWORD;
1704 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
1705 ++i;
1709 if (using_default_torrc) {
1710 /* didn't find one, try CONFDIR */
1711 char *fn;
1712 fn = get_default_conf_file();
1713 if (fn && file_status(fn) == FN_FILE) {
1714 fname = fn;
1715 } else {
1716 tor_free(fn);
1717 #ifndef MS_WINDOWS
1718 fn = expand_filename("~/.torrc");
1719 if (fn && file_status(fn) == FN_FILE) {
1720 fname = fn;
1721 } else {
1722 tor_free(fn);
1723 fname = get_default_conf_file();
1725 #else
1726 fname = get_default_conf_file();
1727 #endif
1730 tor_assert(fname);
1731 log(LOG_DEBUG, "Opening config file '%s'", fname);
1733 if (file_status(fname) != FN_FILE ||
1734 !(cf = read_file_to_str(fname,0))) {
1735 if (using_default_torrc == 1) {
1736 log(LOG_NOTICE, "Configuration file '%s' not present, "
1737 "using reasonable defaults.", fname);
1738 tor_free(fname); /* sets fname to NULL */
1739 } else {
1740 log(LOG_WARN, "Unable to open configuration file '%s'.", fname);
1741 tor_free(fname);
1742 goto err;
1744 } else { /* it opened successfully. use it. */
1745 retval = config_get_lines(cf, &cl);
1746 tor_free(cf);
1747 if (retval < 0)
1748 goto err;
1749 retval = config_assign(newoptions, cl, 0);
1750 config_free_lines(cl);
1751 if (retval < 0)
1752 goto err;
1755 /* Go through command-line variables too */
1756 cl = config_get_commandlines(argc,argv);
1757 retval = config_assign(newoptions,cl,0);
1758 config_free_lines(cl);
1759 if (retval < 0)
1760 goto err;
1762 /* Validate newoptions */
1763 if (options_validate(newoptions) < 0)
1764 goto err;
1766 if (options_transition_allowed(oldoptions, newoptions) < 0)
1767 goto err;
1769 set_options(newoptions); /* frees and replaces old options */
1770 if (options_act() < 0) { /* acting on them failed. die. */
1771 log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying.");
1772 exit(1);
1774 tor_free(config_fname);
1775 config_fname = fname;
1776 return 0;
1777 err:
1778 tor_free(fname);
1779 options_free(newoptions);
1780 return -1;
1783 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
1784 * recognized log severity levels, set *<b>min_out</b> to MIN and
1785 * *<b>max_out</b> to MAX and return 0. Else, if <b>range<b> is of
1786 * the form MIN, act as if MIN-err had been specified. Else, warn and
1787 * return -1.
1789 static int
1790 parse_log_severity_range(const char *range, int *min_out, int *max_out)
1792 int levelMin, levelMax;
1793 const char *cp;
1794 cp = strchr(range, '-');
1795 if (cp) {
1796 if (cp == range) {
1797 levelMin = LOG_DEBUG;
1798 } else {
1799 char *tmp_sev = tor_strndup(range, cp - range);
1800 levelMin = parse_log_level(tmp_sev);
1801 if (levelMin < 0) {
1802 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1803 "err|warn|notice|info|debug", tmp_sev);
1804 tor_free(tmp_sev);
1805 return -1;
1807 tor_free(tmp_sev);
1809 if (!*(cp+1)) {
1810 levelMax = LOG_ERR;
1811 } else {
1812 levelMax = parse_log_level(cp+1);
1813 if (levelMax < 0) {
1814 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1815 "err|warn|notice|info|debug", cp+1);
1816 return -1;
1819 } else {
1820 levelMin = parse_log_level(range);
1821 if (levelMin < 0) {
1822 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1823 "err|warn|notice|info|debug", range);
1824 return -1;
1826 levelMax = LOG_ERR;
1829 *min_out = levelMin;
1830 *max_out = levelMax;
1832 return 0;
1835 /** Try to convert a pair of old-style logging options [LogLevel, and
1836 * (LogFile/Syslog)] to a new-style option, and add the new option to
1837 * options->Logs. */
1838 static int
1839 convert_log_option(or_options_t *options, struct config_line_t *level_opt,
1840 struct config_line_t *file_opt, int isDaemon)
1842 int levelMin = -1, levelMax = -1;
1844 if (level_opt) {
1845 if (parse_log_severity_range(level_opt->value, &levelMin, &levelMax))
1846 return -1;
1848 if (levelMin < 0 && levelMax < 0) {
1849 levelMin = LOG_NOTICE;
1850 levelMax = LOG_ERR;
1851 } else if (levelMin < 0) {
1852 levelMin = levelMax;
1853 } else {
1854 levelMax = LOG_ERR;
1857 if (file_opt && !strcasecmp(file_opt->key, "LogFile")) {
1858 if (add_single_log_option(options, levelMin, levelMax, "file", file_opt->value) < 0) {
1859 log_fn(LOG_WARN, "Cannot write to LogFile '%s': %s.", file_opt->value,
1860 strerror(errno));
1861 return -1;
1863 } else if (file_opt && !strcasecmp(file_opt->key, "SysLog")) {
1864 if (add_single_log_option(options, levelMin, levelMax, "syslog", NULL) < 0)
1865 return -1;
1866 } else if (!isDaemon) {
1867 add_single_log_option(options, levelMin, levelMax, "stdout", NULL);
1869 return 0;
1873 * Initialize the logs based on the configuration file.
1876 config_init_logs(or_options_t *options, int validate_only)
1878 struct config_line_t *opt;
1879 int ok;
1880 smartlist_t *elts;
1882 ok = 1;
1883 elts = smartlist_create();
1884 for (opt = options->Logs; opt; opt = opt->next) {
1885 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
1886 smartlist_split_string(elts, opt->value, NULL,
1887 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
1888 if (smartlist_len(elts) == 0) {
1889 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1890 ok = 0; goto cleanup;
1892 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin, &levelMax)) {
1893 ok = 0; goto cleanup;
1895 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
1896 if (!validate_only)
1897 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
1898 goto cleanup;
1900 if (!strcasecmp(smartlist_get(elts,1), "file")) {
1901 if (smartlist_len(elts) != 3) {
1902 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1903 ok = 0; goto cleanup;
1905 if (!validate_only)
1906 add_file_log(levelMin, levelMax, smartlist_get(elts, 2));
1907 goto cleanup;
1909 if (smartlist_len(elts) != 2) {
1910 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1911 ok = 0; goto cleanup;
1913 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
1914 if (!validate_only) {
1915 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
1916 close_temp_logs();
1918 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
1919 if (!validate_only) {
1920 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
1921 close_temp_logs();
1923 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
1924 #ifdef HAVE_SYSLOG_H
1925 if (!validate_only)
1926 add_syslog_log(levelMin, levelMax);
1927 #else
1928 log_fn(LOG_WARN, "Syslog is not supported in this compilation.");
1929 #endif
1930 } else {
1931 log_fn(LOG_WARN, "Unrecognized log type %s",
1932 (const char*)smartlist_get(elts,1));
1933 if (strchr(smartlist_get(elts,1), '/')) {
1934 log_fn(LOG_WARN, "Did you mean to say 'Log file %s' ?",
1935 (const char *)smartlist_get(elts,1));
1937 ok = 0; goto cleanup;
1939 cleanup:
1940 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
1941 smartlist_clear(elts);
1943 smartlist_free(elts);
1944 if (!validate_only)
1945 close_temp_logs();
1947 return ok?0:-1;
1950 /** Add a single option of the form Log min-max <type> [fname] to options. */
1951 static int
1952 add_single_log_option(or_options_t *options, int minSeverity, int maxSeverity,
1953 const char *type, const char *fname)
1955 char buf[512];
1956 int n;
1958 n = tor_snprintf(buf, sizeof(buf), "%s%s%s %s%s%s",
1959 log_level_to_string(minSeverity),
1960 maxSeverity == LOG_ERR ? "" : "-",
1961 maxSeverity == LOG_ERR ? "" : log_level_to_string(maxSeverity),
1962 type, fname?" ":"", fname?fname:"");
1963 if (n<0) {
1964 log_fn(LOG_WARN, "Normalized log option too long.");
1965 return -1;
1968 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);
1969 config_line_append(&options->Logs, "Log", buf);
1970 return 0;
1973 /** Convert all old-style logging options to new-style Log options. Return 0
1974 * on success, -1 on failure. */
1975 static int
1976 normalize_log_options(or_options_t *options)
1978 /* The order of options is: Level? (File Level?)+
1980 struct config_line_t *opt = options->OldLogOptions;
1982 /* Special case for if first option is LogLevel. */
1983 if (opt && !strcasecmp(opt->key, "LogLevel")) {
1984 if (opt->next && (!strcasecmp(opt->next->key, "LogFile") ||
1985 !strcasecmp(opt->next->key, "SysLog"))) {
1986 if (convert_log_option(options, opt, opt->next, options->RunAsDaemon) < 0)
1987 return -1;
1988 opt = opt->next->next;
1989 } else if (!opt->next) {
1990 if (convert_log_option(options, opt, NULL, options->RunAsDaemon) < 0)
1991 return -1;
1992 opt = opt->next;
1993 } else {
1994 ; /* give warning below */
1998 while (opt) {
1999 if (!strcasecmp(opt->key, "LogLevel")) {
2000 log_fn(LOG_WARN, "Two LogLevel options in a row without intervening LogFile or SysLog");
2001 opt = opt->next;
2002 } else {
2003 tor_assert(!strcasecmp(opt->key, "LogFile") ||
2004 !strcasecmp(opt->key, "SysLog"));
2005 if (opt->next && !strcasecmp(opt->next->key, "LogLevel")) {
2006 /* LogFile/SysLog followed by LogLevel */
2007 if (convert_log_option(options,opt->next,opt, options->RunAsDaemon) < 0)
2008 return -1;
2009 opt = opt->next->next;
2010 } else {
2011 /* LogFile/SysLog followed by LogFile/SysLog or end of list. */
2012 if (convert_log_option(options,NULL, opt, options->RunAsDaemon) < 0)
2013 return -1;
2014 opt = opt->next;
2019 if (options->DebugLogFile) {
2020 if (add_single_log_option(options, LOG_DEBUG, LOG_ERR, "file", options->DebugLogFile) < 0)
2021 return -1;
2024 tor_free(options->DebugLogFile);
2025 config_free_lines(options->OldLogOptions);
2026 options->OldLogOptions = NULL;
2028 return 0;
2032 * Given a linked list of config lines containing "allow" and "deny" tokens,
2033 * parse them and append the result to <b>dest</b>. Return -1 if any tokens
2034 * are malformed, else return 0.
2037 config_parse_addr_policy(struct config_line_t *cfg,
2038 addr_policy_t **dest)
2040 addr_policy_t **nextp;
2041 smartlist_t *entries;
2042 int r = 0;
2044 if (!cfg)
2045 return 0;
2047 nextp = dest;
2049 while (*nextp)
2050 nextp = &((*nextp)->next);
2052 entries = smartlist_create();
2053 for (; cfg; cfg = cfg->next) {
2054 smartlist_split_string(entries, cfg->value, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2055 SMARTLIST_FOREACH(entries, const char *, ent,
2057 log_fn(LOG_DEBUG,"Adding new entry '%s'",ent);
2058 *nextp = router_parse_addr_policy_from_string(ent);
2059 if (*nextp) {
2060 nextp = &((*nextp)->next);
2061 } else {
2062 log_fn(LOG_WARN,"Malformed policy %s.", ent);
2063 r = -1;
2066 SMARTLIST_FOREACH(entries, char *, ent, tor_free(ent));
2067 smartlist_clear(entries);
2069 smartlist_free(entries);
2070 return r;
2073 /** Release all storage held by <b>p</b> */
2074 void
2075 addr_policy_free(addr_policy_t *p) {
2076 addr_policy_t *e;
2078 while (p) {
2079 e = p;
2080 p = p->next;
2081 tor_free(e->string);
2082 tor_free(e);
2086 /** Parse a single RedirectExit line's contents from <b>line</b>. If
2087 * they are valid, and <b>result</b> is not NULL, add an element to
2088 * <b>result</b> and return 0. Else if they are valid, return 0.
2089 * Else return -1. */
2090 static int
2091 parse_redirect_line(smartlist_t *result, struct config_line_t *line)
2093 smartlist_t *elements = NULL;
2094 exit_redirect_t *r;
2096 tor_assert(line);
2098 r = tor_malloc_zero(sizeof(exit_redirect_t));
2099 elements = smartlist_create();
2100 smartlist_split_string(elements, line->value, NULL,
2101 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2102 if (smartlist_len(elements) != 2) {
2103 log_fn(LOG_WARN, "Wrong number of elements in RedirectExit line");
2104 goto err;
2106 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
2107 &r->port_min,&r->port_max)) {
2108 log_fn(LOG_WARN, "Error parsing source address in RedirectExit line");
2109 goto err;
2111 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
2112 r->is_redirect = 0;
2113 } else {
2114 if (parse_addr_port(smartlist_get(elements,1),NULL,&r->addr_dest,
2115 &r->port_dest)) {
2116 log_fn(LOG_WARN, "Error parsing dest address in RedirectExit line");
2117 goto err;
2119 r->is_redirect = 1;
2122 goto done;
2123 err:
2124 tor_free(r);
2125 done:
2126 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2127 smartlist_free(elements);
2128 if (r) {
2129 if (result)
2130 smartlist_add(result, r);
2131 else
2132 tor_free(r);
2133 return 0;
2134 } else {
2135 return -1;
2139 /** Read the contents of a DirServer line from <b>line</b>. Return 0
2140 * if the line is well-formed, and 0 if it isn't. If
2141 * <b>validate_only</b> is 0, and the line is well-formed, then add
2142 * the dirserver described in the line as a valid server. */
2143 static int
2144 parse_dir_server_line(const char *line, int validate_only)
2146 smartlist_t *items = NULL;
2147 int r;
2148 char *addrport, *address=NULL;
2149 uint16_t port;
2150 char digest[DIGEST_LEN];
2152 items = smartlist_create();
2153 smartlist_split_string(items, line, NULL,
2154 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
2155 if (smartlist_len(items) < 2) {
2156 log_fn(LOG_WARN, "Too few arguments to DirServer line.");
2157 goto err;
2159 addrport = smartlist_get(items, 0);
2160 if (parse_addr_port(addrport, &address, NULL, &port)<0) {
2161 log_fn(LOG_WARN, "Error parsing DirServer address '%s'", addrport);
2162 goto err;
2164 if (!port) {
2165 log_fn(LOG_WARN, "Missing port in DirServer address '%s'",addrport);
2166 goto err;
2169 tor_strstrip(smartlist_get(items, 1), " ");
2170 if (strlen(smartlist_get(items, 1)) != HEX_DIGEST_LEN) {
2171 log_fn(LOG_WARN, "Key digest for DirServer is wrong length.");
2172 goto err;
2174 if (base16_decode(digest, DIGEST_LEN,
2175 smartlist_get(items,1), HEX_DIGEST_LEN)<0) {
2176 log_fn(LOG_WARN, "Unable to decode DirServer key digest.");
2177 goto err;
2180 if (!validate_only) {
2181 log_fn(LOG_DEBUG, "Trusted dirserver at %s:%d (%s)", address, (int)port,
2182 (char*)smartlist_get(items,1));
2183 add_trusted_dir_server(address, port, digest);
2186 r = 0;
2187 goto done;
2189 err:
2190 r = -1;
2192 done:
2193 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
2194 smartlist_free(items);
2195 tor_free(address);
2196 return r;
2199 /** Adjust the value of options->DataDirectory, or fill it in if it's
2200 * absent. Return 0 on success, -1 on failure. */
2201 static int
2202 normalize_data_directory(or_options_t *options) {
2203 #ifdef MS_WINDOWS
2204 char *p;
2205 if (options->DataDirectory)
2206 return 0; /* all set */
2207 p = tor_malloc(MAX_PATH);
2208 strlcpy(p,get_windows_conf_root(),MAX_PATH);
2209 options->DataDirectory = p;
2210 return 0;
2211 #else
2212 const char *d = options->DataDirectory;
2213 if (!d)
2214 d = "~/.tor";
2216 if (strncmp(d,"~/",2) == 0) {
2217 char *fn = expand_filename(d);
2218 if (!fn) {
2219 log_fn(LOG_ERR,"Failed to expand filename '%s'.", d);
2220 return -1;
2222 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
2223 /* If our homedir is /, we probably don't want to use it. */
2224 /* XXXX Default to /var/lib/tor? */
2225 log_fn(LOG_WARN, "Defaulting to 'DataDirectory %s', which may not be what you want", fn);
2227 tor_free(options->DataDirectory);
2228 options->DataDirectory = fn;
2230 return 0;
2231 #endif
2234 /** Check and normalize the value of options->DataDirectory; return 0 if it
2235 * sane, -1 otherwise. */
2236 static int
2237 validate_data_directory(or_options_t *options) {
2238 if (normalize_data_directory(options) < 0)
2239 return -1;
2240 tor_assert(options->DataDirectory);
2241 if (strlen(options->DataDirectory) > (512-128)) {
2242 log_fn(LOG_ERR, "DataDirectory is too long.");
2243 return -1;
2245 #if 0
2246 if (check_private_dir(options->DataDirectory, CPD_CHECK != 0)) {
2247 log_fn(LOG_WARN, "Can't create directory %s", options->DataDirectory);
2248 return -1;
2250 #endif
2251 return 0;
2254 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; if you edit it, comments will not be preserved"
2256 /** Save a configuration file for the configuration in <b>options</b>
2257 * into the file <b>fname</b>. If the file already exists, and
2258 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
2259 * replace it. Return 0 on success, -1 on failure. */
2260 static int
2261 write_configuration_file(const char *fname, or_options_t *options)
2263 char fn_tmp[1024];
2264 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
2265 int rename_old = 0, r;
2266 size_t len;
2268 if (fname) {
2269 switch (file_status(fname)) {
2270 case FN_FILE:
2271 old_val = read_file_to_str(fname, 0);
2272 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
2273 rename_old = 1;
2275 tor_free(old_val);
2276 break;
2277 case FN_NOENT:
2278 break;
2279 default:
2280 log_fn(LOG_WARN,"Config file %s is not a file? Failing.", fname);
2281 return -1;
2285 if (!(new_conf = config_dump_options(options, 1))) {
2286 log_fn(LOG_WARN, "Couldn't get configuration string");
2287 goto err;
2290 len = strlen(new_conf)+128;
2291 new_val = tor_malloc(len);
2292 tor_snprintf(new_val, len, "%s\n\n%s", GENERATED_FILE_PREFIX, new_conf);
2294 if (rename_old) {
2295 int i = 1;
2296 while (1) {
2297 if (tor_snprintf(fn_tmp, sizeof(fn_tmp), "%s.orig.%d", fname, i)<0) {
2298 log_fn(LOG_WARN, "Filename too long");
2299 goto err;
2301 if (file_status(fn_tmp) == FN_NOENT)
2302 break;
2303 ++i;
2305 log_fn(LOG_NOTICE, "Renaming old configuration file to %s", fn_tmp);
2306 rename(fname, fn_tmp);
2309 write_str_to_file(fname, new_val, 0);
2311 r = 0;
2312 goto done;
2313 err:
2314 r = -1;
2315 done:
2316 tor_free(new_val);
2317 tor_free(new_conf);
2318 return r;
2322 * Save the current configuration file value to disk. Return 0 on
2323 * success, -1 on failure.
2326 save_current_config(void)
2328 char *fn;
2329 if (config_fname) {
2330 /* XXX This fails if we can't write to our configuration file.
2331 * Arguably, we should try falling back to datadirectory or something.
2332 * But just as arguably, we shouldn't. */
2333 return write_configuration_file(config_fname, get_options());
2335 fn = get_default_conf_file();
2336 return write_configuration_file(fn, get_options());
2339 struct unit_table_t {
2340 const char *unit;
2341 uint64_t multiplier;
2344 static struct unit_table_t memory_units[] = {
2345 { "", 1 },
2346 { "b", 1<< 0 },
2347 { "byte", 1<< 0 },
2348 { "bytes", 1<< 0 },
2349 { "kb", 1<<10 },
2350 { "kilobyte", 1<<10 },
2351 { "kilobytes", 1<<10 },
2352 { "m", 1<<20 },
2353 { "mb", 1<<20 },
2354 { "megabyte", 1<<20 },
2355 { "megabytes", 1<<20 },
2356 { "gb", 1<<30 },
2357 { "gigabyte", 1<<30 },
2358 { "gigabytes", 1<<30 },
2359 { "tb", U64_LITERAL(1)<<40 },
2360 { "terabyte", U64_LITERAL(1)<<40 },
2361 { "terabytes", U64_LITERAL(1)<<40 },
2362 { NULL, 0 },
2365 static struct unit_table_t time_units[] = {
2366 { "", 1 },
2367 { "second", 1 },
2368 { "seconds", 1 },
2369 { "minute", 60 },
2370 { "minutes", 60 },
2371 { "hour", 60*60 },
2372 { "hours", 60*60 },
2373 { "day", 24*60*60 },
2374 { "days", 24*60*60 },
2375 { "week", 7*24*60*60 },
2376 { "weeks", 7*24*60*60 },
2377 { NULL, 0 },
2380 /** Parse a string <b>val</b> containing a number, zero or more
2381 * spaces, and an optional unit string. If the unit appears in the
2382 * table <b>u</b>, then multiply the number by the unit multiplier.
2383 * On success, set *<b>ok</b> to 1 and return this product.
2384 * Otherwise, set *<b>ok</b> to 0.
2386 static uint64_t
2387 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
2389 uint64_t v;
2390 char *cp;
2392 tor_assert(ok);
2394 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
2395 if (!*ok)
2396 return 0;
2397 if (!cp) {
2398 *ok = 1;
2399 return v;
2401 while (TOR_ISSPACE(*cp))
2402 ++cp;
2403 for ( ;u->unit;++u) {
2404 if (!strcasecmp(u->unit, cp)) {
2405 v *= u->multiplier;
2406 *ok = 1;
2407 return v;
2410 log_fn(LOG_WARN, "Unknown unit '%s'.", cp);
2411 *ok = 0;
2412 return 0;
2415 /** Parse a string in the format "number unit", where unit is a unit of
2416 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
2417 * and return the number of bytes specified. Otherwise, set
2418 * *<b>ok</b> to false and return 0. */
2419 static uint64_t
2420 config_parse_memunit(const char *s, int *ok) {
2421 return config_parse_units(s, memory_units, ok);
2424 /** Parse a string in the format "number unit", where unit is a unit of time.
2425 * On success, set *<b>ok</b> to true and return the number of seconds in
2426 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
2428 static int
2429 config_parse_interval(const char *s, int *ok) {
2430 uint64_t r;
2431 r = config_parse_units(s, time_units, ok);
2432 if (!ok)
2433 return -1;
2434 if (r > INT_MAX) {
2435 log_fn(LOG_WARN, "Interval '%s' is too long", s);
2436 *ok = 0;
2437 return -1;
2439 return (int)r;
2442 static void
2443 print_cvs_version(void)
2445 extern const char aes_c_id[];
2446 extern const char compat_c_id[];
2447 extern const char container_c_id[];
2448 extern const char crypto_c_id[];
2449 extern const char log_c_id[];
2450 extern const char torgzip_c_id[];
2451 extern const char tortls_c_id[];
2452 extern const char util_c_id[];
2454 extern const char buffers_c_id[];
2455 extern const char circuitbuild_c_id[];
2456 extern const char circuitlist_c_id[];
2457 extern const char circuituse_c_id[];
2458 extern const char command_c_id[];
2459 // extern const char config_c_id[];
2460 extern const char connection_c_id[];
2461 extern const char connection_edge_c_id[];
2462 extern const char connection_or_c_id[];
2463 extern const char control_c_id[];
2464 extern const char cpuworker_c_id[];
2465 extern const char directory_c_id[];
2466 extern const char dirserv_c_id[];
2467 extern const char dns_c_id[];
2468 extern const char hibernate_c_id[];
2469 extern const char main_c_id[];
2470 extern const char onion_c_id[];
2471 extern const char relay_c_id[];
2472 extern const char rendclient_c_id[];
2473 extern const char rendcommon_c_id[];
2474 extern const char rendmid_c_id[];
2475 extern const char rendservice_c_id[];
2476 extern const char rephist_c_id[];
2477 extern const char router_c_id[];
2478 extern const char routerlist_c_id[];
2479 extern const char routerparse_c_id[];
2481 puts(AES_H_ID);
2482 puts(COMPAT_H_ID);
2483 puts(CONTAINER_H_ID);
2484 puts(CRYPTO_H_ID);
2485 puts(LOG_H_ID);
2486 puts(TORGZIP_H_ID);
2487 puts(TORINT_H_ID);
2488 puts(TORTLS_H_ID);
2489 puts(UTIL_H_ID);
2490 puts(aes_c_id);
2491 puts(compat_c_id);
2492 puts(container_c_id);
2493 puts(crypto_c_id);
2494 puts(log_c_id);
2495 puts(torgzip_c_id);
2496 puts(tortls_c_id);
2497 puts(util_c_id);
2499 puts(OR_H_ID);
2500 puts(buffers_c_id);
2501 puts(circuitbuild_c_id);
2502 puts(circuitlist_c_id);
2503 puts(circuituse_c_id);
2504 puts(command_c_id);
2505 puts(config_c_id);
2506 puts(connection_c_id);
2507 puts(connection_edge_c_id);
2508 puts(connection_or_c_id);
2509 puts(control_c_id);
2510 puts(cpuworker_c_id);
2511 puts(directory_c_id);
2512 puts(dirserv_c_id);
2513 puts(dns_c_id);
2514 puts(hibernate_c_id);
2515 puts(main_c_id);
2516 puts(onion_c_id);
2517 puts(relay_c_id);
2518 puts(rendclient_c_id);
2519 puts(rendcommon_c_id);
2520 puts(rendmid_c_id);
2521 puts(rendservice_c_id);
2522 puts(rephist_c_id);
2523 puts(router_c_id);
2524 puts(routerlist_c_id);
2525 puts(routerparse_c_id);