add dohpath parsing

This commit is contained in:
TCY16 2022-08-15 14:36:35 +02:00
parent 14fe4669e7
commit 6e31d1f5be
3 changed files with 77 additions and 3 deletions

View file

@ -1150,6 +1150,11 @@ sldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
return SVCB_KEY_IPV6HINT;
break;
case sizeof("dohpath")-1:
if (!strncmp(key, "dohpath", sizeof("dohpath")-1))
return SVCB_KEY_DOHPATH;
break;
case sizeof("ech")-1:
if (!strncmp(key, "ech", sizeof("ech")-1))
return SVCB_KEY_ECH;
@ -1515,6 +1520,40 @@ sldns_str2wire_svcbparam_alpn_value(const char* val,
return LDNS_WIREPARSE_ERR_OK;
}
static int
sldns_str2wire_svcbparam_dohpath_value(const char* val,
uint8_t* rd, size_t* rd_len)
{
size_t val_len;
/* RFC6570#section-2.1
* "The characters outside of expressions in a URI Template string are
* intended to be copied literally"
* Practically this means we do not have to look for "double escapes"
* like in the alpn value list.
*/
val_len = strlen(val);
if (*rd_len < 4 + val_len) {
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
}
/* draft-ietf-add-svcb-dns-06#section-5.1
* The URI Template MUST contain a "dns" variable
*/
if (!(strstr(val, "?dns"))) {
return LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH;
}
sldns_write_uint16(rd, SVCB_KEY_DOHPATH);
sldns_write_uint16(rd + 2, val_len);
memcpy(rd + 4, val, val_len);
*rd_len = 4 + val_len;
return LDNS_WIREPARSE_ERR_OK;
}
static int
sldns_str2wire_svcparam_value(const char *key, size_t key_len,
const char *val, uint8_t* rd, size_t* rd_len)
@ -1535,6 +1574,7 @@ sldns_str2wire_svcparam_value(const char *key, size_t key_len,
case SVCB_KEY_PORT:
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
case SVCB_KEY_DOHPATH:
return LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
#endif
default:
@ -1566,6 +1606,8 @@ sldns_str2wire_svcparam_value(const char *key, size_t key_len,
return sldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
case SVCB_KEY_ALPN:
return sldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
case SVCB_KEY_DOHPATH:
return sldns_str2wire_svcbparam_dohpath_value(val, rd, rd_len);
default:
str_len = strlen(val);
if (*rd_len < 4 + str_len)

View file

@ -38,7 +38,8 @@ struct sldns_struct_lookup_table;
#define SVCB_KEY_IPV4HINT 4
#define SVCB_KEY_ECH 5
#define SVCB_KEY_IPV6HINT 6
#define SVCPARAMKEY_COUNT 7
#define SVCB_KEY_DOHPATH 7
#define SVCPARAMKEY_COUNT 8
#define MAX_NUMBER_OF_SVCPARAMS 64
@ -234,7 +235,9 @@ uint8_t* sldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
#define LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES 383
#define LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE 384
#define LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
#define LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH 386
#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 387
/**
* Get reference to a constant string for the (parse) error.

View file

@ -171,6 +171,8 @@ static sldns_lookup_table sldns_wireparse_errors_data[] = {
"Alpn strings need to be smaller than 255 chars"},
{ LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE,
"No-default-alpn should not have a value" },
{ LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH,
"Dohpath must have '?dns' in the URI template variable" },
{ LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA,
"General SVCParam error" },
{ 0, NULL }
@ -224,7 +226,7 @@ sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
const char *svcparamkey_strs[] = {
"mandatory", "alpn", "no-default-alpn", "port",
"ipv4hint", "ech", "ipv6hint"
"ipv4hint", "ech", "ipv6hint", "dohpath"
};
char* sldns_wire2str_pkt(uint8_t* data, size_t len)
@ -1144,6 +1146,29 @@ static int sldns_wire2str_svcparam_ech2str(char** s,
return w + size;
}
static int sldns_wire2str_svcparam_dohpath2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
int w = 0;
uint16_t i;
assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */
w += sldns_str_print(s, slen, "=\"");
/* RC6570#section-2.1 specifies that the '\' (and other non-letter
* characters in the URI) are "intended to be copied literally" */
for (i = 0; i < data_len; i++) {
// @TODO do a check like isprint()?
w += sldns_str_print(s, slen, "%c", data[i]);
}
w += sldns_str_print(s, slen, "\"");
return w;
}
int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
{
uint8_t ch;
@ -1174,6 +1199,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
case SVCB_KEY_MANDATORY:
case SVCB_KEY_DOHPATH:
return -1;
default:
return written_chars;
@ -1201,6 +1227,9 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
case SVCB_KEY_ECH:
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
break;
case SVCB_KEY_DOHPATH:
r = sldns_wire2str_svcparam_dohpath2str(s, slen, data_len, *d);
break;
default:
r = sldns_str_print(s, slen, "=\"");