18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / IEEE 802.11 authentication (ACL) 361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Access control list for IEEE 802.11 authentication can uses statically 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured ACL from configuration files or an external RADIUS server. 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Results from external RADIUS queries are cached to allow faster 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication frame processing. 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha1.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "ieee802_1x.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_ACL_TIMEOUT 30 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_cached_radius_acl { 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_t timestamp; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt macaddr addr; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int accepted; /* HOSTAPD_ACL_* */ 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_cached_radius_acl *next; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 session_timeout; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 acct_interim_interval; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vlan_id; 39d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *psk; 4061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *identity; 4161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *radius_cui; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_acl_query_data { 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_t timestamp; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 radius_id; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt macaddr addr; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *auth_msg; /* IEEE 802.11 authentication frame from station */ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t auth_msg_len; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *next; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e) 5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(e->identity); 5961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(e->radius_cui); 60d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_free_psk_list(e->psk); 6161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(e); 6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_cached_radius_acl *prev; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (acl_cache) { 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = acl_cache; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt acl_cache = acl_cache->next; 7261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_acl_cache_free_entry(prev); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 77d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk, 78d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *src) 79d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 80d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short **copy_to; 81d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *copy_from; 82d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 83d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Copy PSK linked list */ 84d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt copy_to = psk; 85d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt copy_from = src; 86d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt while (copy_from && copy_to) { 87d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *copy_to = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short)); 88d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*copy_to == NULL) 89d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt break; 90d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(*copy_to, copy_from, 91d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sizeof(struct hostapd_sta_wpa_psk_short)); 92d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt copy_from = copy_from->next; 93d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt copy_to = &((*copy_to)->next); 94d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 95d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (copy_to) 96d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *copy_to = NULL; 97d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 98d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 99d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr, 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 *session_timeout, 1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u32 *acct_interim_interval, int *vlan_id, 103d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short **psk, 104d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char **identity, char **radius_cui) 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_cached_radius_acl *entry; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (entry = hapd->acl_cache; entry; entry = entry->next) { 11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_memcmp(entry->addr, addr, ETH_ALEN) != 0) 11361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (now.sec - entry->timestamp > RADIUS_ACL_TIMEOUT) 11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; /* entry has expired */ 11761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT) 11861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (session_timeout) 11961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *session_timeout = entry->session_timeout; 12061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (acct_interim_interval) 12161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *acct_interim_interval = 12261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt entry->acct_interim_interval; 12361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (vlan_id) 12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *vlan_id = entry->vlan_id; 125d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt copy_psk_list(psk, entry->psk); 12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (identity) { 12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (entry->identity) 12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *identity = os_strdup(entry->identity); 12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *identity = NULL; 13161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (radius_cui) { 13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (entry->radius_cui) 13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *radius_cui = os_strdup(entry->radius_cui); 13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *radius_cui = NULL; 13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return entry->accepted; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_acl_query_free(struct hostapd_acl_query_data *query) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query == NULL) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(query->auth_msg); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(query); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr, 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *query) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query->radius_id = radius_client_get_id(hapd->radius); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, query->radius_id); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_make_authenticator(msg, addr, ETH_ALEN); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr)); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(buf))) { 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not add User-Name"); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_attr_user_password( 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, (u8 *) buf, os_strlen(buf), 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->radius->auth_server->shared_secret, 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->radius->auth_server->shared_secret_len)) { 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not add User-Password"); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, 18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt NULL, msg) < 0) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not add Calling-Station-Id"); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "CONNECT 11Mbps 802.11b"); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not add Connect-Info"); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0) 20404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto fail; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_allowed_address - Check whether a specified STA can be authenticated 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: MAC address of the STA 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Authentication message 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of msg in octets 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @session_timeout: Buffer for returning session timeout (from RADIUS) 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @acct_interim_interval: Buffer for returning account interval (from RADIUS) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vlan_id: Buffer for returning VLAN ID 223d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * @psk: Linked list buffer for returning WPA PSK 22461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @identity: Buffer for returning identity (from RADIUS) 22561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @radius_cui: Buffer for returning CUI (from RADIUS) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING 22761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 22861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * The caller is responsible for freeing the returned *identity and *radius_cui 22961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * values with os_free(). 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *msg, size_t len, u32 *session_timeout, 2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u32 *acct_interim_interval, int *vlan_id, 234d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short **psk, 235d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char **identity, char **radius_cui) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (session_timeout) 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *session_timeout = 0; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (acct_interim_interval) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *acct_interim_interval = 0; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vlan_id) 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vlan_id = 0; 2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (psk) 244d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *psk = NULL; 24561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (identity) 24661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *identity = NULL; 24761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (radius_cui) 24861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *radius_cui = NULL; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_maclist_found(hapd->conf->accept_mac, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->num_accept_mac, addr, vlan_id)) 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_ACCEPT; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_maclist_found(hapd->conf->deny_mac, 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->num_deny_mac, addr, vlan_id)) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_ACCEPT; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_RADIUS 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_RADIUS */ 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *query; 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time t; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check whether ACL cache has an entry for this station */ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = hostapd_acl_cache_get(hapd, addr, session_timeout, 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt acct_interim_interval, 273d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt vlan_id, psk, 27461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt identity, radius_cui); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_ACCEPT || 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res == HOSTAPD_ACL_ACCEPT_TIMEOUT) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_REJECT) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = hapd->acl_queries; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (query) { 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) { 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* pending query in RADIUS retransmit queue; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * do not generate a new one */ 28661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (identity) { 28761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(*identity); 28861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *identity = NULL; 28961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 29061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (radius_cui) { 29161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(*radius_cui); 29261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *radius_cui = NULL; 29361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_PENDING; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = query->next; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hapd->conf->radius->auth_server) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No entry in the cache - query external RADIUS server */ 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = os_zalloc(sizeof(*query)); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query == NULL) { 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "malloc for query data failed"); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&t); 3091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt query->timestamp = t.sec; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(query->addr, addr, ETH_ALEN); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_radius_acl_query(hapd, addr, query)) { 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to send Access-Request " 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for ACL query."); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_query_free(query); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query->auth_msg = os_malloc(len); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query->auth_msg == NULL) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to allocate memory for " 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "auth frame."); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_query_free(query); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(query->auth_msg, msg, len); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query->auth_msg_len = len; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query->next = hapd->acl_queries; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->acl_queries = query; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Queued data will be processed in hostapd_acl_recv_radius() 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when RADIUS server replies to the sent Access-Request. */ 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_PENDING; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return HOSTAPD_ACL_REJECT; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_acl_expire_cache(struct hostapd_data *hapd, os_time_t now) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_cached_radius_acl *prev, *entry, *tmp; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = hapd->acl_cache; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (now - entry->timestamp > RADIUS_ACL_TIMEOUT) { 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Cached ACL entry for " MACSTR 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " has expired.", MAC2STR(entry->addr)); 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->acl_cache = entry->next; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_radius_acl_expire(hapd, entry->addr); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = entry; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 35961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_acl_cache_free_entry(tmp); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_acl_expire_queries(struct hostapd_data *hapd, 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_t now) 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *prev, *entry, *tmp; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = hapd->acl_queries; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (now - entry->timestamp > RADIUS_ACL_TIMEOUT) { 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACL query for " MACSTR 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " has expired.", MAC2STR(entry->addr)); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->acl_queries = entry->next; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = entry; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_query_free(tmp); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_acl_expire - ACL cache expiration callback 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eloop_ctx: struct hostapd_data * 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @timeout_ctx: Not used 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_acl_expire(void *eloop_ctx, void *timeout_ctx) 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = eloop_ctx; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_expire_cache(hapd, now.sec); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_expire_queries(hapd, now.sec); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void decode_tunnel_passwords(struct hostapd_data *hapd, 417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *shared_secret, 418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t shared_secret_len, 419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct radius_msg *msg, 420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct radius_msg *req, 421d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_cached_radius_acl *cache) 422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 423d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int passphraselen; 424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char *passphrase, *strpassphrase; 425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t i; 426d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *psk; 427d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 428d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 429d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Decode all tunnel passwords as PSK and save them into a linked list. 430d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 431d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for (i = 0; ; i++) { 432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt passphrase = radius_msg_get_tunnel_password( 433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt msg, &passphraselen, shared_secret, shared_secret_len, 434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt req, i); 435d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 436d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Passphrase is NULL iff there is no i-th Tunnel-Password 437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * attribute in msg. 438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (passphrase == NULL) 440d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt break; 441d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 442d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * passphrase does not contain the NULL termination. 443d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Add it here as pbkdf2_sha1() requires it. 444d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 445d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt strpassphrase = os_zalloc(passphraselen + 1); 446d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short)); 447d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (strpassphrase && psk) { 448d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(strpassphrase, passphrase, passphraselen); 449d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pbkdf2_sha1(strpassphrase, 450d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hapd->conf->ssid.ssid, 451d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hapd->conf->ssid.ssid_len, 4096, 452d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk->psk, PMK_LEN); 453d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk->next = cache->psk; 454d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt cache->psk = psk; 455d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk = NULL; 456d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 457d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(strpassphrase); 458d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(psk); 459d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(passphrase); 460d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 461d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 462d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 463d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_acl_recv_radius - Process incoming RADIUS Authentication messages 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: RADIUS response message 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @req: RADIUS request message 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @shared_secret: RADIUS shared secret 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @shared_secret_len: Length of shared_secret in octets 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Context data (struct hostapd_data *) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: RADIUS_RX_PROCESSED if RADIUS message was a reply to ACL query (and 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * was processed here) or RADIUS_RX_UNKNOWN if not. 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic RadiusRxResult 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *shared_secret, size_t shared_secret_len, 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *data) 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = data; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *query, *prev; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_cached_radius_acl *cache; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(msg); 4831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time t; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = hapd->acl_queries; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (query) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query->radius_id == hdr->identifier) 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = query; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = query->next; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query == NULL) 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Found matching Access-Request for RADIUS " 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message (id=%d)", query->radius_id); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) { 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have " 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "correct authenticator - dropped\n"); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_INVALID_AUTHENTICATOR; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code != RADIUS_CODE_ACCESS_REJECT) { 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Unknown RADIUS message code %d to ACL " 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "query", hdr->code); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Insert Accept/Reject info into ACL cache */ 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache = os_zalloc(sizeof(*cache)); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cache == NULL) { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to add ACL cache entry"); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&t); 5191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cache->timestamp = t.sec; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { 52261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *buf; 52361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len; 5241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cache->session_timeout) == 0) 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->accepted = HOSTAPD_ACL_ACCEPT; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_attr_int32( 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cache->acct_interim_interval) == 0 && 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->acct_interim_interval < 60) { 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Ignored too small " 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Acct-Interim-Interval %d for STA " MACSTR, 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->acct_interim_interval, 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(query->addr)); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->acct_interim_interval = 0; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->vlan_id = radius_msg_get_vlanid(msg); 5431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 544d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt decode_tunnel_passwords(hapd, shared_secret, shared_secret_len, 545d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt msg, req, cache); 546d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, 54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &buf, &len, NULL) == 0) { 54961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt cache->identity = os_zalloc(len + 1); 55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (cache->identity) 55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(cache->identity, buf, len); 55261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 55361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (radius_msg_get_attr_ptr( 55461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &buf, &len, NULL) == 0) { 55661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt cache->radius_cui = os_zalloc(len + 1); 55761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (cache->radius_cui) 55861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(cache->radius_cui, buf, len); 55961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 5601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED && 562d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt !cache->psk) 5631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cache->accepted = HOSTAPD_ACL_REJECT; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->accepted = HOSTAPD_ACL_REJECT; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->next = hapd->acl_cache; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->acl_cache = cache; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DRIVER_RADIUS_ACL 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted, 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cache->session_timeout); 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_DRIVER_RADIUS_ACL */ 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-send original authentication frame for 802.11 processing */ 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Re-sending authentication frame after " 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successful RADIUS ACL query"); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */ 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DRIVER_RADIUS_ACL */ 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt done: 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->acl_queries = query->next; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = query->next; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_query_free(query); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_PROCESSED; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_acl_init: Initialize IEEE 802.11 ACL 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_acl_init(struct hostapd_data *hapd) 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_client_register(hapd->radius, RADIUS_AUTH, 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_recv_radius, hapd)) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_acl_deinit - Deinitialize IEEE 802.11 ACL 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_acl_deinit(struct hostapd_data *hapd) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_acl_query_data *query, *prev; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(hostapd_acl_expire, hapd, NULL); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_cache_free(hapd->acl_cache); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = hapd->acl_queries; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (query) { 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = query; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query = query->next; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_query_free(prev); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 634d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 635d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 636d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk) 637d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 638d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt while (psk) { 639d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *prev = psk; 640d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk = psk->next; 641d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(prev); 642d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 643d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 644