mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
[forward-port] Implement an option, VirtualAddrMask, to set which addresses get handed out in response to mapaddress requests. Needs testing and docs!
svn:r6398
This commit is contained in:
parent
6ebd886511
commit
0df40a393b
@ -238,6 +238,7 @@ static config_var_t _option_vars[] = {
|
|||||||
VAR("User", STRING, User, NULL),
|
VAR("User", STRING, User, NULL),
|
||||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||||
VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
|
VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
|
||||||
|
VAR("VirtualAddrNetwork", STRING, VirtualAddrNetwork, "127.192.0.0/10"),
|
||||||
VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
|
VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
|
||||||
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
|
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
|
||||||
};
|
};
|
||||||
@ -677,6 +678,7 @@ options_act(or_options_t *old_options)
|
|||||||
size_t len;
|
size_t len;
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
int running_tor = options->command == CMD_RUN_TOR;
|
int running_tor = options->command == CMD_RUN_TOR;
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
clear_trusted_dir_servers();
|
clear_trusted_dir_servers();
|
||||||
if (options->DirServers) {
|
if (options->DirServers) {
|
||||||
@ -745,6 +747,7 @@ options_act(or_options_t *old_options)
|
|||||||
|
|
||||||
/* Register addressmap directives */
|
/* Register addressmap directives */
|
||||||
config_register_addressmaps(options);
|
config_register_addressmaps(options);
|
||||||
|
parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
|
||||||
|
|
||||||
/* Update address policies. */
|
/* Update address policies. */
|
||||||
policies_parse_from_options(options);
|
policies_parse_from_options(options);
|
||||||
@ -2404,6 +2407,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
if (rend_config_services(options, 1) < 0)
|
if (rend_config_services(options, 1) < 0)
|
||||||
REJECT("Failed to configure rendezvous options. See logs for details.");
|
REJECT("Failed to configure rendezvous options. See logs for details.");
|
||||||
|
|
||||||
|
if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, msg)<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#undef REJECT
|
#undef REJECT
|
||||||
#undef COMPLAIN
|
#undef COMPLAIN
|
||||||
|
@ -750,15 +750,65 @@ client_dns_set_addressmap(const char *address, uint32_t val,
|
|||||||
time(NULL) + ttl);
|
time(NULL) + ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently, we hand out 127.192.0.1 through 127.254.254.254.
|
/* By default, we hand out 127.192.0.1 through 127.254.254.254.
|
||||||
* These addresses should map to localhost, so even if the
|
* These addresses should map to localhost, so even if the
|
||||||
* application accidentally tried to connect to them directly (not
|
* application accidentally tried to connect to them directly (not
|
||||||
* via Tor), it wouldn't get too far astray.
|
* via Tor), it wouldn't get too far astray.
|
||||||
*
|
*
|
||||||
* Eventually, we should probably make this configurable.
|
* Eventually, we should probably make this configurable.
|
||||||
*/
|
*/
|
||||||
#define MIN_UNUSED_IPV4 0x7fc00001u
|
static uint32_t virtual_addr_network = 0x7fc00000u;
|
||||||
#define MAX_UNUSED_IPV4 0x7ffefefeu
|
static uint32_t virtual_addr_netmask = 0xffc00000u;
|
||||||
|
static int virtual_addr_netmask_bits = 10;
|
||||||
|
static uint32_t next_virtual_addr = 0x7fc00000u;
|
||||||
|
|
||||||
|
/** Read a netmask of the form 127.192.0.0/10 from "val", and check whether
|
||||||
|
* it's a valid set of virtual addresses to hand out in response to MAPADDRESS
|
||||||
|
* requests. Return 0 on success; set *msg and return -1 on failure. If
|
||||||
|
* validate_only is false, sets the actual virtual address range to the parsed
|
||||||
|
* value. */
|
||||||
|
int
|
||||||
|
parse_virtual_addr_network(const char *val, int validate_only,
|
||||||
|
const char **msg)
|
||||||
|
{
|
||||||
|
uint32_t addr, mask;
|
||||||
|
uint16_t port_min, port_max;
|
||||||
|
int bits;
|
||||||
|
|
||||||
|
if (parse_addr_and_port_range(val, &addr, &mask, &port_min, &port_max)) {
|
||||||
|
*msg = "Error parsing VirtualAddressNetwork";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port_min != 1 || port_max != 65535) {
|
||||||
|
*msg = "Can't specify ports on VirtualAddressNetwork";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = addr_mask_get_bits(mask);
|
||||||
|
if (bits < 0) {
|
||||||
|
*msg = "VirtualAddressNetwork must have a mask that can be expressed "
|
||||||
|
"as a prefix";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits > 16) {
|
||||||
|
*msg = "VirtualAddressNetwork expects a class B network or larger";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validate_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
virtual_addr_network = addr & mask;
|
||||||
|
virtual_addr_netmask = mask;
|
||||||
|
virtual_addr_netmask_bits = bits;
|
||||||
|
|
||||||
|
if ((next_virtual_addr & mask) != addr)
|
||||||
|
next_virtual_addr = addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff <b>addr</b> is likely to have been returned by
|
* Return true iff <b>addr</b> is likely to have been returned by
|
||||||
@ -773,7 +823,7 @@ address_is_in_virtual_range(const char *address)
|
|||||||
return 1;
|
return 1;
|
||||||
} else if (tor_inet_aton(address, &in)) {
|
} else if (tor_inet_aton(address, &in)) {
|
||||||
uint32_t addr = ntohl(in.s_addr);
|
uint32_t addr = ntohl(in.s_addr);
|
||||||
if (addr >= MIN_UNUSED_IPV4 && addr <= MAX_UNUSED_IPV4)
|
if ((addr & virtual_addr_netmask) == virtual_addr_network)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -787,7 +837,6 @@ static char *
|
|||||||
addressmap_get_virtual_address(int type)
|
addressmap_get_virtual_address(int type)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
static uint32_t next_ipv4 = MIN_UNUSED_IPV4;
|
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
|
|
||||||
if (type == RESOLVED_TYPE_HOSTNAME) {
|
if (type == RESOLVED_TYPE_HOSTNAME) {
|
||||||
@ -799,19 +848,26 @@ addressmap_get_virtual_address(int type)
|
|||||||
} while (strmap_get(addressmap, buf));
|
} while (strmap_get(addressmap, buf));
|
||||||
return tor_strdup(buf);
|
return tor_strdup(buf);
|
||||||
} else if (type == RESOLVED_TYPE_IPV4) {
|
} else if (type == RESOLVED_TYPE_IPV4) {
|
||||||
while (1) {
|
uint32_t available = 1u << virtual_addr_netmask_bits;
|
||||||
|
while (available) {
|
||||||
/* Don't hand out any .0 or .255 address. */
|
/* Don't hand out any .0 or .255 address. */
|
||||||
while ((next_ipv4 & 0xff) == 0 ||
|
while ((next_virtual_addr & 0xff) == 0 ||
|
||||||
(next_ipv4 & 0xff) == 0xff)
|
(next_virtual_addr & 0xff) == 0xff) {
|
||||||
++next_ipv4;
|
++next_virtual_addr;
|
||||||
in.s_addr = htonl(next_ipv4);
|
}
|
||||||
|
in.s_addr = htonl(next_virtual_addr);
|
||||||
tor_inet_ntoa(&in, buf, sizeof(buf));
|
tor_inet_ntoa(&in, buf, sizeof(buf));
|
||||||
if (!strmap_get(addressmap, buf))
|
if (!strmap_get(addressmap, buf))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++next_ipv4;
|
++next_virtual_addr;
|
||||||
if (next_ipv4 > MAX_UNUSED_IPV4)
|
--available;
|
||||||
next_ipv4 = MIN_UNUSED_IPV4;
|
if (! --available) {
|
||||||
|
log_warn(LD_CONFIG, "Ran out of virtual addresses!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((next_virtual_addr & virtual_addr_netmask) != virtual_addr_network)
|
||||||
|
next_virtual_addr = virtual_addr_network;
|
||||||
}
|
}
|
||||||
return tor_strdup(buf);
|
return tor_strdup(buf);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1383,6 +1383,9 @@ typedef struct {
|
|||||||
* of our PK time by sending CREATE_FAST cells? */
|
* of our PK time by sending CREATE_FAST cells? */
|
||||||
|
|
||||||
addr_policy_t *reachable_addr_policy; /**< Parsed from ReachableAddresses */
|
addr_policy_t *reachable_addr_policy; /**< Parsed from ReachableAddresses */
|
||||||
|
|
||||||
|
char *VirtualAddrNetwork; /**< Address and mask to hand out for virtual
|
||||||
|
* MAPADDRESS requests. */
|
||||||
} or_options_t;
|
} or_options_t;
|
||||||
|
|
||||||
/** Persistent state for an onion router, as saved to disk. */
|
/** Persistent state for an onion router, as saved to disk. */
|
||||||
@ -1725,6 +1728,8 @@ void addressmap_rewrite(char *address, size_t maxlen);
|
|||||||
int addressmap_already_mapped(const char *address);
|
int addressmap_already_mapped(const char *address);
|
||||||
void addressmap_register(const char *address, char *new_address,
|
void addressmap_register(const char *address, char *new_address,
|
||||||
time_t expires);
|
time_t expires);
|
||||||
|
int parse_virtual_addr_network(const char *val, int validate_only,
|
||||||
|
const char **msg);
|
||||||
int client_dns_incr_failures(const char *address);
|
int client_dns_incr_failures(const char *address);
|
||||||
void client_dns_clear_failures(const char *address);
|
void client_dns_clear_failures(const char *address);
|
||||||
void client_dns_set_addressmap(const char *address, uint32_t val,
|
void client_dns_set_addressmap(const char *address, uint32_t val,
|
||||||
|
Loading…
Reference in New Issue
Block a user