mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
add escaping
This commit is contained in:
parent
21413aed78
commit
eb0e029dda
@ -711,6 +711,18 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
|
||||
/* write rdata length */
|
||||
sldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10));
|
||||
*rr_len = rr_cur_len;
|
||||
/* SVCB/HTTPS handling */
|
||||
if (rr_type == LDNS_RR_TYPE_SVCB || rr_type == LDNS_RR_TYPE_HTTPS) {
|
||||
|
||||
|
||||
|
||||
// 1. Find the size
|
||||
// 2. qsort the data according to the keys
|
||||
// 3. verify that keys are unique
|
||||
// 4. verify that mandatory keys are present and unique
|
||||
|
||||
|
||||
}
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
@ -976,14 +988,17 @@ sldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
|
||||
if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
|
||||
return SVCB_KEY_IPV6HINT;
|
||||
break;
|
||||
|
||||
case sizeof("ech")-1:
|
||||
if (!strncmp(key, "ech", sizeof("ech")-1))
|
||||
return SVCB_KEY_ECH;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (key_len > sizeof(buf) - 1) {}
|
||||
|
||||
if (key_len > sizeof(buf) - 1) {}
|
||||
// ERROR: Unknown SvcParamKey
|
||||
else {
|
||||
memcpy(buf, key, key_len);
|
||||
@ -1286,7 +1301,6 @@ int sldns_str2wire_svcbparam_alpn_value(const char* val,
|
||||
size_t str_len;
|
||||
size_t dst_len;
|
||||
size_t val_len;
|
||||
int wire_len;
|
||||
|
||||
val_len = strlen(val);
|
||||
|
||||
@ -1328,8 +1342,28 @@ static int
|
||||
sldns_str2wire_svcparam_key_value(const char *key, size_t key_len,
|
||||
const char *val, uint8_t* rd, size_t* rd_len)
|
||||
{
|
||||
size_t str_len;
|
||||
uint16_t svcparamkey = sldns_str2wire_svcparam_key_lookup(key, key_len);
|
||||
|
||||
|
||||
// @TODO add case where svcparamkey == -1
|
||||
|
||||
/* key and no value case*/
|
||||
if (val == NULL) {
|
||||
sldns_write_uint16(rd, svcparamkey);
|
||||
sldns_write_uint16(rd + 2, 0);
|
||||
*rd_len = 4;
|
||||
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
// @TODO unescape characters in the value list
|
||||
|
||||
// if (val[0] == '"' && val[str_len - 1]) {
|
||||
|
||||
// }
|
||||
|
||||
/* value is non-empty */
|
||||
switch (svcparamkey) {
|
||||
case SVCB_KEY_PORT:
|
||||
return sldns_str2wire_svcparam_port(val, rd, rd_len);
|
||||
@ -1340,18 +1374,24 @@ sldns_str2wire_svcparam_key_value(const char *key, size_t key_len,
|
||||
case SVCB_KEY_MANDATORY:
|
||||
return sldns_str2wire_svcbparam_mandatory(val, rd, rd_len);
|
||||
case SVCB_KEY_NO_DEFAULT_ALPN:
|
||||
|
||||
// @TODO is this superfluous now?
|
||||
|
||||
return sldns_str2wire_svcbparam_no_default_alpn(val, rd, rd_len);
|
||||
// if(zone_is_slave(parser->current_zone->opts))
|
||||
// zc_warning_prev_line("no-default-alpn should not have a value");
|
||||
// else
|
||||
// zc_error_prev_line("no-default-alpn should not have a value");
|
||||
// break;
|
||||
case SVCB_KEY_ECH:
|
||||
return sldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
|
||||
case SVCB_KEY_ALPN:
|
||||
return sldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
|
||||
default:
|
||||
break;
|
||||
// @TODO escaping here -> copy from alpn?
|
||||
|
||||
str_len = strlen(val);
|
||||
sldns_write_uint16(rd, svcparamkey);
|
||||
sldns_write_uint16(rd + 2, str_len);
|
||||
memcpy(rd + 4, val, str_len);
|
||||
*rd_len = 4 + str_len;
|
||||
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
// @TODO change to error?
|
||||
@ -1360,18 +1400,35 @@ sldns_str2wire_svcparam_key_value(const char *key, size_t key_len,
|
||||
|
||||
int sldns_str2wire_svcparam_buf(const char* str, uint8_t* rd, size_t* rd_len)
|
||||
{
|
||||
size_t str_len;
|
||||
const char* eq_pos;
|
||||
|
||||
int ret;
|
||||
char unescaped_val[65536];
|
||||
char* val_out = unescaped_val;
|
||||
const char* val_in;
|
||||
|
||||
eq_pos = strchr(str, '=');
|
||||
|
||||
// @TODO handle "key=" case
|
||||
if (eq_pos != NULL && eq_pos[1]) { /* case: key=value */
|
||||
val_in = eq_pos + 1;
|
||||
|
||||
/* unescape characters and "" blocks */
|
||||
if (*val_in == '"') {
|
||||
val_in++;
|
||||
while (*val_in != '"' && sldns_parse_char( (uint8_t*) val_out, &val_in)) {
|
||||
val_out++;
|
||||
}
|
||||
} else {
|
||||
while ( sldns_parse_char( (uint8_t*) val_out, &val_in)) {
|
||||
val_out++;
|
||||
}
|
||||
}
|
||||
*val_out = 0;
|
||||
|
||||
/* Verify that we have a have a value */
|
||||
if (eq_pos != NULL) {
|
||||
return sldns_str2wire_svcparam_key_value(str, eq_pos - str, eq_pos + 1, rd, rd_len);
|
||||
} else {
|
||||
return sldns_str2wire_svcparam_key_value(str, eq_pos - str,
|
||||
unescaped_val[0] ? unescaped_val : NULL, rd, rd_len);
|
||||
} else if (eq_pos != NULL && !(eq_pos[1])) { /* case: key= */
|
||||
return sldns_str2wire_svcparam_key_value(str, eq_pos - str, NULL, rd, rd_len);
|
||||
} else { /* case: key */
|
||||
return sldns_str2wire_svcparam_key_value(str, strlen(str), NULL, rd, rd_len);
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
|
||||
/* draft-ietf-dnsop-svcb-https-04: 6. Initial SvcParamKeys */
|
||||
const char *svcparamkey_strs[] = {
|
||||
"mandatory", "alpn", "no-default-alpn", "port",
|
||||
"ipv4hint", "echconfig", "ipv6hint"
|
||||
"ipv4hint", "ech", "ipv6hint"
|
||||
};
|
||||
|
||||
char* sldns_wire2str_pkt(uint8_t* data, size_t len)
|
||||
@ -965,6 +965,8 @@ static int sldns_wire2str_svcparam_port2str(char** s,
|
||||
if (data_len != 2)
|
||||
return -1; /* wireformat error, a short is 2 bytes */
|
||||
w = sldns_str_print(s, slen, "=%d", (int)sldns_read_uint16(data));
|
||||
*data += 2;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@ -1117,9 +1119,10 @@ static int sldns_wire2str_svcparam_ech2str(char** s,
|
||||
|
||||
int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
|
||||
{
|
||||
char ch;
|
||||
uint16_t svcparamkey, data_len;
|
||||
int written_chars = 0;
|
||||
int r;
|
||||
int r, i;
|
||||
|
||||
/* verify that we have enough data to read svcparamkey and data_len */
|
||||
if(*dlen < 4)
|
||||
@ -1130,12 +1133,15 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
||||
*d += 4;
|
||||
*dlen -= 4;
|
||||
|
||||
// fprintf(stderr, "data_len: %hu\n", data_len);
|
||||
|
||||
/* verify that we have data_len data */
|
||||
if (data_len > *dlen)
|
||||
return -1;
|
||||
|
||||
written_chars += sldns_print_svcparamkey(s, slen, svcparamkey);
|
||||
if (!data_len) {
|
||||
|
||||
/* Some SvcParams MUST have values */
|
||||
switch (svcparamkey) {
|
||||
case SVCB_KEY_ALPN:
|
||||
@ -1143,11 +1149,12 @@ 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:
|
||||
return -1;
|
||||
return LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE;
|
||||
default:
|
||||
return written_chars;
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
switch (svcparamkey) {
|
||||
case SVCB_KEY_PORT:
|
||||
r = sldns_wire2str_svcparam_port2str(s, slen, data_len, *d);
|
||||
@ -1170,6 +1177,22 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
||||
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||
break;
|
||||
default:
|
||||
r += sldns_str_print(s, slen, "=\"");
|
||||
|
||||
for (i = 0; i < data_len; i++) {
|
||||
ch = (*d)[i];
|
||||
|
||||
if (ch == '"' || ch == '\\')
|
||||
r += sldns_str_print(s, slen, "\\%c", ch);
|
||||
|
||||
else if (!isprint(ch))
|
||||
r += sldns_str_print(s, slen, "\\%03u", (unsigned) ch);
|
||||
|
||||
else
|
||||
r += sldns_str_print(s, slen, "%c", ch);
|
||||
|
||||
}
|
||||
r += sldns_str_print(s, slen, "%c", '"');
|
||||
break;
|
||||
}
|
||||
if (r <= 0)
|
||||
|
Loading…
Reference in New Issue
Block a user