Work better with tools that resist DNS poisoning by using the 0x20 hack: make DNSPort replies perserve case.

svn:r17170
This commit is contained in:
Nick Mathewson 2008-10-29 15:31:26 +00:00
parent 361086005c
commit c8a5e2d588
2 changed files with 38 additions and 2 deletions

View File

@ -10,6 +10,8 @@ Changes in version 0.2.1.7-alpha - 2008-10-xx
- Now NodeFamily and MyFamily config options allow spaces in - Now NodeFamily and MyFamily config options allow spaces in
identity fingerprints, so it's easier to paste them in. identity fingerprints, so it's easier to paste them in.
Suggested by Lucky Green. Suggested by Lucky Green.
- Preserve case in replies to DNSPort requests in order to support
the 0x20 hack for resisting DNS poisoning attacks.
o Hidden service performance improvements: o Hidden service performance improvements:
- When the client launches an introduction circuit, retry with a - When the client launches an introduction circuit, retry with a

View File

@ -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 /** 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 * 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 * <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) int ttl)
{ {
struct evdns_server_request *req = conn->dns_server_request; struct evdns_server_request *req = conn->dns_server_request;
const char *name;
int err = DNS_ERR_NONE; int err = DNS_ERR_NONE;
if (!req) if (!req)
return; return;
name = evdns_get_orig_address(req, answer_type, conn->socks_request->address);
/* XXXX021 Re-do; this is dumb. */ /* XXXX021 Re-do; this is dumb. */
if (ttl < 60) if (ttl < 60)
@ -236,13 +270,13 @@ dnsserv_resolved(edge_connection_t *conn,
} else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4 && } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4 &&
conn->socks_request->command == SOCKS_COMMAND_RESOLVE) { conn->socks_request->command == SOCKS_COMMAND_RESOLVE) {
evdns_server_request_add_a_reply(req, evdns_server_request_add_a_reply(req,
conn->socks_request->address, name,
1, (char*)answer, ttl); 1, (char*)answer, ttl);
} else if (answer_type == RESOLVED_TYPE_HOSTNAME && } else if (answer_type == RESOLVED_TYPE_HOSTNAME &&
conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR) { conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR) {
char *ans = tor_strndup(answer, answer_len); char *ans = tor_strndup(answer, answer_len);
evdns_server_request_add_ptr_reply(req, NULL, evdns_server_request_add_ptr_reply(req, NULL,
conn->socks_request->address, name,
(char*)answer, ttl); (char*)answer, ttl);
tor_free(ans); tor_free(ans);
} else if (answer_type == RESOLVED_TYPE_ERROR) { } else if (answer_type == RESOLVED_TYPE_ERROR) {