diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 5 | ||||
-rw-r--r-- | src/or/config.c | 158 | ||||
-rw-r--r-- | src/or/connection_edge.c | 2 | ||||
-rw-r--r-- | src/or/directory.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 16 | ||||
-rw-r--r-- | src/or/relay.c | 4 | ||||
-rw-r--r-- | src/or/router.c | 2 | ||||
-rw-r--r-- | src/or/routerlist.c | 7 | ||||
-rw-r--r-- | src/or/routerparse.c | 19 | ||||
-rw-r--r-- | src/or/test.c | 2 |
10 files changed, 136 insertions, 85 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 7be062e25d..34ce5e2b9e 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1416,7 +1416,7 @@ choose_good_entry_server(cpath_build_state_t *state) smartlist_add(excluded, r); routerlist_add_family(excluded, r); } - if (options->FascistFirewall) { + if (firewall_is_fascist()) { /* exclude all ORs that listen on the wrong port */ routerlist_t *rl; int i; @@ -1427,7 +1427,7 @@ choose_good_entry_server(cpath_build_state_t *state) for (i=0; i < smartlist_len(rl->routers); i++) { r = smartlist_get(rl->routers, i); - if (!fascist_firewall_allows_address(options,r->addr,r->or_port)) + if (!fascist_firewall_allows_address(r->addr,r->or_port)) smartlist_add(excluded, r); } } @@ -1986,3 +1986,4 @@ helper_nodes_getinfo_helper(const char *question, char **answer) } return 0; } + diff --git a/src/or/config.c b/src/or/config.c index 4dad008d83..e49f303f4a 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -123,7 +123,6 @@ static config_var_t _option_vars[] = { VAR("ExitPolicy", LINELIST, ExitPolicy, NULL), VAR("FascistFirewall", BOOL, FascistFirewall, "0"), VAR("FirewallPorts", CSV, FirewallPorts, ""), - VAR("FirewallIPs", CSV, FirewallIPs, NULL), VAR("Group", STRING, Group, NULL), VAR("HardwareAccel", BOOL, HardwareAccel, "1"), VAR("HashedControlPassword",STRING, HashedControlPassword, NULL), @@ -160,6 +159,7 @@ static config_var_t _option_vars[] = { VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL), VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"), VAR("PidFile", STRING, PidFile, NULL), + VAR("ReachableAddresses", LINELIST, ReachableAddresses, NULL), VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL), VAR("RedirectExit", LINELIST, RedirectExit, NULL), VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL), @@ -285,6 +285,7 @@ static int or_state_validate(or_state_t *options); static uint64_t config_parse_memunit(const char *s, int *ok); static int config_parse_interval(const char *s, int *ok); static void print_cvs_version(void); +static void parse_reachable_addresses(void); static int init_libevent(void); #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD) static void check_libevent_version(const char *m, const char *v, int server); @@ -324,6 +325,8 @@ static or_options_t *global_options = NULL; static char *config_fname = NULL; /** Persistant serialized state. */ static or_state_t *global_state = NULL; +/** DOCDOC */ +static addr_policy_t *reachable_addr_policy = NULL; static void * config_alloc(config_format_t *fmt) @@ -358,6 +361,8 @@ config_free_all(void) { config_free(&options_format, global_options); tor_free(config_fname); + addr_policy_free(reachable_addr_policy); + reachable_addr_policy = NULL; } /** If options->SafeLogging is on, return a not very useful string, @@ -483,6 +488,7 @@ options_act(void) /* Update address policies. */ parse_socks_policy(); parse_dir_policy(); + parse_reachable_addresses(); init_cookie_authentication(options->CookieAuthentication); @@ -1376,7 +1382,6 @@ config_dump(config_format_t *fmt, void *options, int minimal) if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name)) continue; - desc = config_find_description(fmt, fmt->vars[i].name); if (desc) { size_t len = strlen(desc)+8; @@ -1439,56 +1444,51 @@ validate_ports_csv(smartlist_t *sl, const char *name) return result; } -/* Return 0 if every element of sl is a string holding an IP with - * optional mask and port, or if sl is NULL. Otherwise return -1. */ -static int -validate_addr_port_ranges_csv(smartlist_t *sl, const char *name) +/** DOCDOC */ +static void +parse_reachable_addresses(void) { - uint32_t addr, mask; - uint16_t port_min, port_max; - int result = 0; - tor_assert(name); + or_options_t *options = get_options(); - if (!sl) - return 0; + addr_policy_free(reachable_addr_policy); + reachable_addr_policy = NULL; - SMARTLIST_FOREACH(sl, const char *, cp, - { - if (parse_addr_and_port_range(cp, &addr, &mask, &port_min, &port_max)<0) { - log(LOG_WARN, "IP/port range '%s' invalid in %s", cp, name); - result=-1; - } - }); - return result; + if (config_parse_addr_policy(options->ReachableAddresses, + &reachable_addr_policy, + ADDR_POLICY_ACCEPT)) { + log_fn(LOG_WARN, "Error in ReachableAddresses entry; ignoring."); + return; + } } -/** Return true iff we are configured to think that the local fascist - * firewall (if any) will allow a connection to <b>addr</b>:<b>port</b> */ +/** Return true iff the firewall options might block any address:port + * combination + */ int -fascist_firewall_allows_address(or_options_t *options, uint32_t addr, - uint16_t port) +firewall_is_fascist(void) { - uint32_t ipaddr, ipmask; - uint16_t portmin, portmax; - if (!options->FascistFirewall) - return 1; - - if (smartlist_string_num_isin(options->FirewallPorts, port)) - return 1; - - if (!options->FirewallIPs) - return 0; - - SMARTLIST_FOREACH(options->FirewallIPs, const char *, cp, - { - if (parse_addr_and_port_range(cp, &ipaddr, &ipmask, &portmin, &portmax)<0) - continue; - if ((addr&ipmask) == (ipaddr&ipmask) && - (portmin <= port) && (port <= portmax)) - return 1; - }); + return reachable_addr_policy ? 1 : 0; +} - return 0; +/** Return true iff we are configured to think that the local fascist + * firewall (if any) will allow a connection to <b>addr</b>:<b>port</b> */ +int +fascist_firewall_allows_address(uint32_t addr, uint16_t port) +{ + addr_policy_result_t p = router_compare_addr_to_addr_policy( + addr, port, reachable_addr_policy); + + switch (p) { + case ADDR_POLICY_PROBABLY_ACCEPTED: + case ADDR_POLICY_ACCEPTED: + return 1; + case ADDR_POLICY_PROBABLY_REJECTED: + case ADDR_POLICY_REJECTED: + return 0; + default: + log_fn(LOG_WARN, "Unexpected result: %d", (int)p); + return 0; + } } /** Return 0 if every setting in <b>options</b> is reasonable. Else @@ -1632,20 +1632,48 @@ options_validate(or_options_t *options) "FirewallPorts") < 0) result = -1; - if (validate_addr_port_ranges_csv(options->FirewallIPs, - "FirewallIPs") < 0) + if (validate_ports_csv(options->LongLivedPorts, + "LongLivedPorts") < 0) result = -1; - if (options->FascistFirewall && - !smartlist_len(options->FirewallIPs) && - !smartlist_len(options->FirewallPorts)) { - smartlist_add(options->FirewallPorts, tor_strdup("80")); - smartlist_add(options->FirewallPorts, tor_strdup("443")); + if (options->FascistFirewall) { + smartlist_t *instead = smartlist_create(); + config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t)); + new_line->key = tor_strdup("ReachableAddresses"); + /* If we're configured with the old format, we need to prepend some + * open ports. */ + if (!smartlist_len(options->FirewallPorts)) { + smartlist_add(options->FirewallPorts, tor_strdup("80")); + smartlist_add(options->FirewallPorts, tor_strdup("443")); + } + SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno, + { + int p = atoi(portno); + char *s; + if (p<0) continue; + s = tor_malloc(16); + tor_snprintf(s, 16, "*:%d", p); + smartlist_add(instead, s); + }); + new_line->value = smartlist_join_strings(instead,",",0,NULL); + /* These have been deprecated since 0.1.1.5-alpha-cvs */ + log_fn(LOG_WARN, "FascistFirewall and FirewallPorts are deprecated. Instead, use \"ReachableAddresses %s\"", new_line->value); + new_line->next = options->ReachableAddresses; + options->ReachableAddresses = new_line; + SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp)); + smartlist_free(instead); } - if (validate_ports_csv(options->LongLivedPorts, - "LongLivedPorts") < 0) - result = -1; + if (options->FascistFirewall || options->ReachableAddresses) { + /* We need to end with a reject *:*, not an implicit accept *:* */ + config_line_t **linep = &options->ReachableAddresses; + while (*linep) { + linep = &((*linep)->next); + } + *linep = tor_malloc_zero(sizeof(config_line_t)); + (*linep)->key = tor_strdup("ReachableAddresses"); + (*linep)->value = tor_strdup("reject *:*"); + } options->_AllowUnverified = 0; if (options->AllowUnverifiedNodes) { @@ -1844,7 +1872,7 @@ options_validate(or_options_t *options) result = -1; } - if (config_parse_addr_policy(options->ExitPolicy, &addr_policy)) { + if (config_parse_addr_policy(options->ExitPolicy, &addr_policy, -1)) { log_fn(LOG_WARN, "Error in Exit Policy entry."); result = -1; } @@ -1854,14 +1882,19 @@ options_validate(or_options_t *options) } /* The rest of these calls *append* to addr_policy. So don't actually * use the results for anything other than checking if they parse! */ - if (config_parse_addr_policy(options->DirPolicy, &addr_policy)) { + if (config_parse_addr_policy(options->DirPolicy, &addr_policy, -1)) { log_fn(LOG_WARN, "Error in DirPolicy entry."); result = -1; } - if (config_parse_addr_policy(options->SocksPolicy, &addr_policy)) { + if (config_parse_addr_policy(options->SocksPolicy, &addr_policy, -1)) { log_fn(LOG_WARN, "Error in SocksPolicy entry."); result = -1; } + if (config_parse_addr_policy(options->ReachableAddresses, &addr_policy, + ADDR_POLICY_ACCEPT)) { + log_fn(LOG_WARN, "Error in ReachableAddresses entry."); + result = -1; + } addr_policy_free(addr_policy); for (cl = options->RedirectExit; cl; cl = cl->next) { @@ -2461,7 +2494,7 @@ options_append_default_exit_policy(addr_policy_t **policy) tmp.key = NULL; tmp.value = (char*)DEFAULT_EXIT_POLICY; tmp.next = NULL; - config_parse_addr_policy(&tmp, policy); + config_parse_addr_policy(&tmp, policy, -1); /* Remove redundant parts, if any. */ for (ap=*policy; ap; ap=ap->next) { @@ -2482,7 +2515,8 @@ options_append_default_exit_policy(addr_policy_t **policy) */ int config_parse_addr_policy(config_line_t *cfg, - addr_policy_t **dest) + addr_policy_t **dest, + int assume_action) { addr_policy_t **nextp; smartlist_t *entries; @@ -2502,7 +2536,7 @@ config_parse_addr_policy(config_line_t *cfg, SMARTLIST_FOREACH(entries, const char *, ent, { log_fn(LOG_DEBUG,"Adding new entry '%s'",ent); - *nextp = router_parse_addr_policy_from_string(ent); + *nextp = router_parse_addr_policy_from_string(ent, assume_action); if (*nextp) { nextp = &((*nextp)->next); } else { @@ -3140,9 +3174,9 @@ config_getinfo_helper(const char *question, char **answer) size_t len; desc = config_find_description(&options_format, var->name); switch (var->type) { - case CONFIG_TYPE_STRING: type = "String"; break; + case CONFIG_TYPE_STRING: type = "String"; break; case CONFIG_TYPE_UINT: type = "Integer"; break; - case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break; + case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break; case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break; case CONFIG_TYPE_DOUBLE: type = "Float"; break; case CONFIG_TYPE_BOOL: type = "Boolean"; break; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 66613f4f86..edd776b868 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1696,7 +1696,7 @@ parse_socks_policy(void) addr_policy_free(socks_policy); socks_policy = NULL; } - config_parse_addr_policy(get_options()->SocksPolicy, &socks_policy); + config_parse_addr_policy(get_options()->SocksPolicy, &socks_policy, -1); /* ports aren't used. */ for (n=socks_policy; n; n = n->next) { n->prt_min = 1; diff --git a/src/or/directory.c b/src/or/directory.c index d058ca88de..d46501093c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -69,7 +69,7 @@ parse_dir_policy(void) addr_policy_free(dir_policy); dir_policy = NULL; } - config_parse_addr_policy(get_options()->DirPolicy, &dir_policy); + config_parse_addr_policy(get_options()->DirPolicy, &dir_policy, -1); /* ports aren't used. */ for (n=dir_policy; n; n = n->next) { n->prt_min = 1; @@ -138,7 +138,7 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload, * router descriptor, but not when uploading a service * descriptor -- those use Tor. */ if (purpose == DIR_PURPOSE_UPLOAD_DIR && !get_options()->HttpProxy) { - if (!fascist_firewall_allows_address(get_options(),ds->addr,ds->dir_port)) + if (!fascist_firewall_allows_address(ds->addr,ds->dir_port)) continue; } directory_initiate_command_trusted_dir(ds, purpose, purpose_is_private(purpose), @@ -159,7 +159,7 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource, { routerinfo_t *r = NULL; trusted_dir_server_t *ds = NULL; - int fascistfirewall = get_options()->FascistFirewall; + int fascistfirewall = firewall_is_fascist(); int directconn = purpose == DIR_PURPOSE_FETCH_DIR || purpose == DIR_PURPOSE_FETCH_RUNNING_LIST; int fetch_fresh_first = advertised_server_mode(); diff --git a/src/or/or.h b/src/or/or.h index 430dfb2e7a..9e97e09a57 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1094,7 +1094,9 @@ typedef struct { int RunAsDaemon; /**< If true, run in the background. (Unix only) */ int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ smartlist_t *FirewallPorts; /**< Which ports our firewall allows (strings). */ - smartlist_t *FirewallIPs; /**< Which IPs our firewall allows (strings). */ + config_line_t *ReachableAddresses; /**< Which IP:ports our firewall allows + * (exit policy.) */ + /** Application ports that require all nodes in circ to have sufficient uptime. */ smartlist_t *LongLivedPorts; /** Should we try to reuse the same exit node for a given host */ @@ -1175,6 +1177,8 @@ typedef struct { * of fixed nodes? */ int NumHelperNodes; /**< How many helper nodes do we try to establish? */ int RephistTrackTime; /**< How many seconds do we keep rephist info? */ + + addr_policy_t *reachable_addr_policy; /**< Parsed from ReachableAddresses */ } or_options_t; /** Persistent state for an onion router, as saved to disk. */ @@ -1360,7 +1364,8 @@ void options_init(or_options_t *options); int options_init_from_torrc(int argc, char **argv); int options_init_logs(or_options_t *options, int validate_only); int config_parse_addr_policy(config_line_t *cfg, - addr_policy_t **dest); + addr_policy_t **dest, + int assume_action); void options_append_default_exit_policy(addr_policy_t **policy); void addr_policy_free(addr_policy_t *p); int option_is_recognized(const char *key); @@ -1376,8 +1381,8 @@ int or_state_save(void); int config_getinfo_helper(const char *question, char **answer); -int fascist_firewall_allows_address(or_options_t *options, uint32_t addr, - uint16_t port); +int firewall_is_fascist(void); +int fascist_firewall_allows_address(uint32_t addr, uint16_t port); /********************************* connection.c ***************************/ @@ -2022,7 +2027,8 @@ running_routers_t *router_parse_runningrouters(const char *str, int write_to_cache); routerinfo_t *router_parse_entry_from_string(const char *s, const char *end); int router_add_exit_policy_from_string(routerinfo_t *router, const char *s); -addr_policy_t *router_parse_addr_policy_from_string(const char *s); +addr_policy_t *router_parse_addr_policy_from_string(const char *s, + int assume_action); int check_software_version_against_directory(const char *directory); int tor_version_parse(const char *s, tor_version_t *out); int tor_version_as_new_as(const char *platform, const char *cutoff); diff --git a/src/or/relay.c b/src/or/relay.c index ff77955110..856f2c4a52 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -656,7 +656,7 @@ connection_edge_process_end_not_open( log_fn(LOG_NOTICE,"Exitrouter '%s' seems to be more restrictive than its exit policy. Not using this router as exit for now.", exitrouter->nickname); addr_policy_free(exitrouter->exit_policy); exitrouter->exit_policy = - router_parse_addr_policy_from_string("reject *:*"); + router_parse_addr_policy_from_string("reject *:*", -1); } if (connection_ap_detach_retriable(conn, circ) >= 0) return 0; @@ -683,7 +683,7 @@ connection_edge_process_end_not_open( if (exitrouter) { addr_policy_free(exitrouter->exit_policy); exitrouter->exit_policy = - router_parse_addr_policy_from_string("reject *:*"); + router_parse_addr_policy_from_string("reject *:*", -1); } if (connection_ap_detach_retriable(conn, circ) >= 0) return 0; diff --git a/src/or/router.c b/src/or/router.c index 94c1613d92..16a65ed8d1 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -749,7 +749,7 @@ router_rebuild_descriptor(int force) if (options->BandwidthRate > options->MaxAdvertisedBandwidth) ri->bandwidthrate = (int)options->MaxAdvertisedBandwidth; - config_parse_addr_policy(get_options()->ExitPolicy, &ri->exit_policy); + config_parse_addr_policy(get_options()->ExitPolicy, &ri->exit_policy, -1); options_append_default_exit_policy(&ri->exit_policy); if (desc_routerinfo) /* inherit values */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 4f10ed4774..bdac623c75 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -123,7 +123,7 @@ router_pick_directory_server(int requireother, return choice; log_fn(LOG_INFO,"Still no %s router entries. Reloading and trying again.", - get_options()->FascistFirewall ? "reachable" : "known"); + firewall_is_fascist() ? "reachable" : "known"); has_fetched_directory=0; /* reset it */ if (router_reload_router_list()) { return NULL; @@ -187,8 +187,7 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall, if (requireother && router_is_me(router)) continue; if (fascistfirewall) { - if (!fascist_firewall_allows_address(get_options(),router->addr, - router->dir_port)) + if (!fascist_firewall_allows_address(router->addr, router->dir_port)) continue; } /* before 0.0.9rc5-cvs, only trusted dirservers served status info. */ @@ -231,7 +230,7 @@ router_pick_trusteddirserver_impl(int requireother, int fascistfirewall) !memcmp(me->identity_digest, d->digest, DIGEST_LEN)) continue; if (fascistfirewall) { - if (!fascist_firewall_allows_address(get_options(),d->addr,d->dir_port)) + if (!fascist_firewall_allows_address(d->addr, d->dir_port)) continue; } smartlist_add(sl, d); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 856b14eee4..7d58aad684 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1028,10 +1028,12 @@ router_parse_entry_from_string(const char *s, const char *end) return router; } -/** Parse the exit policy in the string <b>s</b> and return it. +/** Parse the exit policy in the string <b>s</b> and return it. If + * assume_action is nonnegative, then insert its action (ADDR_POLICY_ACCEPT or + * ADDR_POLICY_REJECT) for items that specify no action. */ addr_policy_t * -router_parse_addr_policy_from_string(const char *s) +router_parse_addr_policy_from_string(const char *s, int assume_action) { directory_token_t *tok = NULL; const char *cp; @@ -1047,6 +1049,15 @@ router_parse_addr_policy_from_string(const char *s) } tmp[len]='\n'; tmp[len+1]='\0'; + while (TOR_ISSPACE(*cp)) + ++cp; + if ((*cp == '*' || TOR_ISDIGIT(*cp)) && assume_action >= 0) { + char *new_str = tor_malloc(len+10); + tor_snprintf(new_str, len+10, "%s %s\n", + assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", cp); + tor_free(tmp); + cp = tmp = new_str; + } tok = get_next_token(&cp, RTR_ONLY); if (tok->tp == _ERR) { log_fn(LOG_WARN, "Error reading exit policy: %s", tok->error); @@ -1073,7 +1084,7 @@ int router_add_exit_policy_from_string(routerinfo_t *router, const char *s) { addr_policy_t *newe, *tmpe; - newe = router_parse_addr_policy_from_string(s); + newe = router_parse_addr_policy_from_string(s, -1); if (!newe) return -1; for (tmpe = router->exit_policy; tmpe; tmpe=tmpe->next) @@ -1156,7 +1167,7 @@ assert_addr_policy_ok(addr_policy_t *t) tor_assert(t->policy_type == ADDR_POLICY_REJECT || t->policy_type == ADDR_POLICY_ACCEPT); tor_assert(t->prt_min <= t->prt_max); - t2 = router_parse_addr_policy_from_string(t->string); + t2 = router_parse_addr_policy_from_string(t->string, -1); tor_assert(t2); tor_assert(t2->policy_type == t->policy_type); tor_assert(t2->addr == t->addr); diff --git a/src/or/test.c b/src/or/test.c index efb1220c41..0f0abfd2cd 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1385,7 +1385,7 @@ test_exit_policies(void) { addr_policy_t *policy; - policy = router_parse_addr_policy_from_string("reject 192.168.0.0/16:*"); + policy = router_parse_addr_policy_from_string("reject 192.168.0.0/16:*",-1); test_eq(NULL, policy->next); test_eq(ADDR_POLICY_REJECT, policy->policy_type); test_eq(0xc0a80000u, policy->addr); |