mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +01:00
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
This commit is contained in:
parent
06a574b0c9
commit
65230fd39f
12
doc/TODO
12
doc/TODO
@ -59,14 +59,16 @@ N . Implement pending controller features.
|
|||||||
- List of address mappings (all, or mapaddress+config,
|
- List of address mappings (all, or mapaddress+config,
|
||||||
or just mapadddress?)
|
or just mapadddress?)
|
||||||
o POSTDESCRIPTOR
|
o POSTDESCRIPTOR
|
||||||
. MAPADDRESS
|
o MAPADDRESS
|
||||||
o Map A->B.
|
o Map A->B.
|
||||||
- Map DontCare->B.
|
o Map DontCare->B.
|
||||||
|
- Way to handle overlong messages?
|
||||||
- Event for "new descriptors"
|
- Event for "new descriptors"
|
||||||
o Better stream IDs
|
o Better stream IDs
|
||||||
- EXTENDCIRCUIT <depends on revised circ selection stuff.>
|
- EXTENDCIRCUIT <depends on revised circ selection stuff.>
|
||||||
- ATTACHSTREAM <depends on making streams have 'unattached' state.>
|
- ATTACHSTREAM <depends on making streams have 'unattached' state.>
|
||||||
- Stream status changed: "new" state.
|
- Stream status changed: "new" state.
|
||||||
|
- Tests for new controller features
|
||||||
R . HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to
|
R . HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to
|
||||||
other ORs.)
|
other ORs.)
|
||||||
o Changes for forward compatibility
|
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.)
|
(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
|
o Check for any place where we can close an edge connection without
|
||||||
sending an end; see if we should send an end.
|
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.
|
R o cache .foo.exit names better, or differently, or not.
|
||||||
N - make !advertised_server_mode() ORs fetch dirs less often.
|
N - make !advertised_server_mode() ORs fetch dirs less often.
|
||||||
N - Clean up NT service code even more. Document it. Enable it by default.
|
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.
|
* no need to do this yet. few people define their ORPort.
|
||||||
|
|
||||||
Arguable
|
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
|
r - make min uptime a function of the available choices (say, choose 60th
|
||||||
percentile, not 1 day.)
|
percentile, not 1 day.)
|
||||||
r - kill dns workers more slowly
|
r - kill dns workers more slowly
|
||||||
|
@ -534,6 +534,77 @@ void client_dns_set_addressmap(const char *address, uint32_t val, const char *ex
|
|||||||
time(NULL) + MAX_DNS_ENTRY_AGE);
|
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
|
/** Return 1 if <b>address</b> has funny characters in it like
|
||||||
* colons. Return 0 if it's fine.
|
* 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 */
|
/* For address map controls, remap the address */
|
||||||
addressmap_rewrite(socks->address, sizeof(socks->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
|
/* Parse the address provided by SOCKS. Modify it in-place if it
|
||||||
* specifies a hidden-service (.onion) or particular exit node (.exit).
|
* specifies a hidden-service (.onion) or particular exit node (.exit).
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
log_fn(LOG_WARN,"Skipping invalid argument '%s' in MapAddress msg",from);
|
||||||
} else if (!is_plausible_address(to)) {
|
} else if (!is_plausible_address(to)) {
|
||||||
log_fn(LOG_WARN,"Skipping invalid argument '%s' in AddressMap msg",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 {
|
} else {
|
||||||
addressmap_register(from, tor_strdup(to), 0);
|
addressmap_register(from, tor_strdup(to), 0);
|
||||||
smartlist_add(reply, tor_strdup(line));
|
smartlist_add(reply, tor_strdup(line));
|
||||||
|
@ -427,6 +427,7 @@ typedef enum {
|
|||||||
#define END_STREAM_REASON_CONNRESET 12
|
#define END_STREAM_REASON_CONNRESET 12
|
||||||
#define END_STREAM_REASON_TORPROTOCOL 13
|
#define END_STREAM_REASON_TORPROTOCOL 13
|
||||||
|
|
||||||
|
#define RESOLVED_TYPE_HOSTNAME 0
|
||||||
#define RESOLVED_TYPE_IPV4 4
|
#define RESOLVED_TYPE_IPV4 4
|
||||||
#define RESOLVED_TYPE_IPV6 6
|
#define RESOLVED_TYPE_IPV6 6
|
||||||
#define RESOLVED_TYPE_ERROR_TRANSIENT 0xF0
|
#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);
|
void addressmap_register(const char *address, char *new_address, time_t expires);
|
||||||
int client_dns_incr_failures(const char *address);
|
int client_dns_incr_failures(const char *address);
|
||||||
void client_dns_set_addressmap(const char *address, uint32_t val, const char *exitname);
|
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 parse_socks_policy(void);
|
||||||
void free_socks_policy(void);
|
void free_socks_policy(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user