diff options
author | Tomas Hozza <thozza@redhat.com> | 2014-03-25 20:52:28 +0000 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2014-03-25 20:52:28 +0000 |
commit | b37f8b99ae7ef73aaee5fd8db6b1693354ac40cf (patch) | |
tree | ca8071c4ae7f3275bcae0ceb8b79f5b72ea1e57d | |
parent | fc2833f172819a9189bca20fe5777819a096baa4 (diff) | |
download | dnsmasq-b37f8b99ae7ef73aaee5fd8db6b1693354ac40cf.tar.gz |
Handle failure of hash_questions()
-rw-r--r-- | src/forward.c | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/src/forward.c b/src/forward.c index 71addb1..7e87733 100644 --- a/src/forward.c +++ b/src/forward.c @@ -1417,42 +1417,44 @@ static int tcp_check_for_unsigned_zone(time_t now, struct dns_header *header, s /* We rely on the question section coming back unchanged, ensure it is with the hash. */ if ((newhash = hash_questions(header, (unsigned int)m, name))) - memcpy(hash, newhash, HASH_SIZE); - - *length = htons(m); - - if (read_write(server->tcpfd, packet, m + sizeof(u16), 0) && - read_write(server->tcpfd, &c1, 1, 1) && - read_write(server->tcpfd, &c2, 1, 1) && - read_write(server->tcpfd, payload, (c1 << 8) | c2, 1)) { - m = (c1 << 8) | c2; + memcpy(hash, newhash, HASH_SIZE); + + *length = htons(m); - newhash = hash_questions(header, (unsigned int)m, name); - if (newhash && memcmp(hash, newhash, HASH_SIZE) == 0) + if (read_write(server->tcpfd, packet, m + sizeof(u16), 0) && + read_write(server->tcpfd, &c1, 1, 1) && + read_write(server->tcpfd, &c2, 1, 1) && + read_write(server->tcpfd, payload, (c1 << 8) | c2, 1)) { - /* Note this trashes all three name workspaces */ - status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); - - /* We've found a DS which proves the bit of the DNS where the - original query is, is unsigned, so the answer is OK, - if unvalidated. */ - if (status == STAT_NO_DS) - { - free(packet); - return STAT_INSECURE; - } + m = (c1 << 8) | c2; - /* No DS, not got to DNSSEC-land yet, go up. */ - if (status == STAT_INSECURE) + newhash = hash_questions(header, (unsigned int)m, name); + if (newhash && memcmp(hash, newhash, HASH_SIZE) == 0) { - p = (unsigned char *)(header+1); + /* Note this trashes all three name workspaces */ + status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); - if (extract_name(header, plen, &p, name, 1, 4) && - (name_start = strchr(name, '.'))) + /* We've found a DS which proves the bit of the DNS where the + original query is, is unsigned, so the answer is OK, + if unvalidated. */ + if (status == STAT_NO_DS) { - name_start++; /* chop a label off and try again */ - continue; + free(packet); + return STAT_INSECURE; + } + + /* No DS, not got to DNSSEC-land yet, go up. */ + if (status == STAT_INSECURE) + { + p = (unsigned char *)(header+1); + + if (extract_name(header, plen, &p, name, 1, 4) && + (name_start = strchr(name, '.'))) + { + name_start++; /* chop a label off and try again */ + continue; + } } } } @@ -1731,6 +1733,8 @@ unsigned char *tcp_request(int confd, time_t now, unsigned char *newhash, hash[HASH_SIZE]; if ((newhash = hash_questions(header, (unsigned int)size, daemon->keyname))) memcpy(hash, newhash, HASH_SIZE); + else + memset(hash, 0, HASH_SIZE); #else unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff); #endif |