diff options
author | Alan T. DeKok <aland@freeradius.org> | 2024-06-11 15:17:09 -0400 |
---|---|---|
committer | Robert Gingras <rgingras@mieweb.com> | 2025-03-31 11:34:51 -0400 |
commit | 84184844ec80c840a3499bb3fedd74ea9acf4dd2 (patch) | |
tree | ce8d469a0166c3c3d58962a1f539da6e96578886 /src | |
parent | f3d67bba31f61993fc079f89478c0ac7da0ddaaf (diff) | |
download | libpam-radius-auth-84184844ec80c840a3499bb3fedd74ea9acf4dd2.tar.gz libpam-radius-auth-84184844ec80c840a3499bb3fedd74ea9acf4dd2.zip |
always add Message-Authenticator to Access-Request packets
Diffstat (limited to 'src')
-rw-r--r-- | src/md5.h | 1 | ||||
-rw-r--r-- | src/pam_radius_auth.c | 38 | ||||
-rw-r--r-- | src/pam_radius_auth.h | 4 |
3 files changed, 39 insertions, 4 deletions
@@ -39,6 +39,7 @@ #define MD5Transform pra_MD5Transform #include <inttypes.h> +#include <stdint.h> struct MD5Context { uint32_t buf[4]; diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index 009fe4a..aa3a650 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -1001,10 +1001,25 @@ static void build_radius_packet(AUTH_HDR * request, CONST char *user, hostname[0] = '\0'; gethostname(hostname, sizeof(hostname) - 1); - request->length = htons(AUTH_HDR_LEN); + /* + * For Access-Request, create a random authentication + * vector, and always add a Message-Authenticator + * attribute. + */ + if (request->code == PW_AUTHENTICATION_REQUEST) { + uint8_t *attr = (uint8_t *) request + AUTH_HDR_LEN; - if (password) { /* make a random authentication req vector */ - get_random_vector(request->vector); + get_random_vector(request->vector); + + attr[0] = PW_MESSAGE_AUTHENTICATOR; + attr[1] = 18; + memset(attr + 2, 0, AUTH_VECTOR_LEN); + conf->message_authenticator = attr + 2; + + request->length = htons(AUTH_HDR_LEN + 18); + } else { + request->length = htons(AUTH_HDR_LEN); + conf->message_authenticator = NULL; } add_attribute(request, PW_USER_NAME, (unsigned char *)user, @@ -1097,7 +1112,22 @@ static int talk_radius(radius_conf_t * conf, AUTH_HDR * request, /* clear the response */ memset(response, 0, sizeof(AUTH_HDR)); - if (!password) { /* make an RFC 2139 p6 request authenticator */ + /* only look up IP information as necessary */ + retval = host2server(pamh, server); + if (retval != 0) { + _pam_log(pamh, LOG_ERR, + "Failed looking up IP address for RADIUS server %s (error=%s)", + server->hostname, gai_strerror(retval)); + ok = FALSE; + goto next; /* skip to the next server */ + } + + if (request->code == PW_AUTHENTICATION_REQUEST) { + hmac_md5(conf->message_authenticator, (uint8_t *) request, ntohs(request->length), + (const uint8_t *) server->secret, strlen(server->secret)); + + } else { + /* make an RFC 2139 p6 request authenticator */ get_accounting_vector(request, server); } diff --git a/src/pam_radius_auth.h b/src/pam_radius_auth.h index b1a3173..da7177b 100644 --- a/src/pam_radius_auth.h +++ b/src/pam_radius_auth.h @@ -7,6 +7,7 @@ #include <errno.h> #include <sys/time.h> #include <sys/types.h> +#include <stdint.h> #include <sys/stat.h> #include <sys/resource.h> #include <sys/param.h> @@ -155,6 +156,9 @@ typedef struct radius_conf_t { char prompt[MAXPROMPT]; char vrfname[64]; char privusrmap[64]; + int prompt_attribute; + int privilege_level; + uint8_t *message_authenticator; } radius_conf_t; void __write_mapfile(pam_handle_t * p, const char *usr, uid_t uid, int priv, |