From 44fc37033e7a3d799497e7d6198e453f33e669a6 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 29 Oct 2024 16:45:41 +1100 Subject: [PATCH] Add YAML escaping where needed When rendering text, such as domain names or the EXTRA-TEXT field of the EDE option, backslashes and quotation marks must be escaped to ensure that the emitted message is valid YAML. (cherry picked from commit 280e9b7cf4b28bffa6a281bb64b43e35829645ec) --- bin/tests/system/digdelv/tests.sh | 33 +++++++++++++++++++ lib/dns/message.c | 54 ++++++++++++++++++++----------- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 2a1500e5b3..ca84b32ef8 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -679,6 +679,26 @@ if [ -x "$DIG" ]; then if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) + n=$((n + 1)) + echo_i "check that dig processes +ednsopt=chain:02002200 ($n)" + ret=0 + dig_with_opts @10.53.0.3 +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1 + grep '; CHAIN: "\\000\\""' dig.out.test$n >/dev/null || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + + if [ $HAS_PYYAML -ne 0 ]; then + n=$((n + 1)) + echo_i "check that dig processes +ednsopt=chain:02002200 +yaml ($n)" + ret=0 + dig_with_opts @10.53.0.3 +yaml +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1 + $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CHAIN >yamlget.out.test$n 2>&1 || ret=1 + read -r value dig.out.test$n 2>&1 || ret=1 + $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 || ret=1 + read -r value 127)) { + if (namebuf[i] == '\\' || namebuf[i] == '"') { + ADD_STRING(target, "\\"); + } + if (isc_buffer_availablelength(target) < 1) { + return ISC_R_NOSPACE; + } + isc_buffer_putmem(target, &namebuf[i], 1); + } else { + ADD_STRING(target, "."); + } + } +cleanup: + return result; +} + +static isc_result_t +render_nameopt(isc_buffer_t *optbuf, bool yaml, isc_buffer_t *target) { dns_decompress_t dctx = DNS_DECOMPRESS_NEVER; dns_fixedname_t fixed; dns_name_t *name = dns_fixedname_initname(&fixed); @@ -3576,7 +3598,15 @@ render_nameopt(isc_buffer_t *optbuf, isc_buffer_t *target) { if (result == ISC_R_SUCCESS && isc_buffer_activelength(optbuf) == 0) { dns_name_format(name, namebuf, sizeof(namebuf)); ADD_STRING(target, " \""); - ADD_STRING(target, namebuf); + if (yaml) { + result = put_yamlstr(target, (unsigned char *)namebuf, + strlen(namebuf), false); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + } else { + ADD_STRING(target, namebuf); + } ADD_STRING(target, "\""); return result; } @@ -3801,7 +3831,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section, if (optlen > 0U) { isc_buffer_t sb = optbuf; isc_buffer_setactive(&optbuf, optlen); - result = render_nameopt(&optbuf, + result = render_nameopt(&optbuf, true, target); if (result == ISC_R_SUCCESS) { ADD_STRING(target, "\n"); @@ -3937,21 +3967,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section, } else { ADD_STRING(target, "\""); } - if (isc_buffer_availablelength(target) < optlen) - { - result = ISC_R_NOSPACE; - goto cleanup; - } - for (i = 0; i < optlen; i++) { - if (isprint(optdata[i]) || - (utf8ok && optdata[i] > 127)) - { - isc_buffer_putmem( - target, &optdata[i], 1); - } else { - isc_buffer_putstr(target, "."); - } - } + put_yamlstr(target, optdata, optlen, utf8ok); if (!extra_text) { ADD_STRING(target, "\")"); } else { @@ -4196,7 +4212,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section, if (optlen > 0U) { isc_buffer_t sb = optbuf; isc_buffer_setactive(&optbuf, optlen); - result = render_nameopt(&optbuf, + result = render_nameopt(&optbuf, false, target); if (result == ISC_R_SUCCESS) { ADD_STRING(target, "\n");