fix some typos; move to 0.0.9rc1
[tor.git] / src / or / config.c
blob6465969ce71862af08d8885d0e8f05dac7fd951c
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$ */
7 /**
8 * /file config.c
10 * /brief Code to parse and interpret configuration files.
12 **/
14 #include "or.h"
15 #ifdef MS_WINDOWS
16 #include <shlobj.h>
17 #endif
19 /** Enumeration of types which option values can take */
20 typedef enum config_type_t {
21 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
22 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
23 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
24 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
25 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
26 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
27 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and optional
28 * whitespace. */
29 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
30 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
31 * mixed with other keywords. */
32 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
33 * context-sensitive config lines when fetching.
35 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
36 } config_type_t;
38 /* An abbreviation for a configuration option allowed on the command line */
39 typedef struct config_abbrev_t {
40 const char *abbreviated;
41 const char *full;
42 int commandline_only;
43 } config_abbrev_t;
45 /* Handy macro for declaring "In the config file or on the command line,
46 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
47 #define PLURAL(tok) { #tok, #tok "s", 0 }
49 /* A list of command-line abbreviations. */
50 static config_abbrev_t config_abbrevs[] = {
51 PLURAL(ExitNode),
52 PLURAL(EntryNode),
53 PLURAL(ExcludeNode),
54 PLURAL(FirewallPort),
55 PLURAL(HiddenServiceNode),
56 PLURAL(HiddenServiceExcludeNode),
57 PLURAL(RendNode),
58 PLURAL(RendExcludeNode),
59 PLURAL(StrictEntryNode),
60 PLURAL(StrictExitNode),
61 { "l", "Log", 1},
62 { "BandwidthRateBytes", "BandwidthRate", 0},
63 { "BandwidthBurstBytes", "BandwidthBurst", 0},
64 { "DirFetchPostPeriod", "DirFetchPeriod", 0},
65 { NULL, NULL , 0},
67 #undef PLURAL
69 /** A variable allowed in the configuration file or on the command line. */
70 typedef struct config_var_t {
71 const char *name; /**< The full keyword (case insensitive). */
72 config_type_t type; /**< How to interpret the type and turn it into a value. */
73 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
74 const char *initvalue; /**< String (or null) describing initial value. */
75 } config_var_t;
77 /** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */
78 #define STRUCT_OFFSET(tp, member) ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
79 /** An entry for config_vars: "The option <b>name</b> has type
80 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
81 * or_options_t.<b>member</b>"
83 #define VAR(name,conftype,member,initvalue) \
84 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), initvalue }
85 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
86 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
88 /** Array of configuration options. Until we disallow nonstandard
89 * abbreviations, order is significant, since the first matching option will
90 * be chosen first.
92 static config_var_t config_vars[] = {
93 VAR("Address", STRING, Address, NULL),
94 VAR("AccountingStart", STRING, AccountingStart, NULL),
95 VAR("AllowUnverifiedNodes",CSV, AllowUnverifiedNodes, "middle,rendezvous"),
96 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
97 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "780 KB"),
98 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "48 MB"),
99 VAR("ClientOnly", BOOL, ClientOnly, "0"),
100 VAR("ContactInfo", STRING, ContactInfo, NULL),
101 VAR("ControlPort", UINT, ControlPort, "0"),
102 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
103 VAR("DebugLogFile", STRING, DebugLogFile, NULL),
104 VAR("DataDirectory", STRING, DataDirectory, NULL),
105 VAR("DirPort", UINT, DirPort, "0"),
106 VAR("DirBindAddress", LINELIST, DirBindAddress, NULL),
107 VAR("DirFetchPeriod", INTERVAL, DirFetchPeriod, "1 hour"),
108 VAR("DirPostPeriod", INTERVAL, DirPostPeriod, "10 minutes"),
109 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "10 minutes"),
110 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
111 VAR("DirServer", LINELIST, DirServers, NULL),
112 VAR("ExitNodes", STRING, ExitNodes, NULL),
113 VAR("EntryNodes", STRING, EntryNodes, NULL),
114 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
115 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
116 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
117 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
118 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
119 VAR("FirewallPorts", CSV, FirewallPorts, "80,443"),
120 VAR("MyFamily", STRING, MyFamily, NULL),
121 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
122 VAR("Group", STRING, Group, NULL),
123 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
124 VAR("HttpProxy", STRING, HttpProxy, NULL),
125 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
126 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
127 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
128 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
129 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
130 VAR("IgnoreVersion", BOOL, IgnoreVersion, "0"),
131 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
132 VAR("Log", LINELIST, Logs, NULL),
133 VAR("LogLevel", LINELIST_S, OldLogOptions, NULL),
134 VAR("LogFile", LINELIST_S, OldLogOptions, NULL),
135 OBSOLETE("LinkPadding"),
136 VAR("MaxConn", UINT, MaxConn, "1024"),
137 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
138 VAR("MonthlyAccountingStart",UINT, _MonthlyAccountingStart,"0"),
139 VAR("AccountingMaxKB", UINT, _AccountingMaxKB, "0"),
140 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
141 VAR("Nickname", STRING, Nickname, NULL),
142 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
143 VAR("NumCpus", UINT, NumCpus, "1"),
144 VAR("ORPort", UINT, ORPort, "0"),
145 VAR("ORBindAddress", LINELIST, ORBindAddress, NULL),
146 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
147 VAR("PidFile", STRING, PidFile, NULL),
148 VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"),
149 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
150 OBSOLETE("RouterFile"),
151 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
152 VAR("RunTesting", BOOL, RunTesting, "0"),
153 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
154 VAR("RendNodes", STRING, RendNodes, NULL),
155 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
156 VAR("SocksPort", UINT, SocksPort, "9050"),
157 VAR("SocksBindAddress", LINELIST, SocksBindAddress, NULL),
158 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
159 VAR("StatusFetchPeriod", INTERVAL, StatusFetchPeriod, "20 minutes"),
160 VAR("SysLog", LINELIST_S, OldLogOptions, NULL),
161 OBSOLETE("TrafficShaping"),
162 VAR("User", STRING, User, NULL),
163 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
165 #undef VAR
166 #undef OBSOLETE
168 /** Largest allowed config line */
169 #define CONFIG_LINE_T_MAXLEN 4096
171 static void option_reset(or_options_t *options, config_var_t *var);
172 static void options_free(or_options_t *options);
173 static int option_is_same(or_options_t *o1, or_options_t *o2,const char *name);
174 static or_options_t *options_dup(or_options_t *old);
175 static int options_validate(or_options_t *options);
176 static int options_transition_allowed(or_options_t *old, or_options_t *new);
177 static int check_nickname_list(const char *lst, const char *name);
179 static int parse_dir_server_line(const char *line, int validate_only);
180 static int parse_redirect_line(smartlist_t *result,
181 struct config_line_t *line);
182 static int parse_log_severity_range(const char *range, int *min_out,
183 int *max_out);
184 static int convert_log_option(or_options_t *options,
185 struct config_line_t *level_opt,
186 struct config_line_t *file_opt, int isDaemon);
187 static int add_single_log_option(or_options_t *options, int minSeverity,
188 int maxSeverity,
189 const char *type, const char *fname);
190 static int normalize_log_options(or_options_t *options);
191 static int validate_data_directory(or_options_t *options);
192 static int write_configuration_file(const char *fname, or_options_t *options);
194 static uint64_t config_parse_memunit(const char *s, int *ok);
195 static int config_parse_interval(const char *s, int *ok);
198 * Functions to read and write the global options pointer.
201 /** Command-line and config-file options. */
202 static or_options_t *global_options=NULL;
203 /** Name of most recently read torrc file. */
204 static char *config_fname = NULL;
206 /** Return the currently configured options. */
207 or_options_t *
208 get_options(void) {
209 tor_assert(global_options);
210 return global_options;
213 /** Change the current global options to contain <b>new_val</b> instead
214 * of their current value; free the old value as necessary. Where
215 * <b>new_val</b> is different from the old value, update the process to
216 * use the new value instead.
218 * Note 1: <b>new_val</b> must have previously been validated with
219 * options_validate(), or Tor may freak out and exit.
221 * Note 2: We haven't moved all the "act on new configuration" logic
222 * here yet. Some is still in do_hup() and other places.
224 void
225 set_options(or_options_t *new_val) {
226 if (global_options)
227 options_free(global_options);
228 global_options = new_val;
231 /** Fetch the active option list, and take actions based on it. All
232 * of the things we do should survive being done repeatedly.
233 * Return 0 if all goes well, return -1 if it's time to die.
236 options_act(void) {
237 struct config_line_t *cl;
238 or_options_t *options = get_options();
240 clear_trusted_dir_servers();
241 for (cl = options->DirServers; cl; cl = cl->next) {
242 if (parse_dir_server_line(cl->value, 0)<0) {
243 log_fn(LOG_ERR,
244 "Previously validated DirServer line could not be added!");
245 return -1;
249 if (rend_config_services(options, 0)<0) {
250 log_fn(LOG_ERR,
251 "Previously validated hidden services line could not be added!");
252 return -1;
255 /* Setuid/setgid as appropriate */
256 if(options->User || options->Group) {
257 if(switch_id(options->User, options->Group) != 0) {
258 return -1;
262 /* Ensure data directory is private; create if possible. */
263 if (check_private_dir(options->DataDirectory, CPD_CREATE) != 0) {
264 log_fn(LOG_ERR, "Couldn't access/create private data directory %s",
265 options->DataDirectory);
266 return -1;
269 /* Bail out at this point if we're not going to be a server: we want
270 * to not fork, and to log stuff to stderr. */
271 if (options->command != CMD_RUN_TOR)
272 return 0;
274 if (set_max_file_descriptors(options->MaxConn) < 0)
275 return -1;
277 mark_logs_temp(); /* Close current logs once new logs are open. */
278 if (config_init_logs(options, 0)<0) /* Configure the log(s) */
279 return -1;
280 /* Close the temporary log we used while starting up, if it isn't already
281 * gone. */
282 close_temp_logs();
283 add_callback_log(LOG_NOTICE, LOG_ERR, control_event_logmsg);
286 smartlist_t *sl = smartlist_create();
287 for (cl = options->RedirectExit; cl; cl = cl->next) {
288 if (parse_redirect_line(sl, cl)<0)
289 return -1;
291 set_exit_redirects(sl);
294 /* Start backgrounding the process, if requested. */
296 /* XXXX009 We once had a reason to separate start_daemon and finish_daemon:
297 * It let us have the parent process stick around until we were sure Tor
298 * was started. Should we make start_daemon get called earlier? -NM */
299 if (options->RunAsDaemon) {
300 start_daemon(options->DataDirectory);
303 /* Finish backgrounding the process */
304 if(options->RunAsDaemon) {
305 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
306 finish_daemon();
309 /* Write our pid to the pid file. If we do not have write permissions we
310 * will log a warning */
311 if(options->PidFile)
312 write_pidfile(options->PidFile);
314 /* Update address policies. */
315 parse_socks_policy();
316 parse_dir_policy();
318 init_cookie_authentication(options->CookieAuthentication);
320 /* reload keys as needed for rendezvous services. */
321 if (rend_service_load_keys()<0) {
322 log_fn(LOG_ERR,"Error reloading rendezvous service keys");
323 return -1;
326 /* Set up accounting */
327 if (accounting_parse_options(options, 0)<0) {
328 log_fn(LOG_ERR,"Error in accouting options");
329 return -1;
331 if (accounting_is_enabled(options))
332 configure_accounting(time(NULL));
334 if(retry_all_listeners(1) < 0) {
335 log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
336 return -1;
339 #if 0
341 char *smin, *smax;
342 smin = config_dump_options(options, 1);
343 smax = config_dump_options(options, 0);
344 log_fn(LOG_DEBUG, "These are our options:\n%s",smax);
345 log_fn(LOG_DEBUG, "We changed these options:\n%s",smin);
346 tor_free(smin);
347 tor_free(smax);
349 #endif
351 /* Since our options changed, we might need to regenerate and upload our
352 * server descriptor. (We could probably be more clever about only calling
353 * this when something significant changed.)
355 mark_my_descriptor_dirty();
357 return 0;
361 * Functions to parse config options
364 /** If <b>option</b> is an official abbreviation for a longer option,
365 * return the longer option. Otherwise return <b>option</b>.
366 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
367 * apply abbreviations that work for the config file and the command line. */
368 static const char *
369 expand_abbrev(const char *option, int command_line)
371 int i;
372 for (i=0; config_abbrevs[i].abbreviated; ++i) {
373 /* Abbreviations aren't casei. */
374 if (!strcasecmp(option,config_abbrevs[i].abbreviated) &&
375 (command_line || !config_abbrevs[i].commandline_only)) {
376 return config_abbrevs[i].full;
379 return option;
382 /** Helper: Read a list of configuration options from the command line. */
383 static struct config_line_t *
384 config_get_commandlines(int argc, char **argv)
386 struct config_line_t *new;
387 struct config_line_t *front = NULL;
388 char *s;
389 int i = 1;
391 while (i < argc-1) {
392 if (!strcmp(argv[i],"-f") ||
393 !strcmp(argv[i],"--hash-password")) {
394 i += 2; /* command-line option with argument. ignore them. */
395 continue;
396 } else if (!strcmp(argv[i],"--list-fingerprint")) {
397 i += 1; /* command-line option. ignore it. */
398 continue;
401 new = tor_malloc(sizeof(struct config_line_t));
402 s = argv[i];
404 while(*s == '-')
405 s++;
407 new->key = tor_strdup(expand_abbrev(s, 1));
408 new->value = tor_strdup(argv[i+1]);
410 log(LOG_DEBUG,"Commandline: parsed keyword '%s', value '%s'",
411 new->key, new->value);
412 new->next = front;
413 front = new;
414 i += 2;
416 return front;
419 /** Helper: allocate a new configuration option mapping 'key' to 'val',
420 * prepend it to 'front', and return the newly allocated config_line_t */
421 struct config_line_t *
422 config_line_prepend(struct config_line_t *front,
423 const char *key,
424 const char *val)
426 struct config_line_t *newline;
428 newline = tor_malloc(sizeof(struct config_line_t));
429 newline->key = tor_strdup(key);
430 newline->value = tor_strdup(val);
431 newline->next = front;
432 return newline;
435 /** Helper: parse the config string and strdup into key/value
436 * strings. Set *result to the list, or NULL if parsing the string
437 * failed. Return 0 on success, -1 on failure. Warn and ignore any
438 * misformatted lines. */
440 config_get_lines(char *string, struct config_line_t **result)
442 struct config_line_t *list = NULL;
443 char *k, *v;
445 do {
446 string = parse_line_from_str(string, &k, &v);
447 if (!string) {
448 config_free_lines(list);
449 return -1;
451 if (k && v)
452 list = config_line_prepend(list, k, v);
453 } while (*string);
455 *result = list;
456 return 0;
460 * Free all the configuration lines on the linked list <b>front</b>.
462 void
463 config_free_lines(struct config_line_t *front)
465 struct config_line_t *tmp;
467 while (front) {
468 tmp = front;
469 front = tmp->next;
471 tor_free(tmp->key);
472 tor_free(tmp->value);
473 tor_free(tmp);
477 /** If <b>key</b> is a configuration option, return the corresponding
478 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
479 * warn, and return the corresponding config_var_t. Otherwise return NULL.
481 static config_var_t *config_find_option(const char *key)
483 int i;
484 /* First, check for an exact (case-insensitive) match */
485 for (i=0; config_vars[i].name; ++i) {
486 if (!strcasecmp(key, config_vars[i].name))
487 return &config_vars[i];
489 /* If none, check for an abbreviated match */
490 for (i=0; config_vars[i].name; ++i) {
491 if (!strncasecmp(key, config_vars[i].name, strlen(key))) {
492 log_fn(LOG_WARN, "The abbreviation '%s' is deprecated. "
493 "Tell Nick and Roger to make it official, or just use '%s' instead",
494 key, config_vars[i].name);
495 return &config_vars[i];
498 /* Okay, unrecogized options */
499 return NULL;
502 /** If <b>c</b> is a syntactically valid configuration line, update
503 * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
504 * -2 for bad value.
506 * If 'reset' is set, and we get a line containing no value, restore the
507 * option to its default value.
509 static int
510 config_assign_line(or_options_t *options, struct config_line_t *c, int reset)
512 int i, ok;
513 config_var_t *var;
514 void *lvalue;
516 var = config_find_option(c->key);
517 if (!var) {
518 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
519 return -1;
521 /* Put keyword into canonical case. */
522 if (strcmp(var->name, c->key)) {
523 tor_free(c->key);
524 c->key = tor_strdup(var->name);
527 if (reset && !strlen(c->value)) {
528 option_reset(options, var);
529 return 0;
532 lvalue = ((char*)options) + var->var_offset;
533 switch(var->type) {
535 case CONFIG_TYPE_UINT:
536 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
537 if (!ok) {
538 log(LOG_WARN, "Int keyword '%s %s' is malformed or out of bounds.",
539 c->key,c->value);
540 return -2;
542 *(int *)lvalue = i;
543 break;
545 case CONFIG_TYPE_INTERVAL: {
546 i = config_parse_interval(c->value, &ok);
547 if (!ok) {
548 return -2;
550 *(int *)lvalue = i;
551 break;
554 case CONFIG_TYPE_MEMUNIT: {
555 uint64_t u64 = config_parse_memunit(c->value, &ok);
556 if (!ok) {
557 return -2;
559 *(uint64_t *)lvalue = u64;
560 break;
563 case CONFIG_TYPE_BOOL:
564 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
565 if (!ok) {
566 log(LOG_WARN, "Boolean keyword '%s' expects 0 or 1.", c->key);
567 return -2;
569 *(int *)lvalue = i;
570 break;
572 case CONFIG_TYPE_STRING:
573 tor_free(*(char **)lvalue);
574 *(char **)lvalue = tor_strdup(c->value);
575 break;
577 case CONFIG_TYPE_DOUBLE:
578 *(double *)lvalue = atof(c->value);
579 break;
581 case CONFIG_TYPE_CSV:
582 if (*(smartlist_t**)lvalue == NULL)
583 *(smartlist_t**)lvalue = smartlist_create();
585 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
586 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
587 break;
589 case CONFIG_TYPE_LINELIST:
590 case CONFIG_TYPE_LINELIST_S:
591 /* Note: this reverses the order that the lines appear in. That's
592 * just fine, since we build up the list of lines reversed in the
593 * first place. */
594 *(struct config_line_t**)lvalue =
595 config_line_prepend(*(struct config_line_t**)lvalue, c->key, c->value);
596 break;
598 case CONFIG_TYPE_OBSOLETE:
599 log_fn(LOG_WARN, "Skipping obsolete configuration option '%s'", c->key);
600 break;
601 case CONFIG_TYPE_LINELIST_V:
602 log_fn(LOG_WARN, "Can't provide value for virtual option '%s'", c->key);
603 return -2;
604 default:
605 tor_assert(0);
606 break;
608 return 0;
611 /** restore the option named <b>key</b> in options to its default value. */
612 static void
613 config_reset_line(or_options_t *options, const char *key)
615 config_var_t *var;
617 var = config_find_option(key);
618 if (!var)
619 return; /* give error on next pass. */
621 option_reset(options, var);
624 /** Return true iff key is a valid configuration option. */
626 config_option_is_recognized(const char *key)
628 config_var_t *var = config_find_option(key);
629 return (var != NULL);
632 /** Return a canonicalized list of the options assigned for key.
634 struct config_line_t *
635 config_get_assigned_option(or_options_t *options, const char *key)
637 config_var_t *var;
638 const void *value;
639 char buf[32];
640 struct config_line_t *result;
641 tor_assert(options && key);
643 var = config_find_option(key);
644 if (!var) {
645 log_fn(LOG_WARN, "Unknown option '%s'. Failing.", key);
646 return NULL;
647 } else if (var->type == CONFIG_TYPE_LINELIST_S) {
648 log_fn(LOG_WARN, "Can't return context-sensitive '%s' on its own", key);
649 return NULL;
651 value = ((char*)options) + var->var_offset;
653 if (var->type == CONFIG_TYPE_LINELIST ||
654 var->type == CONFIG_TYPE_LINELIST_V) {
655 /* Linelist requires special handling: we just copy and return it. */
656 const struct config_line_t *next_in = *(const struct config_line_t**)value;
657 struct config_line_t **next_out = &result;
658 while (next_in) {
659 *next_out = tor_malloc(sizeof(struct config_line_t));
660 (*next_out)->key = tor_strdup(next_in->key);
661 (*next_out)->value = tor_strdup(next_in->value);
662 next_in = next_in->next;
663 next_out = &((*next_out)->next);
665 (*next_out) = NULL;
666 return result;
669 result = tor_malloc_zero(sizeof(struct config_line_t));
670 result->key = tor_strdup(var->name);
671 switch(var->type)
673 case CONFIG_TYPE_STRING:
674 if (*(char**)value) {
675 result->value = tor_strdup(*(char**)value);
676 } else {
677 tor_free(result->key);
678 tor_free(result);
679 return NULL;
681 break;
682 case CONFIG_TYPE_INTERVAL:
683 case CONFIG_TYPE_UINT:
684 /* This means every or_options_t uint or bool element
685 * needs to be an int. Not, say, a uint16_t or char. */
686 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
687 result->value = tor_strdup(buf);
688 break;
689 case CONFIG_TYPE_MEMUNIT:
690 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
691 U64_PRINTF_ARG(*(uint64_t*)value));
692 result->value = tor_strdup(buf);
693 break;
694 case CONFIG_TYPE_DOUBLE:
695 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
696 result->value = tor_strdup(buf);
697 break;
698 case CONFIG_TYPE_BOOL:
699 result->value = tor_strdup(*(int*)value ? "1" : "0");
700 break;
701 case CONFIG_TYPE_CSV:
702 if (*(smartlist_t**)value)
703 result->value = smartlist_join_strings(*(smartlist_t**)value,",",0,NULL);
704 else
705 result->value = tor_strdup("");
706 break;
707 case CONFIG_TYPE_OBSOLETE:
708 log_fn(LOG_WARN,"You asked me for the value of an obsolete config option %s.", key);
709 tor_free(result->key);
710 tor_free(result);
711 return NULL;
712 default:
713 tor_free(result->key);
714 tor_free(result);
715 log_fn(LOG_WARN,"Bug: unknown type %d for known key %s", var->type, key);
716 return NULL;
719 return result;
722 /** Iterate through the linked list of requested options <b>list</b>.
723 * For each item, convert as appropriate and assign to <b>options</b>.
724 * If an item is unrecognized, return -1 immediately,
725 * else return 0 for success.
727 * If <b>reset</b>, then interpret empty lines as meaning "restore to
728 * default value", and interpret LINELIST* options as replacing (not
729 * extending) their previous values. Return 0 on success, -1 on bad key,
730 * -2 on bad value.
732 static int
733 config_assign(or_options_t *options, struct config_line_t *list, int reset)
735 struct config_line_t *p;
736 tor_assert(options);
738 /* pass 1: normalize keys */
739 for (p = list; p; p = p->next) {
740 const char *full = expand_abbrev(p->key, 0);
741 if (strcmp(full,p->key)) {
742 tor_free(p->key);
743 p->key = tor_strdup(full);
747 /* pass 2: if we're reading from a resetting source, clear all mentioned
748 * linelists. */
749 if (reset) {
750 for (p = list; p; p = p->next)
751 config_reset_line(options, p->key);
754 /* pass 3: assign. */
755 while (list) {
756 int r;
757 if ((r=config_assign_line(options, list, reset)))
758 return r;
759 list = list->next;
761 return 0;
764 /** Try assigning <b>list</b> to the global options. You do this by duping
765 * options, assigning list to the new one, then validating it. If it's
766 * ok, then throw out the old one and stick with the new one. Else,
767 * revert to old and return failure. Return 0 on success, -1 on bad
768 * keys, -2 on bad values, -3 on bad transition.
771 config_trial_assign(struct config_line_t *list, int reset)
773 int r;
774 or_options_t *trial_options = options_dup(get_options());
776 if ((r=config_assign(trial_options, list, reset)) < 0) {
777 options_free(trial_options);
778 return r;
781 if (options_validate(trial_options) < 0) {
782 options_free(trial_options);
783 return -2;
786 if (options_transition_allowed(get_options(), trial_options) < 0) {
787 options_free(trial_options);
788 return -3;
791 set_options(trial_options); /* we liked it. put it in place. */
792 return 0;
795 /** Replace the option indexed by <b>var</b> in <b>options</b> with its
796 * default value. */
797 static void
798 option_reset(or_options_t *options, config_var_t *var)
800 struct config_line_t *c;
801 void *lvalue;
803 lvalue = ((char*)options) + var->var_offset;
804 switch (var->type) {
805 case CONFIG_TYPE_STRING:
806 tor_free(*(char**)lvalue);
807 break;
808 case CONFIG_TYPE_DOUBLE:
809 *(double*)lvalue = 0.0;
810 break;
811 case CONFIG_TYPE_INTERVAL:
812 case CONFIG_TYPE_UINT:
813 case CONFIG_TYPE_BOOL:
814 *(int*)lvalue = 0;
815 break;
816 case CONFIG_TYPE_MEMUNIT:
817 *(uint64_t*)lvalue = 0;
818 break;
819 case CONFIG_TYPE_CSV:
820 if (*(smartlist_t**)lvalue) {
821 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
822 smartlist_free(*(smartlist_t **)lvalue);
823 *(smartlist_t **)lvalue = NULL;
825 break;
826 case CONFIG_TYPE_LINELIST:
827 case CONFIG_TYPE_LINELIST_S:
828 config_free_lines(*(struct config_line_t **)lvalue);
829 *(struct config_line_t **)lvalue = NULL;
830 break;
831 case CONFIG_TYPE_LINELIST_V:
832 /* handled by linelist_s. */
833 break;
834 case CONFIG_TYPE_OBSOLETE:
835 break;
837 if (var->initvalue) {
838 c = tor_malloc_zero(sizeof(struct config_line_t));
839 c->key = tor_strdup(var->name);
840 c->value = tor_strdup(var->initvalue);
841 config_assign_line(options,c,0);
842 config_free_lines(c);
846 /** Set <b>options</b>-&gt;DirServers to contain the default directory
847 * servers. */
848 static void
849 add_default_trusted_dirservers(or_options_t *options)
851 /* moria1 */
852 options->DirServers = config_line_prepend(options->DirServers, "DirServer",
853 "18.244.0.188:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441");
854 /* moria2 */
855 options->DirServers = config_line_prepend(options->DirServers, "DirServer",
856 "18.244.0.114:80 719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF");
857 /* tor26 */
858 options->DirServers = config_line_prepend(options->DirServers, "DirServer",
859 "62.116.124.106:9030 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D");
862 /** Print a usage message for tor. */
863 static void
864 print_usage(void)
866 printf(
867 "Copyright 2001-2004 Roger Dingledine, Nick Mathewson, Matej Pfajfar.\n\n"
868 "tor -f <torrc> [args]\n"
869 "See man page for options, or http://freehaven.net/tor/ for documentation.\n");
873 * Based on <b>address</b>, guess our public IP address and put it
874 * in <b>addr</b>.
877 resolve_my_address(const char *address, uint32_t *addr)
879 struct in_addr in;
880 struct hostent *rent;
881 char hostname[256];
882 int explicit_ip=1;
884 tor_assert(addr);
886 if (address) {
887 strlcpy(hostname, address, sizeof(hostname));
888 } else { /* then we need to guess our address */
889 explicit_ip = 0; /* it's implicit */
891 if (gethostname(hostname, sizeof(hostname)) < 0) {
892 log_fn(LOG_WARN,"Error obtaining local hostname");
893 return -1;
895 log_fn(LOG_DEBUG,"Guessed local host name as '%s'",hostname);
898 /* now we know hostname. resolve it and keep only the IP */
900 if (tor_inet_aton(hostname, &in) == 0) {
901 /* then we have to resolve it */
902 explicit_ip = 0;
903 rent = (struct hostent *)gethostbyname(hostname);
904 if (!rent) {
905 log_fn(LOG_WARN,"Could not resolve local Address %s. Failing.", hostname);
906 return -1;
908 tor_assert(rent->h_length == 4);
909 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
912 if (!explicit_ip && is_internal_IP(htonl(in.s_addr))) {
913 log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
914 "Please set the Address config option to be the IP you want to use.",
915 hostname, inet_ntoa(in));
916 return -1;
919 log_fn(LOG_DEBUG, "Resolved Address to %s.", inet_ntoa(in));
920 *addr = ntohl(in.s_addr);
921 return 0;
924 /** Called when we don't have a nickname set. Try to guess a good
925 * nickname based on the hostname, and return it. */
926 static char *
927 get_default_nickname(void)
929 char localhostname[256];
930 char *cp, *out, *outp;
932 if (gethostname(localhostname, sizeof(localhostname)) < 0) {
933 log_fn(LOG_WARN,"Error obtaining local hostname");
934 return NULL;
937 /* Put it in lowercase; stop at the first dot. */
938 for (cp = localhostname; *cp; ++cp) {
939 if (*cp == '.') {
940 *cp = '\0';
941 break;
943 *cp = tolower(*cp);
946 /* Strip invalid characters. */
947 cp = localhostname;
948 out = outp = tor_malloc(strlen(localhostname) + 1);
949 while (*cp) {
950 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
951 *outp++ = *cp++;
952 else
953 cp++;
955 *outp = '\0';
957 /* Enforce length. */
958 if (strlen(out) > MAX_NICKNAME_LEN)
959 out[MAX_NICKNAME_LEN]='\0';
961 return out;
964 /** Release storage held by <b>options</b> */
965 static void
966 options_free(or_options_t *options)
968 int i;
969 void *lvalue;
971 for (i=0; config_vars[i].name; ++i) {
972 lvalue = ((char*)options) + config_vars[i].var_offset;
973 switch(config_vars[i].type) {
974 case CONFIG_TYPE_MEMUNIT:
975 case CONFIG_TYPE_INTERVAL:
976 case CONFIG_TYPE_UINT:
977 case CONFIG_TYPE_BOOL:
978 case CONFIG_TYPE_DOUBLE:
979 case CONFIG_TYPE_OBSOLETE:
980 break; /* nothing to free for these config types */
981 case CONFIG_TYPE_STRING:
982 tor_free(*(char **)lvalue);
983 break;
984 case CONFIG_TYPE_LINELIST:
985 case CONFIG_TYPE_LINELIST_V:
986 config_free_lines(*(struct config_line_t**)lvalue);
987 *(struct config_line_t**)lvalue = NULL;
988 break;
989 case CONFIG_TYPE_CSV:
990 if (*(smartlist_t**)lvalue) {
991 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
992 smartlist_free(*(smartlist_t**)lvalue);
993 *(smartlist_t**)lvalue = NULL;
995 break;
996 case CONFIG_TYPE_LINELIST_S:
997 /* will be freed by corresponding LINELIST_V. */
998 break;
1003 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
1004 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1006 static int
1007 option_is_same(or_options_t *o1, or_options_t *o2, const char *name)
1009 struct config_line_t *c1, *c2;
1010 int r = 1;
1011 c1 = config_get_assigned_option(o1, name);
1012 c2 = config_get_assigned_option(o2, name);
1013 while (c1 && c2) {
1014 if (strcasecmp(c1->key, c2->key) ||
1015 strcmp(c1->value, c2->value)) {
1016 r = 0;
1017 break;
1019 c1 = c1->next;
1020 c2 = c2->next;
1022 if (r && (c1 || c2)) {
1023 r = 0;
1025 config_free_lines(c1);
1026 config_free_lines(c2);
1027 return r;
1030 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1031 static or_options_t *
1032 options_dup(or_options_t *old)
1034 or_options_t *newopts;
1035 int i;
1036 struct config_line_t *line;
1038 newopts = tor_malloc_zero(sizeof(or_options_t));
1039 for (i=0; config_vars[i].name; ++i) {
1040 if(config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1041 continue;
1042 if(config_vars[i].type == CONFIG_TYPE_OBSOLETE)
1043 continue;
1044 line = config_get_assigned_option(old, config_vars[i].name);
1045 if (line) {
1046 if (config_assign(newopts, line, 0) < 0) {
1047 log_fn(LOG_WARN,"Bug: config_get_assigned_option() generated "
1048 "something we couldn't config_assign().");
1049 tor_assert(0);
1052 config_free_lines(line);
1054 return newopts;
1057 /** Set <b>options</b> to hold reasonable defaults for most options.
1058 * Each option defaults to zero. */
1059 void
1060 options_init(or_options_t *options)
1062 int i;
1063 config_var_t *var;
1065 for (i=0; config_vars[i].name; ++i) {
1066 var = &config_vars[i];
1067 if(!var->initvalue)
1068 continue; /* defaults to NULL or 0 */
1069 option_reset(options, var);
1073 /** Return a string containing a possible configuration file that would give
1074 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
1075 * include options that are the same as Tor's defaults.
1077 char *
1078 config_dump_options(or_options_t *options, int minimal)
1080 smartlist_t *elements;
1081 or_options_t *defaults;
1082 struct config_line_t *line;
1083 char *result;
1084 int i;
1086 defaults = tor_malloc_zero(sizeof(or_options_t));
1087 options_init(defaults);
1088 options_validate(defaults); /* ??? will this work? */
1090 elements = smartlist_create();
1091 for (i=0; config_vars[i].name; ++i) {
1092 if (config_vars[i].type == CONFIG_TYPE_OBSOLETE ||
1093 config_vars[i].type == CONFIG_TYPE_LINELIST_S)
1094 continue;
1095 if (minimal && option_is_same(options, defaults, config_vars[i].name))
1096 continue;
1097 line = config_get_assigned_option(options, config_vars[i].name);
1098 for (; line; line = line->next) {
1099 size_t len = strlen(line->key) + strlen(line->value) + 3;
1100 char *tmp;
1101 tmp = tor_malloc(len);
1102 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
1103 log_fn(LOG_ERR, "Internal error writing log option");
1104 tor_assert(0);
1106 smartlist_add(elements, tmp);
1108 config_free_lines(line);
1111 result = smartlist_join_strings(elements, "", 0, NULL);
1112 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
1113 smartlist_free(elements);
1114 return result;
1117 /** Return 0 if every setting in <b>options</b> is reasonable. Else
1118 * warn and return -1. Should have no side effects, except for
1119 * normalizing the contents of <b>options</b>. */
1120 static int
1121 options_validate(or_options_t *options)
1123 int i;
1124 int result = 0;
1125 struct config_line_t *cl;
1126 struct addr_policy_t *addr_policy=NULL;
1128 if (options->ORPort < 0 || options->ORPort > 65535) {
1129 log(LOG_WARN, "ORPort option out of bounds.");
1130 result = -1;
1133 if (validate_data_directory(options)<0) {
1134 log(LOG_WARN, "Invalid DataDirectory");
1135 result = -1;
1138 if (options->Nickname == NULL) {
1139 if (server_mode(options)) {
1140 if (!(options->Nickname = get_default_nickname()))
1141 return -1;
1142 log_fn(LOG_NOTICE, "Choosing default nickname %s", options->Nickname);
1144 } else {
1145 if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) !=
1146 strlen(options->Nickname)) {
1147 log_fn(LOG_WARN, "Nickname '%s' contains illegal characters.", options->Nickname);
1148 result = -1;
1150 if (strlen(options->Nickname) == 0) {
1151 log_fn(LOG_WARN, "Nickname must have at least one character");
1152 result = -1;
1154 if (strlen(options->Nickname) > MAX_NICKNAME_LEN) {
1155 log_fn(LOG_WARN, "Nickname '%s' has more than %d characters.",
1156 options->Nickname, MAX_NICKNAME_LEN);
1157 result = -1;
1161 if (normalize_log_options(options))
1162 return -1;
1164 /* Special case if no options are given. */
1165 if (!options->Logs) {
1166 options->Logs = config_line_prepend(NULL, "Log", "notice-err stdout");
1169 if (config_init_logs(options, 1)<0) /* Validate the log(s) */
1170 return -1;
1172 if (server_mode(options)) {
1173 /* confirm that our address isn't broken, so we can complain now */
1174 uint32_t tmp;
1175 if (resolve_my_address(options->Address, &tmp) < 0)
1176 result = -1;
1179 if (options->SocksPort < 0 || options->SocksPort > 65535) {
1180 log(LOG_WARN, "SocksPort option out of bounds.");
1181 result = -1;
1184 if (options->SocksPort == 0 && options->ORPort == 0) {
1185 log(LOG_WARN, "SocksPort and ORPort are both undefined? Quitting.");
1186 result = -1;
1189 if (options->ControlPort < 0 || options->ControlPort > 65535) {
1190 log(LOG_WARN, "ControlPort option out of bounds.");
1191 result = -1;
1194 if (options->DirPort < 0 || options->DirPort > 65535) {
1195 log(LOG_WARN, "DirPort option out of bounds.");
1196 result = -1;
1199 if (options->StrictExitNodes &&
1200 (!options->ExitNodes || !strlen(options->ExitNodes))) {
1201 log(LOG_WARN, "StrictExitNodes set, but no ExitNodes listed.");
1204 if (options->StrictEntryNodes &&
1205 (!options->EntryNodes || !strlen(options->EntryNodes))) {
1206 log(LOG_WARN, "StrictEntryNodes set, but no EntryNodes listed.");
1209 if (options->AuthoritativeDir && options->RecommendedVersions == NULL) {
1210 log(LOG_WARN, "Directory servers must configure RecommendedVersions.");
1211 result = -1;
1214 if (options->AuthoritativeDir && !options->DirPort) {
1215 log(LOG_WARN, "Running as authoritative directory, but no DirPort set.");
1216 result = -1;
1219 if (options->AuthoritativeDir && !options->ORPort) {
1220 log(LOG_WARN, "Running as authoritative directory, but no ORPort set.");
1221 result = -1;
1224 if (options->AuthoritativeDir && options->ClientOnly) {
1225 log(LOG_WARN, "Running as authoritative directory, but ClientOnly also set.");
1226 result = -1;
1229 if (options->_AccountingMaxKB) {
1230 log(LOG_WARN, "AccountingMaxKB is deprecated. Say 'AccountingMax %d KB' instead.", options->_AccountingMaxKB);
1231 options->AccountingMax = U64_LITERAL(1024)*options->_AccountingMaxKB;
1232 options->_AccountingMaxKB = 0;
1235 if (options->FirewallPorts) {
1236 SMARTLIST_FOREACH(options->FirewallPorts, const char *, cp,
1238 i = atoi(cp);
1239 if (i < 1 || i > 65535) {
1240 log(LOG_WARN, "Port '%s' out of range in FirewallPorts", cp);
1241 result=-1;
1245 options->_AllowUnverified = 0;
1246 if (options->AllowUnverifiedNodes) {
1247 SMARTLIST_FOREACH(options->AllowUnverifiedNodes, const char *, cp, {
1248 if (!strcasecmp(cp, "entry"))
1249 options->_AllowUnverified |= ALLOW_UNVERIFIED_ENTRY;
1250 else if (!strcasecmp(cp, "exit"))
1251 options->_AllowUnverified |= ALLOW_UNVERIFIED_EXIT;
1252 else if (!strcasecmp(cp, "middle"))
1253 options->_AllowUnverified |= ALLOW_UNVERIFIED_MIDDLE;
1254 else if (!strcasecmp(cp, "introduction"))
1255 options->_AllowUnverified |= ALLOW_UNVERIFIED_INTRODUCTION;
1256 else if (!strcasecmp(cp, "rendezvous"))
1257 options->_AllowUnverified |= ALLOW_UNVERIFIED_RENDEZVOUS;
1258 else {
1259 log(LOG_WARN, "Unrecognized value '%s' in AllowUnverifiedNodes",
1260 cp);
1261 result=-1;
1266 if (options->SocksPort >= 1 &&
1267 (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) {
1268 log(LOG_WARN, "PathlenCoinWeight option must be >=0.0 and <1.0.");
1269 result = -1;
1272 if (options->MaxConn < 1) {
1273 log(LOG_WARN, "MaxConn option must be a non-zero positive integer.");
1274 result = -1;
1277 if (options->MaxConn >= MAXCONNECTIONS) {
1278 log(LOG_WARN, "MaxConn option must be less than %d.", MAXCONNECTIONS);
1279 result = -1;
1282 #define MIN_DIRFETCHPOSTPERIOD 60
1283 if (options->DirFetchPeriod < MIN_DIRFETCHPOSTPERIOD) {
1284 log(LOG_WARN, "DirFetchPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD);
1285 result = -1;
1287 if (options->StatusFetchPeriod < MIN_DIRFETCHPOSTPERIOD) {
1288 log(LOG_WARN, "StatusFetchPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD);
1289 result = -1;
1291 if (options->DirPostPeriod < MIN_DIRFETCHPOSTPERIOD) {
1292 log(LOG_WARN, "DirPostPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD);
1293 result = -1;
1295 if (options->DirFetchPeriod > MIN_ONION_KEY_LIFETIME / 2) {
1296 log(LOG_WARN, "DirFetchPeriod is too large; clipping.");
1297 options->DirFetchPeriod = MIN_ONION_KEY_LIFETIME / 2;
1299 if (options->DirPostPeriod > MIN_ONION_KEY_LIFETIME / 2) {
1300 log(LOG_WARN, "DirPostPeriod is too large; clipping.");
1301 options->DirPostPeriod = MIN_ONION_KEY_LIFETIME / 2;
1304 if (options->KeepalivePeriod < 1) {
1305 log(LOG_WARN,"KeepalivePeriod option must be positive.");
1306 result = -1;
1309 if (2*options->BandwidthRate >= options->BandwidthBurst) {
1310 log(LOG_WARN,"BandwidthBurst must be more than twice BandwidthRate.");
1311 result = -1;
1313 if (options->BandwidthRate > INT_MAX) {
1314 log(LOG_WARN,"BandwidthRate must be less than %d",INT_MAX);
1315 result = -1;
1317 if (options->BandwidthBurst > INT_MAX) {
1318 log(LOG_WARN,"BandwidthBurst must be less than %d",INT_MAX);
1319 result = -1;
1322 if (options->_MonthlyAccountingStart) {
1323 if (options->AccountingStart) {
1324 log(LOG_WARN,"Can't specify AccountingStart and MonthlyAccountingStart");
1325 result = -1;
1326 } else {
1327 options->AccountingStart = tor_malloc(32);
1328 if (tor_snprintf(options->AccountingStart, 32, "month %d 0:00",
1329 options->_MonthlyAccountingStart)<0) {
1330 log_fn(LOG_WARN,"Error translating MonthlyAccountingStart");
1331 result = -1;
1332 } else {
1333 log_fn(LOG_WARN,"MonthlyAccountingStart is deprecated. Use 'AccountingStart %s' instead.", options->AccountingStart);
1338 if (accounting_parse_options(options, 1)<0) {
1339 result = -1;
1342 if (options->HttpProxy) { /* parse it now */
1343 if (parse_addr_port(options->HttpProxy, NULL,
1344 &options->HttpProxyAddr, &options->HttpProxyPort) < 0) {
1345 log(LOG_WARN,"HttpProxy failed to parse or resolve. Please fix.");
1346 result = -1;
1348 if (options->HttpProxyPort == 0) { /* give it a default */
1349 options->HttpProxyPort = 80;
1353 if (options->HashedControlPassword) {
1354 char buf[S2K_SPECIFIER_LEN+DIGEST_LEN];
1355 if (base64_decode(buf,sizeof(buf),options->HashedControlPassword,
1356 strlen(options->HashedControlPassword)!=sizeof(buf))) {
1357 log_fn(LOG_WARN,"Bad HashedControlPassword: wrong length or bad base64");
1358 result = -1;
1361 if (options->HashedControlPassword && options->CookieAuthentication) {
1362 log_fn(LOG_WARN,"Cannot enable both HashedControlPassword and CookieAuthentication");
1363 result = -1;
1366 if (check_nickname_list(options->ExitNodes, "ExitNodes"))
1367 result = -1;
1368 if (check_nickname_list(options->EntryNodes, "EntryNodes"))
1369 result = -1;
1370 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
1371 result = -1;
1372 if (check_nickname_list(options->RendNodes, "RendNodes"))
1373 result = -1;
1374 if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
1375 result = -1;
1376 if (check_nickname_list(options->MyFamily, "MyFamily"))
1377 result = -1;
1378 for (cl = options->NodeFamilies; cl; cl = cl->next) {
1379 if (check_nickname_list(cl->value, "NodeFamily"))
1380 result = -1;
1383 if (config_parse_addr_policy(options->ExitPolicy, &addr_policy)) {
1384 log_fn(LOG_WARN, "Error in Exit Policy entry.");
1385 result = -1;
1387 if (config_parse_addr_policy(options->DirPolicy, &addr_policy)) {
1388 log_fn(LOG_WARN, "Error in DirPolicy entry.");
1389 result = -1;
1391 if (config_parse_addr_policy(options->SocksPolicy, &addr_policy)) {
1392 log_fn(LOG_WARN, "Error in SocksPolicy entry.");
1393 result = -1;
1395 addr_policy_free(addr_policy);
1397 for (cl = options->RedirectExit; cl; cl = cl->next) {
1398 if (parse_redirect_line(NULL, cl)<0)
1399 result = -1;
1402 if (!options->DirServers) {
1403 add_default_trusted_dirservers(options);
1404 } else {
1405 for (cl = options->DirServers; cl; cl = cl->next) {
1406 if (parse_dir_server_line(cl->value, 1)<0)
1407 result = -1;
1411 if (rend_config_services(options, 1) < 0)
1412 result = -1;
1414 return result;
1417 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
1418 * equal strings. */
1419 static int
1420 opt_streq(const char *s1, const char *s2)
1422 if (!s1 && !s2)
1423 return 1;
1424 else if (s1 && s2 && !strcmp(s1,s2))
1425 return 1;
1426 else
1427 return 0;
1430 /** Check if any of the previous options have changed but aren't allowed to. */
1431 static int
1432 options_transition_allowed(or_options_t *old, or_options_t *new_val) {
1434 if(!old)
1435 return 0;
1437 if (!opt_streq(old->PidFile, new_val->PidFile)) {
1438 log_fn(LOG_WARN,"PidFile is not allowed to change. Failing.");
1439 return -1;
1442 if (old->RunAsDaemon && !new_val->RunAsDaemon) {
1443 log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing.");
1444 return -1;
1447 if (old->ORPort != new_val->ORPort) {
1448 log_fn(LOG_WARN,"During reload, changing ORPort is not allowed. Failing.");
1449 return -1;
1452 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
1453 log_fn(LOG_WARN,"During reload, changing DataDirectory (%s->%s) is not allowed. Failing.", old->DataDirectory, new_val->DataDirectory);
1454 return -1;
1457 if (!opt_streq(old->User, new_val->User)) {
1458 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1459 return -1;
1462 if (!opt_streq(old->Group, new_val->Group)) {
1463 log_fn(LOG_WARN,"During reload, changing User is not allowed. Failing.");
1464 return -1;
1467 return 0;
1470 #ifdef MS_WINDOWS
1471 /** Return the directory on windows where we expect to find our application
1472 * data. */
1473 static char *get_windows_conf_root(void)
1475 static int is_set = 0;
1476 static char path[MAX_PATH+1];
1478 LPITEMIDLIST idl;
1479 IMalloc *m;
1480 HRESULT result;
1482 if (is_set)
1483 return path;
1485 /* Find X:\documents and settings\username\applicatation data\ .
1486 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
1488 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
1489 &idl))) {
1490 GetCurrentDirectory(MAX_PATH, path);
1491 is_set = 1;
1492 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);
1493 return path;
1495 /* Convert the path from an "ID List" (whatever that is!) to a path. */
1496 result = SHGetPathFromIDList(idl, path);
1497 /* Now we need to free the */
1498 SHGetMalloc(&m);
1499 if (m) {
1500 m->lpVtbl->Free(m, idl);
1501 m->lpVtbl->Release(m);
1503 if (!SUCCEEDED(result)) {
1504 return NULL;
1506 strlcat(path,"\\tor",MAX_PATH);
1507 is_set = 1;
1508 return path;
1510 #endif
1512 /** Return the default location for our torrc file. */
1513 static char *
1514 get_default_conf_file(void)
1516 #ifdef MS_WINDOWS
1517 char *path = tor_malloc(MAX_PATH);
1518 strlcpy(path, get_windows_conf_root(), MAX_PATH);
1519 strlcat(path,"\\torrc",MAX_PATH);
1520 return path;
1521 #else
1522 return tor_strdup(CONFDIR "/torrc");
1523 #endif
1526 /** Verify whether lst is a string containing valid-looking space-separated
1527 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
1529 static int check_nickname_list(const char *lst, const char *name)
1531 int r = 0;
1532 smartlist_t *sl;
1534 if (!lst)
1535 return 0;
1536 sl = smartlist_create();
1537 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1538 SMARTLIST_FOREACH(sl, const char *, s,
1540 if (!is_legal_nickname_or_hexdigest(s)) {
1541 log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
1542 r = -1;
1545 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
1546 smartlist_free(sl);
1547 return r;
1550 /** Read a configuration file into <b>options</b>, finding the configuration
1551 * file location based on the command line. After loading the options,
1552 * validate them for consistency, then take actions based on them.
1553 * Return 0 if success, -1 if failure. */
1555 init_from_config(int argc, char **argv)
1557 or_options_t *oldoptions, *newoptions;
1558 struct config_line_t *cl;
1559 char *cf=NULL, *fname=NULL;
1560 int i, retval;
1561 int using_default_torrc;
1562 static char **backup_argv;
1563 static int backup_argc;
1565 if (argv) { /* first time we're called. save commandline args */
1566 backup_argv = argv;
1567 backup_argc = argc;
1568 oldoptions = NULL;
1569 } else { /* we're reloading. need to clean up old options first. */
1570 argv = backup_argv;
1571 argc = backup_argc;
1572 oldoptions = get_options();
1574 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
1575 print_usage();
1576 exit(0);
1579 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
1580 printf("Tor version %s.\n",VERSION);
1581 exit(0);
1584 newoptions = tor_malloc_zero(sizeof(or_options_t));
1585 options_init(newoptions);
1587 /* learn config file name, get config lines, assign them */
1588 fname = NULL;
1589 using_default_torrc = 1;
1590 newoptions->command = CMD_RUN_TOR;
1591 for (i = 1; i < argc; ++i) {
1592 if (i < argc-1 && !strcmp(argv[i],"-f")) {
1593 if (fname) {
1594 log(LOG_WARN, "Duplicate -f options on command line.");
1595 tor_free(fname);
1597 fname = tor_strdup(argv[i+1]);
1598 using_default_torrc = 0;
1599 ++i;
1600 } else if (!strcmp(argv[i],"--list-fingerprint")) {
1601 newoptions->command = CMD_LIST_FINGERPRINT;
1602 } else if (!strcmp(argv[i],"--hash-password")) {
1603 newoptions->command = CMD_HASH_PASSWORD;
1604 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
1605 ++i;
1609 if (using_default_torrc) {
1610 /* didn't find one, try CONFDIR */
1611 char *fn;
1612 fn = get_default_conf_file();
1613 if (fn && file_status(fn) == FN_FILE) {
1614 fname = fn;
1615 } else {
1616 tor_free(fn);
1617 fn = expand_filename("~/.torrc");
1618 if (fn && file_status(fn) == FN_FILE) {
1619 fname = fn;
1620 } else {
1621 tor_free(fn);
1622 fname = get_default_conf_file();
1626 tor_assert(fname);
1627 log(LOG_DEBUG, "Opening config file '%s'", fname);
1629 cf = read_file_to_str(fname, 0);
1630 if (!cf) {
1631 if (using_default_torrc == 1) {
1632 log(LOG_NOTICE, "Configuration file '%s' not present, "
1633 "using reasonable defaults.", fname);
1634 tor_free(fname); /* sets fname to NULL */
1635 } else {
1636 log(LOG_WARN, "Unable to open configuration file '%s'.", fname);
1637 tor_free(fname);
1638 goto err;
1640 } else { /* it opened successfully. use it. */
1641 retval = config_get_lines(cf, &cl);
1642 tor_free(cf);
1643 if (retval < 0)
1644 goto err;
1645 retval = config_assign(newoptions, cl, 0);
1646 config_free_lines(cl);
1647 if (retval < 0)
1648 goto err;
1651 /* Go through command-line variables too */
1652 cl = config_get_commandlines(argc,argv);
1653 retval = config_assign(newoptions,cl,0);
1654 config_free_lines(cl);
1655 if (retval < 0)
1656 goto err;
1658 /* Validate newoptions */
1659 if (options_validate(newoptions) < 0)
1660 goto err;
1662 if (options_transition_allowed(oldoptions, newoptions) < 0)
1663 goto err;
1665 set_options(newoptions); /* frees and replaces old options */
1666 if (options_act() < 0) { /* acting on them failed. die. */
1667 log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying.");
1668 exit(1);
1670 tor_free(config_fname);
1671 config_fname = fname;
1672 return 0;
1673 err:
1674 tor_free(fname);
1675 options_free(newoptions);
1676 return -1;
1679 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
1680 * recognized log severity levels, set *<b>min_out</b> to MIN and
1681 * *<b>max_out</b> to MAX and return 0. Else, if <b>range<b> is of
1682 * the form MIN, act as if MIN-err had been specified. Else, warn and
1683 * return -1.
1685 static int
1686 parse_log_severity_range(const char *range, int *min_out, int *max_out)
1688 int levelMin, levelMax;
1689 const char *cp;
1690 cp = strchr(range, '-');
1691 if (cp) {
1692 if (cp == range) {
1693 levelMin = LOG_DEBUG;
1694 } else {
1695 char *tmp_sev = tor_strndup(range, cp - range);
1696 levelMin = parse_log_level(tmp_sev);
1697 if (levelMin < 0) {
1698 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1699 "err|warn|notice|info|debug", tmp_sev);
1700 tor_free(tmp_sev);
1701 return -1;
1703 tor_free(tmp_sev);
1705 if (!*(cp+1)) {
1706 levelMax = LOG_ERR;
1707 } else {
1708 levelMax = parse_log_level(cp+1);
1709 if (levelMax < 0) {
1710 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1711 "err|warn|notice|info|debug", cp+1);
1712 return -1;
1715 } else {
1716 levelMin = parse_log_level(range);
1717 if (levelMin < 0) {
1718 log_fn(LOG_WARN, "Unrecognized log severity '%s': must be one of "
1719 "err|warn|notice|info|debug", range);
1720 return -1;
1722 levelMax = LOG_ERR;
1725 *min_out = levelMin;
1726 *max_out = levelMax;
1728 return 0;
1731 /** Try to convert a pair of old-style logging options [LogLevel, and
1732 * (LogFile/Syslog)] to a new-style option, and add the new option to
1733 * options->Logs. */
1734 static int
1735 convert_log_option(or_options_t *options, struct config_line_t *level_opt,
1736 struct config_line_t *file_opt, int isDaemon)
1738 int levelMin = -1, levelMax = -1;
1740 if (level_opt) {
1741 if (parse_log_severity_range(level_opt->value, &levelMin, &levelMax))
1742 return -1;
1744 if (levelMin < 0 && levelMax < 0) {
1745 levelMin = LOG_NOTICE;
1746 levelMax = LOG_ERR;
1747 } else if (levelMin < 0) {
1748 levelMin = levelMax;
1749 } else {
1750 levelMax = LOG_ERR;
1753 if (file_opt && !strcasecmp(file_opt->key, "LogFile")) {
1754 if (add_single_log_option(options, levelMin, levelMax, "file", file_opt->value) < 0) {
1755 log_fn(LOG_WARN, "Cannot write to LogFile '%s': %s.", file_opt->value,
1756 strerror(errno));
1757 return -1;
1759 } else if (file_opt && !strcasecmp(file_opt->key, "SysLog")) {
1760 if (add_single_log_option(options, levelMin, levelMax, "syslog", NULL) < 0)
1761 return -1;
1762 } else if (!isDaemon) {
1763 add_single_log_option(options, levelMin, levelMax, "stdout", NULL);
1765 return 0;
1769 * Initialize the logs based on the configuration file.
1772 config_init_logs(or_options_t *options, int validate_only)
1774 struct config_line_t *opt;
1775 int ok;
1776 smartlist_t *elts;
1778 ok = 1;
1779 elts = smartlist_create();
1780 for (opt = options->Logs; opt; opt = opt->next) {
1781 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
1782 smartlist_split_string(elts, opt->value, " ",
1783 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
1784 if (smartlist_len(elts) == 0) {
1785 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1786 ok = 0; goto cleanup;
1788 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin, &levelMax)) {
1789 ok = 0; goto cleanup;
1791 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
1792 if (!validate_only)
1793 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
1794 goto cleanup;
1796 if (!strcasecmp(smartlist_get(elts,1), "file")) {
1797 if (smartlist_len(elts) != 3) {
1798 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1799 ok = 0; goto cleanup;
1801 if (!validate_only)
1802 add_file_log(levelMin, levelMax, smartlist_get(elts, 2));
1803 goto cleanup;
1805 if (smartlist_len(elts) != 2) {
1806 log_fn(LOG_WARN, "Bad syntax on Log option 'Log %s'", opt->value);
1807 ok = 0; goto cleanup;
1809 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
1810 if (!validate_only) {
1811 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
1812 close_temp_logs();
1814 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
1815 if (!validate_only) {
1816 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
1817 close_temp_logs();
1819 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
1820 #ifdef HAVE_SYSLOG_H
1821 if (!validate_only)
1822 add_syslog_log(levelMin, levelMax);
1823 #else
1824 log_fn(LOG_WARN, "Syslog is not supported in this compilation.");
1825 #endif
1826 } else {
1827 log_fn(LOG_WARN, "Unrecognized log type %s",
1828 (const char*)smartlist_get(elts,1));
1829 if (strchr(smartlist_get(elts,1), '/')) {
1830 log_fn(LOG_WARN, "Did you mean to say 'Log file %s' ?",
1831 (const char *)smartlist_get(elts,1));
1833 ok = 0; goto cleanup;
1835 cleanup:
1836 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
1837 smartlist_clear(elts);
1839 smartlist_free(elts);
1840 if (!validate_only)
1841 close_temp_logs();
1843 return ok?0:-1;
1846 /** Add a single option of the form Log min-max <type> [fname] to options. */
1847 static int
1848 add_single_log_option(or_options_t *options, int minSeverity, int maxSeverity,
1849 const char *type, const char *fname)
1851 char buf[512];
1852 int n;
1854 n = tor_snprintf(buf, sizeof(buf), "%s-%s %s%s%s",
1855 log_level_to_string(minSeverity),
1856 log_level_to_string(maxSeverity),
1857 type, fname?" ":"", fname?fname:"");
1858 if (n<0) {
1859 log_fn(LOG_WARN, "Normalized log option too long.");
1860 return -1;
1863 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);
1864 options->Logs = config_line_prepend(options->Logs, "Log", buf);
1865 return 0;
1868 /** Convert all old-style logging options to new-style Log options. Return 0
1869 * on success, -1 on faulure. */
1870 static int
1871 normalize_log_options(or_options_t *options)
1873 /* The order of options is: Level? (File Level?)+
1875 struct config_line_t *opt = options->OldLogOptions;
1877 /* Special case for if first option is LogLevel. */
1878 if (opt && !strcasecmp(opt->key, "LogLevel")) {
1879 if (opt->next && (!strcasecmp(opt->next->key, "LogFile") ||
1880 !strcasecmp(opt->next->key, "SysLog"))) {
1881 if (convert_log_option(options, opt, opt->next, options->RunAsDaemon) < 0)
1882 return -1;
1883 opt = opt->next->next;
1884 } else if (!opt->next) {
1885 if (convert_log_option(options, opt, NULL, options->RunAsDaemon) < 0)
1886 return -1;
1887 opt = opt->next;
1888 } else {
1889 ; /* give warning below */
1893 while (opt) {
1894 if (!strcasecmp(opt->key, "LogLevel")) {
1895 log_fn(LOG_WARN, "Two LogLevel options in a row without intervening LogFile or SysLog");
1896 opt = opt->next;
1897 } else {
1898 tor_assert(!strcasecmp(opt->key, "LogFile") ||
1899 !strcasecmp(opt->key, "SysLog"));
1900 if (opt->next && !strcasecmp(opt->next->key, "LogLevel")) {
1901 /* LogFile/SysLog followed by LogLevel */
1902 if (convert_log_option(options,opt->next,opt, options->RunAsDaemon) < 0)
1903 return -1;
1904 opt = opt->next->next;
1905 } else {
1906 /* LogFile/SysLog followed by LogFile/SysLog or end of list. */
1907 if (convert_log_option(options,NULL, opt, options->RunAsDaemon) < 0)
1908 return -1;
1909 opt = opt->next;
1914 if (options->DebugLogFile) {
1915 if (add_single_log_option(options, LOG_DEBUG, LOG_ERR, "file", options->DebugLogFile) < 0)
1916 return -1;
1919 tor_free(options->DebugLogFile);
1920 config_free_lines(options->OldLogOptions);
1921 options->OldLogOptions = NULL;
1923 return 0;
1927 * Given a linked list of config lines containing "allow" and "deny" tokens,
1928 * parse them and append the result to <b>dest</b>. Return -1 if any tokens
1929 * are malformed, else return 0.
1932 config_parse_addr_policy(struct config_line_t *cfg,
1933 struct addr_policy_t **dest)
1935 struct addr_policy_t **nextp;
1936 smartlist_t *entries;
1937 int r = 0;
1939 if (!cfg)
1940 return 0;
1942 nextp = dest;
1944 while (*nextp)
1945 nextp = &((*nextp)->next);
1947 entries = smartlist_create();
1948 for (; cfg; cfg = cfg->next) {
1949 smartlist_split_string(entries, cfg->value, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1950 SMARTLIST_FOREACH(entries, const char *, ent,
1952 log_fn(LOG_DEBUG,"Adding new entry '%s'",ent);
1953 *nextp = router_parse_addr_policy_from_string(ent);
1954 if (*nextp) {
1955 nextp = &((*nextp)->next);
1956 } else {
1957 log_fn(LOG_WARN,"Malformed policy %s.", ent);
1958 r = -1;
1961 SMARTLIST_FOREACH(entries, char *, ent, tor_free(ent));
1962 smartlist_clear(entries);
1964 smartlist_free(entries);
1965 return r;
1968 /** Release all storage held by <b>p</b> */
1969 void
1970 addr_policy_free(struct addr_policy_t *p) {
1971 struct addr_policy_t *e;
1973 while (p) {
1974 e = p;
1975 p = p->next;
1976 tor_free(e->string);
1977 tor_free(e);
1981 /** Parse a single RedirectExit line's contents from <b>line</b>. If
1982 * they are valid, and <b>result</b> is not NULL, add an element to
1983 * <b>result</b> and return 0. Else if they are valid, return 0.
1984 * Else return -1. */
1985 static int
1986 parse_redirect_line(smartlist_t *result, struct config_line_t *line)
1988 smartlist_t *elements = NULL;
1989 exit_redirect_t *r;
1991 tor_assert(line);
1993 r = tor_malloc_zero(sizeof(exit_redirect_t));
1994 elements = smartlist_create();
1995 smartlist_split_string(elements, line->value, " ",
1996 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1997 if (smartlist_len(elements) != 2) {
1998 log_fn(LOG_WARN, "Wrong number of elements in RedirectExit line");
1999 goto err;
2001 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
2002 &r->port_min,&r->port_max)) {
2003 log_fn(LOG_WARN, "Error parsing source address in RedirectExit line");
2004 goto err;
2006 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
2007 r->is_redirect = 0;
2008 } else {
2009 if (parse_addr_port(smartlist_get(elements,1),NULL,&r->addr_dest,
2010 &r->port_dest)) {
2011 log_fn(LOG_WARN, "Error parsing dest address in RedirectExit line");
2012 goto err;
2014 r->is_redirect = 1;
2017 goto done;
2018 err:
2019 tor_free(r);
2020 done:
2021 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2022 smartlist_free(elements);
2023 if (r) {
2024 if (result)
2025 smartlist_add(result, r);
2026 else
2027 tor_free(r);
2028 return 0;
2029 } else {
2030 return -1;
2034 /** Read the contents of a DirServer line from <b>line</b>. Return 0
2035 * if the line is well-formed, and 0 if it isn't. If
2036 * <b>validate_only</b> is 0, and the line is well-formed, then add
2037 * the dirserver desribed in the line as a valid server. */
2038 static int
2039 parse_dir_server_line(const char *line, int validate_only)
2041 smartlist_t *items = NULL;
2042 int r;
2043 char *addrport, *address=NULL;
2044 uint16_t port;
2045 char digest[DIGEST_LEN];
2047 items = smartlist_create();
2048 smartlist_split_string(items, line, " ",
2049 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
2050 if (smartlist_len(items) < 2) {
2051 log_fn(LOG_WARN, "Too few arguments to DirServer line.");
2052 goto err;
2054 addrport = smartlist_get(items, 0);
2055 if (parse_addr_port(addrport, &address, NULL, &port)<0) {
2056 log_fn(LOG_WARN, "Error parsing DirServer address '%s'", addrport);
2057 goto err;
2059 if (!port) {
2060 log_fn(LOG_WARN, "Missing port in DirServe address '%s'",addrport);
2061 goto err;
2064 tor_strstrip(smartlist_get(items, 1), " ");
2065 if (strlen(smartlist_get(items, 1)) != HEX_DIGEST_LEN) {
2066 log_fn(LOG_WARN, "Key digest for DirServer is wrong length.");
2067 goto err;
2069 if (base16_decode(digest, DIGEST_LEN,
2070 smartlist_get(items,1), HEX_DIGEST_LEN)<0) {
2071 log_fn(LOG_WARN, "Unable to decode DirServer key digest.");
2072 goto err;
2075 if (!validate_only) {
2076 log_fn(LOG_DEBUG, "Trusted dirserver at %s:%d (%s)", address, (int)port,
2077 (char*)smartlist_get(items,1));
2078 add_trusted_dir_server(address, port, digest);
2081 r = 0;
2082 goto done;
2084 err:
2085 r = -1;
2087 done:
2088 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
2089 smartlist_free(items);
2090 tor_free(address);
2091 return r;
2094 /** Adjust the value of options->DataDirectory, or fill it in if it's
2095 * absent. Return 0 on success, -1 on failure. */
2096 static int
2097 normalize_data_directory(or_options_t *options) {
2098 #ifdef MS_WINDOWS
2099 char *p;
2100 if (options->DataDirectory)
2101 return 0; /* all set */
2102 p = tor_malloc(MAX_PATH);
2103 strlcpy(p,get_windows_conf_root(),MAX_PATH);
2104 options->DataDirectory = p;
2105 return 0;
2106 #else
2107 const char *d = options->DataDirectory;
2108 if(!d)
2109 d = "~/.tor";
2111 if (strncmp(d,"~/",2) == 0) {
2112 char *fn = expand_filename(d);
2113 if (!fn) {
2114 log_fn(LOG_ERR,"Failed to expand filename '%s'.", d);
2115 return -1;
2117 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
2118 /* If our homedir is /, we probably don't want to use it. */
2119 /* XXXX Default to /var/lib/tor? */
2120 log_fn(LOG_WARN, "Defaulting to 'DataDirectory %s', which may not be what you want", fn);
2122 tor_free(options->DataDirectory);
2123 options->DataDirectory = fn;
2125 return 0;
2126 #endif
2129 /** Check and normalize the value of options->DataDirectory; return 0 if it
2130 * sane, -1 otherwise. */
2131 static int
2132 validate_data_directory(or_options_t *options) {
2133 if (normalize_data_directory(options) < 0)
2134 return -1;
2135 tor_assert(options->DataDirectory);
2136 if (strlen(options->DataDirectory) > (512-128)) {
2137 log_fn(LOG_ERR, "DataDirectory is too long.");
2138 return -1;
2140 #if 0
2141 if (check_private_dir(options->DataDirectory, CPD_CHECK != 0)) {
2142 log_fn(LOG_WARN, "Can't create directory %s", options->DataDirectory);
2143 return -1;
2145 #endif
2146 return 0;
2149 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; if you edit it, comments will not be preserved"
2151 /** Save a configuration file for the configuration in <b>options</b>
2152 * into the file <b>fname</b>. If the file already exists, and
2153 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
2154 * replace it. Return 0 on success, -1 on failure. */
2155 static int
2156 write_configuration_file(const char *fname, or_options_t *options)
2158 char fn_tmp[1024];
2159 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
2160 int rename_old = 0, r;
2161 size_t len;
2163 if (fname) {
2164 switch (file_status(fname)) {
2165 case FN_FILE:
2166 old_val = read_file_to_str(fname, 0);
2167 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
2168 rename_old = 1;
2170 tor_free(old_val);
2171 break;
2172 case FN_NOENT:
2173 break;
2174 default:
2175 log_fn(LOG_WARN,"Config file %s is not a file? Failing.", fname);
2176 return -1;
2180 if (!(new_conf = config_dump_options(options, 1))) {
2181 log_fn(LOG_WARN, "Couldn't get configuration string");
2182 goto err;
2185 len = strlen(new_conf)+128;
2186 new_val = tor_malloc(len);
2187 tor_snprintf(new_val, len, "%s\n\n%s", GENERATED_FILE_PREFIX, new_conf);
2189 if (rename_old) {
2190 int i = 1;
2191 while (1) {
2192 if (tor_snprintf(fn_tmp, sizeof(fn_tmp), "%s.orig.%d", fname, i)<0) {
2193 log_fn(LOG_WARN, "Filename too long");
2194 goto err;
2196 if (file_status(fn_tmp) == FN_NOENT)
2197 break;
2198 ++i;
2200 log_fn(LOG_NOTICE, "Renaming old configuration file to %s", fn_tmp);
2201 rename(fname, fn_tmp);
2204 write_str_to_file(fname, new_val, 0);
2206 r = 0;
2207 goto done;
2208 err:
2209 r = -1;
2210 done:
2211 tor_free(new_val);
2212 tor_free(new_conf);
2213 return r;
2217 * Save the current configuration file value to disk. Return 0 on
2218 * success, -1 on failure.
2221 save_current_config(void)
2223 char *fn;
2224 if (config_fname) {
2225 /* XXX This fails if we can't write to our configuration file.
2226 * Arguably, we should try falling back to datadirectory or something.
2227 * But just as arguably, we shouldn't. */
2228 return write_configuration_file(config_fname, get_options());
2230 fn = get_default_conf_file();
2231 return write_configuration_file(fn, get_options());
2234 struct unit_table_t {
2235 const char *unit;
2236 uint64_t multiplier;
2239 static struct unit_table_t memory_units[] = {
2240 { "b", 1<< 0 },
2241 { "byte", 1<< 0 },
2242 { "bytes", 1<< 0 },
2243 { "kb", 1<<10 },
2244 { "kilobyte", 1<<10 },
2245 { "kilobytes", 1<<10 },
2246 { "m", 1<<20 },
2247 { "mb", 1<<20 },
2248 { "megabyte", 1<<20 },
2249 { "megabytes", 1<<20 },
2250 { "gb", 1<<30 },
2251 { "gigabyte", 1<<30 },
2252 { "gigabytes", 1<<30 },
2253 { "tb", U64_LITERAL(1)<<40 },
2254 { "terabyte", U64_LITERAL(1)<<40 },
2255 { "terabytes", U64_LITERAL(1)<<40 },
2256 { NULL, 0 },
2259 static struct unit_table_t time_units[] = {
2260 { "second", 1 },
2261 { "seconds", 1 },
2262 { "minute", 60 },
2263 { "minutes", 60 },
2264 { "hour", 60*60 },
2265 { "hours", 60*60 },
2266 { "day", 24*60*60 },
2267 { "days", 24*60*60 },
2268 { "week", 7*24*60*60 },
2269 { "weeks", 7*24*60*60 },
2270 { NULL, 0 },
2273 /** Parse a string <b>val</b> containing a number, zero or more
2274 * spaces, and an optional unit string. If the unit appears in the
2275 * table <b>u</b>, then multiply the number by the unit multiplier.
2276 * On success, set *<b>ok</b> to 1 and return this product.
2277 * Otherwise, set *<b>ok</b> to 0.
2279 static uint64_t
2280 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
2282 uint64_t v;
2283 char *cp;
2285 tor_assert(ok);
2287 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
2288 if (!*ok)
2289 return 0;
2290 if (!cp) {
2291 *ok = 1;
2292 return v;
2294 while(isspace(*cp))
2295 ++cp;
2296 for ( ;u->unit;++u) {
2297 if (!strcasecmp(u->unit, cp)) {
2298 v *= u->multiplier;
2299 *ok = 1;
2300 return v;
2303 log_fn(LOG_WARN, "Unknown unit '%s'.", cp);
2304 *ok = 0;
2305 return 0;
2308 /** Parse a string in the format "number unit", where unit is a unit of
2309 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
2310 * and return the number of bytes specified. Otherwise, set
2311 * *<b>ok</b> to false and return 0. */
2312 static uint64_t
2313 config_parse_memunit(const char *s, int *ok) {
2314 return config_parse_units(s, memory_units, ok);
2317 /** Parse a string in the format "number unit", where unit is a unit of time.
2318 * On success, set *<b>ok</b> to true and return the number of seconds in
2319 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
2321 static int
2322 config_parse_interval(const char *s, int *ok) {
2323 uint64_t r;
2324 r = config_parse_units(s, time_units, ok);
2325 if (!ok)
2326 return -1;
2327 if (r > INT_MAX) {
2328 log_fn(LOG_WARN, "Interval '%s' is too long", s);
2329 *ok = 0;
2330 return -1;
2332 return (int)r;
2336 Local Variables:
2337 mode:c
2338 indent-tabs-mode:nil
2339 c-basic-offset:2
2340 End: