From: Alan T. DeKok Date: Thu, 25 Jan 2024 17:03:37 +0000 (-0500) Subject: add foreign encoders for RADIUS X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41169ebc8aabdac7121adfe6896f2ba493488f1a;p=thirdparty%2Ffreeradius-server.git add foreign encoders for RADIUS --- diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 229db60fca0..52c20a93018 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -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, }; diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 238581d2ee6..6aaf3116627 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -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); diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index e43c53bdb19..da9f4614d15 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -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(); diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 9062e66544d..8f3b0ff345a 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -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);