From afd75242c90c4d33ecdb9e9219cd117d82e90c94 Mon Sep 17 00:00:00 2001
From: Nick Lowe <nick.lowe@lugatech.com>
Date: Sun, 28 Feb 2016 14:13:34 +0000
Subject: [PATCH] Define new config option nas-identifier-use-bssid to include
the BSSID in the NAS-Identifier attribute value of RADIUS packets. This value
defaults to 0, maintaining backwards compatibility, and is set to the value 1
in the supplied hostapd.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This new configuration option works in combination with the nas-identifier option.
Where the nas-identifier is unset, the default in hostapd.conf, the BSSID will be used to populate this value in the form in all cases, irrespective of the value of nas-identifier-use-bssid.
Omitting the NAS-Identifier in RADIUS packets causes significant problems in the RADIUS protocol so this is not allowed to ever occur.
(Accounting-On and Accounting-Off forms of RADIUS accounting packets are allowed to be sent in this case.)
Where the nas-identifier is set and the nas-identifier-use-bssid is set to 1, the BSSID will be included in the value used for the NAS-Identifier in the form “”.
(Accounting-On and Accounting-Off forms of RADIUS accounting packets are allowed to be sent in this case.)
Where the nas-identifier is set and the nas-identifier-use-bssid is set to 0, the BSSID will not be included in the value used for the NAS-Identifier.
(Accounting-On and Accounting-Off forms of RADIUS accounting packets will not be sent in this case.)
Range checks for nas-identifier now require this string value to be, inclusive, between 3 and 104 characters in length.
Signed-off-by: Nick Lowe <nick.lowe@lugatech.com>
---
hostapd/config_file.c | 13 +++++++++++--
hostapd/hostapd.conf | 24 ++++++++++++++++++++----
src/ap/accounting.c | 3 ++-
src/ap/ap_config.c | 8 ++++----
src/ap/ap_config.h | 4 +++-
src/ap/hostapd.c | 40 ++++++++++++++++++++++++++++++++--------
src/ap/ieee802_1x.c | 35 ++++++++++++++++++++++++++++-------
src/ap/wpa_auth_glue.c | 6 +++---
src/radius/radius_das.c | 1 -
9 files changed, 103 insertions(+), 31 deletions(-)
@@ -2282,9 +2282,18 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1;
}
} else if (os_strcmp(buf, "nas_identifier") == 0) {
- os_free(bss->nas_identifier);
- bss->nas_identifier = os_strdup(pos);
+ os_free(bss->nas_identifier_base);
+ bss->nas_identifier_base = os_strdup(pos);
+ bss->nas_identifier_base_len = os_strlen(bss->nas_identifier_base);
+ if (bss->nas_identifier_base_len < 3 || bss->nas_identifier_base_len > 104) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid nas_identifier len %lu",
+ line,
+ (unsigned long) bss->nas_identifier_base_len);
+ return 1;
+ }
#ifndef CONFIG_NO_RADIUS
+ } else if (os_strcmp(buf, "nas_identifier_use_bssid") == 0) {
+ bss->nas_identifier_use_bssid = atoi(pos);
} else if (os_strcmp(buf, "radius_client_addr") == 0) {
if (hostapd_parse_ip_addr(pos, &bss->radius->client_addr)) {
wpa_printf(MSG_ERROR,
@@ -909,13 +909,29 @@ eap_server=0
# The own IP address of the access point (used as NAS-IP-Address)
own_ip_addr=127.0.0.1
-# Optional NAS-Identifier string for RADIUS messages. When used, this should be
-# a unique to the NAS within the scope of the RADIUS server. For example, a
-# fully qualified domain name can be used here.
-# When using IEEE 802.11r, nas_identifier must be set and must be between 1 and
+# Optional NAS-Identifier, containing a string value used to identify the NAS
+# originating RADIUS packets. This must be unique to the NAS within the
+# scope of a RADIUS server. For example, a fully qualified domain name can be
+# used here appended with the .
+# Where nas_identifier has not been set, the BSSID will used.
+# This will be of the form "00-10-A4-23-19-C0".
+# When using IEEE 802.11r, nas_identifier must be set and be between 1 and
# 48 octets long.
#nas_identifier=ap.example.com
+# Whether to use the BSSID in the NAS-Identifier sent in RADIUS packets.
+# For example, where the nas_identifier is configured as ap.example.com, a
+# value of the form "00-10-A4-23-19-C0:ap.example.com" will be used.
+# Where mutiple BSSes are offered by a NAS, each BSS for which RADIUS accounting
+# is occuring must be presented as being an individual NAS for Accounting-On and
+# Accounting-Off to be handled correctly by a RADIUS server.
+# This option has no effect where the nas_identifier has not been set.
+# Where this is the case, the BSSID will always be sent.
+# This will be of the form "00-10-A4-23-19-C0".
+# 0 = disabled (default, for backwards compatiblity)
+# 1 = enabled (best practice)
+nas_identifier_use_bssid=1
+
# RADIUS client forced local IP address for the access point
# Normally the local IP address is determined automatically based on configured
# IP addresses, but this field can be used to force a specific address to be
@@ -424,7 +424,8 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
{
struct radius_msg *msg;
- if (!hapd->conf->radius->acct_server || hapd->radius == NULL)
+ if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
+ (hapd->conf->nas_identifier_use_bssid != 1 && hapd->conf->nas_identifier_base))
return;
/* Inform RADIUS server that accounting will start/stop so that the
@@ -455,7 +455,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->erp_domain);
os_free(conf->accept_mac);
os_free(conf->deny_mac);
- os_free(conf->nas_identifier);
+ os_free(conf->nas_identifier_base);
if (conf->radius) {
hostapd_config_free_radius(conf->radius->auth_servers,
conf->radius->num_auth_servers);
@@ -808,9 +808,9 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
#ifdef CONFIG_IEEE80211R
if (full_config && wpa_key_mgmt_ft(bss->wpa_key_mgmt) &&
- (bss->nas_identifier == NULL ||
- os_strlen(bss->nas_identifier) < 1 ||
- os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
+ (bss->nas_identifier_base == NULL ||
+ os_strlen(bss->nas_identifier_base) < 1 ||
+ os_strlen(bss->nas_identifier_base) > FT_R0KH_ID_MAX_LEN)) {
wpa_printf(MSG_ERROR, "FT (IEEE 802.11r) requires "
"nas_identifier to be configured as a 1..48 octet "
"string");
@@ -245,7 +245,9 @@ struct hostapd_bss_config {
unsigned int eap_sim_db_timeout;
int eap_server_erp; /* Whether ERP is enabled on internal EAP server */
struct hostapd_ip_addr own_ip_addr;
- char *nas_identifier;
+ char *nas_identifier_base;
+ size_t nas_identifier_base_len;
+ int nas_identifier_use_bssid;
struct hostapd_radius_servers *radius;
int acct_interim_interval;
int radius_request_cui;
@@ -608,14 +608,38 @@ 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)
{
- 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;
+ char buf[128];
+ int len;
+
+ if (attr->nas_identifier) {
+ if (hapd->conf->nas_identifier_base) {
+ if (hapd->conf->nas_identifier_use_bssid == 1) {
+ len = os_snprintf(buf, sizeof(buf),
+ RADIUS_802_1X_ADDR_FORMAT ":",
+ MAC2STR(hapd->own_addr));
+ os_memcpy(&buf[len],
+ hapd->conf->nas_identifier_base,
+ hapd->conf->nas_identifier_base_len);
+ len += hapd->conf->nas_identifier_base_len;
+ }
+ else {
+ os_memcpy(&buf[0],
+ hapd->conf->nas_identifier_base,
+ hapd->conf->nas_identifier_base_len);
+ len = hapd->conf->nas_identifier_base_len;
+ }
+ }
+ else
+ len = os_snprintf(buf, sizeof(buf),
+ RADIUS_802_1X_ADDR_FORMAT,
+ MAC2STR(hapd->own_addr));
+
+ if (len != attr->nas_identifier_len ||
+ os_memcmp(buf, attr->nas_identifier,
+ len) != 0) {
+ wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
+ return 1;
+ }
}
if (attr->nas_ip_addr &&
@@ -524,13 +524,34 @@ int add_common_radius_attr(struct hostapd_data *hapd,
#endif /* CONFIG_IPV6 */
if (!hostapd_config_get_radius_attr(req_attr,
- RADIUS_ATTR_NAS_IDENTIFIER) &&
- hapd->conf->nas_identifier &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
- (u8 *) hapd->conf->nas_identifier,
- os_strlen(hapd->conf->nas_identifier))) {
- wpa_printf(MSG_ERROR, "Could not add NAS-Identifier");
- return -1;
+ RADIUS_ATTR_NAS_IDENTIFIER)) {
+ if (hapd->conf->nas_identifier_base) {
+ if (hapd->conf->nas_identifier_use_bssid == 1) {
+ len = os_snprintf(buf, sizeof(buf),
+ RADIUS_802_1X_ADDR_FORMAT ":",
+ MAC2STR(hapd->own_addr));
+ os_memcpy(&buf[len],
+ hapd->conf->nas_identifier_base,
+ hapd->conf->nas_identifier_base_len);
+ len += hapd->conf->nas_identifier_base_len;
+ }
+ else {
+ os_memcpy(&buf[0],
+ hapd->conf->nas_identifier_base,
+ hapd->conf->nas_identifier_base_len);
+ len = hapd->conf->nas_identifier_base_len;
+ }
+ }
+ else
+ len = os_snprintf(buf, sizeof(buf),
+ RADIUS_802_1X_ADDR_FORMAT,
+ MAC2STR(hapd->own_addr));
+
+ if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
+ (u8 *) buf, len)) {
+ wpa_printf(MSG_ERROR, "Could not add NAS-Identifier");
+ return -1;
+ }
}
len = os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":",
@@ -59,9 +59,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
os_memcpy(wconf->mobility_domain, conf->mobility_domain,
MOBILITY_DOMAIN_ID_LEN);
- if (conf->nas_identifier &&
- os_strlen(conf->nas_identifier) <= FT_R0KH_ID_MAX_LEN) {
- wconf->r0_key_holder_len = os_strlen(conf->nas_identifier);
+ if (conf->nas_identifier_base &&
+ conf->nas_identifier_base_len <= FT_R0KH_ID_MAX_LEN) {
+ wconf->r0_key_holder_len = conf->nas_identifier_base_len;
os_memcpy(wconf->r0_key_holder, conf->nas_identifier,
wconf->r0_key_holder_len);
}
@@ -72,7 +72,6 @@ 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) {
--
2.7.1
Define new config option nas-identifier-use-bssid to include the BSSID in the NAS-Identifier attribute value of RADIUS packets. This value defaults to 0, maintaining backwards compatibility, and is set to the value 1 in the supplied hostapd.conf This new configuration option works in combination with the nas-identifier option. Where the nas-identifier is unset, the default in hostapd.conf, the BSSID will be used to populate this value in the form in all cases, irrespective of the value of nas-identifier-use-bssid. Omitting the NAS-Identifier in RADIUS packets causes significant problems in the RADIUS protocol so this is not allowed to ever occur. (Accounting-On and Accounting-Off forms of RADIUS accounting packets are allowed to be sent in this case.) Where the nas-identifier is set and the nas-identifier-use-bssid is set to 1, the BSSID will be included in the value used for the NAS-Identifier in the form “”. (Accounting-On and Accounting-Off forms of RADIUS accounting packets are allowed to be sent in this case.) Where the nas-identifier is set and the nas-identifier-use-bssid is set to 0, the BSSID will not be included in the value used for the NAS-Identifier. (Accounting-On and Accounting-Off forms of RADIUS accounting packets will not be sent in this case.) Range checks for nas-identifier now require this string value to be, inclusive, between 3 and 104 characters in length. Signed-off-by: Nick Lowe <nick.lowe@lugatech.com> --- hostapd/config_file.c | 13 +++++++++++-- hostapd/hostapd.conf | 24 ++++++++++++++++++++---- src/ap/accounting.c | 3 ++- src/ap/ap_config.c | 8 ++++---- src/ap/ap_config.h | 4 +++- src/ap/hostapd.c | 40 ++++++++++++++++++++++++++++++++-------- src/ap/ieee802_1x.c | 35 ++++++++++++++++++++++++++++------- src/ap/wpa_auth_glue.c | 6 +++--- src/radius/radius_das.c | 1 - 9 files changed, 103 insertions(+), 31 deletions(-) if (len != 4) {