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_pair_t const *vp;
fr_dcursor_t cursor;
fr_radius_ctx_t common_ctx = {};
fr_radius_encode_ctx_t packet_ctx = {};
common_ctx.secret_length = secret_len;
packet_ctx.common = &common_ctx;
- packet_ctx.request_authenticator = common_ctx.vector;
+ if (original) {
+ packet_ctx.request_authenticator = original + 4;
+ } else {
+ packet_ctx.request_authenticator = packet + 4;
+ }
packet_ctx.rand_ctx.a = fr_rand();
packet_ctx.rand_ctx.b = fr_rand();
packet_ctx.disallow_tunnel_passwords = disallow_tunnel_passwords[code];
case FR_RADIUS_CODE_ACCESS_REQUEST:
case FR_RADIUS_CODE_STATUS_SERVER:
/*
- * Callers in these cases have preloaded the buffer with the authentication vector.
+ * Allow over-rides of the authentication vector for testing.
*/
- FR_DBUFF_OUT_MEMCPY_RETURN(common_ctx.vector, &work_dbuff, sizeof(common_ctx.vector));
+ vp = fr_pair_find_by_da(vps, NULL, attr_packet_authentication_vector);
+ if (vp && (vp->vp_length >= RADIUS_AUTH_VECTOR_LENGTH)) {
+ FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, vp->vp_octets, RADIUS_AUTH_VECTOR_LENGTH);
+ } else {
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ FR_DBUFF_IN_RETURN(&work_dbuff, (uint32_t) fr_rand());
+ }
+ }
break;
case FR_RADIUS_CODE_ACCESS_REJECT:
fr_strerror_const("Cannot encode response without request");
return -1;
}
- memcpy(common_ctx.vector, original + 4, sizeof(common_ctx.vector));
- FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, common_ctx.vector, RADIUS_AUTH_VECTOR_LENGTH);
+ FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, original + 4, RADIUS_AUTH_VECTOR_LENGTH);
break;
case FR_RADIUS_CODE_ACCOUNTING_REQUEST:
* to say "don't do that!"
*/
case FR_RADIUS_CODE_COA_REQUEST:
- memset(common_ctx.vector, 0, sizeof(common_ctx.vector));
FR_DBUFF_MEMSET_RETURN(&work_dbuff, 0, RADIUS_AUTH_VECTOR_LENGTH);
break;
return 0;
}
-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)
+static ssize_t fr_radius_encode_proto(TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, void *proto_ctx)
{
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;
vp = fr_pair_find_by_da(vps, NULL, attr_packet_type);
if (vp) packet_type = vp->vp_uint32;
+ /*
+ * Force specific values for testing.
+ */
if ((packet_type == FR_RADIUS_CODE_ACCESS_REQUEST) || (packet_type == FR_RADIUS_CODE_STATUS_SERVER)) {
vp = fr_pair_find_by_da(vps, NULL, attr_packet_authentication_vector);
- if (vp && (vp->vp_length == RADIUS_AUTH_VECTOR_LENGTH)) {
- memcpy(data + 4, vp->vp_octets, RADIUS_AUTH_VECTOR_LENGTH);
- } else {
+ if (!vp) {
int i;
+ uint8_t vector[RADIUS_AUTH_VECTOR_LENGTH];
for (i = 0; i < RADIUS_AUTH_VECTOR_LENGTH; i++) {
data[4 + i] = fr_fast_rand(&packet_ctx->rand_ctx);
}
+
+ fr_pair_list_append_by_da_len(ctx, vp, vps, attr_packet_authentication_vector, vector, sizeof(vector), false);
}
}