mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
Merge branch '3544-add-dohpath-parsing-to-svbc-v9_18' into 'v9_18'
Add support for 'dohpath' to SVCB (and HTTPS) [v9_18] See merge request isc-projects/bind9!6849
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
||||
5991. [protocol] Add support for parsing and validating "dohpath" to
|
||||
SVCB. [GL #3544]
|
||||
|
||||
5988. [bug] Some out of memory conditions in opensslrsa_link.c
|
||||
could lead to memory leaks. [GL #3551]
|
||||
|
||||
|
@@ -24,3 +24,4 @@ svcb6 SVCB 6 . mandatory=port,alpn port=60 alpn=h3
|
||||
svcb7 SVCB 7 . mandatory=port,alpn port=60 alpn=h1,h3
|
||||
svcb8 SVCB 8 . mandatory=port,alpn port=60 alpn="h1\\,h2,h3"
|
||||
svcb9 SVCB 0 44._svbc.example.net.
|
||||
svcb10 SVCB 7 . alpn="h2,h3" dohpath=/{?dns}
|
||||
|
@@ -957,7 +957,7 @@ AS_IF([test "$enable_tcp_fastopen" = "yes"],
|
||||
#
|
||||
# Check for some other useful functions that are not ever-present.
|
||||
#
|
||||
AC_CHECK_FUNCS([strlcpy strlcat])
|
||||
AC_CHECK_FUNCS([strlcpy strlcat strnstr])
|
||||
|
||||
#
|
||||
# Check for readline support
|
||||
|
@@ -47,6 +47,9 @@ Feature Changes
|
||||
with '-DOPENSSL_API_COMPAT=10100' specified in the CFLAGS at
|
||||
compile time. :gl:`!6711`
|
||||
|
||||
- Add support for parsing and validating ``dohpath`` to SVBC records.
|
||||
:gl:`#3544`
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
||||
|
@@ -34,13 +34,14 @@ enum encoding {
|
||||
sbpr_base64,
|
||||
sbpr_empty,
|
||||
sbpr_alpn,
|
||||
sbpr_keylist
|
||||
sbpr_keylist,
|
||||
sbpr_dohpath
|
||||
};
|
||||
static const struct {
|
||||
const char *name; /* Restricted to lowercase LDH by registry. */
|
||||
unsigned int value;
|
||||
enum encoding encoding;
|
||||
bool initial;
|
||||
bool initial; /* Part of the first defined set of encodings. */
|
||||
} sbpr[] = {
|
||||
{ "mandatory", 0, sbpr_keylist, true },
|
||||
{ "alpn", 1, sbpr_alpn, true },
|
||||
@@ -49,6 +50,7 @@ static const struct {
|
||||
{ "ipv4hint", 4, sbpr_ipv4s, true },
|
||||
{ "ech", 5, sbpr_base64, true },
|
||||
{ "ipv6hint", 6, sbpr_ipv6s, true },
|
||||
{ "dohpath", 7, sbpr_dohpath, false },
|
||||
};
|
||||
|
||||
static isc_result_t
|
||||
@@ -147,6 +149,30 @@ svcb_validate(uint16_t key, isc_region_t *region) {
|
||||
case sbpr_text:
|
||||
case sbpr_base64:
|
||||
break;
|
||||
case sbpr_dohpath:
|
||||
/*
|
||||
* Minimum valid dohpath is "/{?dns}" as
|
||||
* it MUST be relative (leading "/") and
|
||||
* MUST contain "{?dns}".
|
||||
*/
|
||||
if (region->length < 7) {
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
/* MUST be relative */
|
||||
if (region->base[0] != '/') {
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
/* MUST be UTF8 */
|
||||
if (!isc_utf8_valid(region->base,
|
||||
region->length)) {
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
/* MUST contain "{?dns}" */
|
||||
if (strnstr((char *)region->base, "{?dns}",
|
||||
region->length) == NULL) {
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
break;
|
||||
case sbpr_empty:
|
||||
if (region->length != 0) {
|
||||
return (DNS_R_FORMERR);
|
||||
@@ -252,6 +278,7 @@ svc_fromtext(isc_textregion_t *region, isc_buffer_t *target) {
|
||||
|
||||
switch (sbpr[i].encoding) {
|
||||
case sbpr_text:
|
||||
case sbpr_dohpath:
|
||||
RETERR(multitxt_fromtext(region, target));
|
||||
break;
|
||||
case sbpr_alpn:
|
||||
@@ -328,6 +355,19 @@ svc_fromtext(isc_textregion_t *region, isc_buffer_t *target) {
|
||||
len = isc_buffer_usedlength(target) -
|
||||
isc_buffer_usedlength(&sb) - 2;
|
||||
RETERR(uint16_tobuffer(len, &sb)); /* length */
|
||||
switch (sbpr[i].encoding) {
|
||||
case sbpr_dohpath:
|
||||
/*
|
||||
* Apply constraints not applied by multitxt_fromtext.
|
||||
*/
|
||||
keyregion.base = isc_buffer_used(&sb);
|
||||
keyregion.length = isc_buffer_usedlength(target) -
|
||||
isc_buffer_usedlength(&sb);
|
||||
RETERR(svcb_validate(sbpr[i].value, &keyregion));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,11 @@ size_t
|
||||
strlcat(char *dst, const char *src, size_t size);
|
||||
#endif /* if !defined(HAVE_STRLCAT) */
|
||||
|
||||
#if !defined(HAVE_STRNSTR)
|
||||
char *
|
||||
strnstr(const char *s, const char *find, size_t slen);
|
||||
#endif /* if !defined(HAVE_STRNSTR) */
|
||||
|
||||
int
|
||||
isc_string_strerror_r(int errnum, char *buf, size_t buflen);
|
||||
|
||||
|
@@ -12,9 +12,15 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -109,6 +115,28 @@ strlcat(char *dst, const char *src, size_t size) {
|
||||
}
|
||||
#endif /* !defined(HAVE_STRLCAT) */
|
||||
|
||||
#if !defined(HAVE_STRNSTR)
|
||||
char *
|
||||
strnstr(const char *s, const char *find, size_t slen) {
|
||||
char c, sc;
|
||||
size_t len;
|
||||
|
||||
if ((c = *find++) != '\0') {
|
||||
len = strlen(find);
|
||||
do {
|
||||
do {
|
||||
if (slen-- < 1 || (sc = *s++) == '\0')
|
||||
return (NULL);
|
||||
} while (sc != c);
|
||||
if (len > slen)
|
||||
return (NULL);
|
||||
} while (strncmp(s, find, len) != 0);
|
||||
s--;
|
||||
}
|
||||
return ((char *)s);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
isc_string_strerror_r(int errnum, char *buf, size_t buflen) {
|
||||
return (strerror_r(errnum, buf, buflen));
|
||||
|
@@ -2463,7 +2463,7 @@ ISC_RUN_TEST_IMPL(wks) {
|
||||
ISC_RUN_TEST_IMPL(https_svcb) {
|
||||
/*
|
||||
* Known keys: mandatory, apln, no-default-alpn, port,
|
||||
* ipv4hint, port, ipv6hint.
|
||||
* ipv4hint, port, ipv6hint, dohpath.
|
||||
*/
|
||||
text_ok_t text_ok[] = {
|
||||
/* unknown key invalid */
|
||||
@@ -2482,9 +2482,9 @@ ISC_RUN_TEST_IMPL(https_svcb) {
|
||||
TEXT_INVALID("2 svc.example.net. key=\"2222\""),
|
||||
/* zero pad invalid */
|
||||
TEXT_INVALID("2 svc.example.net. key07=\"2222\""),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key7=\"2222\""),
|
||||
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. key7=2222",
|
||||
"2 svc.example.net. key7=\"2222\""),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key8=\"2222\""),
|
||||
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. key8=2222",
|
||||
"2 svc.example.net. key8=\"2222\""),
|
||||
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h2",
|
||||
"2 svc.example.net. alpn=\"h2\""),
|
||||
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h3",
|
||||
@@ -2512,12 +2512,12 @@ ISC_RUN_TEST_IMPL(https_svcb) {
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. ech=abcdefghijkl"),
|
||||
/* bad base64 */
|
||||
TEXT_INVALID("2 svc.example.net. ech=abcdefghijklm"),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key7=\"2222\""),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key8=\"2222\""),
|
||||
/* Out of key order on input (alpn == key1). */
|
||||
TEXT_VALID_LOOPCHG(2,
|
||||
"2 svc.example.net. key7=\"2222\" alpn=h2",
|
||||
"2 svc.example.net. key8=\"2222\" alpn=h2",
|
||||
"2 svc.example.net. alpn=\"h2\" "
|
||||
"key7=\"2222\""),
|
||||
"key8=\"2222\""),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key65535=\"2222\""),
|
||||
TEXT_INVALID("2 svc.example.net. key65536=\"2222\""),
|
||||
TEXT_VALID_LOOP(1, "2 svc.example.net. key10"),
|
||||
@@ -2548,18 +2548,18 @@ ISC_RUN_TEST_IMPL(https_svcb) {
|
||||
TEXT_INVALID("2 svc.example.net. "
|
||||
"mandatory=alpn,,port alpn=h2 port=433"),
|
||||
/* mandatory w/ unknown key values */
|
||||
TEXT_VALID_LOOP(2, "2 svc.example.net. mandatory=key7 key7"),
|
||||
TEXT_VALID_LOOP(3, "2 svc.example.net. mandatory=key7,key8 "
|
||||
"key7 key8"),
|
||||
TEXT_VALID_LOOP(2, "2 svc.example.net. mandatory=key8 key8"),
|
||||
TEXT_VALID_LOOP(3, "2 svc.example.net. mandatory=key8,key9 "
|
||||
"key8 key9"),
|
||||
TEXT_VALID_LOOPCHG(
|
||||
3, "2 svc.example.net. mandatory=key8,key7 key7 key8",
|
||||
"2 svc.example.net. mandatory=key7,key8 key7 key8"),
|
||||
3, "2 svc.example.net. mandatory=key9,key8 key8 key9",
|
||||
"2 svc.example.net. mandatory=key8,key9 key8 key9"),
|
||||
TEXT_INVALID("2 svc.example.net. "
|
||||
"mandatory=key7,key7"),
|
||||
TEXT_INVALID("2 svc.example.net. mandatory=,key7"),
|
||||
TEXT_INVALID("2 svc.example.net. mandatory=key7,"),
|
||||
"mandatory=key8,key8"),
|
||||
TEXT_INVALID("2 svc.example.net. mandatory=,key8"),
|
||||
TEXT_INVALID("2 svc.example.net. mandatory=key8,"),
|
||||
TEXT_INVALID("2 svc.example.net. "
|
||||
"mandatory=key7,,key7"),
|
||||
"mandatory=key8,,key8"),
|
||||
/* Invalid test vectors */
|
||||
TEXT_INVALID("1 foo.example.com. ( key123=abc key123=def )"),
|
||||
TEXT_INVALID("1 foo.example.com. mandatory"),
|
||||
@@ -2572,6 +2572,14 @@ ISC_RUN_TEST_IMPL(https_svcb) {
|
||||
TEXT_INVALID("1 foo.example.com. mandatory=mandatory"),
|
||||
TEXT_INVALID("1 foo.example.com. ( mandatory=key123,key123 "
|
||||
"key123=abc)"),
|
||||
/* dohpath tests */
|
||||
TEXT_VALID_LOOPCHG(1, "1 example.net. dohpath=/{?dns}",
|
||||
"1 example.net. key7=\"/{?dns}\""),
|
||||
TEXT_VALID_LOOPCHG(1, "1 example.net. dohpath=/some/path{?dns}",
|
||||
"1 example.net. key7=\"/some/path{?dns}\""),
|
||||
TEXT_INVALID("1 example.com. dohpath=no-slash"),
|
||||
TEXT_INVALID("1 example.com. dohpath=/{?notdns}"),
|
||||
TEXT_INVALID("1 example.com. dohpath=/notvariable"),
|
||||
TEXT_SENTINEL()
|
||||
|
||||
};
|
||||
|
Reference in New Issue
Block a user