diff --git a/src/or/config.c b/src/or/config.c index c05182fdc0..4a0e8f4fbf 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -103,6 +103,7 @@ static config_var_t config_vars[] = { VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"), VAR("DebugLogFile", STRING, DebugLogFile, NULL), VAR("DataDirectory", STRING, DataDirectory, NULL), + VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL), VAR("DirPort", UINT, DirPort, "0"), VAR("DirBindAddress", LINELIST, DirBindAddress, NULL), /* XXX we'd like dirfetchperiod to be higher for people with dirport not diff --git a/src/or/directory.c b/src/or/directory.c index d07f04532e..696e113486 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -653,7 +653,7 @@ connection_dir_client_reached_eof(connection_t *conn) log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver '%s'. Malformed server descriptor?", conn->address); break; case 403: - log_fn(LOG_WARN,"http status 403 (unapproved server) response from dirserver '%s'. Is your clock skewed? Have you mailed us your key fingerprint? Are you using the right key? See http://tor.eff.org/doc/tor-doc.html#server.", conn->address); + log_fn(LOG_WARN,"http status 403 (unapproved server) response from dirserver '%s'. Is your clock skewed? Have you mailed us your key fingerprint? Are you using the right key? Are you using a private IP address? See http://tor.eff.org/doc/tor-doc.html#server.", conn->address); break; default: log_fn(LOG_WARN,"http status %d response unrecognized (server '%s').", status_code, conn->address); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 2f04cc6a6e..dbe8f636aa 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -284,6 +284,27 @@ dirserv_free_descriptors() smartlist_clear(descriptor_list); } +/** Return -1 if ri has a private or otherwise bad address, + * unless we're configured to not care. Return 0 if all ok. */ +static int +dirserv_router_has_valid_address(routerinfo_t *ri) +{ + struct in_addr iaddr; + if (get_options()->DirAllowPrivateAddresses) + return 0; /* whatever it is, we're fine with it */ + if (!tor_inet_aton(ri->address, &iaddr)) { + log_fn(LOG_INFO,"Router '%s' published non-IP address '%s'. Refusing.", + ri->nickname, ri->address); + return -1; + } + if (is_internal_IP(ntohl(iaddr.s_addr))) { + log_fn(LOG_INFO,"Router '%s' published internal IP address '%s'. Refusing.", + ri->nickname, ri->address); + return -1; /* it's a private IP, we should reject it */ + } + return 0; +} + /** Parse the server descriptor at *desc and maybe insert it into the * list of server descriptors, and (if the descriptor is well-formed) * advance *desc immediately past the descriptor's end. @@ -340,7 +361,7 @@ dirserv_add_descriptor(const char **desc) } if (r==0) { char fp[FINGERPRINT_LEN+1]; - log_fn(LOG_INFO, "Unknown nickname '%s' (%s:%d). Adding.", + log_fn(LOG_INFO, "Unknown nickname '%s' (%s:%d). Will try to add.", ri->nickname, ri->address, ri->or_port); if (crypto_pk_get_fingerprint(ri->identity_pkey, fp, 1) < 0) { log_fn(LOG_WARN, "Error computing fingerprint for '%s'", ri->nickname); @@ -363,6 +384,12 @@ dirserv_add_descriptor(const char **desc) *desc = end; return 0; } + if (dirserv_router_has_valid_address(ri) < 0) { + log_fn(LOG_NOTICE, "Router with nickname '%s' has invalid address '%s'. Not adding.", ri->nickname, ri->address); + routerinfo_free(ri); + *desc = end; + return 0; + } /* Do we already have an entry for this router? */ for (i = 0; i < smartlist_len(descriptor_list); ++i) { diff --git a/src/or/or.h b/src/or/or.h index f09f9ec1fb..0535a7e4ef 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -910,9 +910,11 @@ typedef struct { struct config_line_t *DirBindAddress; /** Local address to bind outbound sockets */ char *OutboundBindAddress; + /** Directory server only: which versions of + * Tor should we tell users to run? */ struct config_line_t *RecommendedVersions; - /**< Directory server only: which versions of - * Tor should we tell users to run? */ + /** Whether dirservers refuse router descriptors with private IPs. */ + int DirAllowPrivateAddresses; char *User; /**< Name of user to run Tor as. */ char *Group; /**< Name of group to run Tor as. */ double PathlenCoinWeight; /**< Parameter used to configure average path