LCOV - code coverage report
Current view: top level - feature/client - addressmap.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 287 469 61.2 %
Date: 2021-11-24 03:28:48 Functions: 23 32 71.9 %

          Line data    Source code
       1             : /* Copyright (c) 2001 Matej Pfajfar.
       2             :  * Copyright (c) 2001-2004, Roger Dingledine.
       3             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       4             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * \file addressmap.c
       9             :  *
      10             :  * \brief The addressmap module manages the processes by which we rewrite
      11             :  * addresses in client requess.  It handles the MapAddress controller and
      12             :  * torrc commands, and the TrackHostExits feature, and the client-side DNS
      13             :  * cache (deprecated).
      14             :  */
      15             : 
      16             : #define ADDRESSMAP_PRIVATE
      17             : 
      18             : #include "lib/crypt_ops/crypto_rand.h"
      19             : 
      20             : #include "core/or/or.h"
      21             : #include "feature/client/addressmap.h"
      22             : #include "core/or/circuituse.h"
      23             : #include "app/config/config.h"
      24             : #include "core/or/connection_edge.h"
      25             : #include "feature/control/control_events.h"
      26             : #include "feature/nodelist/nodelist.h"
      27             : #include "feature/nodelist/routerset.h"
      28             : 
      29             : #include "core/or/entry_connection_st.h"
      30             : 
      31             : /** A client-side struct to remember requests to rewrite addresses
      32             :  * to new addresses. These structs are stored in the hash table
      33             :  * "addressmap" below.
      34             :  *
      35             :  * There are 5 ways to set an address mapping:
      36             :  * - A MapAddress command from the controller [permanent]
      37             :  * - An AddressMap directive in the torrc [permanent]
      38             :  * - When a TrackHostExits torrc directive is triggered [temporary]
      39             :  * - When a DNS resolve succeeds [temporary]
      40             :  * - When a DNS resolve fails [temporary]
      41             :  *
      42             :  * When an addressmap request is made but one is already registered,
      43             :  * the new one is replaced only if the currently registered one has
      44             :  * no "new_address" (that is, it's in the process of DNS resolve),
      45             :  * or if the new one is permanent (expires==0 or 1).
      46             :  *
      47             :  * (We overload the 'expires' field, using "0" for mappings set via
      48             :  * the configuration file, "1" for mappings set from the control
      49             :  * interface, and other values for DNS and TrackHostExit mappings that can
      50             :  * expire.)
      51             :  *
      52             :  * A mapping may be 'wildcarded'.  If "src_wildcard" is true, then
      53             :  * any address that ends with a . followed by the key for this entry will
      54             :  * get remapped by it.  If "dst_wildcard" is also true, then only the
      55             :  * matching suffix of such addresses will get replaced by new_address.
      56             :  */
      57             : typedef struct {
      58             :   char *new_address;
      59             :   time_t expires;
      60             :   addressmap_entry_source_bitfield_t source:3;
      61             :   unsigned src_wildcard:1;
      62             :   unsigned dst_wildcard:1;
      63             :   short num_resolve_failures;
      64             : } addressmap_entry_t;
      65             : 
      66             : /** Entry for mapping addresses to which virtual address we mapped them to. */
      67             : typedef struct {
      68             :   char *ipv4_address;
      69             :   char *ipv6_address;
      70             :   char *hostname_address;
      71             : } virtaddress_entry_t;
      72             : 
      73             : /** A hash table to store client-side address rewrite instructions. */
      74             : static strmap_t *addressmap=NULL;
      75             : 
      76             : /**
      77             :  * Table mapping addresses to which virtual address, if any, we
      78             :  * assigned them to.
      79             :  *
      80             :  * We maintain the following invariant: if [A,B] is in
      81             :  * virtaddress_reversemap, then B must be a virtual address, and [A,B]
      82             :  * must be in addressmap.  We do not require that the converse hold:
      83             :  * if it fails, then we could end up mapping two virtual addresses to
      84             :  * the same address, which is no disaster.
      85             :  **/
      86             : static strmap_t *virtaddress_reversemap=NULL;
      87             : 
      88             : /** Initialize addressmap. */
      89             : void
      90         269 : addressmap_init(void)
      91             : {
      92         269 :   addressmap = strmap_new();
      93         269 :   virtaddress_reversemap = strmap_new();
      94         269 : }
      95             : 
      96             : #define addressmap_ent_free(ent)                                        \
      97             :   FREE_AND_NULL(addressmap_entry_t, addressmap_ent_free_, (ent))
      98             : 
      99             : /** Free the memory associated with the addressmap entry <b>_ent</b>. */
     100             : static void
     101          40 : addressmap_ent_free_(addressmap_entry_t *ent)
     102             : {
     103          40 :   if (!ent)
     104             :     return;
     105             : 
     106          40 :   tor_free(ent->new_address);
     107          40 :   tor_free(ent);
     108             : }
     109             : 
     110             : static void
     111          24 : addressmap_ent_free_void(void *ent)
     112             : {
     113          24 :   addressmap_ent_free_(ent);
     114          24 : }
     115             : 
     116             : #define addressmap_virtaddress_ent_free(ent)                            \
     117             :   FREE_AND_NULL(virtaddress_entry_t, addressmap_virtaddress_ent_free_, (ent))
     118             : 
     119             : /** Free storage held by a virtaddress_entry_t* entry in <b>_ent</b>. */
     120             : static void
     121          13 : addressmap_virtaddress_ent_free_(virtaddress_entry_t *ent)
     122             : {
     123          13 :   if (!ent)
     124             :     return;
     125          13 :   tor_free(ent->ipv4_address);
     126          13 :   tor_free(ent->ipv6_address);
     127          13 :   tor_free(ent->hostname_address);
     128          13 :   tor_free(ent);
     129             : }
     130             : 
     131             : static void
     132          13 : addressmap_virtaddress_ent_free_void(void *ent)
     133             : {
     134          13 :   addressmap_virtaddress_ent_free_(ent);
     135          13 : }
     136             : 
     137             : /** Remove <b>address</b> (which must map to <b>ent</b>) from the
     138             :  * virtual address map. */
     139             : static void
     140          16 : addressmap_virtaddress_remove(const char *address, addressmap_entry_t *ent)
     141             : {
     142          32 :   if (ent && ent->new_address &&
     143          16 :       address_is_in_virtual_range(ent->new_address)) {
     144           0 :     virtaddress_entry_t *ve =
     145           0 :       strmap_get(virtaddress_reversemap, ent->new_address);
     146             :     /*log_fn(LOG_NOTICE,"remove reverse mapping for %s",ent->new_address);*/
     147           0 :     if (ve) {
     148           0 :       if (!strcmp(address, ve->ipv4_address))
     149           0 :         tor_free(ve->ipv4_address);
     150           0 :       if (!strcmp(address, ve->ipv6_address))
     151           0 :         tor_free(ve->ipv6_address);
     152           0 :       if (!strcmp(address, ve->hostname_address))
     153           0 :         tor_free(ve->hostname_address);
     154           0 :       if (!ve->ipv4_address && !ve->ipv6_address && !ve->hostname_address) {
     155           0 :         tor_free(ve);
     156           0 :         strmap_remove(virtaddress_reversemap, ent->new_address);
     157             :       }
     158             :     }
     159             :   }
     160          16 : }
     161             : 
     162             : /** Remove <b>ent</b> (which must be mapped to by <b>address</b>) from the
     163             :  * client address maps, and then free it. */
     164             : static void
     165          16 : addressmap_ent_remove(const char *address, addressmap_entry_t *ent)
     166             : {
     167          16 :   addressmap_virtaddress_remove(address, ent);
     168          16 :   addressmap_ent_free(ent);
     169          16 : }
     170             : 
     171             : /** Unregister all TrackHostExits mappings from any address to
     172             :  * *.exitname.exit. */
     173             : void
     174           0 : clear_trackexithost_mappings(const char *exitname)
     175             : {
     176           0 :   char *suffix = NULL;
     177           0 :   if (!addressmap || !exitname)
     178           0 :     return;
     179           0 :   tor_asprintf(&suffix, ".%s.exit", exitname);
     180           0 :   tor_strlower(suffix);
     181             : 
     182           0 :   STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) {
     183           0 :     if (ent->source == ADDRMAPSRC_TRACKEXIT &&
     184           0 :         !strcmpend(ent->new_address, suffix)) {
     185           0 :       addressmap_ent_remove(address, ent);
     186           0 :       MAP_DEL_CURRENT(address);
     187             :     }
     188           0 :   } STRMAP_FOREACH_END;
     189             : 
     190           0 :   tor_free(suffix);
     191             : }
     192             : 
     193             : /** Remove all TRACKEXIT mappings from the addressmap for which the target
     194             :  * host is unknown or no longer allowed, or for which the source address
     195             :  * is no longer in trackexithosts. */
     196             : void
     197           0 : addressmap_clear_excluded_trackexithosts(const or_options_t *options)
     198             : {
     199           0 :   const routerset_t *allow_nodes = options->ExitNodes;
     200           0 :   const routerset_t *exclude_nodes = options->ExcludeExitNodesUnion_;
     201             : 
     202           0 :   if (!addressmap)
     203             :     return;
     204           0 :   if (routerset_is_empty(allow_nodes))
     205             :     allow_nodes = NULL;
     206           0 :   if (allow_nodes == NULL && routerset_is_empty(exclude_nodes))
     207             :     return;
     208             : 
     209           0 :   STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) {
     210           0 :     size_t len;
     211           0 :     const char *target = ent->new_address, *dot;
     212           0 :     char *nodename;
     213           0 :     const node_t *node;
     214             : 
     215           0 :     if (!target) {
     216             :       /* DNS resolving in progress */
     217           0 :       continue;
     218           0 :     } else if (strcmpend(target, ".exit")) {
     219             :       /* Not a .exit mapping */
     220           0 :       continue;
     221           0 :     } else if (ent->source != ADDRMAPSRC_TRACKEXIT) {
     222             :       /* Not a trackexit mapping. */
     223           0 :       continue;
     224             :     }
     225           0 :     len = strlen(target);
     226           0 :     if (len < 6)
     227           0 :       continue; /* malformed. */
     228           0 :     dot = target + len - 6; /* dot now points to just before .exit */
     229           0 :     while (dot > target && *dot != '.')
     230           0 :       dot--;
     231           0 :     if (*dot == '.') dot++;
     232           0 :     nodename = tor_strndup(dot, len-5-(dot-target));
     233           0 :     node = node_get_by_nickname(nodename, NNF_NO_WARN_UNNAMED);
     234           0 :     tor_free(nodename);
     235           0 :     if (!node ||
     236           0 :         (allow_nodes && !routerset_contains_node(allow_nodes, node)) ||
     237           0 :         routerset_contains_node(exclude_nodes, node) ||
     238           0 :         !hostname_in_track_host_exits(options, address)) {
     239             :       /* We don't know this one, or we want to be rid of it. */
     240           0 :       addressmap_ent_remove(address, ent);
     241           0 :       MAP_DEL_CURRENT(address);
     242             :     }
     243           0 :   } STRMAP_FOREACH_END;
     244             : }
     245             : 
     246             : /** Return true iff <b>address</b> is one that we are configured to
     247             :  * automap on resolve according to <b>options</b>. */
     248             : int
     249           8 : addressmap_address_should_automap(const char *address,
     250             :                                   const or_options_t *options)
     251             : {
     252           8 :   const smartlist_t *suffix_list = options->AutomapHostsSuffixes;
     253             : 
     254           8 :   if (!suffix_list)
     255             :     return 0;
     256             : 
     257          19 :   SMARTLIST_FOREACH_BEGIN(suffix_list, const char *, suffix) {
     258          18 :     if (!strcmp(suffix, "."))
     259             :       return 1;
     260          14 :     if (!strcasecmpend(address, suffix))
     261             :       return 1;
     262          11 :   } SMARTLIST_FOREACH_END(suffix);
     263             :   return 0;
     264             : }
     265             : 
     266             : /** Remove all AUTOMAP mappings from the addressmap for which the
     267             :  * source address no longer matches AutomapHostsSuffixes, which is
     268             :  * no longer allowed by AutomapHostsOnResolve, or for which the
     269             :  * target address is no longer in the virtual network. */
     270             : void
     271           0 : addressmap_clear_invalid_automaps(const or_options_t *options)
     272             : {
     273           0 :   int clear_all = !options->AutomapHostsOnResolve;
     274           0 :   const smartlist_t *suffixes = options->AutomapHostsSuffixes;
     275             : 
     276           0 :   if (!addressmap)
     277             :     return;
     278             : 
     279           0 :   if (!suffixes)
     280           0 :     clear_all = 1; /* This should be impossible, but let's be sure. */
     281             : 
     282           0 :   STRMAP_FOREACH_MODIFY(addressmap, src_address, addressmap_entry_t *, ent) {
     283           0 :     int remove_this = clear_all;
     284           0 :     if (ent->source != ADDRMAPSRC_AUTOMAP)
     285           0 :       continue; /* not an automap mapping. */
     286             : 
     287           0 :     if (!remove_this) {
     288           0 :       remove_this = ! addressmap_address_should_automap(src_address, options);
     289             :     }
     290             : 
     291           0 :     if (!remove_this && ! address_is_in_virtual_range(ent->new_address))
     292             :       remove_this = 1;
     293             : 
     294           0 :     if (remove_this) {
     295           0 :       addressmap_ent_remove(src_address, ent);
     296           0 :       MAP_DEL_CURRENT(src_address);
     297             :     }
     298           0 :   } STRMAP_FOREACH_END;
     299             : }
     300             : 
     301             : /** Remove all entries from the addressmap that were set via the
     302             :  * configuration file or the command line. */
     303             : void
     304          30 : addressmap_clear_configured(void)
     305             : {
     306          30 :   addressmap_get_mappings(NULL, 0, 0, 0);
     307          30 : }
     308             : 
     309             : /** Remove all entries from the addressmap that are set to expire, ever. */
     310             : void
     311           0 : addressmap_clear_transient(void)
     312             : {
     313           0 :   addressmap_get_mappings(NULL, 2, TIME_MAX, 0);
     314           0 : }
     315             : 
     316             : /** Clean out entries from the addressmap cache that were
     317             :  * added long enough ago that they are no longer valid.
     318             :  */
     319             : void
     320           0 : addressmap_clean(time_t now)
     321             : {
     322           0 :   addressmap_get_mappings(NULL, 2, now, 0);
     323           0 : }
     324             : 
     325             : /** Free all the elements in the addressmap, and free the addressmap
     326             :  * itself. */
     327             : void
     328         253 : addressmap_free_all(void)
     329             : {
     330         253 :   strmap_free(addressmap, addressmap_ent_free_void);
     331         253 :   addressmap = NULL;
     332             : 
     333         253 :   strmap_free(virtaddress_reversemap, addressmap_virtaddress_ent_free_void);
     334         253 :   virtaddress_reversemap = NULL;
     335         253 : }
     336             : 
     337             : /** Try to find a match for AddressMap expressions that use
     338             :  *  wildcard notation such as '*.c.d *.e.f' (so 'a.c.d' will map to 'a.e.f') or
     339             :  *  '*.c.d a.b.c' (so 'a.c.d' will map to a.b.c).
     340             :  *  Return the matching entry in AddressMap or NULL if no match is found.
     341             :  *  For expressions such as '*.c.d *.e.f', truncate <b>address</b> 'a.c.d'
     342             :  *  to 'a' before we return the matching AddressMap entry.
     343             :  *
     344             :  * This function does not handle the case where a pattern of the form "*.c.d"
     345             :  * matches the address c.d -- that's done by the main addressmap_rewrite
     346             :  * function.
     347             :  */
     348             : static addressmap_entry_t *
     349         100 : addressmap_match_superdomains(char *address)
     350             : {
     351         100 :   addressmap_entry_t *val;
     352         100 :   char *cp;
     353             : 
     354         100 :   cp = address;
     355         220 :   while ((cp = strchr(cp, '.'))) {
     356             :     /* cp now points to a suffix of address that begins with a . */
     357         159 :     val = strmap_get_lc(addressmap, cp+1);
     358         159 :     if (val && val->src_wildcard) {
     359          39 :       if (val->dst_wildcard)
     360           5 :         *cp = '\0';
     361          39 :       return val;
     362             :     }
     363             :     ++cp;
     364             :   }
     365             :   return NULL;
     366             : }
     367             : 
     368             : /** Look at address, and rewrite it until it doesn't want any
     369             :  * more rewrites; but don't get into an infinite loop.
     370             :  * Don't write more than maxlen chars into address.  Return true if the
     371             :  * address changed; false otherwise.  Set *<b>expires_out</b> to the
     372             :  * expiry time of the result, or to <b>time_max</b> if the result does
     373             :  * not expire.
     374             :  *
     375             :  * If <b>exit_source_out</b> is non-null, we set it as follows.  If we the
     376             :  * address starts out as a non-exit address, and we remap it to an .exit
     377             :  * address at any point, then set *<b>exit_source_out</b> to the
     378             :  * address_entry_source_t of the first such rule.  Set *<b>exit_source_out</b>
     379             :  * to ADDRMAPSRC_NONE if there is no such rewrite, or if the original address
     380             :  * was a .exit.
     381             :  */
     382             : int
     383          74 : addressmap_rewrite(char *address, size_t maxlen,
     384             :                    unsigned flags,
     385             :                    time_t *expires_out,
     386             :                    addressmap_entry_source_t *exit_source_out)
     387             : {
     388          74 :   addressmap_entry_t *ent;
     389          74 :   int rewrites;
     390          74 :   time_t expires = TIME_MAX;
     391          74 :   addressmap_entry_source_t exit_source = ADDRMAPSRC_NONE;
     392          74 :   char *addr_orig = tor_strdup(address);
     393          74 :   char *log_addr_orig = NULL;
     394             : 
     395             :   /* We use a loop here to limit the total number of rewrites we do,
     396             :    * so that we can't hit an infinite loop. */
     397         223 :   for (rewrites = 0; rewrites < 16; rewrites++) {
     398         146 :     int exact_match = 0;
     399         146 :     log_addr_orig = tor_strdup(escaped_safe_str_client(address));
     400             : 
     401             :     /* First check to see if there's an exact match for this address */
     402         146 :     ent = strmap_get(addressmap, address);
     403             : 
     404         146 :     if (!ent || !ent->new_address) {
     405             :       /* And if we don't have an exact match, try to check whether
     406             :        * we have a pattern-based match.
     407             :        */
     408         100 :       ent = addressmap_match_superdomains(address);
     409             :     } else {
     410          46 :       if (ent->src_wildcard && !ent->dst_wildcard &&
     411           1 :           !strcasecmp(address, ent->new_address)) {
     412             :         /* This is a rule like "rewrite *.example.com to example.com", and we
     413             :          * just got "example.com". Instead of calling it an infinite loop,
     414             :          * call it complete. */
     415           0 :         goto done;
     416             :       }
     417             :       exact_match = 1;
     418             :     }
     419             : 
     420         146 :     if (!ent || !ent->new_address) {
     421             :       /* We still have no match at all.  We're done! */
     422          61 :       goto done;
     423             :     }
     424             : 
     425             :     /* Check whether the flags we were passed tell us not to use this
     426             :      * mapping. */
     427          85 :     switch (ent->source) {
     428           8 :       case ADDRMAPSRC_DNS:
     429             :         {
     430           8 :           sa_family_t f;
     431           8 :           tor_addr_t tmp;
     432           8 :           f = tor_addr_parse(&tmp, ent->new_address);
     433           8 :           if (f == AF_INET && !(flags & AMR_FLAG_USE_IPV4_DNS))
     434           6 :             goto done;
     435           5 :           else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS))
     436           3 :             goto done;
     437             :         }
     438           2 :         break;
     439          69 :       case ADDRMAPSRC_CONTROLLER:
     440             :       case ADDRMAPSRC_TORRC:
     441          69 :         if (!(flags & AMR_FLAG_USE_MAPADDRESS))
     442           0 :           goto done;
     443             :         break;
     444           8 :       case ADDRMAPSRC_AUTOMAP:
     445           8 :         if (!(flags & AMR_FLAG_USE_AUTOMAP))
     446           4 :           goto done;
     447             :         break;
     448           0 :       case ADDRMAPSRC_TRACKEXIT:
     449           0 :         if (!(flags & AMR_FLAG_USE_TRACKEXIT))
     450           0 :           goto done;
     451             :         break;
     452           0 :       case ADDRMAPSRC_NONE:
     453             :       default:
     454           0 :         log_warn(LD_BUG, "Unknown addrmap source value %d. Ignoring it.",
     455             :                  (int) ent->source);
     456           0 :         goto done;
     457             :     }
     458             : 
     459             :     /* Now fill in the address with the new address. That might be via
     460             :      * appending some new stuff to the end, or via just replacing it. */
     461          75 :     if (ent->dst_wildcard && !exact_match) {
     462           5 :       strlcat(address, ".", maxlen);
     463           5 :       strlcat(address, ent->new_address, maxlen);
     464             :     } else {
     465          70 :       strlcpy(address, ent->new_address, maxlen);
     466             :     }
     467             : 
     468             :     /* Is this now a .exit address?  If so, remember where we got it.*/
     469          81 :     if (!strcmpend(address, ".exit") &&
     470          12 :         strcmpend(addr_orig, ".exit") &&
     471             :         exit_source == ADDRMAPSRC_NONE) {
     472           6 :       exit_source = ent->source;
     473             :     }
     474             : 
     475          75 :     log_info(LD_APP, "Addressmap: rewriting %s to %s",
     476             :              log_addr_orig, escaped_safe_str_client(address));
     477          75 :     if (ent->expires > 1 && ent->expires < expires)
     478             :       expires = ent->expires;
     479             : 
     480          75 :     tor_free(log_addr_orig);
     481             :   }
     482           3 :   log_warn(LD_CONFIG,
     483             :            "Loop detected: we've rewritten %s 16 times! Using it as-is.",
     484             :            escaped_safe_str_client(address));
     485             :   /* it's fine to rewrite a rewrite, but don't loop forever */
     486             : 
     487          74 :  done:
     488          74 :   tor_free(addr_orig);
     489          74 :   tor_free(log_addr_orig);
     490          74 :   if (exit_source_out)
     491          51 :     *exit_source_out = exit_source;
     492          74 :   if (expires_out)
     493          74 :     *expires_out = expires;
     494          74 :   return (rewrites > 0);
     495             : }
     496             : 
     497             : /** If we have a cached reverse DNS entry for the address stored in the
     498             :  * <b>maxlen</b>-byte buffer <b>address</b> (typically, a dotted quad) then
     499             :  * rewrite to the cached value and return 1.  Otherwise return 0.  Set
     500             :  * *<b>expires_out</b> to the expiry time of the result, or to <b>time_max</b>
     501             :  * if the result does not expire. */
     502             : int
     503           1 : addressmap_rewrite_reverse(char *address, size_t maxlen, unsigned flags,
     504             :                            time_t *expires_out)
     505             : {
     506           1 :   char *s, *cp;
     507           1 :   addressmap_entry_t *ent;
     508           1 :   int r = 0;
     509             :   {
     510           1 :     sa_family_t f;
     511           1 :     tor_addr_t tmp;
     512           1 :     f = tor_addr_parse(&tmp, address);
     513           1 :     if (f == AF_INET && !(flags & AMR_FLAG_USE_IPV4_DNS))
     514           1 :       return 0;
     515           0 :     else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS))
     516             :       return 0;
     517             :     /* FFFF we should reverse-map virtual addresses even if we haven't
     518             :      * enabled DNS caching. */
     519             :   }
     520             : 
     521           0 :   tor_asprintf(&s, "REVERSE[%s]", address);
     522           0 :   ent = strmap_get(addressmap, s);
     523           0 :   if (ent) {
     524           0 :     cp = tor_strdup(escaped_safe_str_client(ent->new_address));
     525           0 :     log_info(LD_APP, "Rewrote reverse lookup %s -> %s",
     526             :              escaped_safe_str_client(s), cp);
     527           0 :     tor_free(cp);
     528           0 :     strlcpy(address, ent->new_address, maxlen);
     529           0 :     r = 1;
     530             :   }
     531             : 
     532           0 :   if (expires_out)
     533           0 :     *expires_out = (ent && ent->expires > 1) ? ent->expires : TIME_MAX;
     534             : 
     535           0 :   tor_free(s);
     536           0 :   return r;
     537             : }
     538             : 
     539             : /** Return 1 if <b>address</b> is already registered, else return 0. If address
     540             :  * is already registered, and <b>update_expires</b> is non-zero, then update
     541             :  * the expiry time on the mapping with update_expires if it is a
     542             :  * mapping created by TrackHostExits. */
     543             : int
     544           6 : addressmap_have_mapping(const char *address, int update_expiry)
     545             : {
     546           6 :   addressmap_entry_t *ent;
     547           6 :   if (!(ent=strmap_get_lc(addressmap, address)))
     548             :     return 0;
     549           0 :   if (update_expiry && ent->source==ADDRMAPSRC_TRACKEXIT)
     550           0 :     ent->expires=time(NULL) + update_expiry;
     551             :   return 1;
     552             : }
     553             : 
     554             : /** Register a request to map <b>address</b> to <b>new_address</b>,
     555             :  * which will expire on <b>expires</b> (or 0 if never expires from
     556             :  * config file, 1 if never expires from controller, 2 if never expires
     557             :  * (virtual address mapping) from the controller.)
     558             :  *
     559             :  * <b>new_address</b> should be a newly dup'ed string, which we'll use or
     560             :  * free as appropriate. We will leave <b>address</b> alone.
     561             :  *
     562             :  * If <b>wildcard_addr</b> is true, then the mapping will match any address
     563             :  * equal to <b>address</b>, or any address ending with a period followed by
     564             :  * <b>address</b>.  If <b>wildcard_addr</b> and <b>wildcard_new_addr</b> are
     565             :  * both true, the mapping will rewrite addresses that end with
     566             :  * ".<b>address</b>" into ones that end with ".<b>new_address</b>".
     567             :  *
     568             :  * If <b>new_address</b> is NULL, or <b>new_address</b> is equal to
     569             :  * <b>address</b> and <b>wildcard_addr</b> is equal to
     570             :  * <b>wildcard_new_addr</b>, remove any mappings that exist from
     571             :  * <b>address</b>.
     572             :  *
     573             :  * It is an error to set <b>wildcard_new_addr</b> if <b>wildcard_addr</b> is
     574             :  * not set. */
     575             : void
     576          41 : addressmap_register(const char *address, char *new_address, time_t expires,
     577             :                     addressmap_entry_source_t source,
     578             :                     const int wildcard_addr,
     579             :                     const int wildcard_new_addr, uint64_t stream_id)
     580             : {
     581          41 :   addressmap_entry_t *ent;
     582             : 
     583          41 :   if (wildcard_new_addr)
     584           4 :     tor_assert(wildcard_addr);
     585             : 
     586          41 :   ent = strmap_get(addressmap, address);
     587          41 :   if (!new_address || (!strcasecmp(address,new_address) &&
     588             :                        wildcard_addr == wildcard_new_addr)) {
     589             :     /* Remove the mapping, if any. */
     590           0 :     tor_free(new_address);
     591           0 :     if (ent) {
     592           0 :       addressmap_ent_remove(address,ent);
     593           0 :       strmap_remove(addressmap, address);
     594             :     }
     595           0 :     return;
     596             :   }
     597          41 :   if (!ent) { /* make a new one and register it */
     598          40 :     ent = tor_malloc_zero(sizeof(addressmap_entry_t));
     599          40 :     strmap_set(addressmap, address, ent);
     600           1 :   } else if (ent->new_address) { /* we need to clean up the old mapping. */
     601           1 :     if (expires > 1) {
     602           0 :       log_info(LD_APP,"Temporary addressmap ('%s' to '%s') not performed, "
     603             :                "since it's already mapped to '%s'",
     604             :                safe_str_client(address),
     605             :                safe_str_client(new_address),
     606             :                safe_str_client(ent->new_address));
     607           0 :       tor_free(new_address);
     608           0 :       return;
     609             :     }
     610           1 :     if (address_is_in_virtual_range(ent->new_address) &&
     611             :         expires != 2) {
     612             :       /* XXX This isn't the perfect test; we want to avoid removing
     613             :        * mappings set from the control interface _as virtual mapping */
     614           0 :       addressmap_virtaddress_remove(address, ent);
     615             :     }
     616           1 :     tor_free(ent->new_address);
     617             :   } /* else { we have an in-progress resolve with no mapping. } */
     618             : 
     619          41 :   ent->new_address = new_address;
     620          41 :   ent->expires = expires==2 ? 1 : expires;
     621          41 :   ent->num_resolve_failures = 0;
     622          41 :   ent->source = source;
     623          41 :   ent->src_wildcard = wildcard_addr ? 1 : 0;
     624          41 :   ent->dst_wildcard = wildcard_new_addr ? 1 : 0;
     625             : 
     626          41 :   log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'",
     627             :            safe_str_client(address),
     628             :            safe_str_client(ent->new_address));
     629          41 :   control_event_address_mapped(address, ent->new_address,
     630             :                                expires, NULL, 1, stream_id);
     631             : }
     632             : 
     633             : /** An attempt to resolve <b>address</b> failed at some OR.
     634             :  * Increment the number of resolve failures we have on record
     635             :  * for it, and then return that number.
     636             :  */
     637             : int
     638           0 : client_dns_incr_failures(const char *address)
     639             : {
     640           0 :   addressmap_entry_t *ent = strmap_get(addressmap, address);
     641           0 :   if (!ent) {
     642           0 :     ent = tor_malloc_zero(sizeof(addressmap_entry_t));
     643           0 :     ent->expires = time(NULL) + MAX_DNS_ENTRY_AGE;
     644           0 :     strmap_set(addressmap,address,ent);
     645             :   }
     646           0 :   if (ent->num_resolve_failures < SHRT_MAX)
     647           0 :     ++ent->num_resolve_failures; /* don't overflow */
     648           0 :   log_info(LD_APP, "Address %s now has %d resolve failures.",
     649             :            safe_str_client(address),
     650             :            ent->num_resolve_failures);
     651           0 :   return ent->num_resolve_failures;
     652             : }
     653             : 
     654             : /** If <b>address</b> is in the client DNS addressmap, reset
     655             :  * the number of resolve failures we have on record for it.
     656             :  * This is used when we fail a stream because it won't resolve:
     657             :  * otherwise future attempts on that address will only try once.
     658             :  */
     659             : void
     660           0 : client_dns_clear_failures(const char *address)
     661             : {
     662           0 :   addressmap_entry_t *ent = strmap_get(addressmap, address);
     663           0 :   if (ent)
     664           0 :     ent->num_resolve_failures = 0;
     665           0 : }
     666             : 
     667             : /** Record the fact that <b>address</b> resolved to <b>name</b>.
     668             :  * We can now use this in subsequent streams via addressmap_rewrite()
     669             :  * so we can more correctly choose an exit that will allow <b>address</b>.
     670             :  *
     671             :  * If <b>exitname</b> is defined, then append the addresses with
     672             :  * ".exitname.exit" before registering the mapping.
     673             :  *
     674             :  * If <b>ttl</b> is nonnegative, the mapping will be valid for
     675             :  * <b>ttl</b>seconds; otherwise, we use the default.
     676             :  */
     677             : static void
     678           0 : client_dns_set_addressmap_impl(entry_connection_t *for_conn,
     679             :                                const char *address, const char *name,
     680             :                                const char *exitname,
     681             :                                int ttl)
     682             : {
     683           0 :   char *extendedaddress=NULL, *extendedval=NULL;
     684           0 :   uint64_t stream_id = 0;
     685             : 
     686           0 :   tor_assert(address);
     687           0 :   tor_assert(name);
     688             : 
     689           0 :   if (for_conn) {
     690           0 :     stream_id = ENTRY_TO_CONN(for_conn)->global_identifier;
     691             :   }
     692             : 
     693           0 :   if (ttl<0)
     694             :     ttl = DEFAULT_DNS_TTL;
     695             :   else
     696           0 :     ttl = clip_dns_ttl(ttl);
     697             : 
     698           0 :   if (exitname) {
     699             :     /* XXXX fails to ever get attempts to get an exit address of
     700             :      * google.com.digest[=~]nickname.exit; we need a syntax for this that
     701             :      * won't make strict RFC952-compliant applications (like us) barf. */
     702           0 :     tor_asprintf(&extendedaddress,
     703             :                  "%s.%s.exit", address, exitname);
     704           0 :     tor_asprintf(&extendedval,
     705             :                  "%s.%s.exit", name, exitname);
     706             :   } else {
     707           0 :     tor_asprintf(&extendedaddress,
     708             :                  "%s", address);
     709           0 :     tor_asprintf(&extendedval,
     710             :                  "%s", name);
     711             :   }
     712           0 :   addressmap_register(extendedaddress, extendedval,
     713           0 :                       time(NULL) + ttl, ADDRMAPSRC_DNS, 0, 0, stream_id);
     714           0 :   tor_free(extendedaddress);
     715           0 : }
     716             : 
     717             : /** Record the fact that <b>address</b> resolved to <b>val</b>.
     718             :  * We can now use this in subsequent streams via addressmap_rewrite()
     719             :  * so we can more correctly choose an exit that will allow <b>address</b>.
     720             :  *
     721             :  * If <b>exitname</b> is defined, then append the addresses with
     722             :  * ".exitname.exit" before registering the mapping.
     723             :  *
     724             :  * If <b>ttl</b> is nonnegative, the mapping will be valid for
     725             :  * <b>ttl</b>seconds; otherwise, we use the default.
     726             :  */
     727             : void
     728           2 : client_dns_set_addressmap(entry_connection_t *for_conn,
     729             :                           const char *address,
     730             :                           const tor_addr_t *val,
     731             :                           const char *exitname,
     732             :                           int ttl)
     733             : {
     734           2 :   tor_addr_t addr_tmp;
     735           2 :   char valbuf[TOR_ADDR_BUF_LEN];
     736             : 
     737           2 :   tor_assert(address);
     738           2 :   tor_assert(val);
     739             : 
     740           2 :   if (tor_addr_parse(&addr_tmp, address) >= 0)
     741           2 :     return; /* If address was an IP address already, don't add a mapping. */
     742             : 
     743           1 :   if (tor_addr_family(val) == AF_INET) {
     744           1 :     if (! for_conn->entry_cfg.cache_ipv4_answers)
     745             :       return;
     746           0 :   } else if (tor_addr_family(val) == AF_INET6) {
     747           0 :     if (! for_conn->entry_cfg.cache_ipv6_answers)
     748             :       return;
     749             :   }
     750             : 
     751           0 :   if (! tor_addr_to_str(valbuf, val, sizeof(valbuf), 1))
     752             :     return;
     753             : 
     754           0 :   client_dns_set_addressmap_impl(for_conn, address, valbuf, exitname, ttl);
     755             : }
     756             : 
     757             : /** Add a cache entry noting that <b>address</b> (ordinarily a dotted quad)
     758             :  * resolved via a RESOLVE_PTR request to the hostname <b>v</b>.
     759             :  *
     760             :  * If <b>exitname</b> is defined, then append the addresses with
     761             :  * ".exitname.exit" before registering the mapping.
     762             :  *
     763             :  * If <b>ttl</b> is nonnegative, the mapping will be valid for
     764             :  * <b>ttl</b>seconds; otherwise, we use the default.
     765             :  */
     766             : void
     767           0 : client_dns_set_reverse_addressmap(entry_connection_t *for_conn,
     768             :                                   const char *address, const char *v,
     769             :                                   const char *exitname,
     770             :                                   int ttl)
     771             : {
     772           0 :   char *s = NULL;
     773             :   {
     774           0 :     tor_addr_t tmp_addr;
     775           0 :     sa_family_t f = tor_addr_parse(&tmp_addr, address);
     776           0 :     if ((f == AF_INET && ! for_conn->entry_cfg.cache_ipv4_answers) ||
     777           0 :         (f == AF_INET6 && ! for_conn->entry_cfg.cache_ipv6_answers))
     778           0 :       return;
     779             :   }
     780           0 :   tor_asprintf(&s, "REVERSE[%s]", address);
     781           0 :   client_dns_set_addressmap_impl(for_conn, s, v, exitname, ttl);
     782           0 :   tor_free(s);
     783             : }
     784             : 
     785             : /* By default, we hand out 127.192.0.1 through 127.254.254.254.
     786             :  * These addresses should map to localhost, so even if the
     787             :  * application accidentally tried to connect to them directly (not
     788             :  * via Tor), it wouldn't get too far astray.
     789             :  *
     790             :  * These options are configured by parse_virtual_addr_network().
     791             :  */
     792             : 
     793             : static virtual_addr_conf_t virtaddr_conf_ipv4;
     794             : static virtual_addr_conf_t virtaddr_conf_ipv6;
     795             : 
     796             : /** Read a netmask of the form 127.192.0.0/10 from "val", and check whether
     797             :  * it's a valid set of virtual addresses to hand out in response to MAPADDRESS
     798             :  * requests.  Return 0 on success; set *msg (if provided) to a newly allocated
     799             :  * string and return -1 on failure.  If validate_only is false, sets the
     800             :  * actual virtual address range to the parsed value. */
     801             : int
     802         875 : parse_virtual_addr_network(const char *val, sa_family_t family,
     803             :                            int validate_only,
     804             :                            char **msg)
     805             : {
     806         875 :   const int ipv6 = (family == AF_INET6);
     807         875 :   tor_addr_t addr;
     808         875 :   maskbits_t bits;
     809         875 :   const int max_prefix_bits = ipv6 ? 104 : 16;
     810         875 :   virtual_addr_conf_t *conf = ipv6 ? &virtaddr_conf_ipv6 : &virtaddr_conf_ipv4;
     811             : 
     812         875 :   if (!val || val[0] == '\0') {
     813           0 :     if (msg)
     814           0 :       tor_asprintf(msg, "Value not present (%s) after VirtualAddressNetwork%s",
     815             :                    val?"Empty":"NULL", ipv6?"IPv6":"");
     816           0 :     return -1;
     817             :   }
     818         875 :   if (tor_addr_parse_mask_ports(val, 0, &addr, &bits, NULL, NULL) < 0) {
     819           2 :     if (msg)
     820           3 :       tor_asprintf(msg, "Error parsing VirtualAddressNetwork%s %s",
     821             :                    ipv6?"IPv6":"", val);
     822           2 :     return -1;
     823             :   }
     824         873 :   if (tor_addr_family(&addr) != family) {
     825           0 :     if (msg)
     826           0 :       tor_asprintf(msg, "Incorrect address type for VirtualAddressNetwork%s",
     827             :                    ipv6?"IPv6":"");
     828           0 :     return -1;
     829             :   }
     830             : #if 0
     831             :   if (port_min != 1 || port_max != 65535) {
     832             :     if (msg)
     833             :       tor_asprintf(msg, "Can't specify ports on VirtualAddressNetwork%s",
     834             :                    ipv6?"IPv6":"");
     835             :     return -1;
     836             :   }
     837             : #endif /* 0 */
     838             : 
     839         873 :   if (bits > max_prefix_bits) {
     840           0 :     if (msg)
     841           0 :       tor_asprintf(msg, "VirtualAddressNetwork%s expects a /%d "
     842             :                    "network or larger",ipv6?"IPv6":"", max_prefix_bits);
     843           0 :     return -1;
     844             :   }
     845             : 
     846         873 :   if (validate_only)
     847             :     return 0;
     848             : 
     849          18 :   tor_addr_copy(&conf->addr, &addr);
     850          18 :   conf->bits = bits;
     851             : 
     852          18 :   return 0;
     853             : }
     854             : 
     855             : /**
     856             :  * Return true iff <b>addr</b> is likely to have been returned by
     857             :  * client_dns_get_unused_address.
     858             :  **/
     859             : int
     860          39 : address_is_in_virtual_range(const char *address)
     861             : {
     862          39 :   tor_addr_t addr;
     863          39 :   tor_assert(address);
     864          39 :   if (!strcasecmpend(address, ".virtual")) {
     865             :     return 1;
     866          39 :   } else if (tor_addr_parse(&addr, address) >= 0) {
     867          13 :     const virtual_addr_conf_t *conf = (tor_addr_family(&addr) == AF_INET6) ?
     868             :       &virtaddr_conf_ipv6 : &virtaddr_conf_ipv4;
     869          13 :     if (tor_addr_compare_masked(&addr, &conf->addr, conf->bits, CMP_EXACT)==0)
     870           2 :       return 1;
     871             :   }
     872             :   return 0;
     873             : }
     874             : 
     875             : /** Return a random address conforming to the virtual address configuration
     876             :  * in <b>conf</b>.
     877             :  */
     878             : STATIC void
     879        5629 : get_random_virtual_addr(const virtual_addr_conf_t *conf, tor_addr_t *addr_out)
     880             : {
     881        5629 :   uint8_t tmp[4];
     882        5629 :   const uint8_t *addr_bytes;
     883        5629 :   uint8_t bytes[16];
     884        5629 :   const int ipv6 = tor_addr_family(&conf->addr) == AF_INET6;
     885        5629 :   const int total_bytes = ipv6 ? 16 : 4;
     886             : 
     887        5629 :   tor_assert(conf->bits <= total_bytes * 8);
     888             : 
     889             :   /* Set addr_bytes to the bytes of the virtual network, in host order */
     890        5629 :   if (ipv6) {
     891        2314 :     addr_bytes = tor_addr_to_in6_addr8(&conf->addr);
     892             :   } else {
     893        3315 :     set_uint32(tmp, tor_addr_to_ipv4n(&conf->addr));
     894        3315 :     addr_bytes = tmp;
     895             :   }
     896             : 
     897             :   /* Get an appropriate number of random bytes. */
     898        5629 :   crypto_rand((char*)bytes, total_bytes);
     899             : 
     900             :   /* Now replace the first "conf->bits" bits of 'bytes' with addr_bytes*/
     901        5629 :   if (conf->bits >= 8)
     902        3581 :     memcpy(bytes, addr_bytes, conf->bits / 8);
     903        5629 :   if (conf->bits & 7) {
     904        3849 :     uint8_t mask = 0xff >> (conf->bits & 7);
     905        3849 :     bytes[conf->bits/8] &= mask;
     906        3849 :     bytes[conf->bits/8] |= addr_bytes[conf->bits/8] & ~mask;
     907             :   }
     908             : 
     909        5629 :   if (ipv6)
     910        2314 :     tor_addr_from_ipv6_bytes(addr_out, bytes);
     911             :   else
     912        3315 :     tor_addr_from_ipv4n(addr_out, get_uint32(bytes));
     913             : 
     914        5629 :   tor_assert(tor_addr_compare_masked(addr_out, &conf->addr,
     915             :                                      conf->bits, CMP_EXACT)==0);
     916        5629 : }
     917             : 
     918             : /** Return a newly allocated string holding an address of <b>type</b>
     919             :  * (one of RESOLVED_TYPE_{IPV4|IPV6|HOSTNAME}) that has not yet been
     920             :  * mapped, and that is very unlikely to be the address of any real host.
     921             :  *
     922             :  * May return NULL if we have run out of virtual addresses.
     923             :  */
     924             : static char *
     925          18 : addressmap_get_virtual_address(int type)
     926             : {
     927          18 :   char buf[64];
     928          18 :   tor_assert(addressmap);
     929             : 
     930          18 :   if (type == RESOLVED_TYPE_HOSTNAME) {
     931           4 :     char rand_bytes[10];
     932           4 :     do {
     933           4 :       crypto_rand(rand_bytes, sizeof(rand_bytes));
     934           4 :       base32_encode(buf,sizeof(buf),rand_bytes,sizeof(rand_bytes));
     935           4 :       strlcat(buf, ".virtual", sizeof(buf));
     936           4 :     } while (strmap_get(addressmap, buf));
     937           3 :     return tor_strdup(buf);
     938          15 :   } else if (type == RESOLVED_TYPE_IPV4 || type == RESOLVED_TYPE_IPV6) {
     939          15 :     const int ipv6 = (type == RESOLVED_TYPE_IPV6);
     940          15 :     const virtual_addr_conf_t *conf = ipv6 ?
     941             :       &virtaddr_conf_ipv6 : &virtaddr_conf_ipv4;
     942             : 
     943             :     /* Don't try more than 1000 times.  This gives us P < 1e-9 for
     944             :      * failing to get a good address so long as the address space is
     945             :      * less than ~97.95% full.  That's always going to be true under
     946             :      * sensible circumstances for an IPv6 /10, and it's going to be
     947             :      * true for an IPv4 /10 as long as we've handed out less than
     948             :      * 4.08 million addresses. */
     949          15 :     uint32_t attempts = 1000;
     950             : 
     951          15 :     tor_addr_t addr;
     952             : 
     953        1022 :     while (attempts--) {
     954        1021 :       get_random_virtual_addr(conf, &addr);
     955             : 
     956        1021 :       if (!ipv6) {
     957             :         /* Don't hand out any .0 or .255 address. */
     958        1011 :         const uint32_t a = tor_addr_to_ipv4h(&addr);
     959        1011 :         if ((a & 0xff) == 0 || (a & 0xff) == 0xff)
     960           2 :           continue;
     961             :       }
     962             : 
     963        1019 :       tor_addr_to_str(buf, &addr, sizeof(buf), 1);
     964        1019 :       if (!strmap_get(addressmap, buf)) {
     965             :         /* XXXX This code is to make sure I didn't add an undecorated version
     966             :          * by mistake. I hope it's needless. */
     967          14 :         char tmp[TOR_ADDR_BUF_LEN];
     968          14 :         tor_addr_to_str(tmp, &addr, sizeof(tmp), 0);
     969          14 :         if (strmap_get(addressmap, tmp)) {
     970             :           // LCOV_EXCL_START
     971             :           log_warn(LD_BUG, "%s wasn't in the addressmap, but %s was.",
     972             :                    buf, tmp);
     973             :           continue;
     974             :           // LCOV_EXCL_STOP
     975             :         }
     976             : 
     977          14 :         return tor_strdup(buf);
     978             :       }
     979             :     }
     980           1 :     log_warn(LD_CONFIG, "Ran out of virtual addresses!");
     981           1 :     return NULL;
     982             :   } else {
     983             :     // LCOV_EXCL_START
     984             :     log_warn(LD_BUG, "Called with unsupported address type (%d)", type);
     985             :     return NULL;
     986             :     // LCOV_EXCL_STOP
     987             :   }
     988             : }
     989             : 
     990             : /** A controller has requested that we map some address of type
     991             :  * <b>type</b> to the address <b>new_address</b>.  Choose an address
     992             :  * that is unlikely to be used, and map it, and return it in a newly
     993             :  * allocated string.  If another address of the same type is already
     994             :  * mapped to <b>new_address</b>, try to return a copy of that address.
     995             :  *
     996             :  * The string in <b>new_address</b> may be freed or inserted into a map
     997             :  * as appropriate.  May return NULL if are out of virtual addresses.
     998             :  **/
     999             : const char *
    1000          21 : addressmap_register_virtual_address(int type, char *new_address)
    1001             : {
    1002          21 :   char **addrp;
    1003          21 :   virtaddress_entry_t *vent;
    1004          21 :   int vent_needs_to_be_added = 0;
    1005             : 
    1006          21 :   tor_assert(new_address);
    1007          21 :   tor_assert(addressmap);
    1008          21 :   tor_assert(virtaddress_reversemap);
    1009             : 
    1010          21 :   vent = strmap_get(virtaddress_reversemap, new_address);
    1011          21 :   if (!vent) {
    1012          14 :     vent = tor_malloc_zero(sizeof(virtaddress_entry_t));
    1013          14 :     vent_needs_to_be_added = 1;
    1014             :   }
    1015             : 
    1016          21 :   if (type == RESOLVED_TYPE_IPV4)
    1017          11 :     addrp = &vent->ipv4_address;
    1018          10 :   else if (type == RESOLVED_TYPE_IPV6)
    1019           7 :     addrp = &vent->ipv6_address;
    1020             :   else
    1021           3 :     addrp = &vent->hostname_address;
    1022             : 
    1023          21 :   if (*addrp) {
    1024           3 :     addressmap_entry_t *ent = strmap_get(addressmap, *addrp);
    1025           3 :     if (ent && ent->new_address &&
    1026           3 :         !strcasecmp(new_address, ent->new_address)) {
    1027           3 :       tor_free(new_address);
    1028           3 :       tor_assert(!vent_needs_to_be_added);
    1029           3 :       return *addrp;
    1030             :     } else {
    1031           0 :       log_warn(LD_BUG,
    1032             :                "Internal confusion: I thought that '%s' was mapped to by "
    1033             :                "'%s', but '%s' really maps to '%s'. This is a harmless bug.",
    1034             :                safe_str_client(new_address),
    1035             :                safe_str_client(*addrp),
    1036             :                safe_str_client(*addrp),
    1037             :                ent?safe_str_client(ent->new_address):"(nothing)");
    1038             :     }
    1039             :   }
    1040             : 
    1041          18 :   tor_free(*addrp);
    1042          18 :   *addrp = addressmap_get_virtual_address(type);
    1043          18 :   if (!*addrp) {
    1044           1 :     tor_free(vent);
    1045           1 :     tor_free(new_address);
    1046           1 :     return NULL;
    1047             :   }
    1048          17 :   log_info(LD_APP, "Registering map from %s to %s", *addrp, new_address);
    1049          17 :   if (vent_needs_to_be_added)
    1050          13 :     strmap_set(virtaddress_reversemap, new_address, vent);
    1051          17 :   addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_AUTOMAP, 0, 0, 0);
    1052             : 
    1053             :   /* FFFF register corresponding reverse mapping. */
    1054             : 
    1055             : #if 0
    1056             :   {
    1057             :     /* Try to catch possible bugs */
    1058             :     addressmap_entry_t *ent;
    1059             :     ent = strmap_get(addressmap, *addrp);
    1060             :     tor_assert(ent);
    1061             :     tor_assert(!strcasecmp(ent->new_address,new_address));
    1062             :     vent = strmap_get(virtaddress_reversemap, new_address);
    1063             :     tor_assert(vent);
    1064             :     tor_assert(!strcasecmp(*addrp,
    1065             :                            (type == RESOLVED_TYPE_IPV4) ?
    1066             :                            vent->ipv4_address : vent->hostname_address));
    1067             :     log_info(LD_APP, "Map from %s to %s okay.",
    1068             :              safe_str_client(*addrp),
    1069             :              safe_str_client(new_address));
    1070             :   }
    1071             : #endif /* 0 */
    1072             : 
    1073          17 :   return *addrp;
    1074             : }
    1075             : 
    1076             : /** Return 1 if <b>address</b> has funny characters in it like colons. Return
    1077             :  * 0 if it's fine, or if we're configured to allow it anyway.  <b>client</b>
    1078             :  * should be true if we're using this address as a client; false if we're
    1079             :  * using it as a server.
    1080             :  */
    1081             : int
    1082          28 : address_is_invalid_destination(const char *address, int client)
    1083             : {
    1084          28 :   if (client) {
    1085          22 :     if (get_options()->AllowNonRFC953Hostnames)
    1086             :       return 0;
    1087             :   } else {
    1088           6 :     if (get_options()->ServerDNSAllowNonRFC953Hostnames)
    1089             :       return 0;
    1090             :   }
    1091             : 
    1092             :   /* It might be an IPv6 address! */
    1093             :   {
    1094          28 :     tor_addr_t a;
    1095          28 :     if (tor_addr_parse(&a, address) >= 0)
    1096           9 :       return 0;
    1097             :   }
    1098             : 
    1099         371 :   while (*address) {
    1100         353 :     if (TOR_ISALNUM(*address) ||
    1101          35 :         *address == '-' ||
    1102           1 :         *address == '.' ||
    1103             :         *address == '_') /* Underscore is not allowed, but Windows does it
    1104             :                           * sometimes, just to thumb its nose at the IETF. */
    1105         352 :       ++address;
    1106             :     else
    1107             :       return 1;
    1108             :   }
    1109             :   return 0;
    1110             : }
    1111             : 
    1112             : /** Iterate over all address mappings which have expiry times between
    1113             :  * min_expires and max_expires, inclusive.  If sl is provided, add an
    1114             :  * "old-addr new-addr expiry" string to sl for each mapping, omitting
    1115             :  * the expiry time if want_expiry is false. If sl is NULL, remove the
    1116             :  * mappings.
    1117             :  */
    1118             : void
    1119          30 : addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
    1120             :                         time_t max_expires, int want_expiry)
    1121             : {
    1122          30 :    strmap_iter_t *iter;
    1123          30 :    const char *key;
    1124          30 :    void *val_;
    1125          30 :    addressmap_entry_t *val;
    1126             : 
    1127          30 :    if (!addressmap)
    1128          17 :      addressmap_init();
    1129             : 
    1130          46 :    for (iter = strmap_iter_init(addressmap); !strmap_iter_done(iter); ) {
    1131          16 :      strmap_iter_get(iter, &key, &val_);
    1132          16 :      val = val_;
    1133          16 :      if (val->expires >= min_expires && val->expires <= max_expires) {
    1134          16 :        if (!sl) {
    1135          16 :          iter = strmap_iter_next_rmv(addressmap,iter);
    1136          16 :          addressmap_ent_remove(key, val);
    1137          16 :          continue;
    1138           0 :        } else if (val->new_address) {
    1139           0 :          const char *src_wc = val->src_wildcard ? "*." : "";
    1140           0 :          const char *dst_wc = val->dst_wildcard ? "*." : "";
    1141           0 :          if (want_expiry) {
    1142           0 :            if (val->expires < 3 || val->expires == TIME_MAX)
    1143           0 :              smartlist_add_asprintf(sl, "%s%s %s%s NEVER",
    1144             :                                     src_wc, key, dst_wc, val->new_address);
    1145             :            else {
    1146           0 :              char isotime[ISO_TIME_LEN+1];
    1147           0 :              format_iso_time(isotime, val->expires);
    1148           0 :              smartlist_add_asprintf(sl, "%s%s %s%s \"%s\"",
    1149             :                                     src_wc, key, dst_wc, val->new_address,
    1150             :                                     isotime);
    1151             :            }
    1152             :          } else {
    1153           0 :            smartlist_add_asprintf(sl, "%s%s %s%s",
    1154             :                                   src_wc, key, dst_wc, val->new_address);
    1155             :          }
    1156             :        }
    1157             :      }
    1158           0 :      iter = strmap_iter_next(addressmap,iter);
    1159             :    }
    1160          30 : }

Generated by: LCOV version 1.14