Commit c8a5e2d5 authored by Nick Mathewson's avatar Nick Mathewson 🐘
Browse files

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

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

svn:r17170
parent 36108600
Loading
Loading
Loading
Loading
+2 −0
Changes for ChangeLog: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ Changes in version 0.2.1.7-alpha - 2008-10-xx
    - Now NodeFamily and MyFamily config options allow spaces in
      identity fingerprints, so it's easier to paste them in.
      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:
    - When the client launches an introduction circuit, retry with a
+36 −2
Changes for src/or/dnsserv.c: 36 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -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) {