]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
respect the "concat" flag when decoding TLVs
authorAlan T. DeKok <aland@freeradius.org>
Fri, 9 Apr 2021 13:51:32 +0000 (09:51 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 12 Apr 2021 21:26:55 +0000 (17:26 -0400)
and add digest tests for the same.

src/protocols/radius/decode.c
src/tests/unit/protocols/radius/digest.txt

index 0f42517c41965db7ed5bdcdd31e4b2788a2fa000..290d5c97f025f675b976fcf2e1e2ac116b49f8e7 100644 (file)
@@ -421,6 +421,8 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co
        fr_dict_attr_t const    *child;
        fr_pair_list_t          head;
        fr_dcursor_t            tlv_cursor;
+       fr_pair_t               *vp;
+       bool                    concat;
 
        fr_pair_list_init(&head);
        if (data_len < 3) return -1; /* type, length, value */
@@ -433,6 +435,20 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co
 
        if (fr_radius_decode_tlv_ok(p, data_len, 1, 1) < 0) return -1;
 
+       /*
+        *      We don't have a "pair find in cursor"
+        */
+       if (flag_concat(&parent->flags)) {
+               vp = fr_pair_find_by_da(fr_pair_list_from_dcursor(cursor), parent);
+               concat = (vp != NULL);
+       } else {
+               vp = NULL;
+               concat = false;
+       }
+
+       if (!vp) vp = fr_pair_afrom_da(ctx, parent);
+       if (!vp) return PAIR_DECODE_OOM;
+
        /*
         *  Record where we were in the list when this function was called
         */
@@ -450,21 +466,21 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co
                        child = fr_dict_unknown_attr_afrom_num(packet_ctx->tmp_ctx, parent, p[0]);
                        if (!child) {
                        error:
-                               fr_pair_list_free(&head);
+                               if (!concat) talloc_free(vp);
                                return -1;
                        }
                }
                FR_PROTO_TRACE("decode context changed %s -> %s", parent->name, child->name);
 
-               tlv_len = fr_radius_decode_pair_value(ctx, &tlv_cursor, dict,
+               tlv_len = fr_radius_decode_pair_value(vp, &tlv_cursor, dict,
                                                      child, p + 2, p[1] - 2, p[1] - 2,
                                                      packet_ctx);
                if (tlv_len < 0) goto error;
                p += p[1];
        }
-       fr_dcursor_head(&tlv_cursor);
-       fr_dcursor_tail(cursor);
-       fr_dcursor_merge(cursor, &tlv_cursor);  /* Wind to the end of the new pairs */
+
+       fr_pair_list_append(&vp->vp_group, &head);
+       if (!concat) fr_dcursor_append(cursor, vp);
 
        return data_len;
 }
index 0c89cfa9c2c648de818f2b2d71286bda0e6396fe..09e3809fa356699095b545e4b70dd77adc3b445f 100644 (file)
@@ -10,5 +10,27 @@ match cf 72 01 0c 62 69 6c 6f 78 69 2e 63 6f 6d 02 24 64 63 64 39 38 62 37 31 30
 decode-pair -
 match Digest-Attributes = { Realm = "biloxi.com", Nonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093", Method = "INVITE", URI = "sip:bob@biloxi.com", User-Name = "bob", QOP = "auth", Algorithm = "MD5", Nonce-Count = "00000001", CNonce = "0a4f113b" }
 
+encode-pair Digest-Attributes = { Realm = "biloxi.com" }
+match cf 0e 01 0c 62 69 6c 6f 78 69 2e 63 6f 6d
+
+encode-pair Digest-Attributes = { User-Name = "bob" }
+match cf 07 0a 05 62 6f 62
+
+#
+#  The two previous things, concatenated as attributes.
+#
+#  The Digest-Attributes dictionary entry is marked "concat",
+#  so the decoder MUST create one Digest-Attributes VP, instead of two.
+#
+decode-pair cf 0e 01 0c 62 69 6c 6f 78 69 2e 63 6f 6d cf 07 0a 05 62 6f 62
+match Digest-Attributes = { Realm = "biloxi.com", User-Name = "bob" }
+
+#
+#  And on encoding it, we mash everything together.
+#
+encode-pair -
+match cf 13 01 0c 62 69 6c 6f 78 69 2e 63 6f 6d 0a 05 62 6f 62
+
+
 count
 match 6