From: Alan T. DeKok Date: Tue, 12 Oct 2021 17:54:16 +0000 (-0400) Subject: add require_ma flag to fr_radius_verify() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67bb7ab6a810197ac6343fe13f463a1878de2377;p=thirdparty%2Ffreeradius-server.git add require_ma flag to fr_radius_verify() --- diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index eedac38d22f..6b28fa67867 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -1204,7 +1204,7 @@ static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *res memcpy(original + RADIUS_AUTH_VECTOR_OFFSET, request_authenticator, RADIUS_AUTH_VECTOR_LENGTH); if (fr_radius_verify(data, original, - (uint8_t const *) inst->secret, talloc_array_length(inst->secret) - 1) < 0) { + (uint8_t const *) inst->secret, talloc_array_length(inst->secret) - 1, false) < 0) { RPWDEBUG("Ignoring response with invalid signature"); return DECODE_FAIL_MA_INVALID; } diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 403a118020d..e3a5f05d6a8 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -767,13 +767,15 @@ finish: * @param original the raw original request (if this is a response) * @param secret the shared secret * @param secret_len the length of the secret + * @param[in] require_ma whether we require Message-Authenticator. * @return * - <0 on error * - 0 on success */ int fr_radius_verify(uint8_t *packet, uint8_t const *original, - uint8_t const *secret, size_t secret_len) + uint8_t const *secret, size_t secret_len, bool require_ma) { + bool found_ma; int rcode; uint8_t *msg, *end; size_t packet_len = (packet[2] << 8) | packet[3]; @@ -794,6 +796,7 @@ int fr_radius_verify(uint8_t *packet, uint8_t const *original, */ msg = packet + RADIUS_HEADER_LENGTH; end = packet + packet_len; + found_ma = false; while (msg < end) { if ((end - msg) < 2) goto invalid_attribute; @@ -819,9 +822,16 @@ int fr_radius_verify(uint8_t *packet, uint8_t const *original, * Found it, save a copy. */ memcpy(message_authenticator, msg + 2, sizeof(message_authenticator)); + found_ma = true; break; } + if ((packet[0] == FR_RADIUS_CODE_ACCESS_REQUEST) && + require_ma && !found_ma) { + fr_strerror_const("Access-Request is missing the required Message-Authenticator attribute"); + return -1; + } + /* * Implement verification as a signature, followed by * checking our signature against the sent one. This is diff --git a/src/protocols/radius/packet.c b/src/protocols/radius/packet.c index 6504189dfb8..5e4cf6151e8 100644 --- a/src/protocols/radius/packet.c +++ b/src/protocols/radius/packet.c @@ -292,7 +292,7 @@ int fr_radius_packet_verify(fr_radius_packet_t *packet, fr_radius_packet_t *orig } if (fr_radius_verify(packet->data, original_data, - (uint8_t const *) secret, talloc_array_length(secret) - 1) < 0) { + (uint8_t const *) secret, talloc_array_length(secret) - 1, false) < 0) { fr_strerror_printf_push("Received invalid packet from %s", inet_ntop(packet->socket.inet.src_ipaddr.af, &packet->socket.inet.src_ipaddr.addr, buffer, sizeof(buffer))); diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 4dc45bddfda..c21131ba45c 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -113,7 +113,7 @@ size_t fr_radius_attr_len(fr_pair_t const *vp); int fr_radius_sign(uint8_t *packet, uint8_t const *original, uint8_t const *secret, size_t secret_len) CC_HINT(nonnull (1,3)); int fr_radius_verify(uint8_t *packet, uint8_t const *original, - uint8_t const *secret, size_t secret_len) CC_HINT(nonnull (1,3)); + uint8_t const *secret, size_t secret_len, bool require_ma) CC_HINT(nonnull (1,3)); bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_ma, decode_fail_t *reason) CC_HINT(nonnull (1,2));