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;
}
* @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];
*/
msg = packet + RADIUS_HEADER_LENGTH;
end = packet + packet_len;
+ found_ma = false;
while (msg < end) {
if ((end - msg) < 2) goto invalid_attribute;
* 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
}
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)));
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));