aboutsummaryrefslogtreecommitdiffstats
path: root/src/ap
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-05-05 20:19:56 +0300
committerJouni Malinen <j@w1.fi>2012-05-05 20:19:56 +0300
commitaf35e7af7f8bb1ca9f0905b4074fb56a264aa12b (patch)
tree47e991a480b8016951fb7f79112478261ad3fa71 /src/ap
parent86f6053aa254e8a5a5ad9ba1ad20815d21314449 (diff)
downloadexternal_wpa_supplicant_8_ti-af35e7af7f8bb1ca9f0905b4074fb56a264aa12b.zip
external_wpa_supplicant_8_ti-af35e7af7f8bb1ca9f0905b4074fb56a264aa12b.tar.gz
external_wpa_supplicant_8_ti-af35e7af7f8bb1ca9f0905b4074fb56a264aa12b.tar.bz2
hostapd: Allow addition of arbitrary RADIUS attributes
New configuration parameters radius_auth_req_attr and radius_acct_req_attr can now be used to add (or override) RADIUS attributes in Access-Request and Accounting-Request packets. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/ap')
-rw-r--r--src/ap/accounting.c46
-rw-r--r--src/ap/ap_config.c28
-rw-r--r--src/ap/ap_config.h10
-rw-r--r--src/ap/ieee802_1x.c44
4 files changed, 111 insertions, 17 deletions
diff --git a/src/ap/accounting.c b/src/ap/accounting.c
index 82443a1..2c3a6d9 100644
--- a/src/ap/accounting.c
+++ b/src/ap/accounting.c
@@ -40,6 +40,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
size_t len;
int i;
struct wpabuf *b;
+ struct hostapd_radius_attr *attr;
msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
radius_client_get_id(hapd->radius));
@@ -68,7 +69,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_ACCT_AUTHENTIC) &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
hapd->conf->ieee802_1x ?
RADIUS_ACCT_AUTHENTIC_RADIUS :
RADIUS_ACCT_AUTHENTIC_LOCAL)) {
@@ -92,7 +95,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
}
}
- if (hapd->conf->own_ip_addr.af == AF_INET &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_NAS_IP_ADDRESS) &&
+ hapd->conf->own_ip_addr.af == AF_INET &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
(u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
printf("Could not add NAS-IP-Address\n");
@@ -100,7 +105,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
}
#ifdef CONFIG_IPV6
- if (hapd->conf->own_ip_addr.af == AF_INET6 &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_NAS_IPV6_ADDRESS) &&
+ hapd->conf->own_ip_addr.af == AF_INET6 &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
(u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
printf("Could not add NAS-IPv6-Address\n");
@@ -108,7 +115,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
}
#endif /* CONFIG_IPV6 */
- if (hapd->conf->nas_identifier &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_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))) {
@@ -116,7 +125,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- if (sta &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_NAS_PORT) &&
+ sta &&
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
printf("Could not add NAS-Port\n");
goto fail;
@@ -124,7 +135,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
- if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_CALLED_STATION_ID) &&
+ !radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
(u8 *) buf, os_strlen(buf))) {
printf("Could not add Called-Station-Id\n");
goto fail;
@@ -139,7 +152,10 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- if (!radius_msg_add_attr_int32(
+ if (!hostapd_config_get_radius_attr(
+ hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_NAS_PORT_TYPE) &&
+ !radius_msg_add_attr_int32(
msg, RADIUS_ATTR_NAS_PORT_TYPE,
RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
printf("Could not add NAS-Port-Type\n");
@@ -150,7 +166,10 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
radius_sta_rate(hapd, sta) / 2,
(radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
radius_mode_txt(hapd));
- if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
+ if (!hostapd_config_get_radius_attr(
+ hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_CONNECT_INFO) &&
+ !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
(u8 *) buf, os_strlen(buf))) {
printf("Could not add Connect-Info\n");
goto fail;
@@ -179,6 +198,17 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
}
}
+ for (attr = hapd->conf->radius_acct_req_attr; attr; attr = attr->next)
+ {
+ if (!radius_msg_add_attr(msg, attr->type,
+ wpabuf_head(attr->val),
+ wpabuf_len(attr->val))) {
+ wpa_printf(MSG_ERROR, "Could not add RADIUS "
+ "attribute");
+ goto fail;
+ }
+ }
+
return msg;
fail:
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 303448b..392b4fd 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -1,6 +1,6 @@
/*
* hostapd / Configuration helper functions
- * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -336,6 +336,30 @@ static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
}
+struct hostapd_radius_attr *
+hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type)
+{
+ for (; attr; attr = attr->next) {
+ if (attr->type == type)
+ return attr;
+ }
+ return NULL;
+}
+
+
+static void hostapd_config_free_radius_attr(struct hostapd_radius_attr *attr)
+{
+ struct hostapd_radius_attr *prev;
+
+ while (attr) {
+ prev = attr;
+ attr = attr->next;
+ wpabuf_free(prev->val);
+ os_free(prev);
+ }
+}
+
+
static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
{
os_free(user->identity);
@@ -392,6 +416,8 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
conf->radius->num_auth_servers);
hostapd_config_free_radius(conf->radius->acct_servers,
conf->radius->num_acct_servers);
+ hostapd_config_free_radius_attr(conf->radius_auth_req_attr);
+ hostapd_config_free_radius_attr(conf->radius_acct_req_attr);
os_free(conf->rsn_preauth_interfaces);
os_free(conf->ctrl_interface);
os_free(conf->ca_cert);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 4304772..5473be1 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -116,6 +116,12 @@ struct hostapd_eap_user {
int ttls_auth; /* EAP_TTLS_AUTH_* bitfield */
};
+struct hostapd_radius_attr {
+ u8 type;
+ struct wpabuf *val;
+ struct hostapd_radius_attr *next;
+};
+
#define NUM_TX_QUEUES 4
@@ -178,6 +184,8 @@ struct hostapd_bss_config {
struct hostapd_radius_servers *radius;
int acct_interim_interval;
int radius_request_cui;
+ struct hostapd_radius_attr *radius_auth_req_attr;
+ struct hostapd_radius_attr *radius_acct_req_attr;
struct hostapd_ssid ssid;
@@ -455,5 +463,7 @@ const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
const struct hostapd_eap_user *
hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
size_t identity_len, int phase2);
+struct hostapd_radius_attr *
+hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type);
#endif /* HOSTAPD_CONFIG_H */
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 9bb63f5..dd0df1d 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -416,6 +416,7 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
struct radius_msg *msg;
char buf[128];
struct eapol_state_machine *sm = sta->eapol_sm;
+ struct hostapd_radius_attr *attr;
if (sm == NULL)
return;
@@ -442,7 +443,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
goto fail;
}
- if (hapd->conf->own_ip_addr.af == AF_INET &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_NAS_IP_ADDRESS) &&
+ hapd->conf->own_ip_addr.af == AF_INET &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
(u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
printf("Could not add NAS-IP-Address\n");
@@ -450,7 +453,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
}
#ifdef CONFIG_IPV6
- if (hapd->conf->own_ip_addr.af == AF_INET6 &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_NAS_IPV6_ADDRESS) &&
+ hapd->conf->own_ip_addr.af == AF_INET6 &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
(u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
printf("Could not add NAS-IPv6-Address\n");
@@ -458,7 +463,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
}
#endif /* CONFIG_IPV6 */
- if (hapd->conf->nas_identifier &&
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_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))) {
@@ -466,7 +473,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
goto fail;
}
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_NAS_PORT) &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
printf("Could not add NAS-Port\n");
goto fail;
}
@@ -474,7 +483,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
buf[sizeof(buf) - 1] = '\0';
- if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_CALLED_STATION_ID) &&
+ !radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
(u8 *) buf, os_strlen(buf))) {
printf("Could not add Called-Station-Id\n");
goto fail;
@@ -492,12 +503,16 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
/* TODO: should probably check MTU from driver config; 2304 is max for
* IEEE 802.11, but use 1400 to avoid problems with too large packets
*/
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_FRAMED_MTU) &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
printf("Could not add Framed-MTU\n");
goto fail;
}
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_NAS_PORT_TYPE) &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
printf("Could not add NAS-Port-Type\n");
goto fail;
@@ -513,7 +528,9 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
radius_mode_txt(hapd));
buf[sizeof(buf) - 1] = '\0';
}
- if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
+ if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
+ RADIUS_ATTR_CONNECT_INFO) &&
+ !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
(u8 *) buf, os_strlen(buf))) {
printf("Could not add Connect-Info\n");
goto fail;
@@ -560,6 +577,17 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
}
}
+ for (attr = hapd->conf->radius_auth_req_attr; attr; attr = attr->next)
+ {
+ if (!radius_msg_add_attr(msg, attr->type,
+ wpabuf_head(attr->val),
+ wpabuf_len(attr->val))) {
+ wpa_printf(MSG_ERROR, "Could not add RADIUS "
+ "attribute");
+ goto fail;
+ }
+ }
+
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr) < 0)
goto fail;