]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add foreign encoders for RADIUS
authorAlan T. DeKok <aland@freeradius.org>
Thu, 25 Jan 2024 17:03:37 +0000 (12:03 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 25 Jan 2024 17:03:37 +0000 (12:03 -0500)
src/protocols/radius/base.c
src/protocols/radius/decode.c
src/protocols/radius/encode.c
src/protocols/radius/radius.h

index 229db60fca0a8e4f6865d1bef472c9cd91c478a7..52c20a93018823fccdc993117ec6638a3a75849b 100644 (file)
@@ -1015,7 +1015,6 @@ ssize_t   fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
                        break;
 
                default:
-               no_vector:
                        fr_strerror_const("No authentication vector passed for packet decode");
                        return -1;
                }
@@ -1328,4 +1327,6 @@ fr_dict_protocol_t libfreeradius_radius_dict_protocol = {
        .subtype_table = subtype_table,
        .subtype_table_len = NUM_ELEMENTS(subtype_table),
        .attr_valid = attr_valid,
+       .decode = fr_radius_decode_foreign,
+       .encode = fr_radius_encode_foreign,
 };
index 238581d2ee6ec64f0c2648fe3a9c316aae0b10ff..6aaf3116627b47fc892deacb41184b761832e009 100644 (file)
@@ -2044,6 +2044,47 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out,
        return 2 + ret;
 }
 
+ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                                uint8_t const *data, size_t data_len)
+{
+       ssize_t slen;
+       uint8_t const *attr, *end;
+
+       fr_radius_ctx_t common_ctx = {};
+       fr_radius_decode_ctx_t decode_ctx = {
+               .common = &common_ctx,
+               .tmp_ctx = talloc(ctx, uint8_t),
+               .end = data + data_len,
+       };
+
+       attr = data;
+       end = decode_ctx.end;
+
+       while (attr < end) {
+               slen = fr_radius_decode_pair(ctx, out, attr, (end - attr), &decode_ctx);
+               if (slen < 0) {
+                       talloc_free(decode_ctx.tmp_ctx);
+                       return slen - (attr - data);
+               }
+
+               /*
+                *      If slen is larger than the room in the packet,
+                *      all kinds of bad things happen.
+                */
+                if (!fr_cond_assert(slen <= (end - attr))) {
+                       talloc_free(decode_ctx.tmp_ctx);
+                        return -slen - (attr - data);
+                }
+
+               attr += slen;
+               talloc_free_children(decode_ctx.tmp_ctx);
+       }
+
+       talloc_free(decode_ctx.tmp_ctx);
+       return data_len;
+}
+
+
 static int _test_ctx_free(fr_radius_decode_ctx_t *ctx)
 {
        TALLOC_FREE(ctx->tags);
index e43c53bdb190fc6aee9eca5a0ed8ed645d4db49f..da9f4614d1516c6877a567b493b1625bdbf366a9 100644 (file)
@@ -290,7 +290,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff,
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
-static ssize_t encode_tags(fr_dbuff_t *dbuff, fr_pair_list_t const *vps, void *encode_ctx)
+static ssize_t encode_pairs(fr_dbuff_t *dbuff, fr_pair_list_t const *vps, void *encode_ctx)
 {
        ssize_t                 slen;
        fr_pair_t const *vp;
@@ -1521,7 +1521,7 @@ ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *enc
                fr_assert(packet_ctx->tag < 0x20);
 
                // recurse to encode the children of this attribute
-               slen = encode_tags(&work_dbuff, &vp->vp_group, encode_ctx);
+               slen = encode_pairs(&work_dbuff, &vp->vp_group, encode_ctx);
                packet_ctx->tag = 0;
                if (slen < 0) return slen;
 
@@ -1652,6 +1652,26 @@ ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *enc
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
+ssize_t        fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t *list)
+{
+               fr_radius_ctx_t common_ctx = {};
+       fr_radius_encode_ctx_t encode_ctx = {
+               .common = &common_ctx,
+       };
+
+       /*
+        *      Just in case we need random numbers.
+        */
+       encode_ctx.rand_ctx.a = fr_rand();
+       encode_ctx.rand_ctx.b = fr_rand();
+
+       /*
+        *      Encode the pairs.
+        */
+       return encode_pairs(dbuff, list, &encode_ctx);
+}
+
+
 static int _test_ctx_free(UNUSED fr_radius_encode_ctx_t *ctx)
 {
        fr_radius_free();
index 9062e66544dc9996dc4a5eb1dd219be4f1dc9d18..8f3b0ff345ab10da5a685d3655a02797d09e00fe 100644 (file)
@@ -219,6 +219,8 @@ ssize_t             fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t dat
  */
 ssize_t                fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx);
 
+ssize_t                fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t *list) CC_HINT(nonnull);
+
 /*
  *     protocols/radius/decode.c
  */
@@ -236,3 +238,6 @@ ssize_t             fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list,
 
 ssize_t                fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list,
                                      uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);
+
+ssize_t                fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                                        uint8_t const *data, size_t data_len) CC_HINT(nonnull);