aboutsummaryrefslogtreecommitdiffstats
path: root/src/ap/ieee802_11_auth.c
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-08-29 16:22:06 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-09-04 17:24:09 -0700
commit61d9df3e62aaa0e87ad05452fcb95142159a17b6 (patch)
tree192ecb010484c58cdec7d39086d64723063268ae /src/ap/ieee802_11_auth.c
parent4b86ea55603eded752b5773179884a35e74e1a89 (diff)
downloadandroid_external_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.tar.gz
android_external_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.tar.bz2
android_external_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.zip
wpa_supplicant: Update to 29-Aug-2012 TOT
commit 6ffdc2f7bd496ace7a46e055f9714e7db4b1f722 Author: Jouni Malinen <jouni@qca.qualcomm.com> Date: Fri Mar 2 22:31:04 2012 +0200 WFD: Add preliminary WSD request processing and response This commit does not yet address support for different device roles, i.e., the same set of subelements are returned regardless of which role was indicated in the request. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com> Change-Id: I9d63acce719b982c02e589bb59602382e82988c8 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/ap/ieee802_11_auth.c')
-rw-r--r--src/ap/ieee802_11_auth.c147
1 files changed, 84 insertions, 63 deletions
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index 0c4c5f32..63ae3452 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -1,6 +1,6 @@
/*
* hostapd / IEEE 802.11 authentication (ACL)
- * 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.
@@ -22,6 +22,7 @@
#include "ap_config.h"
#include "ap_drv_ops.h"
#include "ieee802_11.h"
+#include "ieee802_1x.h"
#include "ieee802_11_auth.h"
#define RADIUS_ACL_TIMEOUT 30
@@ -37,6 +38,8 @@ struct hostapd_cached_radius_acl {
int vlan_id;
int has_psk;
u8 psk[PMK_LEN];
+ char *identity;
+ char *radius_cui;
};
@@ -51,6 +54,14 @@ struct hostapd_acl_query_data {
#ifndef CONFIG_NO_RADIUS
+static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e)
+{
+ os_free(e->identity);
+ os_free(e->radius_cui);
+ os_free(e);
+}
+
+
static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
{
struct hostapd_cached_radius_acl *prev;
@@ -58,7 +69,7 @@ static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
while (acl_cache) {
prev = acl_cache;
acl_cache = acl_cache->next;
- os_free(prev);
+ hostapd_acl_cache_free_entry(prev);
}
}
@@ -66,35 +77,45 @@ static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
u32 *session_timeout,
u32 *acct_interim_interval, int *vlan_id,
- u8 *psk, int *has_psk)
+ u8 *psk, int *has_psk, char **identity,
+ char **radius_cui)
{
struct hostapd_cached_radius_acl *entry;
struct os_time now;
os_get_time(&now);
- entry = hapd->acl_cache;
- while (entry) {
- if (os_memcmp(entry->addr, addr, ETH_ALEN) == 0) {
- if (now.sec - entry->timestamp > RADIUS_ACL_TIMEOUT)
- return -1; /* entry has expired */
- if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
- if (session_timeout)
- *session_timeout =
- entry->session_timeout;
- if (acct_interim_interval)
- *acct_interim_interval =
- entry->acct_interim_interval;
- if (vlan_id)
- *vlan_id = entry->vlan_id;
- if (psk)
- os_memcpy(psk, entry->psk, PMK_LEN);
- if (has_psk)
- *has_psk = entry->has_psk;
- return entry->accepted;
- }
+ for (entry = hapd->acl_cache; entry; entry = entry->next) {
+ if (os_memcmp(entry->addr, addr, ETH_ALEN) != 0)
+ continue;
- entry = entry->next;
+ if (now.sec - entry->timestamp > RADIUS_ACL_TIMEOUT)
+ return -1; /* entry has expired */
+ if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
+ if (session_timeout)
+ *session_timeout = entry->session_timeout;
+ if (acct_interim_interval)
+ *acct_interim_interval =
+ entry->acct_interim_interval;
+ if (vlan_id)
+ *vlan_id = entry->vlan_id;
+ if (psk)
+ os_memcpy(psk, entry->psk, PMK_LEN);
+ if (has_psk)
+ *has_psk = entry->has_psk;
+ if (identity) {
+ if (entry->identity)
+ *identity = os_strdup(entry->identity);
+ else
+ *identity = NULL;
+ }
+ if (radius_cui) {
+ if (entry->radius_cui)
+ *radius_cui = os_strdup(entry->radius_cui);
+ else
+ *radius_cui = NULL;
+ }
+ return entry->accepted;
}
return -1;
@@ -140,37 +161,9 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
goto fail;
}
- if (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)) {
- wpa_printf(MSG_DEBUG, "Could not add NAS-IP-Address");
- goto fail;
- }
-
-#ifdef CONFIG_IPV6
- if (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)) {
- wpa_printf(MSG_DEBUG, "Could not add NAS-IPv6-Address");
- goto fail;
- }
-#endif /* CONFIG_IPV6 */
-
- if (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_DEBUG, "Could not add NAS-Identifier");
+ if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr,
+ NULL, msg) < 0)
goto fail;
- }
-
- 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,
- (u8 *) buf, os_strlen(buf))) {
- wpa_printf(MSG_DEBUG, "Could not add Called-Station-Id");
- goto fail;
- }
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
MAC2STR(addr));
@@ -180,12 +173,6 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
goto fail;
}
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
- RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
- wpa_printf(MSG_DEBUG, "Could not add NAS-Port-Type");
- goto fail;
- }
-
os_snprintf(buf, sizeof(buf), "CONNECT 11Mbps 802.11b");
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
(u8 *) buf, os_strlen(buf))) {
@@ -215,12 +202,18 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
* @vlan_id: Buffer for returning VLAN ID
* @psk: Buffer for returning WPA PSK
* @has_psk: Buffer for indicating whether psk was filled
+ * @identity: Buffer for returning identity (from RADIUS)
+ * @radius_cui: Buffer for returning CUI (from RADIUS)
* Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
+ *
+ * The caller is responsible for freeing the returned *identity and *radius_cui
+ * values with os_free().
*/
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
const u8 *msg, size_t len, u32 *session_timeout,
u32 *acct_interim_interval, int *vlan_id,
- u8 *psk, int *has_psk)
+ u8 *psk, int *has_psk, char **identity,
+ char **radius_cui)
{
if (session_timeout)
*session_timeout = 0;
@@ -232,6 +225,10 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
*has_psk = 0;
if (psk)
os_memset(psk, 0, PMK_LEN);
+ if (identity)
+ *identity = NULL;
+ if (radius_cui)
+ *radius_cui = NULL;
if (hostapd_maclist_found(hapd->conf->accept_mac,
hapd->conf->num_accept_mac, addr, vlan_id))
@@ -256,7 +253,8 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
/* Check whether ACL cache has an entry for this station */
int res = hostapd_acl_cache_get(hapd, addr, session_timeout,
acct_interim_interval,
- vlan_id, psk, has_psk);
+ vlan_id, psk, has_psk,
+ identity, radius_cui);
if (res == HOSTAPD_ACL_ACCEPT ||
res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
return res;
@@ -268,6 +266,14 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) {
/* pending query in RADIUS retransmit queue;
* do not generate a new one */
+ if (identity) {
+ os_free(*identity);
+ *identity = NULL;
+ }
+ if (radius_cui) {
+ os_free(*radius_cui);
+ *radius_cui = NULL;
+ }
return HOSTAPD_ACL_PENDING;
}
query = query->next;
@@ -333,7 +339,7 @@ static void hostapd_acl_expire_cache(struct hostapd_data *hapd, os_time_t now)
hostapd_drv_set_radius_acl_expire(hapd, entry->addr);
tmp = entry;
entry = entry->next;
- os_free(tmp);
+ hostapd_acl_cache_free_entry(tmp);
continue;
}
@@ -450,6 +456,8 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
int passphraselen;
char *passphrase;
+ u8 *buf;
+ size_t len;
if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
&cache->session_timeout) == 0)
@@ -491,6 +499,19 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
}
os_free(passphrase);
}
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
+ &buf, &len, NULL) == 0) {
+ cache->identity = os_zalloc(len + 1);
+ if (cache->identity)
+ os_memcpy(cache->identity, buf, len);
+ }
+ if (radius_msg_get_attr_ptr(
+ msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
+ &buf, &len, NULL) == 0) {
+ cache->radius_cui = os_zalloc(len + 1);
+ if (cache->radius_cui)
+ os_memcpy(cache->radius_cui, buf, len);
+ }
if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED &&
!cache->has_psk)