]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
split encode / decode context into two different fields
authorAlan T. DeKok <aland@freeradius.org>
Tue, 23 Jan 2024 16:22:55 +0000 (11:22 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 23 Jan 2024 16:22:55 +0000 (11:22 -0500)
and add a common context with secret, etc.

src/protocols/radius/base.c
src/protocols/radius/decode.c
src/protocols/radius/encode.c
src/protocols/radius/packet.c
src/protocols/radius/radius.h

index 6e8f7d0dc12c2631086c68b8c3e6079f739dec77..b4b6456ea3474125467a6cbef27cab828a0b971e 100644 (file)
@@ -862,16 +862,19 @@ static const bool disallow_tunnel_passwords[FR_RADIUS_CODE_MAX] = {
 };
 
 ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
-                        char const *secret, UNUSED size_t secret_len, int code, int id, fr_pair_list_t *vps)
+                        char const *secret, size_t secret_len, int code, int id, fr_pair_list_t *vps)
 {
        ssize_t                 slen;
        fr_pair_t const *vp;
        fr_dcursor_t            cursor;
-       fr_radius_ctx_t         packet_ctx;
+       fr_radius_ctx_t         common_ctx = {};
+       fr_radius_encode_ctx_t  packet_ctx = {};
        fr_dbuff_t              work_dbuff, length_dbuff;
 
-       memset(&packet_ctx, 0, sizeof(packet_ctx));
-       packet_ctx.secret = secret;
+       common_ctx.secret = secret;
+       common_ctx.secret_length = secret_len;
+
+       packet_ctx.common = &common_ctx;
        packet_ctx.rand_ctx.a = fr_rand();
        packet_ctx.rand_ctx.b = fr_rand();
        packet_ctx.disallow_tunnel_passwords = disallow_tunnel_passwords[code];
@@ -891,7 +894,7 @@ ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
                /*
                 *      Callers in these cases have preloaded the buffer with the authentication vector.
                 */
-               FR_DBUFF_OUT_MEMCPY_RETURN(packet_ctx.vector, &work_dbuff, sizeof(packet_ctx.vector));
+               FR_DBUFF_OUT_MEMCPY_RETURN(common_ctx.vector, &work_dbuff, sizeof(common_ctx.vector));
                break;
 
        case FR_RADIUS_CODE_ACCESS_REJECT:
@@ -907,8 +910,8 @@ ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
                        fr_strerror_const("Cannot encode response without request");
                        return -1;
                }
-               memcpy(packet_ctx.vector, original + 4, sizeof(packet_ctx.vector));
-               FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, packet_ctx.vector, RADIUS_AUTH_VECTOR_LENGTH);
+               memcpy(common_ctx.vector, original + 4, sizeof(common_ctx.vector));
+               FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, common_ctx.vector, RADIUS_AUTH_VECTOR_LENGTH);
                break;
 
        case FR_RADIUS_CODE_ACCOUNTING_REQUEST:
@@ -923,7 +926,7 @@ ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
                 *      to say "don't do that!"
                 */
        case FR_RADIUS_CODE_COA_REQUEST:
-               memset(packet_ctx.vector, 0, sizeof(packet_ctx.vector));
+               memset(common_ctx.vector, 0, sizeof(common_ctx.vector));
                FR_DBUFF_MEMSET_RETURN(&work_dbuff, 0, RADIUS_AUTH_VECTOR_LENGTH);
                break;
 
@@ -975,17 +978,20 @@ ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
  */
 ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
                         uint8_t const *packet, size_t packet_len, uint8_t const *original,
-                        char const *secret, UNUSED size_t secret_len)
+                        char const *secret, size_t secret_len)
 {
        ssize_t                 slen;
        uint8_t const           *attr, *end;
-       fr_radius_ctx_t         packet_ctx;
+       fr_radius_ctx_t         common_ctx = {};
+       fr_radius_decode_ctx_t  packet_ctx = {};
+
+       common_ctx.secret = secret;
+       common_ctx.secret_length = secret_len;
+       memcpy(common_ctx.vector, original ? original + 4 : packet + 4, sizeof(common_ctx.vector));
 
-       memset(&packet_ctx, 0, sizeof(packet_ctx));
+       packet_ctx.common = &common_ctx;
        packet_ctx.tmp_ctx = talloc_init_const("tmp");
-       packet_ctx.secret = secret;
        packet_ctx.end = packet + packet_len;
-       memcpy(packet_ctx.vector, original ? original + 4 : packet + 4, sizeof(packet_ctx.vector));
 
        attr = packet + 20;
        end = packet + packet_len;
index 47108a932061cd085fd48d8f9225974c7b92bd87..569a85e0a756d0d66111a0bd7b5ac33221f2e474 100644 (file)
@@ -433,7 +433,7 @@ static ssize_t decode_rfc(TALLOC_CTX *ctx, fr_pair_list_t *out,
        size_t                  len;
        ssize_t                 slen;
        fr_dict_attr_t const    *da;
-       fr_radius_ctx_t         *packet_ctx = decode_ctx;
+       fr_radius_decode_ctx_t  *packet_ctx = decode_ctx;
 
 #ifdef STATIC_ANALYZER
        if (!packet_ctx || !packet_ctx->tmp_ctx) return PAIR_DECODE_FATAL_ERROR;
@@ -496,7 +496,7 @@ static ssize_t decode_rfc(TALLOC_CTX *ctx, fr_pair_list_t *out,
  */
 static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                      fr_dict_attr_t const *parent, uint8_t const *data,
-                                     size_t const data_len, fr_radius_ctx_t *packet_ctx)
+                                     size_t const data_len, fr_radius_decode_ctx_t *packet_ctx)
 {
        uint8_t const   *ptr = data;
        uint8_t const   *end = data + data_len;
@@ -609,7 +609,7 @@ static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_pair_list_t *out,
  */
 static ssize_t decode_digest_attributes(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                        fr_dict_attr_t const *parent, uint8_t const *data,
-                                       size_t const data_len, fr_radius_ctx_t *packet_ctx)
+                                       size_t const data_len, fr_radius_decode_ctx_t *packet_ctx)
 {
        ssize_t slen;
        fr_pair_t *vp;
@@ -646,7 +646,7 @@ redo:
  */
 ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out,
                             fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len,
-                            fr_radius_ctx_t *packet_ctx)
+                            fr_radius_decode_ctx_t *packet_ctx)
 {
        uint8_t const           *p = data, *end = data + data_len;
        fr_dict_attr_t const    *child;
@@ -726,7 +726,7 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out,
 static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                   fr_dict_attr_t const *parent,
                                   uint8_t const *data, size_t data_len,
-                                  fr_radius_ctx_t *packet_ctx, fr_dict_vendor_t const *dv)
+                                  fr_radius_decode_ctx_t *packet_ctx, fr_dict_vendor_t const *dv)
 {
        unsigned int            attribute;
        ssize_t                 attrlen, my_len;
@@ -848,7 +848,7 @@ static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_pair_list_t *out,
 static ssize_t decode_extended_fragments(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                         fr_dict_attr_t const *parent,
                                         uint8_t const *data, size_t attr_len,
-                                        fr_radius_ctx_t *packet_ctx)
+                                        fr_radius_decode_ctx_t *packet_ctx)
 {
        ssize_t         ret;
        size_t          fraglen;
@@ -953,7 +953,7 @@ static ssize_t decode_extended_fragments(TALLOC_CTX *ctx, fr_pair_list_t *out,
 static ssize_t decode_extended(TALLOC_CTX *ctx, fr_pair_list_t *out,
                               fr_dict_attr_t const *da,
                               uint8_t const *data, UNUSED size_t data_len,
-                              fr_radius_ctx_t *packet_ctx)
+                              fr_radius_decode_ctx_t *packet_ctx)
 {
        ssize_t slen;
        fr_dict_attr_t const *child;
@@ -1035,7 +1035,7 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_pair_list_t *out,
 static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_pair_list_t *out,
                            fr_dict_attr_t const *parent,
                            uint8_t const *data, size_t attr_len,
-                           fr_radius_ctx_t *packet_ctx)
+                           fr_radius_decode_ctx_t *packet_ctx)
 {
        ssize_t                 ret;
        size_t                  wimax_len;
@@ -1276,7 +1276,7 @@ static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_pair_list_t *out,
 static ssize_t  CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                            fr_dict_attr_t const *parent,
                                            uint8_t const *data, size_t attr_len,
-                                           fr_radius_ctx_t *packet_ctx)
+                                           fr_radius_decode_ctx_t *packet_ctx)
 {
        size_t                  total;
        ssize_t                 ret;
@@ -1484,7 +1484,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
        fr_pair_t               *vp = NULL;
        uint8_t const           *p = data;
        uint8_t                 buffer[256];
-       fr_radius_ctx_t *packet_ctx = decode_ctx;
+       fr_radius_decode_ctx_t *packet_ctx = decode_ctx;
 
        if (attr_len > 128 * 1024) {
                fr_strerror_printf("%s: packet is too large to be RADIUS", __FUNCTION__);
@@ -1625,7 +1625,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
                 */
                case FLAG_ENCRYPT_USER_PASSWORD:
                        fr_radius_decode_password((char *)buffer, attr_len,
-                                                 packet_ctx->secret, packet_ctx->vector);
+                                                 packet_ctx->common->secret, packet_ctx->common->vector);
                        buffer[253] = '\0';
 
                        /*
@@ -1660,7 +1660,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
                case FLAG_TAGGED_TUNNEL_PASSWORD:
                case FLAG_ENCRYPT_TUNNEL_PASSWORD:
                        if (fr_radius_decode_tunnel_password(buffer, &data_len,
-                                                            packet_ctx->secret, packet_ctx->vector,
+                                                            packet_ctx->common->secret, packet_ctx->common->vector,
                                                             packet_ctx->tunnel_password_zeros) < 0) {
                                goto raw;
                        }
@@ -1672,7 +1672,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
                 */
                case FLAG_ENCRYPT_ASCEND_SECRET:
                        fr_radius_ascend_secret(&FR_DBUFF_TMP(buffer, sizeof(buffer)), p, data_len,
-                                               packet_ctx->secret, packet_ctx->vector);
+                                               packet_ctx->common->secret, packet_ctx->common->vector);
                        buffer[RADIUS_AUTH_VECTOR_LENGTH] = '\0';
                        data_len = strlen((char *) buffer);
                        break;
@@ -1950,7 +1950,7 @@ static const bool special[UINT8_MAX + 1] = {
  *
  */
 ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out,
-                             uint8_t const *data, size_t data_len, fr_radius_ctx_t *packet_ctx)
+                             uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
 {
        ssize_t                 ret;
        fr_dict_attr_t const    *da;
@@ -2054,7 +2054,7 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out,
        return 2 + ret;
 }
 
-static int _test_ctx_free(fr_radius_ctx_t *ctx)
+static int _test_ctx_free(fr_radius_decode_ctx_t *ctx)
 {
        TALLOC_FREE(ctx->tags);
 
@@ -2069,13 +2069,17 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
 
-       fr_radius_ctx_t *test_ctx;
+       fr_radius_decode_ctx_t  *test_ctx;
 
        if (fr_radius_init() < 0) return -1;
 
-       test_ctx = talloc_zero(ctx, fr_radius_ctx_t);
-       test_ctx->secret = talloc_strdup(test_ctx, "testing123");
-       memcpy(test_ctx->vector, vector, sizeof(test_ctx->vector));
+       test_ctx = talloc_zero(ctx, fr_radius_decode_ctx_t);
+       test_ctx->common = talloc_zero(test_ctx, fr_radius_ctx_t);
+
+       test_ctx->common->secret = talloc_strdup(test_ctx->common, "testing123");
+       test_ctx->common->secret_length = talloc_array_length(test_ctx->common->secret);
+
+       memcpy(test_ctx->common->vector, vector, sizeof(test_ctx->common->vector));
        test_ctx->tmp_ctx = talloc_zero(test_ctx, uint8_t);
        talloc_set_destructor(test_ctx, _test_ctx_free);
 
@@ -2087,7 +2091,7 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
 static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                      uint8_t const *data, size_t data_len, void *proto_ctx)
 {
-       fr_radius_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_radius_ctx_t);
+       fr_radius_decode_ctx_t  *test_ctx = talloc_get_type_abort(proto_ctx, fr_radius_decode_ctx_t);
        decode_fail_t   reason;
        fr_pair_t       *vp;
        size_t          packet_len = data_len;
@@ -2117,15 +2121,15 @@ static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
        fr_pair_append(out, vp);
 
        memset(original, 0, 4);
-       memcpy(original + 4, test_ctx->vector, sizeof(test_ctx->vector));
+       memcpy(original + 4, test_ctx->common->vector, sizeof(test_ctx->common->vector));
        test_ctx->end = data + packet_len;
 
        return fr_radius_decode(ctx, out, data, packet_len, original,
-                               test_ctx->secret, talloc_array_length(test_ctx->secret) - 1);
+                               test_ctx->common->secret, talloc_array_length(test_ctx->common->secret) - 1);
 }
 
 static ssize_t decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, NDEBUG_UNUSED fr_dict_attr_t const *parent,
-                          uint8_t const *data, size_t data_len, fr_radius_ctx_t *packet_ctx)
+                          uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
 {
        fr_assert(parent == fr_dict_root(dict_radius));
 
index 7d6811b51fe4cfe4ebac13e96fea3e5a30d86cfa..d71841d962fd08834986ece1a8a925f54042522c 100644 (file)
@@ -104,7 +104,7 @@ static ssize_t encode_tunnel_password(fr_dbuff_t *dbuff, fr_dbuff_marker_t *in,
        uint8_t         digest[RADIUS_AUTH_VECTOR_LENGTH];
        uint8_t         tpasswd[RADIUS_MAX_STRING_LENGTH];
        size_t          i, n;
-       fr_radius_ctx_t *packet_ctx = encode_ctx;
+       fr_radius_encode_ctx_t  *packet_ctx = encode_ctx;
        uint32_t        r;
        size_t          output_len, encrypted_len, padding;
        ssize_t         slen;
@@ -187,10 +187,10 @@ static ssize_t encode_tunnel_password(fr_dbuff_t *dbuff, fr_dbuff_marker_t *in,
        md5_ctx = fr_md5_ctx_alloc_from_list();
        md5_ctx_old = fr_md5_ctx_alloc_from_list();
 
-       fr_md5_update(md5_ctx, (uint8_t const *) packet_ctx->secret, talloc_array_length(packet_ctx->secret) - 1);
+       fr_md5_update(md5_ctx, (uint8_t const *) packet_ctx->common->secret, talloc_array_length(packet_ctx->common->secret) - 1);
        fr_md5_ctx_copy(md5_ctx_old, md5_ctx);
 
-       fr_md5_update(md5_ctx, packet_ctx->vector, RADIUS_AUTH_VECTOR_LENGTH);
+       fr_md5_update(md5_ctx, packet_ctx->common->vector, RADIUS_AUTH_VECTOR_LENGTH);
        fr_md5_update(md5_ctx, &tpasswd[0], 2);
 
        /*
@@ -337,7 +337,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
        size_t                  len;
        fr_pair_t const *vp = fr_dcursor_current(cursor);
        fr_dict_attr_t const    *da = da_stack->da[depth];
-       fr_radius_ctx_t         *packet_ctx = encode_ctx;
+       fr_radius_encode_ctx_t  *packet_ctx = encode_ctx;
        fr_dbuff_t              work_dbuff = FR_DBUFF(dbuff);
        fr_dbuff_t              value_dbuff;
        fr_dbuff_marker_t       value_start, src, dest;
@@ -506,7 +506,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
                 *      Encode the password in place
                 */
                slen = encode_password(&work_dbuff, &value_start, fr_dbuff_used(&value_dbuff),
-                                      packet_ctx->secret, packet_ctx->vector);
+                                      packet_ctx->common->secret, packet_ctx->common->vector);
                if (slen < 0) return slen;
                encrypted = true;
                break;
@@ -557,7 +557,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
                 *      there can pass a marker so we can use it here, too.
                 */
                slen = fr_radius_ascend_secret(&work_dbuff, fr_dbuff_current(&value_start), fr_dbuff_used(&value_dbuff),
-                                              packet_ctx->secret, packet_ctx->vector);
+                                              packet_ctx->common->secret, packet_ctx->common->vector);
                if (slen < 0) return slen;
                encrypted = true;
                break;
@@ -1511,7 +1511,7 @@ ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *enc
         *      Tags are *top-level*, and are never nested.
         */
        if (vp->vp_type == FR_TYPE_GROUP) {
-               fr_radius_ctx_t *packet_ctx = encode_ctx;
+               fr_radius_encode_ctx_t  *packet_ctx = encode_ctx;
 
                if (!vp->da->flags.internal ||
                    !((vp->da->attr > FR_TAG_BASE) && (vp->da->attr < (FR_TAG_BASE + 0x20)))) {
@@ -1655,7 +1655,7 @@ ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *enc
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
-static int _test_ctx_free(UNUSED fr_radius_ctx_t *ctx)
+static int _test_ctx_free(UNUSED fr_radius_encode_ctx_t *ctx)
 {
        fr_radius_free();
 
@@ -1668,15 +1668,19 @@ static int encode_test_ctx(void **out, TALLOC_CTX *ctx)
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
 
-       fr_radius_ctx_t *test_ctx;
+       fr_radius_encode_ctx_t  *test_ctx;
 
        if (fr_radius_init() < 0) return -1;
 
-       test_ctx = talloc_zero(ctx, fr_radius_ctx_t);
+       test_ctx = talloc_zero(ctx, fr_radius_encode_ctx_t);
        if (!test_ctx) return -1;
 
-       test_ctx->secret = talloc_strdup(test_ctx, "testing123");
-       memcpy(test_ctx->vector, vector, sizeof(test_ctx->vector));
+       test_ctx->common = talloc_zero(test_ctx, fr_radius_ctx_t);
+
+       test_ctx->common->secret = talloc_strdup(test_ctx->common, "testing123");
+       test_ctx->common->secret_length = talloc_array_length(test_ctx->common->secret);
+
+       memcpy(test_ctx->common->vector, vector, sizeof(test_ctx->common->vector));
        test_ctx->rand_ctx.a = 6809;
        test_ctx->rand_ctx.b = 2112;
        talloc_set_destructor(test_ctx, _test_ctx_free);
@@ -1688,7 +1692,7 @@ static int encode_test_ctx(void **out, TALLOC_CTX *ctx)
 
 static ssize_t fr_radius_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, void *proto_ctx)
 {
-       fr_radius_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_radius_ctx_t);
+       fr_radius_encode_ctx_t  *packet_ctx = talloc_get_type_abort(proto_ctx, fr_radius_encode_ctx_t);
        int packet_type = FR_RADIUS_CODE_ACCESS_REQUEST;
        fr_pair_t *vp;
        ssize_t slen;
@@ -1704,20 +1708,20 @@ static ssize_t fr_radius_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vp
                        int i;
 
                        for (i = 0; i < RADIUS_AUTH_VECTOR_LENGTH; i++) {
-                               data[4 + i] = fr_fast_rand(&test_ctx->rand_ctx);
+                               data[4 + i] = fr_fast_rand(&packet_ctx->rand_ctx);
                        }
                }
        }
 
        /*
-        *      @todo - pass in test_ctx to this function, so that we
+        *      @todo - pass in packet_ctx to this function, so that we
         *      can leverage a consistent random number generator.
         */
-       slen = fr_radius_encode(data, data_len, NULL, test_ctx->secret, talloc_array_length(test_ctx->secret) - 1,
+       slen = fr_radius_encode(data, data_len, NULL, packet_ctx->common->secret, talloc_array_length(packet_ctx->common->secret) - 1,
                                packet_type, 0, vps);
        if (slen <= 0) return slen;
 
-       if (fr_radius_sign(data, NULL, (uint8_t const *) test_ctx->secret, talloc_array_length(test_ctx->secret) - 1) < 0) {
+       if (fr_radius_sign(data, NULL, (uint8_t const *) packet_ctx->common->secret, talloc_array_length(packet_ctx->common->secret) - 1) < 0) {
                return -1;
        }
 
index be268d385d0699cccd60b82b252f8f5499abca26..163c9fb4c79415f1825ad12a5dc3ab390bc3a1c8 100644 (file)
@@ -122,10 +122,14 @@ int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
        uint8_t                 *ptr;
        radius_packet_t         *hdr;
        fr_pair_list_t          tmp_list;
-       fr_radius_ctx_t         packet_ctx = {
-                                       .secret = secret,
-                                       .tunnel_password_zeros = tunnel_password_zeros
-                               };
+       fr_radius_ctx_t         common_ctx = {};
+       fr_radius_decode_ctx_t  packet_ctx = {};
+
+       common_ctx.secret = secret;
+       common_ctx.secret_length = strlen(secret);
+
+       packet_ctx.common = &common_ctx;
+       packet_ctx.tunnel_password_zeros = tunnel_password_zeros;
 
 #ifndef NDEBUG
        if (fr_debug_lvl >= L_DBG_LVL_4) fr_radius_packet_log_hex(&default_log, packet);
@@ -134,7 +138,7 @@ int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
        switch (packet->code) {
        case FR_RADIUS_CODE_ACCESS_REQUEST:
        case FR_RADIUS_CODE_STATUS_SERVER:
-               memcpy(packet_ctx.vector, packet->vector, sizeof(packet_ctx.vector));
+               memcpy(common_ctx.vector, packet->vector, sizeof(common_ctx.vector));
                break;
 
        case FR_RADIUS_CODE_ACCESS_ACCEPT:
@@ -149,10 +153,10 @@ int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
                 *      radsniff doesn't always have a response
                 */
                if (original) {
-                       memcpy(packet_ctx.vector, original->vector, sizeof(packet_ctx.vector));
+                       memcpy(common_ctx.vector, original->vector, sizeof(common_ctx.vector));
                } else {
                        memset(packet->vector, 0, sizeof(packet->vector));
-                       memset(packet_ctx.vector, 0, sizeof(packet_ctx.vector));
+                       memset(common_ctx.vector, 0, sizeof(common_ctx.vector));
                }
                break;
 
@@ -160,7 +164,7 @@ int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
        case FR_RADIUS_CODE_COA_REQUEST:
        case FR_RADIUS_CODE_DISCONNECT_REQUEST:
                memset(packet->vector, 0, sizeof(packet->vector));
-               memset(packet_ctx.vector, 0, sizeof(packet_ctx.vector));
+               memset(common_ctx.vector, 0, sizeof(common_ctx.vector));
                break;
 
        default:
index 47e14a9ee91c317192d5cde6aecd9de5b95756ae..fd8f2f696b7c3c67fdb41e7fd44771fa833369f6 100644 (file)
@@ -163,20 +163,40 @@ typedef struct {
 } fr_radius_tag_ctx_t;
 
 typedef struct {
-       TALLOC_CTX              *tmp_ctx;               //!< for temporary things cleaned up during decoding
-       uint8_t                 vector[RADIUS_AUTH_VECTOR_LENGTH]; //!< vector for encryption / decryption of data
-       char const              *secret;                //!< shared secret.  MUST be talloc'd
+       char const      *secret;
+       size_t          secret_length;
+
+       bool            add_proxy_state;                //!< do we add a Proxy-State?
+       uint64_t        my_proxy_state;                 //!< if so, this is its value
+
+       uint32_t        acct_delay_time;                //!< additional time to add to acct_delay_time
+
+       uint8_t         vector[RADIUS_AUTH_VECTOR_LENGTH]; //!< vector for authenticating the reply
+} fr_radius_ctx_t;
+
+typedef struct {
+       fr_radius_ctx_t         *common;
+
        fr_fast_rand_t          rand_ctx;               //!< for tunnel passwords
-       uint8_t const           *end;                   //!< end of the packet
        int                     salt_offset;            //!< for tunnel passwords
-       bool                    tunnel_password_zeros;  //!< check for trailing zeros on decode
-       bool                    disallow_tunnel_passwords; //!< not all packets can have tunnel passwords
 
        uint8_t                 tag;                    //!< current tag for encoding
+       bool                    disallow_tunnel_passwords; //!< not all packets can have tunnel passwords
+       bool                    seen_message_authenticator;
+} fr_radius_encode_ctx_t;
+
+typedef struct {
+       fr_radius_ctx_t         *common;
+
+       TALLOC_CTX              *tmp_ctx;               //!< for temporary things cleaned up during decoding
+       uint8_t const           *end;                   //!< end of the packet
+
+       bool                    tunnel_password_zeros;  //!< check for trailing zeros on decode
+
        fr_radius_tag_ctx_t     **tags;                 //!< for decoding tagged attributes
        fr_pair_list_t          *tag_root;              //!< Where to insert tag attributes.
        TALLOC_CTX              *tag_root_ctx;          //!< Where to allocate new tag attributes.
-} fr_radius_ctx_t;
+} fr_radius_decode_ctx_t;
 
 /*
  *     protocols/radius/abinary.c
@@ -209,7 +229,7 @@ ssize_t             fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *list,
 ssize_t                fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list,
                                     fr_dict_attr_t const *parent,
                                     uint8_t const *data, size_t data_len,
-                                    fr_radius_ctx_t *packet_ctx) CC_HINT(nonnull);
+                                    fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);
 
 ssize_t                fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list,
-                                     uint8_t const *data, size_t data_len, fr_radius_ctx_t *packet_ctx) CC_HINT(nonnull);
+                                     uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);