diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index dc2c79cc0..98148da46 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -529,7 +529,34 @@ static int mac_in_conf(struct hostapd_config *conf, const void *a) static int hostapd_das_nas_mismatch(struct hostapd_data *hapd, struct radius_das_attrs *attr) { - /* TODO */ + if (attr->nas_identifier && + (!hapd->conf->nas_identifier || + os_strlen(hapd->conf->nas_identifier) != + attr->nas_identifier_len || + os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier, + attr->nas_identifier_len) != 0)) { + wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch"); + return 1; + } + + if (attr->nas_ip_addr && + (hapd->conf->own_ip_addr.af != AF_INET || + os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) != + 0)) { + wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch"); + return 1; + } + +#ifdef CONFIG_IPV6 + if (attr->nas_ipv6_addr && + (hapd->conf->own_ip_addr.af != AF_INET6 || + os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16) + != 0)) { + wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch"); + return 1; + } +#endif /* CONFIG_IPV6 */ + return 0; } diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c index b2a27735b..9655f4cea 100644 --- a/src/radius/radius_das.c +++ b/src/radius/radius_das.c @@ -38,11 +38,16 @@ static struct radius_msg * radius_das_disconnect(struct radius_das_data *das, struct radius_msg *reply; u8 allowed[] = { RADIUS_ATTR_USER_NAME, + RADIUS_ATTR_NAS_IP_ADDRESS, RADIUS_ATTR_CALLING_STATION_ID, + RADIUS_ATTR_NAS_IDENTIFIER, RADIUS_ATTR_ACCT_SESSION_ID, RADIUS_ATTR_EVENT_TIMESTAMP, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, +#ifdef CONFIG_IPV6 + RADIUS_ATTR_NAS_IPV6_ADDRESS, +#endif /* CONFIG_IPV6 */ 0 }; int error = 405; @@ -67,6 +72,36 @@ static struct radius_msg * radius_das_disconnect(struct radius_das_data *das, os_memset(&attrs, 0, sizeof(attrs)); + if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, + &buf, &len, NULL) == 0) { + if (len != 4) { + wpa_printf(MSG_INFO, "DAS: Invalid NAS-IP-Address from %s:%d", + abuf, from_port); + error = 407; + goto fail; + } + attrs.nas_ip_addr = buf; + } + +#ifdef CONFIG_IPV6 + if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS, + &buf, &len, NULL) == 0) { + if (len != 16) { + wpa_printf(MSG_INFO, "DAS: Invalid NAS-IPv6-Address from %s:%d", + abuf, from_port); + error = 407; + goto fail; + } + attrs.nas_ipv6_addr = buf; + } +#endif /* CONFIG_IPV6 */ + + if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, + &buf, &len, NULL) == 0) { + attrs.nas_identifier = buf; + attrs.nas_identifier_len = len; + } + if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CALLING_STATION_ID, &buf, &len, NULL) == 0) { if (len >= sizeof(tmp)) diff --git a/src/radius/radius_das.h b/src/radius/radius_das.h index 738b18b05..e3ed5408e 100644 --- a/src/radius/radius_das.h +++ b/src/radius/radius_das.h @@ -18,6 +18,13 @@ enum radius_das_res { }; struct radius_das_attrs { + /* NAS identification attributes */ + const u8 *nas_ip_addr; + const u8 *nas_identifier; + size_t nas_identifier_len; + const u8 *nas_ipv6_addr; + + /* Session identification attributes */ const u8 *sta_addr; const u8 *user_name; size_t user_name_len;