preauth.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #ifdef CONFIG_RSN_PREAUTH
00019 
00020 #include "hostapd.h"
00021 #include "config.h"
00022 #include "l2_packet/l2_packet.h"
00023 #include "ieee802_1x.h"
00024 #include "eloop.h"
00025 #include "sta_info.h"
00026 #include "wpa_common.h"
00027 #include "eapol_sm.h"
00028 #include "wpa.h"
00029 #include "preauth.h"
00030 
00031 #ifndef ETH_P_PREAUTH
00032 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
00033 #endif /* ETH_P_PREAUTH */
00034 
00035 static const int dot11RSNAConfigPMKLifetime = 43200;
00036 
00037 struct rsn_preauth_interface {
00038         struct rsn_preauth_interface *next;
00039         struct hostapd_data *hapd;
00040         struct l2_packet_data *l2;
00041         char *ifname;
00042         int ifindex;
00043 };
00044 
00045 
00046 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
00047                                 const u8 *buf, size_t len)
00048 {
00049         struct rsn_preauth_interface *piface = ctx;
00050         struct hostapd_data *hapd = piface->hapd;
00051         struct ieee802_1x_hdr *hdr;
00052         struct sta_info *sta;
00053         struct l2_ethhdr *ethhdr;
00054 
00055         wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet "
00056                    "from interface '%s'", piface->ifname);
00057         if (len < sizeof(*ethhdr) + sizeof(*hdr)) {
00058                 wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet "
00059                            "(len=%lu)", (unsigned long) len);
00060                 return;
00061         }
00062 
00063         ethhdr = (struct l2_ethhdr *) buf;
00064         hdr = (struct ieee802_1x_hdr *) (ethhdr + 1);
00065 
00066         if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) {
00067                 wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address "
00068                            MACSTR, MAC2STR(ethhdr->h_dest));
00069                 return;
00070         }
00071 
00072         sta = ap_get_sta(hapd, ethhdr->h_source);
00073         if (sta && (sta->flags & WLAN_STA_ASSOC)) {
00074                 wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association "
00075                            "STA " MACSTR, MAC2STR(sta->addr));
00076                 return;
00077         }
00078         if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
00079                 sta = ap_sta_add(hapd, ethhdr->h_source);
00080                 if (sta == NULL)
00081                         return;
00082                 sta->flags = WLAN_STA_PREAUTH;
00083 
00084                 ieee802_1x_new_station(hapd, sta);
00085                 if (sta->eapol_sm == NULL) {
00086                         ap_free_sta(hapd, sta);
00087                         sta = NULL;
00088                 } else {
00089                         sta->eapol_sm->radius_identifier = -1;
00090                         sta->eapol_sm->portValid = TRUE;
00091                         sta->eapol_sm->flags |= EAPOL_SM_PREAUTH;
00092                 }
00093         }
00094         if (sta == NULL)
00095                 return;
00096         sta->preauth_iface = piface;
00097         ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
00098                            len - sizeof(*ethhdr));
00099 }
00100 
00101 
00102 static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
00103 {
00104         struct rsn_preauth_interface *piface;
00105 
00106         wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
00107 
00108         piface = os_zalloc(sizeof(*piface));
00109         if (piface == NULL)
00110                 return -1;
00111         piface->hapd = hapd;
00112 
00113         piface->ifname = os_strdup(ifname);
00114         if (piface->ifname == NULL) {
00115                 goto fail1;
00116         }
00117 
00118         piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH,
00119                                     rsn_preauth_receive, piface, 1);
00120         if (piface->l2 == NULL) {
00121                 wpa_printf(MSG_ERROR, "Failed to open register layer 2 access "
00122                            "to ETH_P_PREAUTH");
00123                 goto fail2;
00124         }
00125 
00126         piface->next = hapd->preauth_iface;
00127         hapd->preauth_iface = piface;
00128         return 0;
00129 
00130 fail2:
00131         os_free(piface->ifname);
00132 fail1:
00133         os_free(piface);
00134         return -1;
00135 }
00136 
00137 
00138 void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
00139 {
00140         struct rsn_preauth_interface *piface, *prev;
00141 
00142         piface = hapd->preauth_iface;
00143         hapd->preauth_iface = NULL;
00144         while (piface) {
00145                 prev = piface;
00146                 piface = piface->next;
00147                 l2_packet_deinit(prev->l2);
00148                 os_free(prev->ifname);
00149                 os_free(prev);
00150         }
00151 }
00152 
00153 
00154 int rsn_preauth_iface_init(struct hostapd_data *hapd)
00155 {
00156         char *tmp, *start, *end;
00157 
00158         if (hapd->conf->rsn_preauth_interfaces == NULL)
00159                 return 0;
00160 
00161         tmp = os_strdup(hapd->conf->rsn_preauth_interfaces);
00162         if (tmp == NULL)
00163                 return -1;
00164         start = tmp;
00165         for (;;) {
00166                 while (*start == ' ')
00167                         start++;
00168                 if (*start == '\0')
00169                         break;
00170                 end = os_strchr(start, ' ');
00171                 if (end)
00172                         *end = '\0';
00173 
00174                 if (rsn_preauth_iface_add(hapd, start)) {
00175                         rsn_preauth_iface_deinit(hapd);
00176                         return -1;
00177                 }
00178 
00179                 if (end)
00180                         start = end + 1;
00181                 else
00182                         break;
00183         }
00184         os_free(tmp);
00185         return 0;
00186 }
00187 
00188 
00189 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
00190 {
00191         struct hostapd_data *hapd = eloop_ctx;
00192         struct sta_info *sta = timeout_ctx;
00193         wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for "
00194                    MACSTR, MAC2STR(sta->addr));
00195         ap_free_sta(hapd, sta);
00196 }
00197 
00198 
00199 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
00200                           int success)
00201 {
00202         const u8 *key;
00203         size_t len;
00204         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
00205                        HOSTAPD_LEVEL_INFO, "pre-authentication %s",
00206                        success ? "succeeded" : "failed");
00207 
00208         key = ieee802_1x_get_key(sta->eapol_sm, &len);
00209         if (len > PMK_LEN)
00210                 len = PMK_LEN;
00211         if (success && key) {
00212                 if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
00213                                                sta->addr,
00214                                                dot11RSNAConfigPMKLifetime,
00215                                                sta->eapol_sm) == 0) {
00216                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
00217                                        HOSTAPD_LEVEL_DEBUG,
00218                                        "added PMKSA cache entry (pre-auth)");
00219                 } else {
00220                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
00221                                        HOSTAPD_LEVEL_DEBUG,
00222                                        "failed to add PMKSA cache entry "
00223                                        "(pre-auth)");
00224                 }
00225         }
00226 
00227         /*
00228          * Finish STA entry removal from timeout in order to avoid freeing
00229          * STA data before the caller has finished processing.
00230          */
00231         eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
00232 }
00233 
00234 
00235 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
00236                       u8 *buf, size_t len)
00237 {
00238         struct rsn_preauth_interface *piface;
00239         struct l2_ethhdr *ethhdr;
00240 
00241         piface = hapd->preauth_iface;
00242         while (piface) {
00243                 if (piface == sta->preauth_iface)
00244                         break;
00245                 piface = piface->next;
00246         }
00247 
00248         if (piface == NULL) {
00249                 wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
00250                            "interface for " MACSTR, MAC2STR(sta->addr));
00251                 return;
00252         }
00253 
00254         ethhdr = os_malloc(sizeof(*ethhdr) + len);
00255         if (ethhdr == NULL)
00256                 return;
00257 
00258         os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
00259         os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
00260         ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH);
00261         os_memcpy(ethhdr + 1, buf, len);
00262 
00263         if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
00264                            sizeof(*ethhdr) + len) < 0) {
00265                 wpa_printf(MSG_ERROR, "Failed to send preauth packet using "
00266                            "l2_packet_send\n");
00267         }
00268         os_free(ethhdr);
00269 }
00270 
00271 
00272 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
00273 {
00274         eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
00275 }
00276 
00277 #endif /* CONFIG_RSN_PREAUTH */
00278 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:48 2009 for hostapd by  doxygen 1.6.1