#include "wpa.h"
#include "preauth.h"
#include "pmksa_cache.h"
-#include "driver.h"
+#include "driver_i.h"
#include "hw_features.h"
#include "eap_server/eap.h"
+#include "ieee802_11_defs.h"
static void ieee802_1x_finished(struct hostapd_data *hapd,
}
+#ifndef CONFIG_NO_VLAN
static struct hostapd_wep_keys *
ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
{
return ssid->dyn_vlan_keys[vlan_id];
}
+#endif /* CONFIG_NO_VLAN */
void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
{
- struct hostapd_wep_keys *key = NULL;
struct eapol_state_machine *sm = sta->eapol_sm;
+#ifndef CONFIG_NO_VLAN
+ struct hostapd_wep_keys *key = NULL;
int vlan_id;
+#endif /* CONFIG_NO_VLAN */
if (sm == NULL || !sm->eap_if->eapKeyData)
return;
wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR,
MAC2STR(sta->addr));
+#ifndef CONFIG_NO_VLAN
vlan_id = sta->vlan_id;
if (vlan_id < 0 || vlan_id > MAX_VLAN_ID)
vlan_id = 0;
ieee802_1x_tx_key_one(hapd, sta, key->idx, 1,
key->key[key->idx],
key->len[key->idx]);
- } else if (hapd->default_wep_key) {
+ } else
+#endif /* CONFIG_NO_VLAN */
+ if (hapd->default_wep_key) {
ieee802_1x_tx_key_one(hapd, sta, hapd->default_wep_key_idx, 1,
hapd->default_wep_key,
hapd->conf->default_wep_key_len);
}
+#ifndef CONFIG_NO_RADIUS
static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
struct eapol_state_machine *sm,
const u8 *eap, size_t len)
radius_msg_free(msg);
os_free(msg);
}
+#endif /* CONFIG_NO_RADIUS */
char *eap_type_text(u8 type)
}
-/* Process the EAPOL frames from the Supplicant */
+/**
+ * ieee802_1x_receive - Process the EAPOL frames from the Supplicant
+ * @hapd: hostapd BSS data
+ * @sa: Source address (sender of the EAPOL frame)
+ * @buf: EAPOL frame
+ * @len: Length of buf in octets
+ *
+ * This function is called for each incoming EAPOL frame from the interface
+ */
void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
size_t len)
{
wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
(unsigned long) len, MAC2STR(sa));
sta = ap_get_sta(hapd, sa);
- if (!sta) {
- printf(" no station information available\n");
+ if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
+ wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
+ "associated STA");
return;
}
}
+/**
+ * ieee802_1x_new_station - Start IEEE 802.1X authentication
+ * @hapd: hostapd BSS data
+ * @sta: The station
+ *
+ * This function is called to start IEEE 802.1X authentication when a new
+ * station completes IEEE 802.11 association.
+ */
void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
{
struct rsn_pmksa_cache_entry *pmksa;
}
-void ieee802_1x_free_radius_class(struct radius_class_data *class)
-{
- size_t i;
- if (class == NULL)
- return;
- for (i = 0; i < class->count; i++)
- os_free(class->attr[i].data);
- os_free(class->attr);
- class->attr = NULL;
- class->count = 0;
-}
-
-
-int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
- const struct radius_class_data *src)
-{
- size_t i;
-
- if (src->attr == NULL)
- return 0;
-
- dst->attr = os_zalloc(src->count * sizeof(struct radius_attr_data));
- if (dst->attr == NULL)
- return -1;
-
- dst->count = 0;
-
- for (i = 0; i < src->count; i++) {
- dst->attr[i].data = os_malloc(src->attr[i].len);
- if (dst->attr[i].data == NULL)
- break;
- dst->count++;
- os_memcpy(dst->attr[i].data, src->attr[i].data,
- src->attr[i].len);
- dst->attr[i].len = src->attr[i].len;
- }
-
- return 0;
-}
-
-
void ieee802_1x_free_station(struct sta_info *sta)
{
struct eapol_state_machine *sm = sta->eapol_sm;
sta->eapol_sm = NULL;
+#ifndef CONFIG_NO_RADIUS
if (sm->last_recv_radius) {
radius_msg_free(sm->last_recv_radius);
os_free(sm->last_recv_radius);
}
+ radius_free_class(&sm->radius_class);
+#endif /* CONFIG_NO_RADIUS */
os_free(sm->identity);
- ieee802_1x_free_radius_class(&sm->radius_class);
eapol_auth_free(sm);
}
+#ifndef CONFIG_NO_RADIUS
static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
struct sta_info *sta)
{
static void ieee802_1x_get_keys(struct hostapd_data *hapd,
struct sta_info *sta, struct radius_msg *msg,
struct radius_msg *req,
- u8 *shared_secret, size_t shared_secret_len)
+ const u8 *shared_secret,
+ size_t shared_secret_len)
{
struct radius_ms_mppe_keys *keys;
struct eapol_state_machine *sm = sta->eapol_sm;
sm == NULL)
return;
- ieee802_1x_free_radius_class(&sm->radius_class);
+ radius_free_class(&sm->radius_class);
count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
if (count <= 0)
return;
}
-/* Process the RADIUS frames from Authentication Server */
+/**
+ * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server
+ * @msg: RADIUS response message
+ * @req: RADIUS request message
+ * @shared_secret: RADIUS shared secret
+ * @shared_secret_len: Length of shared_secret in octets
+ * @data: Context data (struct hostapd_data *)
+ * Returns: Processing status
+ */
static RadiusRxResult
ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
- u8 *shared_secret, size_t shared_secret_len,
+ const u8 *shared_secret, size_t shared_secret_len,
void *data)
{
struct hostapd_data *hapd = data;
case RADIUS_CODE_ACCESS_ACCEPT:
if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
sta->vlan_id = 0;
+#ifndef CONFIG_NO_VLAN
else {
old_vlanid = sta->vlan_id;
sta->vlan_id = radius_msg_get_vlanid(msg);
"ID in Access-Accept");
break;
}
+#endif /* CONFIG_NO_VLAN */
ap_sta_bind_vlan(hapd, sta, old_vlanid);
return RADIUS_RX_QUEUED;
}
+#endif /* CONFIG_NO_RADIUS */
void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG, "aborting authentication");
+#ifndef CONFIG_NO_RADIUS
if (sm->last_recv_radius) {
radius_msg_free(sm->last_recv_radius);
os_free(sm->last_recv_radius);
sm->last_recv_radius = NULL;
}
+#endif /* CONFIG_NO_RADIUS */
+
+ if (sm->eap_if->eapTimeout) {
+ /*
+ * Disconnect the STA since it did not reply to the last EAP
+ * request and we cannot continue EAP processing (EAP-Failure
+ * could only be sent if the EAP peer actually replied).
+ */
+ sm->eap_if->portEnabled = FALSE;
+ hostapd_sta_deauth(hapd, sta->addr,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+ sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
+ WLAN_STA_AUTHORIZED);
+ eloop_cancel_timeout(ap_handle_timer, hapd, sta);
+ eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
+ sta->timeout_next = STA_REMOVE;
+ }
}
static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
const u8 *data, size_t datalen)
{
+#ifndef CONFIG_NO_RADIUS
struct hostapd_data *hapd = ctx;
struct sta_info *sta = sta_ctx;
ieee802_1x_encapsulate_radius(hapd, sta, data, datalen);
+#endif /* CONFIG_NO_RADIUS */
}
static void ieee802_1x_logger(void *ctx, const u8 *addr,
eapol_logger_level level, const char *txt)
{
+#ifndef CONFIG_NO_HOSTAPD_LOGGER
struct hostapd_data *hapd = ctx;
int hlevel;
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s",
txt);
+#endif /* CONFIG_NO_HOSTAPD_LOGGER */
}
hostapd_set_ieee8021x(hapd->conf->iface, hapd, 1))
return -1;
+#ifndef CONFIG_NO_RADIUS
if (radius_client_register(hapd->radius, RADIUS_AUTH,
ieee802_1x_receive_auth, hapd))
return -1;
+#endif /* CONFIG_NO_RADIUS */
if (hapd->conf->default_wep_key_len) {
hostapd_set_privacy(hapd, 1);
int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
- u8 *buf, size_t len, int ack)
+ const u8 *buf, size_t len, int ack)
{
struct ieee80211_hdr *hdr;
struct ieee802_1x_hdr *xhdr;