diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-09-15 14:39:05 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-09-15 14:39:05 +0000 |
commit | e72e76cad62fb971a047582381354a083baa220a (patch) | |
tree | bfc98dd9bab0b0fe76eba222f3f2856f3911308c /src/or | |
parent | ed21abfe8792a7180c63d5c0243ebd182a66be3b (diff) | |
download | tor-e72e76cad62fb971a047582381354a083baa220a.tar.gz tor-e72e76cad62fb971a047582381354a083baa220a.zip |
Make authdirs smarter. Reject/invalidate by key and IP. Remember that not every authdir has to be a naming authdir.
svn:r5074
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 18 | ||||
-rw-r--r-- | src/or/dirserv.c | 98 | ||||
-rw-r--r-- | src/or/or.h | 10 | ||||
-rw-r--r-- | src/or/routerlist.c | 25 |
4 files changed, 127 insertions, 24 deletions
diff --git a/src/or/config.c b/src/or/config.c index 69217df622..d1a229976b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -101,9 +101,9 @@ static config_var_t _option_vars[] = { VAR("Address", STRING, Address, NULL), VAR("AllowUnverifiedNodes",CSV, AllowUnverifiedNodes, "middle,rendezvous"), VAR("AssumeReachable", BOOL, AssumeReachable, "0"), + VAR("AuthDirInvalid", LINELIST, AuthDirInvalid, NULL), + VAR("AuthDirReject", LINELIST, AuthDirReject, NULL), VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"), - /* XXXX 011 change this default on 0.1.1.x */ - VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "1"), VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "5 MB"), VAR("BandwidthRate", MEMUNIT, BandwidthRate, "2 MB"), VAR("ClientOnly", BOOL, ClientOnly, "0"), @@ -152,6 +152,8 @@ static config_var_t _option_vars[] = { OBSOLETE("MonthlyAccountingStart"), VAR("MyFamily", STRING, MyFamily, NULL), VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"), + /* XXXX 011 change this default on 0.1.1.x */ + VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "1"), VAR("Nickname", STRING, Nickname, NULL), VAR("NoPublish", BOOL, NoPublish, "0"), VAR("NodeFamily", LINELIST, NodeFamilies, NULL), @@ -188,6 +190,7 @@ static config_var_t _option_vars[] = { OBSOLETE("TrafficShaping"), VAR("UseHelperNodes", BOOL, UseHelperNodes, "0"), VAR("User", STRING, User, NULL), + VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"), VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"), { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL } }; @@ -593,6 +596,7 @@ options_act(or_options_t *old_options) /* Update address policies. */ parse_socks_policy(); parse_dir_policy(); + parse_authdir_policy(); parse_reachable_addresses(); init_cookie_authentication(options->CookieAuthentication); @@ -2075,6 +2079,16 @@ options_validate(or_options_t *options) log_fn(LOG_WARN, "Error in ReachableAddresses entry."); result = -1; } + if (config_parse_addr_policy(options->AuthDirReject, &addr_policy, + ADDR_POLICY_ACCEPT)) { + log_fn(LOG_WARN, "Error in ReachableAddresses entry."); + result = -1; + } + if (config_parse_addr_policy(options->AuthDirInvalid, &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) { diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 30b1f5b9e1..4dd696f32f 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -44,6 +44,39 @@ static int dirserv_thinks_router_is_reachable(routerinfo_t *router, /************** Fingerprint handling code ************/ +static addr_policy_t *authdir_reject_policy = NULL; +static addr_policy_t *authdir_invalid_policy = NULL; + +/** Parse authdir policy strings from the configuration. + */ +void +parse_authdir_policy(void) { + addr_policy_t *n; + if (authdir_reject_policy) { + addr_policy_free(authdir_reject_policy); + authdir_reject_policy = NULL; + } + config_parse_addr_policy(get_options()->AuthDirReject, + &authdir_reject_policy, ADDR_POLICY_ACCEPT); + /* ports aren't used. */ + for (n=authdir_reject_policy; n; n = n->next) { + n->prt_min = 1; + n->prt_max = 65535; + } + + if (authdir_invalid_policy) { + addr_policy_free(authdir_invalid_policy); + authdir_invalid_policy = NULL; + } + config_parse_addr_policy(get_options()->AuthDirInvalid, + &authdir_invalid_policy, ADDR_POLICY_ACCEPT); + /* ports aren't used. */ + for (n=authdir_invalid_policy; n; n = n->next) { + n->prt_min = 1; + n->prt_max = 65535; + } +} + typedef struct fingerprint_entry_t { char *nickname; char *fingerprint; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */ @@ -137,6 +170,12 @@ dirserv_parse_fingerprint_file(const char *fname) log(LOG_NOTICE, "Nickname '%s' too long in fingerprint file. Skipping.", nickname); continue; } + if (!is_legal_nickname(nickname) && + !strcasecmp(nickname, "!reject") && + !strcasecmp(nickname, "!invalid")) { + log(LOG_NOTICE, "Invalid nickname '%s' too long in fingerprint file. Skipping.", nickname); + continue; + } if (strlen(fingerprint) != FINGERPRINT_LEN || !crypto_pk_check_fingerprint_syntax(fingerprint)) { log_fn(LOG_NOTICE, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.", @@ -173,22 +212,56 @@ dirserv_parse_fingerprint_file(const char *fname) static router_status_t dirserv_router_get_status(const routerinfo_t *router, const char **msg) { - fingerprint_entry_t *nn_ent = NULL; + fingerprint_entry_t *nn_ent = NULL, *fp_ent = NULL; char fp[FINGERPRINT_LEN+1]; if (!fingerprint_list) fingerprint_list = smartlist_create(); + if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) { + log_fn(LOG_WARN,"Error computing fingerprint"); + return -1; + } + log_fn(LOG_DEBUG, "%d fingerprints known.", smartlist_len(fingerprint_list)); SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t *, ent, { - if (!strcasecmp(router->nickname,ent->nickname)) { + if (!strcasecmp(fp,ent->fingerprint)) + fp_ent = ent; + if (!strcasecmp(router->nickname,ent->nickname)) nn_ent = ent; - break; - } }); + if (fp_ent) { + if (!strcasecmp(fp_ent->nickname, "!reject")) { + if (msg) + *msg = "Fingerprint is marked rejected"; + return FP_REJECT; + } else if (!strcasecmp(fp_ent->nickname, "!invalid")) { + if (msg) + *msg = "Fingerprint is marged invalid"; + return FP_INVALID; + } + } + if (!nn_ent) { /* No such server known with that nickname */ + addr_policy_result_t rej = router_compare_addr_to_addr_policy( + router->addr, router->or_port, authdir_reject_policy); + addr_policy_result_t inv = router_compare_addr_to_addr_policy( + router->addr, router->or_port, authdir_invalid_policy); + + if (rej == ADDR_POLICY_PROBABLY_ACCEPTED || rej == ADDR_POLICY_ACCEPTED) { + log_fn(LOG_INFO, "Rejecting '%s' because of address %s", + router->nickname, router->address); + if (msg) + *msg = "Authdir is rejecting routers in this range."; + return FP_REJECT; + } + if (inv == ADDR_POLICY_PROBABLY_ACCEPTED || inv == ADDR_POLICY_ACCEPTED) { + log_fn(LOG_INFO, "Not marking '%s' valid because of address %s", + router->nickname, router->address); + return FP_INVALID; + } if (tor_version_as_new_as(router->platform,"0.1.0.2-rc")) return FP_VALID; else @@ -196,10 +269,6 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg) log_fn(LOG_INFO,"No fingerprint found for '%s'",router->nickname); return 0; } - if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) { - log_fn(LOG_WARN,"Error computing fingerprint"); - return -1; - } if (0==strcasecmp(nn_ent->fingerprint, fp)) { log_fn(LOG_DEBUG,"Good fingerprint for '%s'",router->nickname); return FP_NAMED; /* Right fingerprint. */ @@ -1080,6 +1149,7 @@ generate_v2_networkstatus(void) crypto_pk_env_t *private_key = get_identity_key(); smartlist_t *descriptor_list = get_descriptor_list(); time_t now = time(NULL); + int naming = options->NamingAuthoritativeDir; const char *contact; if (!descriptor_list) { @@ -1124,7 +1194,7 @@ generate_v2_networkstatus(void) "fingerprint %s\n" "contact %s\n" "published %s\n" - "dir-options %s\n" + "dir-options%s\n" "client-versions %s\n" "server-versions %s\n" "dir-signing-key\n%s\n", @@ -1132,7 +1202,7 @@ generate_v2_networkstatus(void) fingerprint, contact, published, - "Names", + naming ? " Names" : "", client_versions, server_versions, identity_pkey); @@ -1144,8 +1214,8 @@ generate_v2_networkstatus(void) int f_stable = !router_is_unreliable(ri, 1, 0); int f_fast = !router_is_unreliable(ri, 0, 1); int f_running; - int f_named = ri->is_verified; - int f_valid = f_named; + int f_named = naming && ri->is_named; + int f_valid = ri->is_verified; char identity64[128]; char digest64[128]; @@ -1410,6 +1480,10 @@ dirserv_free_all(void) smartlist_free(fingerprint_list); fingerprint_list = NULL; } + if (authdir_reject_policy) + addr_policy_free(authdir_reject_policy); + if (authdir_invalid_policy) + addr_policy_free(authdir_invalid_policy); clear_cached_dir(&the_directory); clear_cached_dir(&the_runningrouters); clear_cached_dir(&cached_directory); diff --git a/src/or/or.h b/src/or/or.h index a554057678..030ed64f69 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1178,7 +1178,10 @@ typedef struct { int DirPort; /**< Port to listen on for directory connections. */ int AssumeReachable; /**< Whether to publish our descriptor regardless. */ int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */ - int V1AuthoritativeDir; /**< Boolean: is this an authoritative directory? */ + int V1AuthoritativeDir; /**< Boolean: is this an authoritative directory? + * for version 1 directories? */ + int NamingAuthoritativeDir; /**< Boolean: is this an authoritative directory + * that's willing to bind names? */ int ClientOnly; /**< Boolean: should we never evolve into a server role? */ int NoPublish; /**< Boolean: should we never publish a descriptor? */ int ConnLimit; /**< Requested maximum number of simultaneous connections. */ @@ -1243,6 +1246,10 @@ typedef struct { config_line_t *RedirectExit; /**< List of config lines for simple * addr/port redirection */ smartlist_t *RedirectExitList; /**< List of exit_redirect_t */ + config_line_t *AuthDirReject; /**< Address policy for descriptors to + * reject. */ + config_line_t *AuthDirInvalid; /**< Address policy for descriptors to + * never mark as valid. */ char *AccountingStart; /**< How long is the accounting interval, and when * does it start? */ uint64_t AccountingMax; /**< How many bytes do we allow per accounting @@ -1711,6 +1718,7 @@ void free_dir_policy(void); /********************************* dirserv.c ***************************/ +void parse_authdir_policy(void); int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk); int dirserv_parse_fingerprint_file(const char *fname); void dirserv_free_fingerprint_list(void); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index ef839711ba..9c1e1d0c3b 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2270,10 +2270,12 @@ routers_update_status_from_networkstatus(smartlist_t *routers) int i; time_t now = time(NULL); trusted_dir_server_t *ds; + or_options_t *options = get_options(); + int authdir = options->AuthoritativeDir; - if (authdir_mode(get_options())) { - /* An authoritative directory should never believer someone else about - * a server's status. */ + if (authdir && options->NamingAuthoritativeDir) { + /* A completely authoritative directory should never believer someone else + * about a server's status. */ return; } @@ -2336,12 +2338,17 @@ routers_update_status_from_networkstatus(smartlist_t *routers) n_running, n_recent); router->is_named = (n_named > n_naming/2); - router->is_verified = (n_valid > n_statuses/2); - router->is_running = (n_running > n_recent/2); - - if (router->is_running && ds) - /*Hm. What about authorities? When do they reset n_networkstatus_failures?*/ - ds->n_networkstatus_failures = 0; + if (authdir) { + /* We're a non-naming authdir; don't believe others. */ + router->is_verified = (n_valid > n_statuses/2); + router->is_running = (n_running > n_recent/2); + + if (router->is_running && ds) { + /* XXXX001 NM Hm. What about authorities? When do they reset + * n_networkstatus_failures? */ + ds->n_networkstatus_failures = 0; + } + } }); } |