X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdns.cpp;h=17641c585be5de1d320c868a9c669dfc9861d2df;hb=37d7160b3a2434abcb4b39898bb86fa314fc3e5b;hp=21b0d9e39f400134cded6218bed3355ce71f3d75;hpb=84ab0478f9dd7f7f8dc92aa1edaf6b71fe28035b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dns.cpp b/src/dns.cpp index 21b0d9e39..17641c585 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -1,16 +1,27 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2012 William Pitcock + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2006, 2009 Robin Burchell + * Copyright (C) 2007, 2009 Dennis Friis + * Copyright (C) 2008 Thomas Stagner + * Copyright (C) 2005-2007 Craig Edwards * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. * - * This program is free but copyrighted software; see - * the file COPYING for details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * --------------------------------------------------- + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + /* $Core */ /* @@ -100,7 +111,7 @@ class DNSRequest DNSRequest(DNS* dns, int id, const std::string &original); ~DNSRequest(); - DNSInfo ResultIsReady(DNSHeader &h, int length); + DNSInfo ResultIsReady(DNSHeader &h, unsigned length); int SendRequests(const DNSHeader *header, const int length, QueryType qt); }; @@ -693,7 +704,7 @@ DNSResult DNS::GetResult() } /** A result is ready, process it */ -DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) +DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) { unsigned i = 0, o; int q = 0; @@ -722,7 +733,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) /* Subtract the length of the header from the length of the packet */ length -= 12; - while ((unsigned int)q < header.qdcount && i < (unsigned) length) + while ((unsigned int)q < header.qdcount && i < length) { if (header.payload[i] > 63) { @@ -743,7 +754,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) while ((unsigned)curanswer < header.ancount) { q = 0; - while (q == 0 && i < (unsigned) length) + while (q == 0 && i < length) { if (header.payload[i] > 63) { @@ -760,7 +771,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) else i += header.payload[i] + 1; /* skip length and label */ } } - if ((unsigned) length - i < 10) + if (static_cast(length - i) < 10) return std::make_pair((unsigned char*)NULL,"Incorrectly sized DNS reply"); /* XXX: We actually initialise 'rr' here including its ttl field */ @@ -800,9 +811,11 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) */ case DNS_QUERY_CNAME: case DNS_QUERY_PTR: + { + unsigned short lowest_pos = length; o = 0; q = 0; - while (q == 0 && i < (unsigned) length && o + 256 < 1023) + while (q == 0 && i < length && o + 256 < 1023) { /* DN label found (byte over 63) */ if (header.payload[i] > 63) @@ -812,14 +825,18 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) i = ntohs(ptr); /* check that highest two bits are set. if not, we've been had */ - if (!(i & DN_COMP_BITMASK)) + if ((i & DN_COMP_BITMASK) != DN_COMP_BITMASK) return std::make_pair((unsigned char *) NULL, "DN label decompression header is bogus"); /* mask away the two highest bits. */ i &= ~DN_COMP_BITMASK; /* and decrease length by 12 bytes. */ - i =- 12; + i -= 12; + + if (i >= lowest_pos) + return std::make_pair((unsigned char *) NULL, "Invalid decompression pointer"); + lowest_pos = i; } else { @@ -843,6 +860,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) } } res[o] = 0; + } break; case DNS_QUERY_AAAA: if (rr.rdlength != sizeof(struct in6_addr))