From: Otto Moerbeek Date: Tue, 6 Sep 2022 11:30:21 +0000 (+0200) Subject: Implement padding of (DoT) messages to auth X-Git-Tag: rec-4.8.0-alpha1~33^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1050a5c8f71ac77ad48b938a394daab04ab278a1;p=thirdparty%2Fpdns.git Implement padding of (DoT) messages to auth --- diff --git a/pdns/lwres.cc b/pdns/lwres.cc index 650e868264..4cef99eb60 100644 --- a/pdns/lwres.cc +++ b/pdns/lwres.cc @@ -50,7 +50,7 @@ #include "query-local-address.hh" #include "tcpiohandler.hh" #include "ednsoptions.hh" - +#include "ednspadding.hh" #include "rec-protozero.hh" #include "uuid-utils.hh" #include "rec-tcpout.hh" @@ -359,6 +359,25 @@ static LWResult::Result tcpsendrecv(const ComboAddress& ip, TCPOutConnectionMana return LWResult::Result::Success; } +static void addPadding(const DNSPacketWriter& pw, size_t bufsize, DNSPacketWriter::optvect_t& opts) +{ + const size_t currentSize = pw.getSizeWithOpts(opts); + if (currentSize < (bufsize - 4)) { + const size_t remaining = bufsize - (currentSize + 4); + /* from rfc8647, "4.1. Recommended Strategy: Block-Length Padding": + Clients SHOULD pad queries to the closest multiple of 128 octets. + Note we are in the client role here. + */ + const size_t blockSize = 128; + const size_t modulo = (currentSize + 4) % blockSize; + size_t padSize = 0; + if (modulo > 0) { + padSize = std::min(blockSize - modulo, remaining); + } + opts.emplace_back(EDNSOptionCode::PADDING, makeEDNSPaddingOptString(padSize)); + } +} + /** lwr is only filled out in case 1 was returned, and even when returning 1 for 'success', lwr might contain DNS errors Never throws! */ @@ -372,6 +391,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma // string mapped0x20=dns0x20(domain); uint16_t qid = dns_random_uint16(); DNSPacketWriter pw(vpacket, domain, type); + bool dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853; pw.getHeader()->rd=sendRDQuery; pw.getHeader()->id=qid; @@ -403,7 +423,11 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma weWantEDNSSubnet=true; } - pw.addOpt(g_outgoingEDNSBufsize, 0, g_dnssecmode == DNSSECMode::Off ? 0 : EDNSOpts::DNSSECOK, opts); + if (dnsOverTLS /* and other conditions? */) { + addPadding(pw, bufsize, opts); + } + + pw.addOpt(g_outgoingEDNSBufsize, 0, g_dnssecmode == DNSSECMode::Off ? 0 : EDNSOpts::DNSSECOK, opts); pw.commit(); } lwr->d_rcode = 0; @@ -416,7 +440,6 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma boost::uuids::uuid uuid; const struct timeval queryTime = *now; - bool dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853; if (outgoingLoggers) { uuid = getUniqueID();