mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Don't assign Exit flag incorrectly
exit_policy_is_general_exit() assumed that there are no redundancies in the passed policy, in the sense that we actively combine entries in the policy to really get rid of any redundancy. Since we cannot do that without massively rewriting the policy lines the relay operators set, fix exit_policy_is_general_exit(). Fixes bug 1238, discovered by Martin Kowalczyk.
This commit is contained in:
parent
c7a2efb380
commit
03bd98b3b1
@ -1,4 +1,10 @@
|
||||
Changes in version 0.2.2.9-alpha - 2010-??-??
|
||||
o Major bugfixes:
|
||||
- Authorities could be tricked into giving out the Exit flag to relays
|
||||
that didn't allow exiting to any ports. This could screw with load
|
||||
balancing and stats. Bugfix on 0.1.1.6-alpha, fixes bug 1238. Bug
|
||||
discovered by Martin Kowalczyk.
|
||||
|
||||
o Minor bugfixes:
|
||||
- When deciding whether to use strange flags to turn TLS renegotiation
|
||||
on, detect the OpenSSL version at run-time, not compile time. We
|
||||
|
@ -865,6 +865,43 @@ policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r)
|
||||
smartlist_add(r->exit_policy, item);
|
||||
}
|
||||
|
||||
/** Return 1 if there is at least one /8 subnet in <b>policy</b> that
|
||||
* allows exiting to <b>port</b>. */
|
||||
static int
|
||||
exit_policy_is_general_exit_helper(smartlist_t *policy, int port)
|
||||
{
|
||||
uint32_t j;
|
||||
/* Is this /8 rejected (1), or undecided (0)? */
|
||||
char subnet_status[256];
|
||||
|
||||
memset(subnet_status, 0, sizeof(subnet_status));
|
||||
SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
|
||||
if (p->prt_min > port || p->prt_max < port)
|
||||
continue; /* Doesn't cover our port. */
|
||||
for (j = 0; j < 256; ++j) {
|
||||
tor_addr_t addr;
|
||||
if (subnet_status[j] != 0)
|
||||
continue; /* We already reject some part of this /8 */
|
||||
tor_addr_from_ipv4h(&addr, j<<24);
|
||||
if (tor_addr_is_internal(&addr, 1)) /* 1 because * = 0.0.0.0 */
|
||||
continue; /* Local or non-routable addresses */
|
||||
if (tor_addr_compare_masked(&addr, &p->addr, p->maskbits,
|
||||
CMP_EXACT) == 0) {
|
||||
if (p->policy_type == ADDR_POLICY_ACCEPT) {
|
||||
if (p->maskbits > 8)
|
||||
continue; /* Narrower than a /8. */
|
||||
/* We found an allowed subnet of at least size /8. Done
|
||||
* for this port! */
|
||||
return 1;
|
||||
} else if (p->policy_type == ADDR_POLICY_REJECT) {
|
||||
subnet_status[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return true iff <b>ri</b> is "useful as an exit node", meaning
|
||||
* it allows exit to at least one /8 address space for at least
|
||||
* two of ports 80, 443, and 6667. */
|
||||
@ -878,19 +915,7 @@ exit_policy_is_general_exit(smartlist_t *policy)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
|
||||
if (p->prt_min > ports[i] || p->prt_max < ports[i])
|
||||
continue; /* Doesn't cover our port. */
|
||||
if (p->maskbits > 8)
|
||||
continue; /* Narrower than a /8. */
|
||||
if (tor_addr_is_loopback(&p->addr))
|
||||
continue; /* 127.x or ::1. */
|
||||
/* We have a match that is at least a /8. */
|
||||
if (p->policy_type == ADDR_POLICY_ACCEPT) {
|
||||
++n_allowed;
|
||||
break; /* stop considering this port */
|
||||
}
|
||||
});
|
||||
n_allowed += exit_policy_is_general_exit_helper(policy, ports[i]);
|
||||
}
|
||||
return n_allowed >= 2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user