]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow the RADIUS encoder to encode nested TLVs
authorAlan T. DeKok <aland@freeradius.org>
Wed, 7 Apr 2021 15:09:39 +0000 (11:09 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 8 Apr 2021 11:55:45 +0000 (07:55 -0400)
and add test case for the same.

src/protocols/radius/encode.c
src/tests/unit/protocols/radius/unit.txt

index 4e1c647e0b6fd0566bad1c9884da91f1d27c626f..fe9397e97c70da98bf27bb954704b1ffd57791ff 100644 (file)
@@ -256,8 +256,27 @@ static ssize_t encode_tlv_hdr_internal(fr_dbuff_t *dbuff,
                /*
                 *      Determine the nested type and call the appropriate encoder
                 */
-               if (da_stack->da[depth + 1]->type == FR_TYPE_TLV) {
+               if (!da_stack->da[depth + 1]) {
+                       fr_dcursor_t child_cursor;
+
+                       if (vp->da != da_stack->da[depth]) {
+                               fr_strerror_printf("%s: Can't encode empty TLV", __FUNCTION__);
+                               return PAIR_ENCODE_SKIPPED;
+                       }
+
+                       fr_dcursor_init(&child_cursor, &vp->vp_group);
+                       vp = fr_dcursor_current(&child_cursor);
+                       fr_proto_da_stack_build(da_stack, vp->da);
+
+                       slen = encode_tlv_hdr_internal(&FR_DBUFF_MAX(&work_dbuff, 253), da_stack, depth, &child_cursor, encode_ctx);
+                       if (slen <= 0) return slen;
+
+                       vp = fr_dcursor_next(cursor);
+                       fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
+
+               } else if (da_stack->da[depth + 1]->type == FR_TYPE_TLV) {
                        slen = encode_tlv_hdr(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx);
+
                } else {
                        slen = encode_rfc_hdr_internal(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx);
                }
@@ -298,11 +317,6 @@ static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff,
                return PAIR_ENCODE_FATAL_ERROR;
        }
 
-       if (!da_stack->da[depth + 1]) {
-               fr_strerror_printf("%s: Can't encode empty TLV", __FUNCTION__);
-               return PAIR_ENCODE_SKIPPED;
-       }
-
        /*
         *      Encode the first level of TLVs
         */
index 666edd6d14991550533d40fe7d74b02e03861373..dde21f5bd6999fbc490a9328950ac1c8142bf6f3 100644 (file)
@@ -88,5 +88,14 @@ match fe 08 03 06 00 00 00 0a
 decode-pair -
 match Unit-TLV.Delta-Sec = 10
 
+#
+#  Allow encoding as nested VPs
+#
+encode-pair Unit-TLV.Milliseconds = 1
+match fe 08 01 06 00 00 00 01
+
+encode-pair Unit-TLV = { Milliseconds = 1 }
+match fe 08 01 06 00 00 00 01
+
 count
-match 44
+match 48