Commit 5e8b772a authored by Mark Andrews's avatar Mark Andrews

Ensure base64/base32/hex fields in DNS records that should be non-empty are.

parent 5114270f
Pipeline #8587 passed with stages
in 18 minutes and 45 seconds
5126. [bug] Named incorrectly accepted empty base64 and hex encoded
fields when reading master files. [GL #807]
5125. [bug] Allow for up to 100 records or 64k of data when caching 5125. [bug] Allow for up to 100 records or 64k of data when caching
a negative response. [GL #804] a negative response. [GL #804]
......
...@@ -36,15 +36,16 @@ done ...@@ -36,15 +36,16 @@ done
for db in zones/bad*.db for db in zones/bad*.db
do do
echo_i "checking $db ($n)" echo_i "checking $db ($n)"
ret=0 ret=0 v=0
case $db in case $db in
zones/bad-dns-sd-reverse.db) zones/bad-dns-sd-reverse.db)
$CHECKZONE -k fail -i local 0.0.0.0.in-addr.arpa $db > test.out.$n 2>&1 && ret=1 $CHECKZONE -k fail -i local 0.0.0.0.in-addr.arpa $db > test.out.$n 2>&1 || v=$?
;; ;;
*) *)
$CHECKZONE -i local example $db > test.out.$n 2>&1 && ret=1 $CHECKZONE -i local example $db > test.out.$n 2>&1 || v=$?
;; ;;
esac esac
test $v = 1 || ret=1
n=`expr $n + 1` n=`expr $n + 1`
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret` status=`expr $status + $ret`
......
...@@ -14,7 +14,7 @@ dyn.example.net. 7200 IN SOA ns1.example.net. hostmaster.example.net. ( ...@@ -14,7 +14,7 @@ dyn.example.net. 7200 IN SOA ns1.example.net. hostmaster.example.net. (
1209600 ; expire (2 weeks) 1209600 ; expire (2 weeks)
7200 ; minimum (2 hours) 7200 ; minimum (2 hours)
) )
7200 RRSIG SOA 7 3 7200 2010 20100225214229 30323 dyn.example.net. 7200 RRSIG SOA 7 3 7200 2010 20100225214229 30323 dyn.example.net. MuyI
7200 NS ns1.example.net. 7200 NS ns1.example.net.
7200 NS ns2.example.net. 7200 NS ns2.example.net.
3600 RRSIG DNSKEY 7 3 3600 20100227180048 ( 3600 RRSIG DNSKEY 7 3 3600 20100227180048 (
......
...@@ -868,13 +868,16 @@ unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, ...@@ -868,13 +868,16 @@ unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
result = isc_hex_tobuffer(lexer, buf, if (token.value.as_ulong != 0U) {
(unsigned int)token.value.as_ulong); result = isc_hex_tobuffer(lexer, buf,
if (result != ISC_R_SUCCESS) (unsigned int)token.value.as_ulong);
goto failure; if (result != ISC_R_SUCCESS) {
if (isc_buffer_usedlength(buf) != token.value.as_ulong) { goto failure;
result = ISC_R_UNEXPECTEDEND; }
goto failure; if (isc_buffer_usedlength(buf) != token.value.as_ulong) {
result = ISC_R_UNEXPECTEDEND;
goto failure;
}
} }
if (dns_rdatatype_isknown(type)) { if (dns_rdatatype_isknown(type)) {
......
...@@ -55,7 +55,7 @@ fromtext_cert(ARGS_FROMTEXT) { ...@@ -55,7 +55,7 @@ fromtext_cert(ARGS_FROMTEXT) {
RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion));
RETERR(mem_tobuffer(target, &secalg, 1)); RETERR(mem_tobuffer(target, &secalg, 1));
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -74,7 +74,7 @@ generic_fromtext_ds(ARGS_FROMTEXT) { ...@@ -74,7 +74,7 @@ generic_fromtext_ds(ARGS_FROMTEXT) {
length = ISC_SHA384_DIGESTLENGTH; length = ISC_SHA384_DIGESTLENGTH;
break; break;
default: default:
length = -1; length = -2;
break; break;
} }
return (isc_hex_tobuffer(lexer, target, length)); return (isc_hex_tobuffer(lexer, target, length));
......
...@@ -108,7 +108,7 @@ fromtext_ipseckey(ARGS_FROMTEXT) { ...@@ -108,7 +108,7 @@ fromtext_ipseckey(ARGS_FROMTEXT) {
/* /*
* Public key. * Public key.
*/ */
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
static inline isc_result_t static inline isc_result_t
generic_fromtext_key(ARGS_FROMTEXT) { generic_fromtext_key(ARGS_FROMTEXT) {
isc_result_t result;
isc_token_t token; isc_token_t token;
dns_secalg_t alg; dns_secalg_t alg;
dns_secproto_t proto; dns_secproto_t proto;
...@@ -55,11 +54,7 @@ generic_fromtext_key(ARGS_FROMTEXT) { ...@@ -55,11 +54,7 @@ generic_fromtext_key(ARGS_FROMTEXT) {
if ((flags & 0xc000) == 0xc000) if ((flags & 0xc000) == 0xc000)
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
result = isc_base64_tobuffer(lexer, target, -1); return (isc_base64_tobuffer(lexer, target, -2));
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
static inline isc_result_t static inline isc_result_t
fromtext_keydata(ARGS_FROMTEXT) { fromtext_keydata(ARGS_FROMTEXT) {
isc_result_t result;
isc_token_t token; isc_token_t token;
dns_secalg_t alg; dns_secalg_t alg;
dns_secproto_t proto; dns_secproto_t proto;
...@@ -76,11 +75,7 @@ fromtext_keydata(ARGS_FROMTEXT) { ...@@ -76,11 +75,7 @@ fromtext_keydata(ARGS_FROMTEXT) {
if ((flags & 0xc000) == 0xc000) if ((flags & 0xc000) == 0xc000)
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
result = isc_base64_tobuffer(lexer, target, -1); return (isc_base64_tobuffer(lexer, target, -2));
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -28,7 +28,7 @@ fromtext_openpgpkey(ARGS_FROMTEXT) { ...@@ -28,7 +28,7 @@ fromtext_openpgpkey(ARGS_FROMTEXT) {
/* /*
* Keyring. * Keyring.
*/ */
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -140,7 +140,7 @@ fromtext_rrsig(ARGS_FROMTEXT) { ...@@ -140,7 +140,7 @@ fromtext_rrsig(ARGS_FROMTEXT) {
/* /*
* Sig. * Sig.
*/ */
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -112,7 +112,7 @@ fromtext_sig(ARGS_FROMTEXT) { ...@@ -112,7 +112,7 @@ fromtext_sig(ARGS_FROMTEXT) {
/* /*
* Sig. * Sig.
*/ */
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -50,7 +50,7 @@ fromtext_sshfp(ARGS_FROMTEXT) { ...@@ -50,7 +50,7 @@ fromtext_sshfp(ARGS_FROMTEXT) {
/* /*
* Digest. * Digest.
*/ */
return (isc_hex_tobuffer(lexer, target, -1)); return (isc_hex_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -56,7 +56,7 @@ generic_fromtext_tlsa(ARGS_FROMTEXT) { ...@@ -56,7 +56,7 @@ generic_fromtext_tlsa(ARGS_FROMTEXT) {
/* /*
* Certificate Association Data. * Certificate Association Data.
*/ */
return (isc_hex_tobuffer(lexer, target, -1)); return (isc_hex_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -29,7 +29,7 @@ fromtext_in_dhcid(ARGS_FROMTEXT) { ...@@ -29,7 +29,7 @@ fromtext_in_dhcid(ARGS_FROMTEXT) {
UNUSED(options); UNUSED(options);
UNUSED(callbacks); UNUSED(callbacks);
return (isc_base64_tobuffer(lexer, target, -1)); return (isc_base64_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -28,7 +28,7 @@ fromtext_in_eid(ARGS_FROMTEXT) { ...@@ -28,7 +28,7 @@ fromtext_in_eid(ARGS_FROMTEXT) {
UNUSED(rdclass); UNUSED(rdclass);
UNUSED(callbacks); UNUSED(callbacks);
return (isc_hex_tobuffer(lexer, target, -1)); return (isc_hex_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -28,7 +28,7 @@ fromtext_in_nimloc(ARGS_FROMTEXT) { ...@@ -28,7 +28,7 @@ fromtext_in_nimloc(ARGS_FROMTEXT) {
UNUSED(rdclass); UNUSED(rdclass);
UNUSED(callbacks); UNUSED(callbacks);
return (isc_hex_tobuffer(lexer, target, -1)); return (isc_hex_tobuffer(lexer, target, -2));
} }
static inline isc_result_t static inline isc_result_t
......
...@@ -282,31 +282,43 @@ static isc_result_t ...@@ -282,31 +282,43 @@ static isc_result_t
base32_tobuffer(isc_lex_t *lexer, const char base[], bool pad, base32_tobuffer(isc_lex_t *lexer, const char base[], bool pad,
isc_buffer_t *target, int length) isc_buffer_t *target, int length)
{ {
unsigned int before, after;
base32_decode_ctx_t ctx; base32_decode_ctx_t ctx;
isc_textregion_t *tr; isc_textregion_t *tr;
isc_token_t token; isc_token_t token;
bool eol; bool eol;
REQUIRE(length >= -2);
base32_decode_init(&ctx, length, base, pad, target); base32_decode_init(&ctx, length, base, pad, target);
before = isc_buffer_usedlength(target);
while (!ctx.seen_end && (ctx.length != 0)) { while (!ctx.seen_end && (ctx.length != 0)) {
unsigned int i; unsigned int i;
if (length > 0) if (length > 0) {
eol = false; eol = false;
else } else {
eol = true; eol = true;
}
RETERR(isc_lex_getmastertoken(lexer, &token, RETERR(isc_lex_getmastertoken(lexer, &token,
isc_tokentype_string, eol)); isc_tokentype_string, eol));
if (token.type != isc_tokentype_string) if (token.type != isc_tokentype_string) {
break; break;
}
tr = &token.value.as_textregion; tr = &token.value.as_textregion;
for (i = 0; i < tr->length; i++) for (i = 0; i < tr->length; i++) {
RETERR(base32_decode_char(&ctx, tr->base[i])); RETERR(base32_decode_char(&ctx, tr->base[i]));
}
} }
if (ctx.length < 0 && !ctx.seen_end) after = isc_buffer_usedlength(target);
if (ctx.length < 0 && !ctx.seen_end) {
isc_lex_ungettoken(lexer, &token); isc_lex_ungettoken(lexer, &token);
}
RETERR(base32_decode_finish(&ctx)); RETERR(base32_decode_finish(&ctx));
if (length == -2 && before == after) {
return (ISC_R_UNEXPECTEDEND);
}
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
......
...@@ -173,31 +173,43 @@ base64_decode_finish(base64_decode_ctx_t *ctx) { ...@@ -173,31 +173,43 @@ base64_decode_finish(base64_decode_ctx_t *ctx) {
isc_result_t isc_result_t
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
unsigned int before, after;
base64_decode_ctx_t ctx; base64_decode_ctx_t ctx;
isc_textregion_t *tr; isc_textregion_t *tr;
isc_token_t token; isc_token_t token;
bool eol; bool eol;
REQUIRE(length >= -2);
base64_decode_init(&ctx, length, target); base64_decode_init(&ctx, length, target);
before = isc_buffer_usedlength(target);
while (!ctx.seen_end && (ctx.length != 0)) { while (!ctx.seen_end && (ctx.length != 0)) {
unsigned int i; unsigned int i;
if (length > 0) if (length > 0) {
eol = false; eol = false;
else } else {
eol = true; eol = true;
}
RETERR(isc_lex_getmastertoken(lexer, &token, RETERR(isc_lex_getmastertoken(lexer, &token,
isc_tokentype_string, eol)); isc_tokentype_string, eol));
if (token.type != isc_tokentype_string) if (token.type != isc_tokentype_string) {
break; break;
}
tr = &token.value.as_textregion; tr = &token.value.as_textregion;
for (i = 0; i < tr->length; i++) for (i = 0; i < tr->length; i++) {
RETERR(base64_decode_char(&ctx, tr->base[i])); RETERR(base64_decode_char(&ctx, tr->base[i]));
}
} }
if (ctx.length < 0 && !ctx.seen_end) after = isc_buffer_usedlength(target);
if (ctx.length < 0 && !ctx.seen_end) {
isc_lex_ungettoken(lexer, &token); isc_lex_ungettoken(lexer, &token);
}
RETERR(base64_decode_finish(&ctx)); RETERR(base64_decode_finish(&ctx));
if (length == -2 && before == after) {
return (ISC_R_UNEXPECTEDEND);
}
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
......
...@@ -121,31 +121,43 @@ hex_decode_finish(hex_decode_ctx_t *ctx) { ...@@ -121,31 +121,43 @@ hex_decode_finish(hex_decode_ctx_t *ctx) {
isc_result_t isc_result_t
isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
unsigned int before, after;
hex_decode_ctx_t ctx; hex_decode_ctx_t ctx;
isc_textregion_t *tr; isc_textregion_t *tr;
isc_token_t token; isc_token_t token;
bool eol; bool eol;
REQUIRE(length >= -2);
hex_decode_init(&ctx, length, target); hex_decode_init(&ctx, length, target);
before = isc_buffer_usedlength(target);
while (ctx.length != 0) { while (ctx.length != 0) {
unsigned int i; unsigned int i;
if (length > 0) if (length > 0) {
eol = false; eol = false;
else } else {
eol = true; eol = true;
}
RETERR(isc_lex_getmastertoken(lexer, &token, RETERR(isc_lex_getmastertoken(lexer, &token,
isc_tokentype_string, eol)); isc_tokentype_string, eol));
if (token.type != isc_tokentype_string) if (token.type != isc_tokentype_string) {
break; break;
}
tr = &token.value.as_textregion; tr = &token.value.as_textregion;
for (i = 0; i < tr->length; i++) for (i = 0; i < tr->length; i++) {
RETERR(hex_decode_char(&ctx, tr->base[i])); RETERR(hex_decode_char(&ctx, tr->base[i]));
}
} }
if (ctx.length < 0) after = isc_buffer_usedlength(target);
if (ctx.length < 0) {
isc_lex_ungettoken(lexer, &token); isc_lex_ungettoken(lexer, &token);
}
RETERR(hex_decode_finish(&ctx)); RETERR(hex_decode_finish(&ctx));
if (length == -2 && before == after) {
return (ISC_R_UNEXPECTEDEND);
}
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
......
...@@ -96,18 +96,27 @@ isc_result_t ...@@ -96,18 +96,27 @@ isc_result_t
isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
/*!< /*!<
* \brief Convert text encoded in base32, base32hex, or base32hex * \brief Convert text encoded in base32, base32hex, or base32hex
* non-padded from a lexer context into data. * non-padded from a lexer context into `target`. If 'length' is
* non-negative, it is the expected number of encoded octets to convert.
*
* If 'length' is -1 then 0 or more encoded octets are expected.
* If 'length' is -2 then 1 or more encoded octets are expected.
*
* Returns:
*\li #ISC_R_BADBASE32 -- invalid base32 encoding.
*\li #ISC_R_UNEXPECTEDEND: the text does not contain the expected
* number of encoded octets.
* *
* Requires: * Requires:
*\li 'lex' is a valid lexer context *\li 'lexer' is a valid lexer context
*\li 'target' is a buffer containing binary data *\li 'target' is a buffer containing binary data
*\li 'length' is an integer *\li 'length' is -2, -1, or non-negative
* *
* Ensures: * Ensures:
*\li target will contain the data represented by the base32 encoded *\li target will contain the data represented by the base32 encoded
* string parsed by the lexer. No more than length bytes will be read, * string parsed by the lexer. No more than `length` octets will
* if length is positive. The 'used' pointer in target will be * be read, if `length` is non-negative. The 'used' pointer in
* advanced as necessary. * 'target' will be advanced as necessary.
*/ */
isc_result_t isc_result_t
......
...@@ -71,22 +71,30 @@ isc_base64_decodestring(const char *cstr, isc_buffer_t *target); ...@@ -71,22 +71,30 @@ isc_base64_decodestring(const char *cstr, isc_buffer_t *target);
isc_result_t isc_result_t
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
/*!< /*!<
* \brief Convert base64 encoded text from a lexer context into data. * \brief Convert base64 encoded text from a lexer context into
* `target`. If 'length' is non-negative, it is the expected number of
* encoded octets to convert.
*
* If 'length' is -1 then 0 or more encoded octets are expected.
* If 'length' is -2 then 1 or more encoded octets are expected.
*
* Returns:
*\li #ISC_R_BADBASE64 -- invalid base64 encoding.
*\li #ISC_R_UNEXPECTEDEND: the text does not contain the expected
* number of encoded octets.
* *
* Requires: * Requires:
*\li 'lex' is a valid lexer context *\li 'lexer' is a valid lexer context
*\li 'target' is a buffer containing binary data *\li 'target' is a buffer containing binary data
*\li 'length' is an integer *\li 'length' is -2, -1, or non-negative
* *
* Ensures: * Ensures:
*\li target will contain the data represented by the base64 encoded *\li target will contain the data represented by the base64 encoded
* string parsed by the lexer. No more than length bytes will be read, * string parsed by the lexer. No more than `length` octets will
* if length is positive. The 'used' pointer in target will be * be read, if `length` is non-negative. The 'used' pointer in
* advanced as necessary. * 'target' will be advanced as necessary.
*/ */
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS
#endif /* ISC_BASE64_H */ #endif /* ISC_BASE64_H */
...@@ -71,21 +71,30 @@ isc_hex_decodestring(const char *cstr, isc_buffer_t *target); ...@@ -71,21 +71,30 @@ isc_hex_decodestring(const char *cstr, isc_buffer_t *target);
isc_result_t isc_result_t
isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
/*!< /*!<
* \brief Convert hex encoded text from a lexer context into data. * \brief Convert hex-encoded text from a lexer context into
* `target`. If 'length' is non-negative, it is the expected number of
* encoded octets to convert.
*
* If 'length' is -1 then 0 or more encoded octets are expected.
* If 'length' is -2 then 1 or more encoded octets are expected.
*