Allow MapAddress and Automap to work together

The trick here is to apply mapaddress first, and only then apply
automapping.  Otherwise, the automap checks don't get done.

Fix for bug 7555; bugfix on all versions of Tor supporting both
MapAddress and AutoMap.
This commit is contained in:
Nick Mathewson 2014-04-08 18:02:03 -04:00
parent ab6bd78eca
commit 9d0fab9872
6 changed files with 58 additions and 18 deletions

5
changes/bug7555 Normal file
View File

@ -0,0 +1,5 @@
o Major bugfixes (client):
- Allow MapAddress and AutomapHostsOnResolve to work together when an
address is mapped into another address type that must be
automapped at resolve time. Fixes bug 7555; bugfix on
0.2.0.1-alpha.

View File

@ -390,7 +390,9 @@ addressmap_rewrite(char *address, size_t maxlen,
goto done; goto done;
} }
if (ent && ent->source == ADDRMAPSRC_DNS) { switch (ent->source) {
case ADDRMAPSRC_DNS:
{
sa_family_t f; sa_family_t f;
tor_addr_t tmp; tor_addr_t tmp;
f = tor_addr_parse(&tmp, ent->new_address); f = tor_addr_parse(&tmp, ent->new_address);
@ -399,6 +401,26 @@ addressmap_rewrite(char *address, size_t maxlen,
else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS)) else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS))
goto done; goto done;
} }
break;
case ADDRMAPSRC_CONTROLLER:
case ADDRMAPSRC_TORRC:
if (!(flags & AMR_FLAG_USE_MAPADDRESS))
goto done;
break;
case ADDRMAPSRC_AUTOMAP:
if (!(flags & AMR_FLAG_USE_AUTOMAP))
goto done;
break;
case ADDRMAPSRC_TRACKEXIT:
if (!(flags & AMR_FLAG_USE_TRACKEXIT))
goto done;
break;
case ADDRMAPSRC_NONE:
default:
log_warn(LD_BUG, "Unknown addrmap source value %d. Ignoring it.",
(int) ent->source);
goto done;
}
if (ent->dst_wildcard && !exact_match) { if (ent->dst_wildcard && !exact_match) {
strlcat(address, ".", maxlen); strlcat(address, ".", maxlen);

View File

@ -18,6 +18,9 @@ void addressmap_clear_transient(void);
void addressmap_free_all(void); void addressmap_free_all(void);
#define AMR_FLAG_USE_IPV4_DNS (1u<<0) #define AMR_FLAG_USE_IPV4_DNS (1u<<0)
#define AMR_FLAG_USE_IPV6_DNS (1u<<1) #define AMR_FLAG_USE_IPV6_DNS (1u<<1)
#define AMR_FLAG_USE_MAPADDRESS (1u<<2)
#define AMR_FLAG_USE_AUTOMAP (1u<<3)
#define AMR_FLAG_USE_TRACKEXIT (1u<<4)
int addressmap_rewrite(char *address, size_t maxlen, unsigned flags, int addressmap_rewrite(char *address, size_t maxlen, unsigned flags,
time_t *expires_out, time_t *expires_out,
addressmap_entry_source_t *exit_source_out); addressmap_entry_source_t *exit_source_out);

View File

@ -946,6 +946,15 @@ connection_ap_handshake_rewrite(entry_connection_t *conn,
if (! conn->original_dest_address) if (! conn->original_dest_address)
conn->original_dest_address = tor_strdup(conn->socks_request->address); conn->original_dest_address = tor_strdup(conn->socks_request->address);
if (socks->command != SOCKS_COMMAND_RESOLVE_PTR) {
const unsigned rewrite_flags = AMR_FLAG_USE_MAPADDRESS;
if (addressmap_rewrite(socks->address, sizeof(socks->address),
rewrite_flags, &out->map_expires, &out->exit_source)) {
control_event_stream_status(conn, STREAM_EVENT_REMAP,
REMAP_STREAM_SOURCE_CACHE);
}
}
if (socks->command == SOCKS_COMMAND_RESOLVE && if (socks->command == SOCKS_COMMAND_RESOLVE &&
tor_addr_parse(&addr_tmp, socks->address)<0 && tor_addr_parse(&addr_tmp, socks->address)<0 &&
options->AutomapHostsOnResolve) { options->AutomapHostsOnResolve) {
@ -1014,16 +1023,20 @@ connection_ap_handshake_rewrite(entry_connection_t *conn,
} }
} else if (!out->automap) { } else if (!out->automap) {
/* For address map controls, remap the address. */ /* For address map controls, remap the address. */
unsigned rewrite_flags = 0; unsigned rewrite_flags = AMR_FLAG_USE_AUTOMAP | AMR_FLAG_USE_TRACKEXIT;
addressmap_entry_source_t exit_source2;
if (conn->use_cached_ipv4_answers) if (conn->use_cached_ipv4_answers)
rewrite_flags |= AMR_FLAG_USE_IPV4_DNS; rewrite_flags |= AMR_FLAG_USE_IPV4_DNS;
if (conn->use_cached_ipv6_answers) if (conn->use_cached_ipv6_answers)
rewrite_flags |= AMR_FLAG_USE_IPV6_DNS; rewrite_flags |= AMR_FLAG_USE_IPV6_DNS;
if (addressmap_rewrite(socks->address, sizeof(socks->address), if (addressmap_rewrite(socks->address, sizeof(socks->address),
rewrite_flags, &out->map_expires, &out->exit_source)) { rewrite_flags, &out->map_expires, &exit_source2)) {
control_event_stream_status(conn, STREAM_EVENT_REMAP, control_event_stream_status(conn, STREAM_EVENT_REMAP,
REMAP_STREAM_SOURCE_CACHE); REMAP_STREAM_SOURCE_CACHE);
} }
if (out->exit_source == ADDRMAPSRC_NONE) {
out->exit_source = exit_source2;
}
} }
if (!out->automap && address_is_in_virtual_range(socks->address)) { if (!out->automap && address_is_in_virtual_range(socks->address)) {

View File

@ -51,8 +51,7 @@ test_config_addressmap(void *arg)
/* Use old interface for now, so we don't need to rewrite the unit tests */ /* Use old interface for now, so we don't need to rewrite the unit tests */
#define addressmap_rewrite(a,s,eo,ao) \ #define addressmap_rewrite(a,s,eo,ao) \
addressmap_rewrite((a),(s),AMR_FLAG_USE_IPV4_DNS|AMR_FLAG_USE_IPV6_DNS, \ addressmap_rewrite((a),(s), ~0, (eo),(ao))
(eo),(ao))
/* MapAddress .invalidwildcard.com .torserver.exit - no match */ /* MapAddress .invalidwildcard.com .torserver.exit - no match */
strlcpy(address, "www.invalidwildcard.com", sizeof(address)); strlcpy(address, "www.invalidwildcard.com", sizeof(address));

View File

@ -643,7 +643,6 @@ test_entryconn_rewrite_mapaddress_automap_onion(void *arg)
connection_free_(ENTRY_TO_CONN(ec4)); connection_free_(ENTRY_TO_CONN(ec4));
} }
#if 0
/* This fails because of #7555 */ /* This fails because of #7555 */
/* This time is the same, but we start with a mapping from a non-onion /* This time is the same, but we start with a mapping from a non-onion
* address. */ * address. */
@ -654,6 +653,7 @@ test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
entry_connection_t *ec2 = NULL; entry_connection_t *ec2 = NULL;
entry_connection_t *ec3 = NULL; entry_connection_t *ec3 = NULL;
rewrite_result_t rr; rewrite_result_t rr;
char *msg = NULL;
ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
@ -662,6 +662,7 @@ test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
get_options_mutable()->AllowDotExit = 1; get_options_mutable()->AllowDotExit = 1;
smartlist_add(get_options_mutable()->AutomapHostsSuffixes, smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
tor_strdup(".onion")); tor_strdup(".onion"));
parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
config_line_append(&get_options_mutable()->AddressMap, config_line_append(&get_options_mutable()->AddressMap,
"MapAddress", "irc.example.com abcdefghijklmnop.onion"); "MapAddress", "irc.example.com abcdefghijklmnop.onion");
config_register_addressmaps(get_options()); config_register_addressmaps(get_options());
@ -708,7 +709,6 @@ test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
connection_free_(ENTRY_TO_CONN(ec2)); connection_free_(ENTRY_TO_CONN(ec2));
connection_free_(ENTRY_TO_CONN(ec3)); connection_free_(ENTRY_TO_CONN(ec3));
} }
#endif
#define REWRITE(name) \ #define REWRITE(name) \
{ #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL } { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
@ -727,10 +727,8 @@ struct testcase_t entryconn_tests[] = {
REWRITE(rewrite_automap_exit), REWRITE(rewrite_automap_exit),
REWRITE(rewrite_mapaddress_exit), REWRITE(rewrite_mapaddress_exit),
REWRITE(rewrite_mapaddress_automap_onion), REWRITE(rewrite_mapaddress_automap_onion),
/*
This fails because of #7555
REWRITE(rewrite_mapaddress_automap_onion2), REWRITE(rewrite_mapaddress_automap_onion2),
*/
END_OF_TESTCASES END_OF_TESTCASES
}; };