]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
push markup buffer to proto_dns, too
authorAlan T. DeKok <aland@freeradius.org>
Tue, 12 Oct 2021 20:12:43 +0000 (16:12 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 12 Oct 2021 20:12:43 +0000 (16:12 -0400)
src/lib/util/dns.c
src/lib/util/dns.h
src/listen/dns/proto_dns.c
src/protocols/dns/decode.c
src/protocols/dns/encode.c

index b6e487a7a6cbd3975b646ab579e24668351d27a7..67e5f1aa2b5903f708f86f00fdaf2dadcaec0ed9 100644 (file)
@@ -30,16 +30,19 @@ RCSID("$Id$")
 #include <freeradius-devel/util/dns.h>
 #include <freeradius-devel/util/proto.h>
 
-fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, int max_labels)
+fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, int max_labels)
 {
        fr_dns_labels_t *lb;
 
+       if (max_labels <= 0) max_labels = 0;
+
        lb = (fr_dns_labels_t *) talloc_zero_array(ctx, uint8_t, sizeof(fr_dns_labels_t) + sizeof(lb->blocks[0]) * max_labels);
        if (!lb) return NULL;
 
        talloc_set_name_const(lb, "fr_dns_labels_t");
 
        lb->start = packet;
+       lb->end = packet + packet_len;
        lb->max = max_labels;
 
        /*
@@ -77,6 +80,11 @@ static int dns_label_add(fr_dns_labels_t *lb, uint8_t const *start, uint8_t cons
         */
        if ((offset + size) >= MAX_OFFSET) return 0;
 
+       /*
+        *      We're not tracking labels, so don't do anything.
+        */
+       if (lb->max == 1) return 0;
+
        FR_PROTO_TRACE("adding label at offset %zu", offset);
 
        /*
@@ -132,6 +140,9 @@ static bool dns_pointer_valid(fr_dns_labels_t *lb, uint16_t offset)
 
        if (lb->mark) return (lb->mark[offset] != 0);
 
+       /*
+        *      Brute-force searching.
+        */
        for (i = 0; i < lb->num; i++) {
                FR_PROTO_TRACE("Checking block %d %u..%u against %u",
                               i, lb->blocks[i].start, lb->blocks[i].end, offset);
@@ -1076,6 +1087,9 @@ ssize_t fr_dns_label_uncompressed_length(uint8_t const *packet, uint8_t const *b
                 */
                if ((p + *p + 1) > end) goto overflow;
 
+               /*
+                *      It's a valid label.  Mark it as such.
+                */
                dns_label_mark(lb, p);
 
                /*
@@ -1124,7 +1138,10 @@ ssize_t fr_dns_label_uncompressed_length(uint8_t const *packet, uint8_t const *b
         */
        if (!already_set_next) *next = p; /* should be <='end' */
 
-       (void) dns_label_add(lb, start, *next);
+       /*
+        *      Add the label, only if we're not using the markup field.
+        */
+       if (lb && !lb->mark) (void) dns_label_add(lb, start, *next);
 
        return length;
 }
index f639c156f2e2d2dae6cafaa8fed955fd699f1980..5bb03058b7d8e9a6f3dec3ce0d73a8a0ec4d9d75 100644 (file)
@@ -53,7 +53,7 @@ ssize_t               fr_dns_label_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *dst,
                                            uint8_t const *src, size_t len, uint8_t const *label,
                                            bool tainted, fr_dns_labels_t *lb);
 
-fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, int max_labels) CC_HINT(nonnull);
+fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, int max_labels) CC_HINT(nonnull);
 
 #ifdef __cplusplus
 }
index 3d5f83687e828234d1573d140af69b7306f5734f..c732b1f001d5a95a2c7415016cd0594e4af5868c 100644 (file)
@@ -198,9 +198,9 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d
        packet_ctx.packet = request->packet->data;
        packet_ctx.packet_len = data_len;
 
-       packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, packet_ctx.packet, 256);
+       packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, packet_ctx.packet, data_len, 0);
        fr_assert(packet_ctx.lb != NULL);
-
+       packet_ctx.lb->mark = talloc_zero_array(packet_ctx.lb, uint8_t, data_len);
 
        /*
         *      Note that we don't set a limit on max_attributes here.
@@ -270,8 +270,9 @@ static ssize_t mod_encode(void const *instance, request_t *request, uint8_t *buf
        packet_ctx.packet = buffer;
        packet_ctx.packet_len = buffer_len;
 
-       packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, buffer, 256);
+       packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, buffer, buffer_len, 256);
        fr_assert(packet_ctx.lb != NULL);
+       /* no need to set "mark" here, as that field is only used for decoding */
 
        data_len = fr_dns_encode(&FR_DBUFF_TMP(buffer, buffer_len), &request->reply_pairs, &packet_ctx);
        talloc_free(packet_ctx.tmp_ctx);
index 6ec8c9a0280108ac302ebb643ae705dd46faede2..ea2154d22d05e7719fd9689df256a74a26036c3d 100644 (file)
@@ -689,6 +689,7 @@ static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t
                fr_dns_labels_t *lb = packet_ctx->lb;
 
                lb->start = data;
+               lb->end = data + data_len;
 
                /*
                 *      Always skip the DNS packet header.
@@ -699,7 +700,7 @@ static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t
 
                memset(packet_ctx->lb->mark, 0, talloc_array_length(packet_ctx->lb->mark));
        } else {
-               packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, 256);
+               packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, data_len, 256);
                fr_assert(packet_ctx->lb != NULL);
 
                packet_ctx->lb->end = data + data_len;
index 16615312a5f9725d4953eff4db498bea8c89ede9..a7736446d9095b3668ee30fedc4b1828a5a0b6fe 100644 (file)
@@ -705,7 +705,7 @@ static ssize_t fr_dns_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps,
        packet_ctx->packet = data;
        packet_ctx->packet_len = data_len;
 
-       packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, 256);
+       packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, data_len, 256);
        fr_assert(packet_ctx->lb != NULL);
 
        slen = fr_dns_encode(&FR_DBUFF_TMP(data, data_len), vps, packet_ctx);