diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 13 | ||||
-rw-r--r-- | src/or/connection_edge.c | 25 |
2 files changed, 28 insertions, 10 deletions
diff --git a/src/or/config.c b/src/or/config.c index afcea1f4c..1744b84c4 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4464,7 +4464,18 @@ config_register_addressmaps(const or_options_t *options) if (smartlist_len(elts) >= 2) { from = smartlist_get(elts,0); to = smartlist_get(elts,1); - if (address_is_invalid_destination(to, 1)) { + + /* Remove leading asterisk in expressions of type: '*.example.com' */ + if (from[0] == '*' && strlen(from) > 1) + from++; + if (to[0] == '*' && strlen(to) > 1) + to++; + if (to[0] == '.' && from[0] != '.') { + log_warn(LD_CONFIG, + "Skipping invalid argument '%s' to MapAddress: " + "can only use wildcard (i.e. '.' or '*.') if 'from' address " + "uses wildcard also", to); + } else if (address_is_invalid_destination(to, 1)) { log_warn(LD_CONFIG, "Skipping invalid argument '%s' to MapAddress", to); } else { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4bb49c831..2c8c9da25 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -794,6 +794,7 @@ typedef struct { char *new_address; time_t expires; addressmap_entry_source_t source:3; + int is_wildcard:1; short num_resolve_failures; } addressmap_entry_t; @@ -1037,8 +1038,12 @@ addressmap_free_all(void) virtaddress_reversemap = NULL; } -/** Try to find a match for AddressMap directives that use - * domain notation such as '.torproject.org .exitnode.exit'. +/** Try to find a match for AddressMap expressions that use + * wildcard notation such as '*.c.d *.e.f' (so 'a.c.d' will map to 'a.e.f') or + * '*.c.d a.b.c' (so 'a.c.d' will map to a.b.c). + * Returns the matching entry in AddressMap or 0 if no match is found. + * For expressions such as '*.c.d *.e.f' the <b>address</b> 'a.c.d' will + * get truncated to 'a' before we return the matching AddressMap entry. */ static addressmap_entry_t * addressmap_match_superdomains(char *address) @@ -1047,13 +1052,18 @@ addressmap_match_superdomains(char *address) const char *key; void *_val; addressmap_entry_t *val; + char *matched_domains = 0; for (iter = strmap_iter_init(addressmap); !strmap_iter_done(iter); ) { strmap_iter_get(iter, &key, &_val); val = _val; - if (key[0] == '.') { /* match end */ - if (!strcasecmpend(address, key) || !strcasecmp(address, &key[1])) + if (key[0] == '.') { + if (!strcasecmpend(address, key) || !strcasecmp(address, &key[1])) { + matched_domains = strstr(address, key); + if (val->is_wildcard && matched_domains) + *matched_domains = '\0'; return val; + } } iter = strmap_iter_next(addressmap,iter); } @@ -1073,7 +1083,6 @@ addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out) addressmap_entry_t *ent; int rewrites; char *cp; - char *s; time_t expires = TIME_MAX; for (rewrites = 0; rewrites < 16; rewrites++) { @@ -1089,10 +1098,7 @@ addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out) } cp = tor_strdup(escaped_safe_str_client(address)); - /* If the address to rewrite to is in the form '.exitnode.exit' - then append it to the given address */ - s = strrchr(ent->new_address,'.'); - if (ent->new_address[0] == '.' && !strcmp(s+1,"exit")) + if (ent->is_wildcard) strlcpy(address + strlen(address), ent->new_address, (maxlen - strlen(address))); else @@ -1211,6 +1217,7 @@ addressmap_register(const char *address, char *new_address, time_t expires, ent->expires = expires==2 ? 1 : expires; ent->num_resolve_failures = 0; ent->source = source; + ent->is_wildcard = (new_address[0] == '.') ? 1 : 0; log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'", safe_str_client(address), |