diff --git a/USAGE b/USAGE index 35c7923..d18b8b4 100644 --- a/USAGE +++ b/USAGE @@ -101,5 +101,8 @@ prompt_attribute - Enable honoring of Prompt attribute sent from server for input. Without this option all user input during challenge-response will be echoed. See RFC2869 Section 5.10 +require_message_authenticator - Discard Access-Accept, Access-Challenge, and + Access-Reject packets which do not contain Message-Authenticator. + --------------------------------------------------------------------------- diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index 3fe2834..1d957a3 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -197,6 +197,9 @@ static int _pam_parse(int argc, CONST char **argv, radius_conf_t *conf) } else if (!strcmp(arg, "privilege_level")) { conf->privilege_level = TRUE; + } else if (!strcmp(arg, "require_message_authenticator")) { + conf->require_message_authenticator = TRUE; + } else { _pam_log(LOG_WARNING, "unrecognized option '%s'", arg); } @@ -435,7 +438,7 @@ static void get_accounting_vector(AUTH_HDR *request, radius_server_t *server) /** * Verify the response from the server */ -static int verify_packet(radius_server_t *server, AUTH_HDR *response, AUTH_HDR *request) +static int verify_packet(radius_server_t *server, AUTH_HDR *response, AUTH_HDR *request, radius_conf_t *conf) { MD5_CTX my_md5; uint8_t calculated[AUTH_VECTOR_LEN]; @@ -470,6 +473,10 @@ static int verify_packet(radius_server_t *server, AUTH_HDR *response, AUTH_HDR * attr += attr[1]; } + if ((request->code == PW_ACCESS_REQUEST) && conf->require_message_authenticator && !message_authenticator) { + return FALSE; + } + /* * We could dispense with the memcpy, and do MD5's of the packet * + vector piece by piece. This is easier understand, and maybe faster. @@ -1242,7 +1249,7 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons continue; } - if (!verify_packet(server, response, request)) { + if (!verify_packet(server, response, request, conf)) { _pam_log(LOG_ERR, "packet from RADIUS server %s failed verification: " "The shared secret is probably incorrect.", server->hostname); continue; diff --git a/src/pam_radius_auth.h b/src/pam_radius_auth.h index a18f321..acecb4d 100644 --- a/src/pam_radius_auth.h +++ b/src/pam_radius_auth.h @@ -188,6 +188,7 @@ typedef struct radius_conf_t { char prompt[MAXPROMPT]; int prompt_attribute; int privilege_level; + int require_message_authenticator; uint8_t *message_authenticator; } radius_conf_t;