]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add require_ma flag to fr_radius_verify()
authorAlan T. DeKok <aland@freeradius.org>
Tue, 12 Oct 2021 17:54:16 +0000 (13:54 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 12 Oct 2021 17:54:16 +0000 (13:54 -0400)
src/modules/rlm_radius/rlm_radius_udp.c
src/protocols/radius/base.c
src/protocols/radius/packet.c
src/protocols/radius/radius.h

index eedac38d22f7e2cd461c09d4bf1a9641a43b46cd..6b28fa678674d13a697419e60fd7e2e78ec01193 100644 (file)
@@ -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;
        }
index 403a118020dd3be9b87796248fcf739d94a83f47..e3a5f05d6a800c8bcfa271007914178059e8c5f5 100644 (file)
@@ -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
index 6504189dfb88ee7982732188084a1a2380f90eb1..5e4cf6151e851975d9f4ec02d8c11283c5632925 100644 (file)
@@ -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)));
index 4dc45bddfda2dc5214efb47acb7ac63cda34baeb..c21131ba45cec7c3cecef1ff0923ca079645efc7 100644 (file)
@@ -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));