Skip to content

Commit

Permalink
decode multiple DNS labels for the tests
Browse files Browse the repository at this point in the history
and fix issues with the decoder.
  • Loading branch information
alandekok committed Oct 20, 2019
1 parent 72c783d commit 81a212a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 31 deletions.
52 changes: 36 additions & 16 deletions src/bin/unit_test_attribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,32 +1301,52 @@ static size_t command_decode_dns_label(command_result_t *result, UNUSED command_
char *data, UNUSED size_t data_used, char *in, size_t inlen)
{
size_t len;
ssize_t slen;
ssize_t slen, total, i;
uint8_t dns_label[1024];
char *out, *end;
fr_value_box_t *box = talloc_zero(NULL, fr_value_box_t);

/*
* Decode hex from input text
*/
slen = hex_to_bin(dns_label, sizeof(dns_label), in, inlen);
if (slen <= 0) RETURN_PARSE_ERROR(-(slen));
total = hex_to_bin(dns_label, sizeof(dns_label), in, inlen);
if (total <= 0) RETURN_PARSE_ERROR(-total);

/*
* @todo - decode multiple labels, and print them with commas separating them.
*/
slen = fr_value_box_from_dns_label(box, box, dns_label, slen, dns_label, false);
if (slen < 0) {
talloc_free(box);
RETURN_OK_WITH_ERROR();
out = data;
end = data + COMMAND_OUTPUT_MAX;

for (i = 0; i < total; i += slen) {
slen = fr_value_box_from_dns_label(box, box, dns_label, total, dns_label + i, false);
if (slen < 0) {
talloc_free(box);
RETURN_OK_WITH_ERROR();
}

/*
* Separate names by commas
*/
if (i > 0) *(out++) = ',';

/*
* As a special case, print '.' if there is no label
*/
if (box->vb_length == 0) {
*(out++) = '.';
*out = '\0';

} else {
/*
* We don't print it with quotes.
*/
len = fr_value_box_snprint(out, end - out, box, '\0');
out += len;
}

fr_value_box_clear(box);
}

/*
* We don't print it with quotes.
*/
len = fr_value_box_snprint(data, COMMAND_OUTPUT_MAX, box, '\0');
talloc_free(box);

RETURN_OK(len);
RETURN_OK(out - data);
}

static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc,
Expand Down
44 changes: 31 additions & 13 deletions src/lib/util/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,19 @@ ssize_t fr_dns_label_length(uint8_t const *buf, size_t buf_len, uint8_t const **
* We silently accept labels *without* a trailing 0x00,
* so long as they end at the end of the input buffer.
*/
while (*p != 0x00) {
while (p < end) {
/*
* End of label byte. Skip it.
*
* If necessary, also tell the caller to skip
* over it, too.
*/
if (*p == 0x00) {
p++;
if (at_first_label) length++;
break;
}

/*
* Maybe it's a compression pointer.
*/
Expand Down Expand Up @@ -1776,9 +1788,11 @@ ssize_t fr_dns_labels_network_verify(uint8_t const *buf, size_t buf_len)
return buf_len;
}

static ssize_t dns_label_decode(uint8_t const *buf, uint8_t const *label, uint8_t const **next)
static ssize_t dns_label_decode(uint8_t const *buf, uint8_t const **p_label, uint8_t const **next)
{
uint8_t const *p = label;
uint8_t const *p;

p = *p_label;

if (*p == 0x00) {
*next = p + 1;
Expand All @@ -1798,6 +1812,7 @@ static ssize_t dns_label_decode(uint8_t const *buf, uint8_t const *label, uint8_
p = buf + offset;
}

*p_label = p;
*next = p + *p + 1;
return *p;
}
Expand Down Expand Up @@ -1835,26 +1850,29 @@ ssize_t fr_value_box_from_dns_label(TALLOC_CTX *ctx, fr_value_box_t *dst,
* label after this one.
*/
slen = fr_dns_label_length(src, len, &after);
if (slen < 0) return slen;
if (slen <= 0) return slen;

/*
* Allocate the string and set up the value_box
*/
dst->vb_strvalue = q = talloc_zero_array(ctx, char, slen + 1);
dst->datum.length = slen;
dst->type = FR_TYPE_STRING;
dst->tainted = tainted;
dst->enumv = NULL;
dst->next = NULL;

/*
* An empty label, just create an empty string.
* An empty label is a 0x00 byte. Just create an empty
* string.
*/
if (slen == 0) {
*q = '\0';
if (slen == 1) {
dst->vb_strvalue = talloc_zero_array(ctx, char, 1);
dst->datum.length = 0;
return after - label;
}

/*
* Allocate the string and set up the value_box
*/
dst->vb_strvalue = q = talloc_array(ctx, char, slen + 1);
dst->datum.length = slen;

current = label;
p = (uint8_t *) q;
q += slen;
Expand All @@ -1864,7 +1882,7 @@ ssize_t fr_value_box_from_dns_label(TALLOC_CTX *ctx, fr_value_box_t *dst,
* Get how many bytes this label has, and where
* we will go to obtain the next label.
*/
slen = dns_label_decode(src, current, &next);
slen = dns_label_decode(src, &current, &next);
if (slen < 0) {
fail:
fr_value_box_clear(dst);
Expand Down
13 changes: 11 additions & 2 deletions src/tests/unit/data_types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,23 @@ match foo.com
encode-dns-label foo.com,b.ca
match 03 66 6f 6f 03 63 6f 6d 00 01 62 02 63 61 00

decode-dns-label -
match foo.com,b.ca

# root gets encoded as a plain 0.
encode-dns-label .
match 00

decode-dns-label -
match .

# From RFC 1035 Section 4.1.4
encode-dns-label F.ISI.ARPA,FOO.F.ISI.ARPA, ARPA, .
encode-dns-label F.ISI.ARPA,FOO.F.ISI.ARPA,ARPA,.
match 01 46 03 49 53 49 04 41 52 50 41 00 03 46 4f 4f c0 00 c0 06 00

decode-dns-label -
match F.ISI.ARPA,FOO.F.ISI.ARPA,ARPA,.


count
match 52
match 58

0 comments on commit 81a212a

Please sign in to comment.