mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Block OutboundBindAddressIPv[4|6]_ and configured ports on exit relays
Modify policies_parse_exit_policy_reject_private so it also blocks the addresses configured for OutboundBindAddressIPv4_ and OutboundBindAddressIPv6_, and any publicly routable port addresses on exit relays. Add and update unit tests for these functions.
This commit is contained in:
parent
e726ad4664
commit
66fac9fbad
6 changed files with 304 additions and 75 deletions
|
@ -562,7 +562,6 @@ static char *get_bindaddr_from_transport_listen_line(const char *line,
|
|||
static int parse_dir_authority_line(const char *line,
|
||||
dirinfo_type_t required_type,
|
||||
int validate_only);
|
||||
static void port_cfg_free(port_cfg_t *port);
|
||||
static int parse_ports(or_options_t *options, int validate_only,
|
||||
char **msg_out, int *n_ports_out,
|
||||
int *world_writable_control_socket);
|
||||
|
@ -5737,7 +5736,7 @@ parse_dir_fallback_line(const char *line,
|
|||
}
|
||||
|
||||
/** Allocate and return a new port_cfg_t with reasonable defaults. */
|
||||
static port_cfg_t *
|
||||
STATIC port_cfg_t *
|
||||
port_cfg_new(size_t namelen)
|
||||
{
|
||||
tor_assert(namelen <= SIZE_T_CEILING - sizeof(port_cfg_t) - 1);
|
||||
|
@ -5749,7 +5748,7 @@ port_cfg_new(size_t namelen)
|
|||
}
|
||||
|
||||
/** Free all storage held in <b>port</b> */
|
||||
static void
|
||||
STATIC void
|
||||
port_cfg_free(port_cfg_t *port)
|
||||
{
|
||||
tor_free(port);
|
||||
|
@ -6673,8 +6672,8 @@ check_server_ports(const smartlist_t *ports,
|
|||
|
||||
/** Return a list of port_cfg_t for client ports parsed from the
|
||||
* options. */
|
||||
const smartlist_t *
|
||||
get_configured_ports(void)
|
||||
MOCK_IMPL(const smartlist_t *,
|
||||
get_configured_ports,(void))
|
||||
{
|
||||
if (!configured_ports)
|
||||
configured_ports = smartlist_new();
|
||||
|
|
|
@ -76,7 +76,7 @@ int write_to_data_subdir(const char* subdir, const char* fname,
|
|||
|
||||
int get_num_cpus(const or_options_t *options);
|
||||
|
||||
const smartlist_t *get_configured_ports(void);
|
||||
MOCK_DECL(const smartlist_t *,get_configured_ports,(void));
|
||||
int get_first_advertised_port_by_type_af(int listener_type,
|
||||
int address_family);
|
||||
#define get_primary_or_port() \
|
||||
|
@ -140,6 +140,8 @@ smartlist_t *get_options_for_server_transport(const char *transport);
|
|||
extern struct config_format_t options_format;
|
||||
#endif
|
||||
|
||||
STATIC port_cfg_t *port_cfg_new(size_t namelen);
|
||||
STATIC void port_cfg_free(port_cfg_t *port);
|
||||
STATIC void or_options_free(or_options_t *options);
|
||||
STATIC int options_validate(or_options_t *old_options,
|
||||
or_options_t *options,
|
||||
|
|
|
@ -62,14 +62,18 @@ static const char *private_nets[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int policies_parse_exit_policy_internal(config_line_t *cfg,
|
||||
smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
int rejectprivate,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses,
|
||||
int add_default_policy);
|
||||
static int policies_parse_exit_policy_internal(
|
||||
config_line_t *cfg,
|
||||
smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
int rejectprivate,
|
||||
uint32_t local_address,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address,
|
||||
int reject_interface_addresses,
|
||||
int reject_configured_port_addresses,
|
||||
int add_default_policy);
|
||||
|
||||
/** Replace all "private" entries in *<b>policy</b> with their expanded
|
||||
* equivalents. */
|
||||
|
@ -443,7 +447,7 @@ validate_addr_policies(const or_options_t *options, char **msg)
|
|||
smartlist_t *addr_policy=NULL;
|
||||
*msg = NULL;
|
||||
|
||||
if (policies_parse_exit_policy_from_options(options,0,NULL,0,&addr_policy)) {
|
||||
if (policies_parse_exit_policy_from_options(options,0,NULL,&addr_policy)) {
|
||||
REJECT("Error in ExitPolicy entry.");
|
||||
}
|
||||
|
||||
|
@ -993,16 +997,25 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
|||
}
|
||||
}
|
||||
|
||||
/* Is addr public for the purposes of rejection? */
|
||||
static int
|
||||
tor_addr_is_public_for_reject(const tor_addr_t *addr)
|
||||
{
|
||||
return !tor_addr_is_null(addr) && !tor_addr_is_internal(addr, 0);
|
||||
}
|
||||
|
||||
/** Reject private helper for policies_parse_exit_policy_internal: rejects
|
||||
* publicly routable addresses on this exit relay.
|
||||
*
|
||||
* Add reject entries to the linked list *dest:
|
||||
* - if local_address is non-zero, treat it as a host-order IPv4 address,
|
||||
* and prepend an entry that rejects it as a destination.
|
||||
* - if ipv6_local_address is non-NULL, prepend an entry that rejects it as
|
||||
* a destination.
|
||||
* - if reject_interface_addresses is true, prepend entries that reject each
|
||||
* and add an entry that rejects it as a destination.
|
||||
* - if ipv6_local_address, ipv4_outbound_address, or ipv6_outbound_address
|
||||
* are non-NULL, add entries that reject them as destinations.
|
||||
* - if reject_interface_addresses is true, add entries that reject each
|
||||
* public IPv4 and IPv6 address of each interface on this machine.
|
||||
* - if reject_configured_port_addresses is true, add entries that reject
|
||||
* each IPv4 and IPv6 address configured for a port.
|
||||
*
|
||||
* IPv6 entries are only added if ipv6_exit is true. (All IPv6 addresses are
|
||||
* already blocked by policies_parse_exit_policy_internal if ipv6_exit is
|
||||
|
@ -1011,33 +1024,81 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
|||
* The list *dest is created as needed.
|
||||
*/
|
||||
void
|
||||
policies_parse_exit_policy_reject_private(smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses)
|
||||
policies_parse_exit_policy_reject_private(
|
||||
smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
uint32_t local_address,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address,
|
||||
int reject_interface_addresses,
|
||||
int reject_configured_port_addresses)
|
||||
{
|
||||
tor_assert(dest);
|
||||
|
||||
|
||||
/* Reject our local IPv4 address */
|
||||
if (local_address) {
|
||||
tor_addr_t v4_local;
|
||||
tor_addr_from_ipv4h(&v4_local, local_address);
|
||||
addr_policy_append_reject_addr(dest, &v4_local);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject %s:*' for our "
|
||||
"published IPv4 address", fmt_addr32(local_address));
|
||||
if (tor_addr_is_public_for_reject(&v4_local)) {
|
||||
addr_policy_append_reject_addr(dest, &v4_local);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject %s:*' for our "
|
||||
"published IPv4 address", fmt_addr32(local_address));
|
||||
}
|
||||
}
|
||||
|
||||
/* Reject our local IPv6 address */
|
||||
if (ipv6_exit && ipv6_local_address != NULL) {
|
||||
if (tor_addr_is_v4(ipv6_local_address)) {
|
||||
log_warn(LD_CONFIG, "IPv4 address '%s' provided as our IPv6 local "
|
||||
"address", fmt_addr(ipv6_local_address));
|
||||
} else {
|
||||
addr_policy_append_reject_addr(dest, ipv6_local_address);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject [%s]:*' for "
|
||||
"our published IPv6 address", fmt_addr(ipv6_local_address));
|
||||
/* Reject the outbound IPv4 connection address */
|
||||
if (ipv4_outbound_address
|
||||
&& tor_addr_is_public_for_reject(ipv4_outbound_address)) {
|
||||
addr_policy_append_reject_addr(dest, ipv4_outbound_address);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject %s:*' for "
|
||||
"our outbound IPv4 connection address",
|
||||
fmt_addr(ipv4_outbound_address));
|
||||
}
|
||||
|
||||
/* If we're not an IPv6 exit, all IPv6 addresses have already been rejected
|
||||
* by policies_parse_exit_policy_internal */
|
||||
if (ipv6_exit) {
|
||||
|
||||
/* Reject our local IPv6 address */
|
||||
if (ipv6_local_address != NULL
|
||||
&& tor_addr_is_public_for_reject(ipv6_local_address)) {
|
||||
if (tor_addr_is_v4(ipv6_local_address)) {
|
||||
log_warn(LD_CONFIG, "IPv4 address '%s' provided as our IPv6 local "
|
||||
"address", fmt_addr(ipv6_local_address));
|
||||
} else {
|
||||
addr_policy_append_reject_addr(dest, ipv6_local_address);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject [%s]:*' for "
|
||||
"our published IPv6 address", fmt_addr(ipv6_local_address));
|
||||
}
|
||||
}
|
||||
|
||||
/* Reject the outbound IPv6 connection address */
|
||||
if (ipv6_outbound_address
|
||||
&& tor_addr_is_public_for_reject(ipv6_outbound_address)) {
|
||||
addr_policy_append_reject_addr(dest, ipv6_outbound_address);
|
||||
log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject [%s]:*' for "
|
||||
"our outbound IPv6 connection address",
|
||||
fmt_addr(ipv6_outbound_address));
|
||||
}
|
||||
}
|
||||
|
||||
/* Reject configured port addresses, if they are from public netblocks. */
|
||||
if (reject_configured_port_addresses) {
|
||||
const smartlist_t *port_addrs = get_configured_ports();
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(port_addrs, port_cfg_t *, port) {
|
||||
|
||||
/* Only reject IP addresses which are public */
|
||||
if (!port->is_unix_addr && tor_addr_is_public_for_reject(&port->addr)) {
|
||||
|
||||
/* Reject IPv4 addresses. If we are an IPv6 exit, also reject IPv6
|
||||
* addresses */
|
||||
if (tor_addr_is_v4(&port->addr) || ipv6_exit) {
|
||||
addr_policy_append_reject_addr(dest, &port->addr);
|
||||
}
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(port);
|
||||
}
|
||||
|
||||
/* Reject local addresses from public netblocks on any interface. */
|
||||
|
@ -1074,8 +1135,8 @@ policies_parse_exit_policy_reject_private(smartlist_t **dest,
|
|||
*
|
||||
* If <b>rejectprivate</b> is true:
|
||||
* - prepend "reject private:*" to the policy.
|
||||
* - call policies_parse_exit_policy_reject_private to reject publicly
|
||||
* routable addresses on this exit relay
|
||||
* - prepend entries that reject publicly routable addresses on this exit
|
||||
* relay by calling policies_parse_exit_policy_reject_private
|
||||
*
|
||||
* If cfg doesn't end in an absolute accept or reject and if
|
||||
* <b>add_default_policy</b> is true, add the default exit
|
||||
|
@ -1092,8 +1153,11 @@ policies_parse_exit_policy_internal(config_line_t *cfg, smartlist_t **dest,
|
|||
int ipv6_exit,
|
||||
int rejectprivate,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address,
|
||||
int reject_interface_addresses,
|
||||
int reject_configured_port_addresses,
|
||||
int add_default_policy)
|
||||
{
|
||||
if (!ipv6_exit) {
|
||||
|
@ -1103,9 +1167,13 @@ policies_parse_exit_policy_internal(config_line_t *cfg, smartlist_t **dest,
|
|||
/* Reject IPv4 and IPv6 reserved private netblocks */
|
||||
append_exit_policy_string(dest, "reject private:*");
|
||||
/* Reject IPv4 and IPv6 publicly routable addresses on this exit relay */
|
||||
policies_parse_exit_policy_reject_private(dest, ipv6_exit, local_address,
|
||||
ipv6_local_address,
|
||||
reject_interface_addresses);
|
||||
policies_parse_exit_policy_reject_private(
|
||||
dest, ipv6_exit, local_address,
|
||||
ipv6_local_address,
|
||||
ipv4_outbound_address,
|
||||
ipv6_outbound_address,
|
||||
reject_interface_addresses,
|
||||
reject_configured_port_addresses);
|
||||
}
|
||||
if (parse_addr_policy(cfg, dest, -1))
|
||||
return -1;
|
||||
|
@ -1202,8 +1270,9 @@ int
|
|||
policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
|
||||
exit_policy_parser_cfg_t options,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses)
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address)
|
||||
{
|
||||
int ipv6_enabled = (options & EXIT_POLICY_IPV6_ENABLED) ? 1 : 0;
|
||||
int reject_private = (options & EXIT_POLICY_REJECT_PRIVATE) ? 1 : 0;
|
||||
|
@ -1213,7 +1282,10 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
|
|||
reject_private,
|
||||
local_address,
|
||||
ipv6_local_address,
|
||||
reject_interface_addresses,
|
||||
ipv4_outbound_address,
|
||||
ipv6_outbound_address,
|
||||
reject_private,
|
||||
reject_private,
|
||||
add_default);
|
||||
}
|
||||
|
||||
|
@ -1241,8 +1313,7 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
|
|||
int
|
||||
policies_parse_exit_policy_from_options(const or_options_t *or_options,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
smartlist_t **result)
|
||||
{
|
||||
exit_policy_parser_cfg_t parser_cfg = 0;
|
||||
|
@ -1268,7 +1339,8 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options,
|
|||
return policies_parse_exit_policy(or_options->ExitPolicy,result,
|
||||
parser_cfg,local_address,
|
||||
ipv6_local_address,
|
||||
reject_interface_addresses);
|
||||
&or_options->OutboundBindAddressIPv4_,
|
||||
&or_options->OutboundBindAddressIPv6_);
|
||||
}
|
||||
|
||||
/** Add "reject *:*" to the end of the policy in *<b>dest</b>, allocating
|
||||
|
|
|
@ -48,21 +48,26 @@ MOCK_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
|
|||
addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr,
|
||||
uint16_t port, const node_t *node);
|
||||
|
||||
int policies_parse_exit_policy_from_options(const or_options_t *or_options,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses,
|
||||
smartlist_t **result);
|
||||
int policies_parse_exit_policy_from_options(
|
||||
const or_options_t *or_options,
|
||||
uint32_t local_address,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
smartlist_t **result);
|
||||
int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
|
||||
exit_policy_parser_cfg_t options,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses);
|
||||
void policies_parse_exit_policy_reject_private(smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
uint32_t local_address,
|
||||
tor_addr_t *ipv6_local_address,
|
||||
int reject_interface_addresses);
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address);
|
||||
void policies_parse_exit_policy_reject_private(
|
||||
smartlist_t **dest,
|
||||
int ipv6_exit,
|
||||
uint32_t local_address,
|
||||
const tor_addr_t *ipv6_local_address,
|
||||
const tor_addr_t *ipv4_outbound_address,
|
||||
const tor_addr_t *ipv6_outbound_address,
|
||||
int reject_interface_addresses,
|
||||
int reject_configured_port_addresses);
|
||||
void policies_exit_policy_append_reject_star(smartlist_t **dest);
|
||||
void addr_policy_append_reject_addr(smartlist_t **dest,
|
||||
const tor_addr_t *addr);
|
||||
|
|
|
@ -1922,7 +1922,7 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
|
|||
/* DNS is screwed up; don't claim to be an exit. */
|
||||
policies_exit_policy_append_reject_star(&ri->exit_policy);
|
||||
} else {
|
||||
policies_parse_exit_policy_from_options(options,ri->addr,&ri->ipv6_addr,1,
|
||||
policies_parse_exit_policy_from_options(options,ri->addr,&ri->ipv6_addr,
|
||||
&ri->exit_policy);
|
||||
}
|
||||
ri->policy_is_reject_star =
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
/* See LICENSE for licensing information */
|
||||
|
||||
#include "or.h"
|
||||
#define CONFIG_PRIVATE
|
||||
#include "config.h"
|
||||
#include "router.h"
|
||||
#include "routerparse.h"
|
||||
#include "policies.h"
|
||||
|
@ -49,7 +51,7 @@ test_policy_summary_helper(const char *policy_str,
|
|||
|
||||
r = policies_parse_exit_policy(&line, &policy,
|
||||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0, NULL, 0);
|
||||
EXIT_POLICY_ADD_DEFAULT, 0, NULL, NULL, NULL);
|
||||
tt_int_op(r,OP_EQ, 0);
|
||||
|
||||
summary = policy_summarize(policy, AF_INET);
|
||||
|
@ -116,7 +118,7 @@ test_policies_general(void *arg)
|
|||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_REJECT_PRIVATE |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0,
|
||||
NULL, 0));
|
||||
NULL, NULL, NULL));
|
||||
|
||||
tt_assert(policy2);
|
||||
|
||||
|
@ -125,7 +127,8 @@ test_policies_general(void *arg)
|
|||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_REJECT_PRIVATE |
|
||||
EXIT_POLICY_ADD_DEFAULT,
|
||||
0x0306090cu, &tar, 1));
|
||||
0x0306090cu, &tar, NULL,
|
||||
NULL));
|
||||
|
||||
tt_assert(policy12);
|
||||
|
||||
|
@ -207,14 +210,14 @@ test_policies_general(void *arg)
|
|||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_REJECT_PRIVATE |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0,
|
||||
NULL, 0));
|
||||
NULL, NULL, NULL));
|
||||
|
||||
tt_assert(policy8);
|
||||
|
||||
tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy9,
|
||||
EXIT_POLICY_REJECT_PRIVATE |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0,
|
||||
NULL, 0));
|
||||
NULL, NULL, NULL));
|
||||
|
||||
tt_assert(policy9);
|
||||
|
||||
|
@ -269,7 +272,7 @@ test_policies_general(void *arg)
|
|||
tt_int_op(0, OP_EQ, policies_parse_exit_policy(&line,&policy,
|
||||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0,
|
||||
NULL, 0));
|
||||
NULL, NULL, NULL));
|
||||
tt_assert(policy);
|
||||
|
||||
//test_streq(policy->string, "accept *:80");
|
||||
|
@ -530,7 +533,7 @@ test_policies_reject_exit_address(void *arg)
|
|||
/* test that local_address is interpreted as an IPv4 host-order address and
|
||||
* rejected on an IPv4-only exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, TEST_IPV4_ADDR, NULL,
|
||||
0);
|
||||
NULL, NULL, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
|
@ -540,7 +543,7 @@ test_policies_reject_exit_address(void *arg)
|
|||
/* test that local_address is interpreted as an IPv4 host-order address and
|
||||
* rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, TEST_IPV4_ADDR, NULL,
|
||||
0);
|
||||
NULL, NULL, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
|
@ -548,7 +551,8 @@ test_policies_reject_exit_address(void *arg)
|
|||
policy = NULL;
|
||||
|
||||
/* test that ipv6_local_address is rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, &ipv6_addr, 0);
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, &ipv6_addr, NULL,
|
||||
NULL, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv6_addr));
|
||||
|
@ -559,13 +563,155 @@ test_policies_reject_exit_address(void *arg)
|
|||
* (all IPv6 addresses are rejected by policies_parse_exit_policy_internal
|
||||
* on IPv4-only exits, so policies_parse_exit_policy_reject_private doesn't
|
||||
* need to do anything) */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, &ipv6_addr, 0);
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, &ipv6_addr, NULL,
|
||||
NULL, 0, 0);
|
||||
tt_assert(policy == NULL);
|
||||
|
||||
done:
|
||||
addr_policy_list_free(policy);
|
||||
}
|
||||
|
||||
/** Run unit tests for rejecting outbound connection addresses on this
|
||||
* exit relay using policies_parse_exit_policy_reject_private */
|
||||
static void
|
||||
test_policies_reject_outbound_address(void *arg)
|
||||
{
|
||||
smartlist_t *policy = NULL;
|
||||
tor_addr_t ipv4_addr, ipv6_addr;
|
||||
(void)arg;
|
||||
|
||||
tor_addr_from_ipv4h(&ipv4_addr, TEST_IPV4_ADDR);
|
||||
tor_addr_parse(&ipv6_addr, TEST_IPV6_ADDR);
|
||||
|
||||
/* test that OutboundBindAddressIPv4_ is rejected on an IPv4-only exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, &ipv4_addr,
|
||||
NULL, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* test that OutboundBindAddressIPv4_ is rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, NULL, &ipv4_addr,
|
||||
NULL, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* test that OutboundBindAddressIPv6_ is rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, NULL, NULL,
|
||||
&ipv6_addr, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv6_addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* test that OutboundBindAddressIPv6_ is NOT rejected on an IPv4-only exit
|
||||
* (all IPv6 addresses are rejected by policies_parse_exit_policy_internal
|
||||
* on IPv4-only exits, so policies_parse_exit_policy_reject_private doesn't
|
||||
* need to do anything with IPv6 addresses on IPv4-only exits) */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, NULL,
|
||||
&ipv6_addr, 0, 0);
|
||||
tt_assert(policy == NULL);
|
||||
|
||||
/* test that OutboundBindAddressIPv4_ is rejected on an IPv4-only exit,
|
||||
* but OutboundBindAddressIPv6_ is NOT rejected (all IPv6 addresses are
|
||||
* rejected by policies_parse_exit_policy_internal on IPv4-only exits, so
|
||||
* policies_parse_exit_policy_reject_private doesn't need to do anything
|
||||
* with IPv6 addresses on IPv4-only exits) */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, &ipv4_addr,
|
||||
&ipv6_addr, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* test that OutboundBindAddressIPv4_ and OutboundBindAddressIPv6_ are
|
||||
* rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, NULL, &ipv4_addr,
|
||||
&ipv6_addr, 0, 0);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 2);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_addr));
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv6_addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
done:
|
||||
addr_policy_list_free(policy);
|
||||
}
|
||||
|
||||
static smartlist_t *test_configured_ports = NULL;
|
||||
const smartlist_t *mock_get_configured_ports(void);
|
||||
|
||||
/** Returns test_configured_ports */
|
||||
const smartlist_t *
|
||||
mock_get_configured_ports(void)
|
||||
{
|
||||
return test_configured_ports;
|
||||
}
|
||||
|
||||
/** Run unit tests for rejecting publicly routable configured port addresses
|
||||
* on this exit relay using policies_parse_exit_policy_reject_private */
|
||||
static void
|
||||
test_policies_reject_port_address(void *arg)
|
||||
{
|
||||
smartlist_t *policy = NULL;
|
||||
port_cfg_t *ipv4_port = NULL;
|
||||
port_cfg_t *ipv6_port = NULL;
|
||||
(void)arg;
|
||||
|
||||
test_configured_ports = smartlist_new();
|
||||
|
||||
ipv4_port = port_cfg_new(0);
|
||||
tor_addr_from_ipv4h(&ipv4_port->addr, TEST_IPV4_ADDR);
|
||||
smartlist_add(test_configured_ports, ipv4_port);
|
||||
|
||||
ipv6_port = port_cfg_new(0);
|
||||
tor_addr_parse(&ipv6_port->addr, TEST_IPV6_ADDR);
|
||||
smartlist_add(test_configured_ports, ipv6_port);
|
||||
|
||||
MOCK(get_configured_ports, mock_get_configured_ports);
|
||||
|
||||
/* test that an IPv4 port is rejected on an IPv4-only exit, but an IPv6 port
|
||||
* is NOT rejected (all IPv6 addresses are rejected by
|
||||
* policies_parse_exit_policy_internal on IPv4-only exits, so
|
||||
* policies_parse_exit_policy_reject_private doesn't need to do anything
|
||||
* with IPv6 addresses on IPv4-only exits) */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, NULL, NULL,
|
||||
0, 1);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 1);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_port->addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* test that IPv4 and IPv6 ports are rejected on an IPv4/IPv6 exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 1, 0, NULL, NULL, NULL,
|
||||
0, 1);
|
||||
tt_assert(policy);
|
||||
tt_assert(smartlist_len(policy) == 2);
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv4_port->addr));
|
||||
tt_assert(test_policy_has_address_helper(policy, &ipv6_port->addr));
|
||||
addr_policy_list_free(policy);
|
||||
policy = NULL;
|
||||
|
||||
done:
|
||||
addr_policy_list_free(policy);
|
||||
if (test_configured_ports) {
|
||||
SMARTLIST_FOREACH(test_configured_ports,
|
||||
port_cfg_t *, p, port_cfg_free(p));
|
||||
smartlist_free(test_configured_ports);
|
||||
test_configured_ports = NULL;
|
||||
}
|
||||
UNMOCK(get_configured_ports);
|
||||
}
|
||||
|
||||
#undef TEST_IPV4_ADDR
|
||||
#undef TEST_IPV6_ADDR
|
||||
|
||||
|
@ -582,12 +728,14 @@ test_policies_reject_interface_address(void *arg)
|
|||
(void)arg;
|
||||
|
||||
/* test that no addresses are rejected when none are supplied/requested */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, 0);
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, NULL, NULL,
|
||||
0, 0);
|
||||
tt_assert(policy == NULL);
|
||||
|
||||
/* test that only IPv4 interface addresses are rejected on an IPv4-only exit
|
||||
*/
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, 1);
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, NULL, NULL,
|
||||
1, 0);
|
||||
if (policy) {
|
||||
tt_assert(smartlist_len(policy) == smartlist_len(public_ipv4_addrs));
|
||||
addr_policy_list_free(policy);
|
||||
|
@ -596,7 +744,8 @@ test_policies_reject_interface_address(void *arg)
|
|||
|
||||
/* test that IPv4 and IPv6 interface addresses are rejected on an IPv4/IPv6
|
||||
* exit */
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, 1);
|
||||
policies_parse_exit_policy_reject_private(&policy, 0, 0, NULL, NULL, NULL,
|
||||
1, 0);
|
||||
if (policy) {
|
||||
tt_assert(smartlist_len(policy) == (smartlist_len(public_ipv4_addrs)
|
||||
+ smartlist_len(public_ipv6_addrs)));
|
||||
|
@ -705,6 +854,8 @@ struct testcase_t policy_tests[] = {
|
|||
{ "general", test_policies_general, 0, NULL, NULL },
|
||||
{ "reject_exit_address", test_policies_reject_exit_address, 0, NULL, NULL },
|
||||
{ "reject_interface_address", test_policies_reject_interface_address, 0, NULL, NULL },
|
||||
{ "reject_outbound_address", test_policies_reject_outbound_address, 0, NULL, NULL },
|
||||
{ "reject_port_address", test_policies_reject_port_address, 0, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue