From 23aa2fe5a93ea0250eee9d683f41e0e94477925e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sat, 6 Apr 2024 18:03:57 +0200 Subject: [PATCH 1/3] add environment variable attribute Framed-IPv6-Prefix when present --- src/pam_radius_auth.c | 25 +++++++++++++++++++++++++ src/radius.h | 1 + 2 files changed, 26 insertions(+) diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index be1d0ed..8f7f6cb 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -1591,6 +1591,31 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, UNUSED int flags, int arg _pam_log(LOG_DEBUG, "Set PAM environment variable : %s", frameip); } } + if ((attr_fip = find_attribute(response, PW_FRAMED_IPV6_PREFIX))) { + static const char name[] = "Framed-IPv6-Prefix"; + char buffer[INET6_ADDRSTRLEN]; + char frameip[sizeof(name) + INET6_ADDRSTRLEN]; + struct in6_addr ip6_addr; + const char *s; + + memcpy(&ip6_addr.s6_addr, attr_fip->data, 16); + + s = inet_ntop(AF_INET6, (const void *)&ip6_addr, buffer, INET6_ADDRSTRLEN); + if (s) + { + snprintf(frameip, sizeof(frameip), "%s=%s", name, s); + retval = pam_putenv(pamh, frameip); + } + else { + retval = PAM_SERVICE_ERR; + } + if (retval != PAM_SUCCESS) { + _pam_log(LOG_ERR, "unable to set PAM environment variable : %s", name); + } + else { + _pam_log(LOG_DEBUG, "Set PAM environment variable : %s", frameip); + } + } } else { retval = PAM_AUTH_ERR; /* authentication failure */ diff --git a/src/radius.h b/src/radius.h index 287d4d8..3620203 100644 --- a/src/radius.h +++ b/src/radius.h @@ -123,6 +123,7 @@ typedef struct pw_auth_hdr { #define PW_MANAGEMENT_PRIVILEGE_LEVEL 136 /* integer */ #define PW_NAS_IPV6_ADDRESS 95 /* octets */ +#define PW_FRAMED_IPV6_PREFIX 97 /* octets */ /* * INTEGER TRANSLATIONS From e46db2eaeff08a5be1f86797789f3aba38e0c029 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sat, 6 Apr 2024 18:29:56 +0200 Subject: [PATCH 2/3] consistency between IPv4 and IPv6 --- src/pam_radius_auth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index 8f7f6cb..6338d9d 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -1577,15 +1577,16 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, UNUSED int flags, int arg attribute_t *attr_fip; if ((attr_fip = find_attribute(response, PW_FRAMED_ADDRESS))) { - char frameip[100]; + static const char name[] = "Framed-IP-Address"; + char frameip[sizeof(name) + INET_ADDRSTRLEN]; struct in_addr ip_addr; ip_addr.s_addr = *(int*) attr_fip->data; - snprintf(frameip, sizeof(frameip), "Framed-IP-Address=%s", inet_ntoa(ip_addr)); + snprintf(frameip, sizeof(frameip), "%s=%s", name, inet_ntoa(ip_addr)); retval = pam_putenv(pamh, frameip); - if(retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "unable to set PAM environment variable : Framed-IP-Address"); + if (retval != PAM_SUCCESS) { + _pam_log(LOG_ERR, "unable to set PAM environment variable : %s", name); } else { _pam_log(LOG_DEBUG, "Set PAM environment variable : %s", frameip); From e0936855f60b2c56ec7c256a5bf9af9edb7b57cb Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sat, 6 Apr 2024 20:38:44 +0200 Subject: [PATCH 3/3] do not consider opaque type of `s_addr` as `int` The current code implies `int` is 4 bytes - which it is on current Linux platforms - and that `attr_fip->data` is aligned - which I presume it is. Neverthless, it might be clearer to use memcpy() here. From the Linux header : /* Internet address. */ struct in_addr { __be32 s_addr; }; --- src/pam_radius_auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index 6338d9d..b6f8a6d 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -1581,7 +1581,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, UNUSED int flags, int arg char frameip[sizeof(name) + INET_ADDRSTRLEN]; struct in_addr ip_addr; - ip_addr.s_addr = *(int*) attr_fip->data; + memcpy(&ip_addr.s_addr, attr_fip->data, 4); snprintf(frameip, sizeof(frameip), "%s=%s", name, inet_ntoa(ip_addr)); retval = pam_putenv(pamh, frameip);