From: Pieter Lexis Date: Mon, 8 Feb 2021 20:22:57 +0000 (+0100) Subject: SVCB: use proper escaping when writing text format X-Git-Tag: dnsdist-1.6.0-rc1~33^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a064bd5a09c53c23d32e0fe2276f2390d368c233;p=thirdparty%2Fpdns.git SVCB: use proper escaping when writing text format --- diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index d249cabee7..e84a6588b0 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -29,6 +29,7 @@ #include "utility.hh" #include #include +#include #include #include "base32.hh" @@ -742,6 +743,27 @@ static string txtEscape(const string &name) return ret; } +void RecordTextWriter::xfrSVCBValueList(const vector &val) { + bool shouldQuote{false}; + vector escaped; + escaped.reserve(val.size()); + for (auto const &v : val) { + if (v.find_first_of(' ') != string::npos) { + shouldQuote = true; + } + string tmp = txtEscape(v); + boost::replace_all(tmp, ",", "\\,"); + escaped.push_back(tmp); + } + if (shouldQuote) { + d_string.append(1, '"'); + } + d_string.append(boost::join(escaped, ",")); + if (shouldQuote) { + d_string.append(1, '"'); + } +} + void RecordTextWriter::xfrSvcParamKeyVals(const set& val) { for (auto const ¶m : val) { if (!d_string.empty()) @@ -762,8 +784,7 @@ void RecordTextWriter::xfrSvcParamKeyVals(const set& val) { d_string.append(ComboAddress::caContainerToString(param.getIPHints(), false)); break; case SvcParam::alpn: - // This is safe, as this value needs no quotes - d_string.append(boost::join(param.getALPN(), ",")); + xfrSVCBValueList(param.getALPN()); break; case SvcParam::mandatory: { diff --git a/pdns/rcpgenerator.hh b/pdns/rcpgenerator.hh index 22b79ce87e..099417b31b 100644 --- a/pdns/rcpgenerator.hh +++ b/pdns/rcpgenerator.hh @@ -105,6 +105,8 @@ public: void xfrSvcParamKeyVals(const set& val); bool eof() { return true; }; + void xfrSVCBValueList(const vector &val); + const string getRemaining() const { return ""; } diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 22f87700ef..9404e2fc14 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -229,6 +229,13 @@ BOOST_AUTO_TEST_CASE(test_record_types) { (CASE_S(QType::SVCB, "16 foo.powerdns.org. mandatory=alpn alpn=h2,h3 ipv4hint=192.0.2.1", "\0\x10\3foo\x08powerdns\x03org\x00\x00\x00\x00\x02\x00\x01\x00\x01\x00\x06\x02h2\x02h3\x00\x04\x00\x04\xc0\x00\x02\x01")) (CASE_L(QType::SVCB, "16 foo.powerdns.org. alpn=h2,h3 mandatory=alpn ipv4hint=192.0.2.1", "16 foo.powerdns.org. mandatory=alpn alpn=h2,h3 ipv4hint=192.0.2.1", "\0\x10\3foo\x08powerdns\x03org\x00\x00\x00\x00\x02\x00\x01\x00\x01\x00\x06\x02h2\x02h3\x00\x04\x00\x04\xc0\x00\x02\x01")) + // IPv4hint is quoted + (CASE_L(QType::SVCB, "16 foo.powerdns.org. alpn=h2,h3 mandatory=alpn ipv4hint=\"192.0.2.1\"", "16 foo.powerdns.org. mandatory=alpn alpn=h2,h3 ipv4hint=192.0.2.1", "\0\x10\3foo\x08powerdns\x03org\x00\x00\x00\x00\x02\x00\x01\x00\x01\x00\x06\x02h2\x02h3\x00\x04\x00\x04\xc0\x00\x02\x01")) + // Escaped ALPN value + (CASE_S(QType::SVCB, "1 foo.powerdns.org. alpn=h3\\,cool,h2", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x01\x00\x0b\x07h3,cool\x02h2")) + // Escaped _and_ spaced ALPN value + (CASE_S(QType::SVCB, "1 foo.powerdns.org. alpn=\"h3\\,co ol,h2\"", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x01\x00\x0c\x08h3,co ol\x02h2")) + (CASE_S(QType::SPF, "\"v=spf1 a:mail.rec.test ~all\"", "\x1bv=spf1 a:mail.rec.test ~all")) (CASE_S(QType::EUI48, "00-11-22-33-44-55", "\x00\x11\x22\x33\x44\x55")) (CASE_S(QType::EUI64, "00-11-22-33-44-55-66-77", "\x00\x11\x22\x33\x44\x55\x66\x77"))