diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-03-02 19:26:46 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-03-02 19:26:46 +0000 |
commit | 65230fd39f0c333ce8616f5a578f4941ea9f0b94 (patch) | |
tree | e6d33d51eac0f07d35e7fbebcc021f350c724646 | |
parent | 06a574b0c95b332b01aa8beb30bfb8237c1f7747 (diff) | |
download | tor-65230fd39f0c333ce8616f5a578f4941ea9f0b94.tar.gz tor-65230fd39f0c333ce8616f5a578f4941ea9f0b94.zip |
Implement "Dont-Care" from addresses to MapAddress control message. For safety, refuse to launch connections to unmapped addresses in the dont-care range.
svn:r3725
-rw-r--r-- | doc/TODO | 12 | ||||
-rw-r--r-- | src/or/connection_edge.c | 82 | ||||
-rw-r--r-- | src/or/control.c | 12 | ||||
-rw-r--r-- | src/or/or.h | 2 |
4 files changed, 104 insertions, 4 deletions
@@ -59,14 +59,16 @@ N . Implement pending controller features. - List of address mappings (all, or mapaddress+config, or just mapadddress?) o POSTDESCRIPTOR - . MAPADDRESS + o MAPADDRESS o Map A->B. - - Map DontCare->B. + o Map DontCare->B. + - Way to handle overlong messages? - Event for "new descriptors" o Better stream IDs - EXTENDCIRCUIT <depends on revised circ selection stuff.> - ATTACHSTREAM <depends on making streams have 'unattached' state.> - Stream status changed: "new" state. + - Tests for new controller features R . HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to other ORs.) o Changes for forward compatibility @@ -86,7 +88,7 @@ R . HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to (Turns out, if package_raw_inbuf fails, it *can't* send an end cell.) o Check for any place where we can close an edge connection without sending an end; see if we should send an end. -N . Feed end reason back into SOCK5 as reasonable. +N . Feed end reason back into SOCK5 as reasonable. R o cache .foo.exit names better, or differently, or not. N - make !advertised_server_mode() ORs fetch dirs less often. N - Clean up NT service code even more. Document it. Enable it by default. @@ -128,7 +130,9 @@ R o client software not upload descriptor until: * no need to do this yet. few people define their ORPort. Arguable -N - Reverse DNS: specify and implement. +N . Reverse DNS + o specify + - implement r - make min uptime a function of the available choices (say, choose 60th percentile, not 1 day.) r - kill dns workers more slowly diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index f0a9fbde26..52619e392f 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -534,6 +534,77 @@ void client_dns_set_addressmap(const char *address, uint32_t val, const char *ex time(NULL) + MAX_DNS_ENTRY_AGE); } +/* Currently, we hand out 127.192.0.1 through 127.254.254.254. + * These addresses should map to localhost, so even if the + * application accidentally tried to connect to them directly (not + * via Tor), it wouldn't get too far astray. + * + * Eventually, we should probably make this configurable. + */ +#define MIN_UNUSED_IPV4 0x7fc00001u +#define MAX_UNUSED_IPV4 0x7ffefefeu + +/** + * Return true iff <b>addr</b> is likely to have been returned by + * client_dns_get_unmapped_address. + **/ +static int +address_is_in_unmapped_range(const char *addr) +{ + struct in_addr in; + tor_assert(addr); + if (!strcasecmpend(addr, ".virtual")) { + return 1; + } else if (tor_inet_aton(addr, &in)) { + uint32_t a = ntohl(in.s_addr); + if (a >= MIN_UNUSED_IPV4 && a <= MAX_UNUSED_IPV4) + return 1; + } + return 0; +} + +/** Return a newly allocated string holding an address of <b>type</b> + * (one of RESOLVED_TYPE_{IPV4|HOSTNAME}) that has not yet been mapped, + * and that is very unlikely to be the address of any real host. + */ +char * +client_dns_get_unmapped_address(int type) +{ + char buf[64]; + static uint32_t next_ipv4 = MIN_UNUSED_IPV4; + struct in_addr in; + + if (type == RESOLVED_TYPE_HOSTNAME) { + char rand[16]; + do { + crypto_rand(rand, sizeof(rand)); + base32_encode(buf,sizeof(buf),rand,sizeof(rand)); + strlcat(buf, ".virtual", sizeof(buf)); + } while (strmap_get(addressmap, buf)); + return tor_strdup(buf); + } else if (type == RESOLVED_TYPE_IPV4) { + while (1) { + /* Don't hand out any .0 or .255 address. */ + while ((next_ipv4 & 0xff) == 0 || + (next_ipv4 & 0xff) == 0xff) + ++next_ipv4; + in.s_addr = htonl(next_ipv4); + tor_inet_ntoa(&in, buf, sizeof(buf)); + if (!strmap_get(addressmap, buf)) + break; + + ++next_ipv4; + if (next_ipv4 > MAX_UNUSED_IPV4) + next_ipv4 = MIN_UNUSED_IPV4; + } + return tor_strdup(buf); + } else { + log_fn(LOG_WARN, "Called with unsupported address type (%d)", + type); + return NULL; + } +} + /** Return 1 if <b>address</b> has funny characters in it like * colons. Return 0 if it's fine. */ @@ -593,6 +664,17 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { /* For address map controls, remap the address */ addressmap_rewrite(socks->address, sizeof(socks->address)); + if (address_is_in_unmapped_range(socks->address)) { + /* This address was probably handed out by client_dns_get_unmapped_address, + * but the mapping was discarded for some reason. We *don't* want to send + * the address through tor; that's likely to fail, and may leak + * information. + */ + log_fn(LOG_WARN,"Missing mapping for virtual address '%s'. Refusing.", + socks->address); + return -1; + } + /* Parse the address provided by SOCKS. Modify it in-place if it * specifies a hidden-service (.onion) or particular exit node (.exit). */ diff --git a/src/or/control.c b/src/or/control.c index 4ce437283b..ff54f38959 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -471,6 +471,18 @@ handle_control_mapaddress(connection_t *conn, uint16_t len, const char *body) log_fn(LOG_WARN,"Skipping invalid argument '%s' in MapAddress msg",from); } else if (!is_plausible_address(to)) { log_fn(LOG_WARN,"Skipping invalid argument '%s' in AddressMap msg",to); + } else if (!strcmp(from, ".") || !strcmp(from, "0.0.0.0")) { + char *addr = client_dns_get_unmapped_address( + strcmp(from,".") ? RESOLVED_TYPE_HOSTNAME : RESOLVED_TYPE_IPV4); + if (!addr) { + log_fn(LOG_WARN, + "Unable to allocate address for '%s' in AdressMap msg", line); + } else { + char *ans = tor_malloc(strlen(addr)+strlen(to)+2); + tor_snprintf(ans, "%s %s", addr, to); + addressmap_register(addr, tor_strdup(to), 0); + smartlist_add(reply, ans); + } } else { addressmap_register(from, tor_strdup(to), 0); smartlist_add(reply, tor_strdup(line)); diff --git a/src/or/or.h b/src/or/or.h index 90a3245321..fa76f55d5c 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -427,6 +427,7 @@ typedef enum { #define END_STREAM_REASON_CONNRESET 12 #define END_STREAM_REASON_TORPROTOCOL 13 +#define RESOLVED_TYPE_HOSTNAME 0 #define RESOLVED_TYPE_IPV4 4 #define RESOLVED_TYPE_IPV6 6 #define RESOLVED_TYPE_ERROR_TRANSIENT 0xF0 @@ -1318,6 +1319,7 @@ int addressmap_already_mapped(const char *address); void addressmap_register(const char *address, char *new_address, time_t expires); int client_dns_incr_failures(const char *address); void client_dns_set_addressmap(const char *address, uint32_t val, const char *exitname); +char *client_dns_get_unmapped_address(int type); void parse_socks_policy(void); void free_socks_policy(void); |