It looks like the Message-Authenticator validation done by radclient for Disconnect-ACK/NAK and CoA-ACK/NAK messages does not match with the mechanism described in RFC 5176. Message-Authenticator is generated correctly for Disconnect-Request and CoA-Request, but I needed to modify rad_verify() to get this matching with the code I'm writing for hostapd. RFC 5176, 3.4: When a Message-Authenticator Attribute is included within a CoA- ACK, CoA-NAK, Disconnect-ACK, or Disconnect-NAK, it is calculated as follows: Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator, Attributes) When the HMAC-MD5 message integrity check is calculated, the Message-Authenticator Attribute MUST be considered to be sixteen octets of zero. The Request Authenticator is taken from the corresponding CoA/Disconnect-Request. The Message-Authenticator is calculated and inserted in the packet before the Response Authenticator is calculated. It is that "The Request Authenticator is taken from the corresponding CoA/Disconnect-Request" part that does not seem to be followed by the current rad_verify() implementation. It clears the Authenticator field to all zeros (which is the mechanism used for the Request message) instead of using the Authenticator field from the Request message when validating the ACK/NAK message. Is this a workaround for some deployed NAS implementations or can this be fixed to match with RFC 5176? The following change was enough to make this interoperate with my hostapd implementation. diff --git a/src/lib/radius.c b/src/lib/radius.c index 7025573..dec3849 100644 --- a/src/lib/radius.c +++ b/src/lib/radius.c @@ -2619,11 +2619,7 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, case PW_ACCOUNTING_REQUEST: case PW_DISCONNECT_REQUEST: - case PW_DISCONNECT_ACK: - case PW_DISCONNECT_NAK: case PW_COA_REQUEST: - case PW_COA_ACK: - case PW_COA_NAK: memset(packet->data + 4, 0, AUTH_VECTOR_LEN); break; @@ -2631,6 +2627,10 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, case PW_AUTHENTICATION_ACK: case PW_AUTHENTICATION_REJECT: case PW_ACCESS_CHALLENGE: + case PW_DISCONNECT_ACK: + case PW_DISCONNECT_NAK: + case PW_COA_ACK: + case PW_COA_NAK: if (!original) { fr_strerror_printf("ERROR: Cannot validate Message-Authenticator in response packet without a request packet."); return -1; -- Jouni Malinen PGP id EFC895FA