Move wpa_drivers dependency into config_file.c
[libeap.git] / hostapd / ieee802_1x.c
index 322026c..9340709 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * hostapd / IEEE 802.1X-2004 Authenticator
- * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include "hostapd.h"
 #include "ieee802_1x.h"
 #include "accounting.h"
-#include "sta_flags.h"
 #include "sta_info.h"
 #include "wpa.h"
 #include "preauth.h"
 #include "pmksa_cache.h"
-#include "driver_i.h"
+#include "config.h"
 #include "hw_features.h"
 #include "eap_server/eap.h"
 
@@ -71,7 +70,7 @@ static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
        if (sta->flags & WLAN_STA_PREAUTH) {
                rsn_preauth_send(hapd, sta, buf, len);
        } else {
-               hostapd_send_eapol(hapd, sta->addr, buf, len, encrypt);
+               hapd->drv.send_eapol(hapd, sta->addr, buf, len, encrypt);
        }
 
        os_free(buf);
@@ -91,8 +90,7 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
                        wpa_msg(hapd->msg_ctx, MSG_INFO,
                                AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
                sta->flags |= WLAN_STA_AUTHORIZED;
-               res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-                                           WLAN_STA_AUTHORIZED, ~0);
+               res = hapd->drv.set_authorized(hapd, sta, 1);
                hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
                               HOSTAPD_LEVEL_DEBUG, "authorizing port");
        } else {
@@ -102,8 +100,7 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
                                AP_STA_DISCONNECTED MACSTR,
                                MAC2STR(sta->addr));
                sta->flags &= ~WLAN_STA_AUTHORIZED;
-               res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-                                           0, ~WLAN_STA_AUTHORIZED);
+               res = hapd->drv.set_authorized(hapd, sta, 0);
                hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
                               HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
        }
@@ -232,8 +229,8 @@ ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
        wpa_hexdump_key(MSG_DEBUG, "Default WEP key (dynamic VLAN)",
                        key->key[key->idx], key->len[key->idx]);
 
-       if (hostapd_set_key(ifname, hapd, WPA_ALG_WEP, NULL, key->idx, 1,
-                           NULL, 0, key->key[key->idx], key->len[key->idx]))
+       if (hapd->drv.set_key(ifname, hapd, WPA_ALG_WEP, NULL, key->idx, 1,
+                             NULL, 0, key->key[key->idx], key->len[key->idx]))
                printf("Could not set dynamic VLAN WEP encryption key.\n");
 
        hostapd_set_drv_ieee8021x(hapd, ifname, 1);
@@ -348,9 +345,9 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
 
                /* TODO: set encryption in TX callback, i.e., only after STA
                 * has ACKed EAPOL-Key frame */
-               if (hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
-                                   sta->addr, 0, 1, NULL, 0, ikey,
-                                   hapd->conf->individual_wep_key_len)) {
+               if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
+                                     sta->addr, 0, 1, NULL, 0, ikey,
+                                     hapd->conf->individual_wep_key_len)) {
                        wpa_printf(MSG_ERROR, "Could not set individual WEP "
                                   "encryption.");
                }
@@ -362,10 +359,7 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
 
 const char *radius_mode_txt(struct hostapd_data *hapd)
 {
-       if (hapd->iface->current_mode == NULL)
-               return "802.11";
-
-       switch (hapd->iface->current_mode->mode) {
+       switch (hapd->iface->conf->hw_mode) {
        case HOSTAPD_MODE_IEEE80211A:
                return "802.11a";
        case HOSTAPD_MODE_IEEE80211G:
@@ -540,7 +534,8 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
 
        /* State attribute must be copied if and only if this packet is
         * Access-Request reply to the previous Access-Challenge */
-       if (sm->last_recv_radius && sm->last_recv_radius->hdr->code ==
+       if (sm->last_recv_radius &&
+           radius_msg_get_hdr(sm->last_recv_radius)->code ==
            RADIUS_CODE_ACCESS_CHALLENGE) {
                int res = radius_msg_copy_attr(msg, sm->last_recv_radius,
                                               RADIUS_ATTR_STATE);
@@ -559,7 +554,6 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
 
  fail:
        radius_msg_free(msg);
-       os_free(msg);
 }
 #endif /* CONFIG_NO_RADIUS */
 
@@ -923,10 +917,7 @@ void ieee802_1x_free_station(struct sta_info *sta)
        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_msg_free(sm->last_recv_radius);
        radius_free_class(&sm->radius_class);
 #endif /* CONFIG_NO_RADIUS */
 
@@ -1202,8 +1193,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
        int session_timeout_set, old_vlanid = 0;
        struct eapol_state_machine *sm;
        int override_eapReq = 0;
+       struct radius_hdr *hdr = radius_msg_get_hdr(msg);
 
-       sm = ieee802_1x_search_radius_identifier(hapd, msg->hdr->identifier);
+       sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier);
        if (sm == NULL) {
                wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching "
                           "station for this RADIUS message");
@@ -1213,7 +1205,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
 
        /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
         * present when packet contains an EAP-Message attribute */
-       if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
+       if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
            radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
                                0) < 0 &&
            radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
@@ -1227,9 +1219,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
                return RADIUS_RX_INVALID_AUTHENTICATOR;
        }
 
-       if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
-           msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
-           msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
+       if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
+           hdr->code != RADIUS_CODE_ACCESS_REJECT &&
+           hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
                printf("Unknown RADIUS message code\n");
                return RADIUS_RX_UNKNOWN;
        }
@@ -1238,11 +1230,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
        wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR,
                   MAC2STR(sta->addr));
 
-       if (sm->last_recv_radius) {
-               radius_msg_free(sm->last_recv_radius);
-               os_free(sm->last_recv_radius);
-       }
-
+       radius_msg_free(sm->last_recv_radius);
        sm->last_recv_radius = msg;
 
        session_timeout_set =
@@ -1253,7 +1241,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
                termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
 
        if (hapd->conf->acct_interim_interval == 0 &&
-           msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
+           hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
            radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
                                      &acct_interim_interval) == 0) {
                if (acct_interim_interval < 60) {
@@ -1268,7 +1256,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
        }
 
 
-       switch (msg->hdr->code) {
+       switch (hdr->code) {
        case RADIUS_CODE_ACCESS_ACCEPT:
                if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
                        sta->vlan_id = 0;
@@ -1365,11 +1353,8 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
                       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;
-       }
+       radius_msg_free(sm->last_recv_radius);
+       sm->last_recv_radius = NULL;
 #endif /* CONFIG_NO_RADIUS */
 
        if (sm->eap_if->eapTimeout) {
@@ -1379,13 +1364,8 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
                 * 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;
+               ap_sta_disconnect(hapd, sta, sta->addr,
+                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
        }
 }
 
@@ -1452,10 +1432,10 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
 
        /* TODO: Could setup key for RX here, but change default TX keyid only
         * after new broadcast key has been sent to all stations. */
-       if (hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, NULL,
-                           eapol->default_wep_key_idx, 1, NULL, 0,
-                           eapol->default_wep_key,
-                           hapd->conf->default_wep_key_len)) {
+       if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, NULL,
+                             eapol->default_wep_key_idx, 1, NULL, 0,
+                             eapol->default_wep_key,
+                             hapd->conf->default_wep_key_len)) {
                hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
                               HOSTAPD_LEVEL_WARNING, "failed to configure a "
                               "new broadcast key");
@@ -1674,11 +1654,10 @@ int ieee802_1x_init(struct hostapd_data *hapd)
 #endif /* CONFIG_NO_RADIUS */
 
        if (hapd->conf->default_wep_key_len) {
-               hostapd_set_privacy(hapd, 1);
-
                for (i = 0; i < 4; i++)
-                       hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
-                                       NULL, i, 0, NULL, 0, NULL, 0);
+                       hapd->drv.set_key(hapd->conf->iface, hapd,
+                                         WPA_ALG_NONE, NULL, i, 0, NULL, 0,
+                                         NULL, 0);
 
                ieee802_1x_rekey(hapd, NULL);