}
for(unsigned int n = 0; n+1 < bitmap.size();) {
- unsigned int window=static_cast<unsigned char>(bitmap[n++]);
- unsigned int blen=static_cast<unsigned char>(bitmap[n++]);
+ uint8_t window=static_cast<uint8_t>(bitmap[n++]);
+ uint8_t blen=static_cast<uint8_t>(bitmap[n++]);
// end if zero padding and ensure packet length
- if(window == 0 && blen == 0) {
+ if (window == 0 && blen == 0) {
break;
}
- if(n + blen > bitmap.size()) {
+ if (blen > 32) {
+ throw MOADNSException("NSEC record with invalid bitmap length");
+ }
+
+ if (n + blen > bitmap.size()) {
throw MOADNSException("NSEC record with bitmap length > packet length");
}
}
}
+BOOST_AUTO_TEST_CASE(test_nsec_invalid_bitmap_len) {
+ auto validNSEC = DNSRecordContent::mastermake(QType::NSEC, QClass::IN, "host.example.com. A MX RRSIG NSEC AAAA NSEC3 TYPE1234 TYPE65535");
+ const DNSName powerdnsName("powerdns.com.");
+
+ vector<uint8_t> packet;
+ DNSPacketWriter writer(packet, powerdnsName, QType::NSEC, QClass::IN, 0);
+ writer.getHeader()->qr = 1;
+ writer.startRecord(powerdnsName, QType::NSEC, 100, QClass::IN, DNSResourceRecord::ANSWER, false);
+ validNSEC->toPacket(writer);
+ writer.commit();
+
+ size_t nsecDataPos = sizeof(dnsheader) + powerdnsName.wirelength() + sizeof(uint16_t) + sizeof (uint16_t) + powerdnsName.wirelength() + sizeof(uint16_t) + sizeof (uint16_t) + sizeof(uint32_t) + sizeof(uint16_t);
+ size_t typeBitMapsFieldPos = nsecDataPos + DNSName("host.example.com.").wirelength();
+ auto invalidPacket = packet;
+ /* set the bitmap length value to 33, while the maximum possible value is 32 */
+ invalidPacket.at(typeBitMapsFieldPos + 1) = 33;
+
+ MOADNSParser parser(false, reinterpret_cast<const char*>(packet.data()), packet.size());
+ BOOST_CHECK_THROW(MOADNSParser failParser(false, reinterpret_cast<const char*>(invalidPacket.data()), invalidPacket.size()), MOADNSException);
+}
+
BOOST_AUTO_TEST_CASE(test_nsec3_records_types) {
{