Pārlūkot izejas kodu

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

svn:r17170
Nick Mathewson 17 gadi atpakaļ
vecāks
revīzija
c8a5e2d588
2 mainītis faili ar 38 papildinājumiem un 2 dzēšanām
  1. 2 0
      ChangeLog
  2. 36 2
      src/or/dnsserv.c

+ 2 - 0
ChangeLog

@@ -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

+ 36 - 2
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
 /** 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) {