int hostapd_allowed_address(hostapd *hapd, u8 *addr, u8 *msg, size_t len, u32 *session_timeout, u32 *acct_interim_interval) { *session_timeout = 0; *acct_interim_interval = 0; if (hostapd_maclist_found(hapd->conf->accept_mac, hapd->conf->num_accept_mac, addr)) return HOSTAPD_ACL_ACCEPT; if (hostapd_maclist_found(hapd->conf->deny_mac, hapd->conf->num_deny_mac, addr)) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) return HOSTAPD_ACL_ACCEPT; if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { struct hostapd_acl_query_data *query; /* Check whether ACL cache has an entry for this station */ int res = hostapd_acl_cache_get(hapd, addr, session_timeout, acct_interim_interval); if (res == HOSTAPD_ACL_ACCEPT || res == HOSTAPD_ACL_ACCEPT_TIMEOUT) return res; if (res == HOSTAPD_ACL_REJECT) return HOSTAPD_ACL_REJECT; query = hapd->acl_queries; while (query) { if (memcmp(query->addr, addr, ETH_ALEN) == 0) { /* pending query in RADIUS retransmit queue; * do not generate a new one */ return HOSTAPD_ACL_PENDING; } query = query->next; } if (!hapd->conf->auth_server) return HOSTAPD_ACL_REJECT; /* No entry in the cache - query external RADIUS server */ query = malloc(sizeof(*query)); if (query == NULL) { printf("malloc for query data failed\n"); return HOSTAPD_ACL_REJECT; } memset(query, 0, sizeof(*query)); time(&query->timestamp); memcpy(query->addr, addr, ETH_ALEN); if (hostapd_radius_acl_query(hapd, addr, query)) { printf("Failed to send Access-Request for ACL " "query.\n"); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } query->auth_msg = malloc(len); if (query->auth_msg == NULL) { printf("Failed to allocate memory for auth frame.\n"); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } memcpy(query->auth_msg, msg, len); query->auth_msg_len = len; query->next = hapd->acl_queries; hapd->acl_queries = query; /* Queued data will be processed in hostapd_acl_recv_radius() * when RADIUS server replies to the sent Access-Request. */ return HOSTAPD_ACL_PENDING; } return HOSTAPD_ACL_REJECT; }
/** * hostapd_allowed_address - Check whether a specified STA can be authenticated * @hapd: hostapd BSS data * @addr: MAC address of the STA * @msg: Authentication message * @len: Length of msg in octets * @session_timeout: Buffer for returning session timeout (from RADIUS) * @acct_interim_interval: Buffer for returning account interval (from RADIUS) * @vlan_id: Buffer for returning VLAN ID * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING */ 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) { if (session_timeout) *session_timeout = 0; if (acct_interim_interval) *acct_interim_interval = 0; if (vlan_id) *vlan_id = 0; if (hostapd_maclist_found(hapd->conf->accept_mac, hapd->conf->num_accept_mac, addr, vlan_id)) return HOSTAPD_ACL_ACCEPT; if (hostapd_maclist_found(hapd->conf->deny_mac, hapd->conf->num_deny_mac, addr, vlan_id)) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) return HOSTAPD_ACL_ACCEPT; if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { #ifdef CONFIG_NO_RADIUS return HOSTAPD_ACL_REJECT; #else /* CONFIG_NO_RADIUS */ struct hostapd_acl_query_data *query; /* 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); if (res == HOSTAPD_ACL_ACCEPT || res == HOSTAPD_ACL_ACCEPT_TIMEOUT) return res; if (res == HOSTAPD_ACL_REJECT) return HOSTAPD_ACL_REJECT; query = hapd->acl_queries; while (query) { if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) { /* pending query in RADIUS retransmit queue; * do not generate a new one */ return HOSTAPD_ACL_PENDING; } query = query->next; } if (!hapd->conf->radius->auth_server) return HOSTAPD_ACL_REJECT; /* No entry in the cache - query external RADIUS server */ query = os_zalloc(sizeof(*query)); if (query == NULL) { wpa_printf(MSG_ERROR, "malloc for query data failed"); return HOSTAPD_ACL_REJECT; } time(&query->timestamp); os_memcpy(query->addr, addr, ETH_ALEN); if (hostapd_radius_acl_query(hapd, addr, query)) { wpa_printf(MSG_DEBUG, "Failed to send Access-Request " "for ACL query."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } query->auth_msg = os_malloc(len); if (query->auth_msg == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "auth frame."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } os_memcpy(query->auth_msg, msg, len); query->auth_msg_len = len; query->next = hapd->acl_queries; hapd->acl_queries = query; /* Queued data will be processed in hostapd_acl_recv_radius() * when RADIUS server replies to the sent Access-Request. */ return HOSTAPD_ACL_PENDING; #endif /* CONFIG_NO_RADIUS */ } return HOSTAPD_ACL_REJECT; }
/** * hostapd_allowed_address - Check whether a specified STA can be authenticated * @hapd: hostapd BSS data * @addr: MAC address of the STA * @msg: Authentication message * @len: Length of msg in octets * @session_timeout: Buffer for returning session timeout (from RADIUS) * @acct_interim_interval: Buffer for returning account interval (from RADIUS) * @vlan_id: Buffer for returning VLAN ID * @psk: Linked list buffer for returning WPA PSK * @identity: Buffer for returning identity (from RADIUS) * @radius_cui: Buffer for returning CUI (from RADIUS) * @is_probe_req: Whether this query for a Probe Request frame * 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, struct vlan_description *vlan_id, struct hostapd_sta_wpa_psk_short **psk, char **identity, char **radius_cui, int is_probe_req) { int res; if (session_timeout) *session_timeout = 0; if (acct_interim_interval) *acct_interim_interval = 0; if (vlan_id) os_memset(vlan_id, 0, sizeof(*vlan_id)); if (psk) *psk = NULL; if (identity) *identity = NULL; if (radius_cui) *radius_cui = NULL; res = hostapd_check_acl(hapd, addr, vlan_id); if (res != HOSTAPD_ACL_PENDING) return res; if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { #ifdef CONFIG_NO_RADIUS return HOSTAPD_ACL_REJECT; #else /* CONFIG_NO_RADIUS */ struct hostapd_acl_query_data *query; if (is_probe_req) { /* Skip RADIUS queries for Probe Request frames to avoid * excessive load on the authentication server. */ return HOSTAPD_ACL_ACCEPT; }; if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED) vlan_id = NULL; /* Check whether ACL cache has an entry for this station */ res = hostapd_acl_cache_get(hapd, addr, session_timeout, acct_interim_interval, vlan_id, psk, identity, radius_cui); if (res == HOSTAPD_ACL_ACCEPT || res == HOSTAPD_ACL_ACCEPT_TIMEOUT) return res; if (res == HOSTAPD_ACL_REJECT) return HOSTAPD_ACL_REJECT; query = hapd->acl_queries; while (query) { 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; } if (!hapd->conf->radius->auth_server) return HOSTAPD_ACL_REJECT; /* No entry in the cache - query external RADIUS server */ query = os_zalloc(sizeof(*query)); if (query == NULL) { wpa_printf(MSG_ERROR, "malloc for query data failed"); return HOSTAPD_ACL_REJECT; } os_get_reltime(&query->timestamp); os_memcpy(query->addr, addr, ETH_ALEN); if (hostapd_radius_acl_query(hapd, addr, query)) { wpa_printf(MSG_DEBUG, "Failed to send Access-Request " "for ACL query."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } query->auth_msg = os_memdup(msg, len); if (query->auth_msg == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "auth frame."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } query->auth_msg_len = len; query->next = hapd->acl_queries; hapd->acl_queries = query; /* Queued data will be processed in hostapd_acl_recv_radius() * when RADIUS server replies to the sent Access-Request. */ return HOSTAPD_ACL_PENDING; #endif /* CONFIG_NO_RADIUS */ } return HOSTAPD_ACL_REJECT; }