From: Alan T. DeKok Date: Fri, 9 Apr 2021 13:51:32 +0000 (-0400) Subject: respect the "concat" flag when decoding TLVs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=650c75a68bd73f4b09e87dd77f62f812c31aca96;p=thirdparty%2Ffreeradius-server.git respect the "concat" flag when decoding TLVs and add digest tests for the same. --- diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 0f42517c419..290d5c97f02 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -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; } diff --git a/src/tests/unit/protocols/radius/digest.txt b/src/tests/unit/protocols/radius/digest.txt index 0c89cfa9c2c..09e3809fa35 100644 --- a/src/tests/unit/protocols/radius/digest.txt +++ b/src/tests/unit/protocols/radius/digest.txt @@ -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