diff options
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 308 |
1 files changed, 163 insertions, 145 deletions
diff --git a/src/or/config.c b/src/or/config.c index 17ce9bdc3..cceb402ef 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -724,140 +724,23 @@ static int check_nickname_list(const char *lst, const char *name) return r; } -/** Read a configuration file into <b>options</b>, finding the configuration - * file location based on the command line. After loading the options, - * validate them for consistency. Return 0 if success, <0 if failure. */ -int -getconfig(int argc, char **argv, or_options_t *options) -{ - struct config_line_t *cl; - FILE *cf; - char *fname; - int i; - int result = 0; - static int first_load = 1; - static char **backup_argv; - static int backup_argc; - char *previous_pidfile = NULL; - int previous_runasdaemon = 0; - int previous_orport = -1; - int using_default_torrc; - - if (first_load) { /* first time we're called. save commandline args */ - backup_argv = argv; - backup_argc = argc; - first_load = 0; - } else { /* we're reloading. need to clean up old ones first. */ - argv = backup_argv; - argc = backup_argc; - - /* record some previous values, so we can fail if they change */ - if (options->PidFile) - previous_pidfile = tor_strdup(options->PidFile); - previous_runasdaemon = options->RunAsDaemon; - previous_orport = options->ORPort; - free_options(options); - } - init_options(options); - - if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) { - print_usage(); - exit(0); - } - - if (argc > 1 && (!strcmp(argv[1],"--version"))) { - printf("Tor version %s.\n",VERSION); - exit(0); - } - - /* learn config file name, get config lines, assign them */ - fname = NULL; - using_default_torrc = 1; - options->command = CMD_RUN_TOR; - for (i = 1; i < argc; ++i) { - if (i < argc-1 && !strcmp(argv[i],"-f")) { - if (fname) { - log(LOG_WARN, "Duplicate -f options on command line."); - tor_free(fname); - } - fname = tor_strdup(argv[i+1]); - using_default_torrc = 0; - ++i; - } else if (!strcmp(argv[i],"--list-fingerprint")) { - options->command = CMD_LIST_FINGERPRINT; - } else if (!strcmp(argv[i],"--hash-password")) { - options->command = CMD_HASH_PASSWORD; - options->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : ""); - ++i; - } - } - - if (using_default_torrc) { - /* didn't find one, try CONFDIR */ - char *fn; - fn = get_default_conf_file(); - if (fn && file_status(fn) == FN_FILE) { - fname = fn; - } else { - tor_free(fn); - fn = expand_filename("~/.torrc"); - if (fn && file_status(fn) == FN_FILE) { - fname = fn; - } else { - tor_free(fn); - fname = get_default_conf_file(); - } - } - } - tor_assert(fname); - log(LOG_DEBUG, "Opening config file '%s'", fname); - - cf = fopen(fname, "r"); - if (!cf) { - if (using_default_torrc == 1) { - log(LOG_NOTICE, "Configuration file '%s' not present, " - "using reasonable defaults.", fname); - tor_free(fname); - } else { - log(LOG_WARN, "Unable to open configuration file '%s'.", fname); - tor_free(fname); - return -1; - } - } else { /* it opened successfully. use it. */ - tor_free(fname); - if (config_get_lines(cf, &cl)<0) - return -1; - if (config_assign(options,cl) < 0) - return -1; - config_free_lines(cl); - fclose(cf); - } - -/* go through command-line variables too */ - cl = config_get_commandlines(argc,argv); - if (config_assign(options,cl) < 0) - return -1; - config_free_lines(cl); - -/* Validate options */ - - /* first check if any of the previous options have changed but aren't allowed to */ - if (previous_pidfile && strcmp(previous_pidfile,options->PidFile)) { - log_fn(LOG_WARN,"During reload, PidFile changed from %s to %s. Failing.", - previous_pidfile, options->PidFile); - return -1; - } - tor_free(previous_pidfile); +smartlist_t *config_get_default_firewallports(void) { + static smartlist_t *answer; - if (previous_runasdaemon && !options->RunAsDaemon) { - log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing."); - return -1; + if(!answer) { + answer = smartlist_create(); + smartlist_add(answer, tor_strdup("80")); + smartlist_add(answer, tor_strdup("443")); } + return answer; +} - if (previous_orport == 0 && options->ORPort > 0) { - log_fn(LOG_WARN,"During reload, change from ORPort=0 to >0 not allowed. Failing."); - return -1; - } +static int +validate_options(or_options_t *options) +{ + int i; + int result = 0; + struct config_line_t *cl; if (options->ORPort < 0 || options->ORPort > 65535) { log(LOG_WARN, "ORPort option out of bounds."); @@ -944,11 +827,6 @@ getconfig(int argc, char **argv, or_options_t *options) result = -1; } - if (options->FascistFirewall && !options->FirewallPorts) { - options->FirewallPorts = smartlist_create(); - smartlist_add(options->FirewallPorts, tor_strdup("80")); - smartlist_add(options->FirewallPorts, tor_strdup("443")); - } if (options->FirewallPorts) { SMARTLIST_FOREACH(options->FirewallPorts, const char *, cp, { @@ -1032,27 +910,28 @@ getconfig(int argc, char **argv, or_options_t *options) } if (check_nickname_list(options->ExitNodes, "ExitNodes")) - return -1; + result = -1; if (check_nickname_list(options->EntryNodes, "EntryNodes")) - return -1; + result = -1; if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes")) - return -1; + result = -1; if (check_nickname_list(options->RendNodes, "RendNodes")) - return -1; + result = -1; if (check_nickname_list(options->RendNodes, "RendExcludeNodes")) - return -1; + result = -1; if (check_nickname_list(options->MyFamily, "MyFamily")) - return -1; + result = -1; for (cl = options->NodeFamilies; cl; cl = cl->next) { if (check_nickname_list(cl->value, "NodeFamily")) - return -1; + result = -1; } if (!options->RedirectExitList) options->RedirectExitList = smartlist_create(); +/* XXX need to free the old one if it's there, else they just keep piling up */ for (cl = options->RedirectExit; cl; cl = cl->next) { if (parse_redirect_line(options, cl)<0) - return -1; + result = -1; } clear_trusted_dir_servers(); @@ -1061,10 +940,149 @@ getconfig(int argc, char **argv, or_options_t *options) } else { for (cl = options->DirServers; cl; cl = cl->next) { if (parse_dir_server_line(cl->value)<0) - return -1; + result = -1; } } + return result; +} + +/** Read a configuration file into <b>options</b>, finding the configuration + * file location based on the command line. After loading the options, + * validate them for consistency. Return 0 if success, <0 if failure. */ +int +getconfig(int argc, char **argv, or_options_t *options) +{ + struct config_line_t *cl; + FILE *cf; + char *fname; + int i; + int result = 0; + int using_default_torrc; + static char **backup_argv; + static int backup_argc; + char *previous_pidfile = NULL; + int previous_runasdaemon = 0; + int previous_orport = -1; + + if (argv) { /* first time we're called. save commandline args */ + backup_argv = argv; + backup_argc = argc; + } else { /* we're reloading. need to clean up old options first. */ + argv = backup_argv; + argc = backup_argc; + + /* record some previous values, so we can fail if they change */ + if (options->PidFile) + previous_pidfile = tor_strdup(options->PidFile); + previous_runasdaemon = options->RunAsDaemon; + previous_orport = options->ORPort; + free_options(options); + } + init_options(options); + + if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) { + print_usage(); + exit(0); + } + + if (argc > 1 && (!strcmp(argv[1],"--version"))) { + printf("Tor version %s.\n",VERSION); + exit(0); + } + + /* learn config file name, get config lines, assign them */ + fname = NULL; + using_default_torrc = 1; + options->command = CMD_RUN_TOR; + for (i = 1; i < argc; ++i) { + if (i < argc-1 && !strcmp(argv[i],"-f")) { + if (fname) { + log(LOG_WARN, "Duplicate -f options on command line."); + tor_free(fname); + } + fname = tor_strdup(argv[i+1]); + using_default_torrc = 0; + ++i; + } else if (!strcmp(argv[i],"--list-fingerprint")) { + options->command = CMD_LIST_FINGERPRINT; + } else if (!strcmp(argv[i],"--hash-password")) { + options->command = CMD_HASH_PASSWORD; + options->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : ""); + ++i; + } + } + + if (using_default_torrc) { + /* didn't find one, try CONFDIR */ + char *fn; + fn = get_default_conf_file(); + if (fn && file_status(fn) == FN_FILE) { + fname = fn; + } else { + tor_free(fn); + fn = expand_filename("~/.torrc"); + if (fn && file_status(fn) == FN_FILE) { + fname = fn; + } else { + tor_free(fn); + fname = get_default_conf_file(); + } + } + } + tor_assert(fname); + log(LOG_DEBUG, "Opening config file '%s'", fname); + + cf = fopen(fname, "r"); + if (!cf) { + if (using_default_torrc == 1) { + log(LOG_NOTICE, "Configuration file '%s' not present, " + "using reasonable defaults.", fname); + tor_free(fname); + } else { + log(LOG_WARN, "Unable to open configuration file '%s'.", fname); + tor_free(fname); + return -1; + } + } else { /* it opened successfully. use it. */ + tor_free(fname); + if (config_get_lines(cf, &cl)<0) + return -1; + if (config_assign(options,cl) < 0) + return -1; + config_free_lines(cl); + fclose(cf); + } + +/* go through command-line variables too */ + cl = config_get_commandlines(argc,argv); + if (config_assign(options,cl) < 0) + return -1; + config_free_lines(cl); + +/* Validate options */ + + /* first check if any of the previous options have changed but aren't allowed to */ + if (previous_pidfile && strcmp(previous_pidfile,options->PidFile)) { + log_fn(LOG_WARN,"During reload, PidFile changed from %s to %s. Failing.", + previous_pidfile, options->PidFile); + return -1; + } + tor_free(previous_pidfile); + + if (previous_runasdaemon && !options->RunAsDaemon) { + log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing."); + return -1; + } + + if (previous_orport == 0 && options->ORPort > 0) { + log_fn(LOG_WARN,"During reload, change from ORPort=0 to >0 not allowed. Failing."); + return -1; + } + + if (validate_options(options) < 0) + result = -1; + if (rend_config_services(options) < 0) { result = -1; } |