diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-12-19 18:52:00 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-12-19 18:52:00 +0000 |
commit | 029be5ad02cfec8d9b96b3466a03a353183f561a (patch) | |
tree | 1cd1a87b153e8aabfef10d8d6d8f8813f6e1bdf0 /src/or | |
parent | efb863189cd4500e9cdaf8f5665f9756ae12dfde (diff) | |
download | tor-029be5ad02cfec8d9b96b3466a03a353183f561a.tar.gz tor-029be5ad02cfec8d9b96b3466a03a353183f561a.zip |
Move in-addr.arpa parsing and generation into address.c, and simplify the code that does it elsewhere. Incidentally, this lets exit servers answer requests for ip6.arpa addresses.
svn:r17707
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/connection_edge.c | 60 | ||||
-rw-r--r-- | src/or/dns.c | 69 | ||||
-rw-r--r-- | src/or/eventdns.c | 4 | ||||
-rw-r--r-- | src/or/eventdns.h | 4 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/test.c | 64 |
6 files changed, 107 insertions, 95 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 620db73a62..9b192b5565 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1436,17 +1436,10 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, if (options->ClientDNSRejectInternalAddresses) { /* Don't let people try to do a reverse lookup on 10.0.0.1. */ tor_addr_t addr; - struct in_addr in; int ok; - if (!strcasecmpend(socks->address, ".in-addr.arpa")) - ok = !parse_inaddr_arpa_address(socks->address, &in); - else - ok = tor_inet_aton(socks->address, &in); - /*XXXX021 make this a function. */ - addr.family = AF_INET; - memcpy(&addr.addr.in_addr, &in, sizeof(struct in_addr)); - - if (ok && tor_addr_is_internal(&addr, 0)) { + ok = tor_addr_parse_reverse_lookup_name( + &addr, socks->address, AF_UNSPEC, 1); + if (ok == 1 && tor_addr_is_internal(&addr, 0)) { connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR, 0, NULL, -1, TIME_MAX); connection_mark_unattached_ap(conn, @@ -2130,7 +2123,7 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn) { int payload_len, command; const char *string_addr; - char inaddr_buf[32]; + char inaddr_buf[REVERSE_LOOKUP_NAME_BUF_LEN]; origin_circuit_t *circ; tor_assert(ap_conn->on_circuit); circ = TO_ORIGIN_CIRCUIT(ap_conn->on_circuit); @@ -2155,36 +2148,29 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn) payload_len = (int)strlen(string_addr)+1; tor_assert(payload_len <= RELAY_PAYLOAD_SIZE); } else { - struct in_addr in; - uint32_t a; - size_t len = strlen(ap_conn->socks_request->address); - char c = 0; - /* XXXX This logic is a little ugly: we check for an in-addr.arpa ending - * on the address. If we have one, the address is already in the right - * order, so we'll leave it alone later. Otherwise, we reverse it and - * turn it into an in-addr.arpa address. */ - if (!strcasecmpend(ap_conn->socks_request->address, ".in-addr.arpa")) { - /* Temporarily truncate the address, so we can give it to inet_aton. */ - c = ap_conn->socks_request->address[len-13]; - ap_conn->socks_request->address[len-13] = '\0'; - } - if (tor_inet_aton(ap_conn->socks_request->address, &in) == 0) { + /* command == SOCKS_COMMAND_RESOLVE_PTR */ + const char *a = ap_conn->socks_request->address; + tor_addr_t addr; + int r; + + /* We're doing a reverse lookup. The input could be an IP address, or + * could be an .in-addr.arpa or .ip6.arpa address */ + r = tor_addr_parse_reverse_lookup_name(&addr, a, AF_INET, 1); + if (r <= 0) { + log_warn(LD_APP, "Rejecting ill-formed reverse lookup of %s", + safe_str(a)); connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL); return -1; } - if (c) { - /* this path happens on DNS. Can we unify? XXXX021 */ - ap_conn->socks_request->address[len-13] = c; - strlcpy(inaddr_buf, ap_conn->socks_request->address, sizeof(inaddr_buf)); - } else { - /* this path happens on tor-resolve. Can we unify? XXXX021 */ - a = ntohl(in.s_addr); - tor_snprintf(inaddr_buf, sizeof(inaddr_buf), "%d.%d.%d.%d.in-addr.arpa", - (int)(uint8_t)((a )&0xff), - (int)(uint8_t)((a>>8 )&0xff), - (int)(uint8_t)((a>>16)&0xff), - (int)(uint8_t)((a>>24)&0xff)); + + r = tor_addr_to_reverse_lookup_name(inaddr_buf, sizeof(inaddr_buf), &addr); + if (r < 0) { + log_warn(LD_BUG, "Couldn't generate reverse lookup hostname of %s", + safe_str(a)); + connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL); + return -1; } + string_addr = inaddr_buf; payload_len = (int)strlen(inaddr_buf)+1; tor_assert(payload_len <= RELAY_PAYLOAD_SIZE); diff --git a/src/or/dns.c b/src/or/dns.c index a83c48981d..191fd068c1 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -494,49 +494,6 @@ send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname) // log_notice(LD_EXIT, "Sent"); } -/** Given a lower-case <b>address</b>, check to see whether it's a - * 1.2.3.4.in-addr.arpa address used for reverse lookups. If so, - * parse it and place the address in <b>in</b> if present. Return 1 on success; - * 0 if the address is not in in-addr.arpa format, and -1 if the address is - * malformed. */ -/* XXXX021 move this to address.c; unify with logic in connection_edge.c */ -int -parse_inaddr_arpa_address(const char *address, struct in_addr *in) -{ - char buf[INET_NTOA_BUF_LEN]; - char *cp; - size_t len; - struct in_addr inaddr; - - cp = strstr(address, ".in-addr.arpa"); - if (!cp || *(cp+strlen(".in-addr.arpa"))) - return 0; /* not an .in-addr.arpa address */ - - len = cp - address; - - if (len >= INET_NTOA_BUF_LEN) - return -1; /* Too long. */ - - memcpy(buf, address, len); - buf[len] = '\0'; - if (tor_inet_aton(buf, &inaddr) == 0) - return -1; /* malformed. */ - - if (in) { - uint32_t a; - /* reverse the bytes */ - a = (uint32_t) ( ((inaddr.s_addr & 0x000000fful) << 24) - |((inaddr.s_addr & 0x0000ff00ul) << 8) - |((inaddr.s_addr & 0x00ff0000ul) >> 8) - |((inaddr.s_addr & 0xff000000ul) >> 24)); - inaddr.s_addr = a; - - memcpy(in, &inaddr, sizeof(inaddr)); - } - - return 1; -} - /** See if we have a cache entry for <b>exitconn</b>-\>address. if so, * if resolve valid, put it into <b>exitconn</b>-\>addr and return 1. * If resolve failed, free exitconn and return -1. @@ -646,7 +603,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, cached_resolve_t search; pending_connection_t *pending_connection; routerinfo_t *me; - struct in_addr in; + tor_addr_t addr; time_t now = time(NULL); uint8_t is_reverse = 0; int r; @@ -657,8 +614,8 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, /* first check if exitconn->_base.address is an IP. If so, we already * know the answer. */ - if (tor_inet_aton(exitconn->_base.address, &in) != 0) { - tor_addr_from_ipv4n(&exitconn->_base.addr, in.s_addr); + if (tor_addr_from_str(&addr, exitconn->_base.address)<0) { + tor_addr_assign(&exitconn->_base.addr, &addr); exitconn->address_ttl = DEFAULT_DNS_TTL; return 1; } @@ -685,11 +642,12 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, * .in-addr.arpa address but this isn't a resolve request, kill the * connection. */ - if ((r = parse_inaddr_arpa_address(exitconn->_base.address, &in)) != 0) { + if ((r = tor_addr_parse_reverse_lookup_name(&addr, exitconn->_base.address, + AF_UNSPEC, 0)) != 0) { if (r == 1) { is_reverse = 1; - if (is_internal_IP(ntohl(in.s_addr), 0)) /* internal address */ - return -1; + if (tor_addr_is_internal(&addr, 0)) /* internal address? */ + return -1; } if (!is_reverse || !is_resolve) { @@ -1298,7 +1256,7 @@ static int launch_resolve(edge_connection_t *exitconn) { char *addr = tor_strdup(exitconn->_base.address); - struct in_addr in; + tor_addr_t a; int r; int options = get_options()->ServerDNSSearchDomains ? 0 : DNS_QUERY_NO_SEARCH; @@ -1311,7 +1269,8 @@ launch_resolve(edge_connection_t *exitconn) } } - r = parse_inaddr_arpa_address(exitconn->_base.address, &in); + r = tor_addr_parse_reverse_lookup_name( + &a, exitconn->_base.address, AF_UNSPEC, 0); if (r == 0) { log_info(LD_EXIT, "Launching eventdns request for %s", escaped_safe_str(exitconn->_base.address)); @@ -1320,8 +1279,12 @@ launch_resolve(edge_connection_t *exitconn) } else if (r == 1) { log_info(LD_EXIT, "Launching eventdns reverse request for %s", escaped_safe_str(exitconn->_base.address)); - r = evdns_resolve_reverse(&in, DNS_QUERY_NO_SEARCH, - evdns_callback, addr); + if (tor_addr_family(&a) == AF_INET) + r = evdns_resolve_reverse(tor_addr_to_in(&a), DNS_QUERY_NO_SEARCH, + evdns_callback, addr); + else + r = evdns_resolve_reverse_ipv6(tor_addr_to_in6(&a), DNS_QUERY_NO_SEARCH, + evdns_callback, addr); } else if (r == -1) { log_warn(LD_BUG, "Somehow a malformed in-addr.arpa address reached here."); } diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 2b28b2bf94..cd486caaa1 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -2534,7 +2534,7 @@ int evdns_resolve_ipv6(const char *name, int flags, } } -int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) { +int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) { char buf[32]; struct request *req; u32 a; @@ -2552,7 +2552,7 @@ int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal return 0; } -int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) { +int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) { /* 32 nybbles, 32 periods, "ip6.arpa", NUL. */ char buf[73]; char *cp; diff --git a/src/or/eventdns.h b/src/or/eventdns.h index d1c34ade7c..df5b936923 100644 --- a/src/or/eventdns.h +++ b/src/or/eventdns.h @@ -268,8 +268,8 @@ int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr); struct in_addr; struct in6_addr; -int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr); -int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr); +int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr); +int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr); int evdns_set_option(const char *option, const char *val, int flags); int evdns_resolv_conf_parse(int flags, const char *); #ifdef MS_WINDOWS diff --git a/src/or/or.h b/src/or/or.h index b766083f44..9093127ee3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3541,7 +3541,6 @@ int dns_resolve(edge_connection_t *exitconn); void dns_launch_correctness_checks(void); int dns_seems_to_be_broken(void); void dns_reset_correctness_checks(void); -int parse_inaddr_arpa_address(const char *address, struct in_addr *in); /********************************* dnsserv.c ************************/ diff --git a/src/or/test.c b/src/or/test.c index 8b07ee536a..28bf46f952 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1621,6 +1621,70 @@ test_util_ip6_helpers(void) p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "18.0.0.1"); + /* Test tor_addr_parse_reverse_lookup_name */ + i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 0); + test_eq(0, i); + i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 1); + test_eq(0, i); + i = tor_addr_parse_reverse_lookup_name(&t1, "1.0.168.192.in-addr.arpa", + AF_UNSPEC, 1); + test_eq(1, i); + test_eq(tor_addr_family(&t1), AF_INET); + p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); + test_streq(p1, "192.168.0.1"); + i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 0); + test_eq(0, i); + i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 1); + test_eq(1, i); + p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); + test_streq(p1, "192.168.0.99"); + memset(&t1, 0, sizeof(t1)); + i = tor_addr_parse_reverse_lookup_name(&t1, + "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." + "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." + "ip6.ARPA", + AF_UNSPEC, 0); + test_eq(1, i); + p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); + test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); + /* Failing cases. */ + i = tor_addr_parse_reverse_lookup_name(&t1, + "6.7.8.9.a.b.c.d.e.f." + "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." + "ip6.ARPA", + AF_UNSPEC, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, + "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." + "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." + "ip6.ARPA", + AF_UNSPEC, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, + "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." + "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." + "ip6.ARPA", + AF_UNSPEC, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, "32.1.1.in-addr.arpa", + AF_UNSPEC, 0); + /* test_eq(i, -1); XXXX021 Apparently '32.1.1' is a valid aton address. */ + i = tor_addr_parse_reverse_lookup_name(&t1, ".in-addr.arpa", + AF_UNSPEC, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa", + AF_UNSPEC, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa", + AF_INET6, 0); + test_eq(i, -1); + i = tor_addr_parse_reverse_lookup_name(&t1, + "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." + "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." + "ip6.ARPA", + AF_INET, 0); + test_eq(i, -1); + /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); |