diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-10-29 15:31:26 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-10-29 15:31:26 +0000 |
commit | c8a5e2d588e0d91fd13070dc0ee4d6b19de779c3 (patch) | |
tree | a112111104af36d5c086e798e9b072ba73b6b7d8 /src | |
parent | 361086005ca70d8acce55f140a701b0b3a90e48c (diff) | |
download | tor-c8a5e2d588e0d91fd13070dc0ee4d6b19de779c3.tar.gz tor-c8a5e2d588e0d91fd13070dc0ee4d6b19de779c3.zip |
Work better with tools that resist DNS poisoning by using the 0x20 hack: make DNSPort replies perserve case.
svn:r17170
Diffstat (limited to 'src')
-rw-r--r-- | src/or/dnsserv.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index afd0f28364..46017f89cb 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -207,6 +207,38 @@ dnsserv_reject_request(edge_connection_t *conn) } } +/** Look up the original name that corresponds to 'addr' in req. We use this + * to preserve case in order to facilitate people using 0x20-hacks to avoid + * DNS poisoning. */ +static const char * +evdns_get_orig_address(const struct evdns_server_request *req, + int rtype, const char *addr) +{ + int i, type; + + switch (rtype) { + case RESOLVED_TYPE_IPV4: + type = EVDNS_TYPE_A; + break; + case RESOLVED_TYPE_HOSTNAME: + type = EVDNS_TYPE_PTR; + break; + case RESOLVED_TYPE_IPV6: + type = EVDNS_TYPE_AAAA; + break; + default: + tor_fragile_assert(); + return addr; + } + + for (i = 0; i < req->nquestions; ++i) { + const struct evdns_server_question *q = req->questions[i]; + if (q->type == type && !strcasecmp(q->name, addr)) + return q->name; + } + return addr; +} + /** Tell the dns request waiting for an answer on <b>conn</b> that we have an * answer of type <b>answer_type</b> (RESOLVE_TYPE_IPV4/IPV6/ERR), of length * <b>answer_len</b>, in <b>answer</b>, with TTL <b>ttl</b>. Doesn't do @@ -219,9 +251,11 @@ dnsserv_resolved(edge_connection_t *conn, int ttl) { struct evdns_server_request *req = conn->dns_server_request; + const char *name; int err = DNS_ERR_NONE; if (!req) return; + name = evdns_get_orig_address(req, answer_type, conn->socks_request->address); /* XXXX021 Re-do; this is dumb. */ if (ttl < 60) @@ -236,13 +270,13 @@ dnsserv_resolved(edge_connection_t *conn, } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4 && conn->socks_request->command == SOCKS_COMMAND_RESOLVE) { evdns_server_request_add_a_reply(req, - conn->socks_request->address, + name, 1, (char*)answer, ttl); } else if (answer_type == RESOLVED_TYPE_HOSTNAME && conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR) { char *ans = tor_strndup(answer, answer_len); evdns_server_request_add_ptr_reply(req, NULL, - conn->socks_request->address, + name, (char*)answer, ttl); tor_free(ans); } else if (answer_type == RESOLVED_TYPE_ERROR) { |