[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor/master] Address nickm's comments at https://trac.torproject.org/projects/tor/ticket/933#comment:4



commit 909e9769ece9e89ad0c4bbb558a6f8247c6a62bd
Author: Robert Hogan <robert@xxxxxxxxxxxxxxx>
Date:   Mon Dec 13 22:13:01 2010 +0000

    Address nickm's comments at https://trac.torproject.org/projects/tor/ticket/933#comment:4
    
    1. Implement the following mapping rules:
    
       MapAddress a.b.c d.e.f # This is what we have now
       MapAddress .a.b.c d.e.f # Replaces any address ending with .a.b.c with d.e.f
       MapAddress .a.b.c .d.e.f # Replaces the .a.b.c at the end of any addr with .d.e.f
    
       (Note that 'a.b.c .d.e.f' is invalid, and will be rejected.)
    
    2. Add tests for the new rules.
    
    3. Allow proper wildcard annotation, i.e. '*.d.e' '.d.e' will still work.
    
    4. Update addressmap_entry_t with an is_wildcard member.
---
 doc/tor.1.txt            |   10 ++++++----
 src/or/config.c          |   13 ++++++++++++-
 src/or/connection_edge.c |   25 ++++++++++++++++---------
 src/test/test_config.c   |   33 +++++++++++++++++++++++++++++++--
 4 files changed, 65 insertions(+), 16 deletions(-)

diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 4d4ad9f..1c9d387 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -659,12 +659,14 @@ The following options are useful only for clients (that is, if
     before processing it. For example, if you always want connections to
     www.indymedia.org to exit via __torserver__ (where __torserver__ is the
     nickname of the server), use "MapAddress www.indymedia.org
-    www.indymedia.org.torserver.exit". If the value is prepended with a \'.\',
-    it is treated as matching an entire domain.For example, if you always
+    www.indymedia.org.torserver.exit". If the value is prepended with a \'*.\',
+    it is treated as matching an entire domain. For example, if you always
     want connections to  any sub-domain of indymedia.org to exit via
     __torserver__ (where __torserver__ is the nickname of the server), use
-    "MapAddress .indymedia.org .torserver.exit". (Note the leading '.' in
-    each part of the directive.)
+    "MapAddress *.indymedia.org *.indymedia.org.torserver.exit". (Note the
+    leading '*.' in each part of the directive.) You can also redirect all
+    subdomains of a domain to a single address. For example, "MapAddress
+    *.indymedia.org www.indymedia.org".
 
 **NewCircuitPeriod** __NUM__::
     Every NUM seconds consider whether to build a new circuit. (Default: 30
diff --git a/src/or/config.c b/src/or/config.c
index afcea1f..1744b84 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 4bb49c8..2c8c9da 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),
diff --git a/src/test/test_config.c b/src/test/test_config.c
index f39a9ef..a7b5d03 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -16,6 +16,11 @@ test_config_addressmap(void)
   char address[256];
   time_t expires = TIME_MAX;
   strlcpy(buf, "MapAddress .google.com .torserver.exit\n"
+          "MapAddress *.yahoo.com *.google.com.torserver.exit\n"
+          "MapAddress .cn.com www.cnn.com\n"
+          "MapAddress *.cnn.com www.cnn.com\n"
+          "MapAddress ex.com www.cnn.com\n"
+          "MapAddress ey.com *.cnn.com\n"
           "MapAddress www.torproject.org 1.1.1.1\n"
           "MapAddress other.torproject.org "
             "this.torproject.org.otherserver.exit\n"
@@ -31,10 +36,34 @@ test_config_addressmap(void)
   config_register_addressmaps(get_options());
 
   /* Where no mapping for FQDN match on top-level domain */
+  /* MapAddress .google.com .torserver.exit */
   strlcpy(address, "reader.google.com", sizeof(address));
   test_assert(addressmap_rewrite(address, sizeof(address), &expires));
+  test_streq(address, "reader.torserver.exit");
+
+  /* MapAddress *.yahoo.com *.google.com.torserver.exit */
+  strlcpy(address, "reader.yahoo.com", sizeof(address));
+  test_assert(addressmap_rewrite(address, sizeof(address), &expires));
   test_streq(address, "reader.google.com.torserver.exit");
 
+  /*MapAddress *.cnn.com www.cnn.com */
+  strlcpy(address, "cnn.com", sizeof(address));
+  test_assert(addressmap_rewrite(address, sizeof(address), &expires));
+  test_streq(address, "www.cnn.com");
+
+  /* MapAddress .cn.com www.cnn.com */
+  strlcpy(address, "www.cn.com", sizeof(address));
+  test_assert(addressmap_rewrite(address, sizeof(address), &expires));
+  test_streq(address, "www.cnn.com");
+
+  /* MapAddress ex.com www.cnn.com  - no match */
+  strlcpy(address, "www.ex.com", sizeof(address));
+  test_assert(!addressmap_rewrite(address, sizeof(address), &expires));
+
+  /* MapAddress ey.com *.cnn.com - invalid expression */
+  strlcpy(address, "ey.com", sizeof(address));
+  test_assert(!addressmap_rewrite(address, sizeof(address), &expires));
+
   /* Where mapping for FQDN match on FQDN */
   strlcpy(address, "www.google.com", sizeof(address));
   test_assert(addressmap_rewrite(address, sizeof(address), &expires));
@@ -77,11 +106,11 @@ test_config_addressmap(void)
 
   strlcpy(address, "www.abc.com", sizeof(address));
   test_assert(addressmap_rewrite(address, sizeof(address), &expires));
-  test_streq(address, "www.abc.com.torserver.exit");
+  test_streq(address, "www.abc.torserver.exit");
 
   strlcpy(address, "www.def.com", sizeof(address));
   test_assert(addressmap_rewrite(address, sizeof(address), &expires));
-  test_streq(address, "www.def.com.torserver.exit");
+  test_streq(address, "www.def.torserver.exit");
 
   strlcpy(address, "www.torproject.org", sizeof(address));
   test_assert(addressmap_rewrite(address, sizeof(address), &expires));



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits