2 * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication
3 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_RSN_PREAUTH
21 #include "l2_packet/l2_packet.h"
22 #include "ieee802_1x.h"
24 #include "sta_flags.h"
26 #include "common/wpa_common.h"
32 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
33 #endif /* ETH_P_PREAUTH */
35 static const int dot11RSNAConfigPMKLifetime = 43200;
37 struct rsn_preauth_interface {
38 struct rsn_preauth_interface *next;
39 struct hostapd_data *hapd;
40 struct l2_packet_data *l2;
46 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
47 const u8 *buf, size_t len)
49 struct rsn_preauth_interface *piface = ctx;
50 struct hostapd_data *hapd = piface->hapd;
51 struct ieee802_1x_hdr *hdr;
53 struct l2_ethhdr *ethhdr;
55 wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet "
56 "from interface '%s'", piface->ifname);
57 if (len < sizeof(*ethhdr) + sizeof(*hdr)) {
58 wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet "
59 "(len=%lu)", (unsigned long) len);
63 ethhdr = (struct l2_ethhdr *) buf;
64 hdr = (struct ieee802_1x_hdr *) (ethhdr + 1);
66 if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) {
67 wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address "
68 MACSTR, MAC2STR(ethhdr->h_dest));
72 sta = ap_get_sta(hapd, ethhdr->h_source);
73 if (sta && (sta->flags & WLAN_STA_ASSOC)) {
74 wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association "
75 "STA " MACSTR, MAC2STR(sta->addr));
78 if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
79 sta = ap_sta_add(hapd, ethhdr->h_source);
82 sta->flags = WLAN_STA_PREAUTH;
84 ieee802_1x_new_station(hapd, sta);
85 if (sta->eapol_sm == NULL) {
86 ap_free_sta(hapd, sta);
89 sta->eapol_sm->radius_identifier = -1;
90 sta->eapol_sm->portValid = TRUE;
91 sta->eapol_sm->flags |= EAPOL_SM_PREAUTH;
96 sta->preauth_iface = piface;
97 ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
98 len - sizeof(*ethhdr));
102 static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
104 struct rsn_preauth_interface *piface;
106 wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
108 piface = os_zalloc(sizeof(*piface));
113 piface->ifname = os_strdup(ifname);
114 if (piface->ifname == NULL) {
118 piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH,
119 rsn_preauth_receive, piface, 1);
120 if (piface->l2 == NULL) {
121 wpa_printf(MSG_ERROR, "Failed to open register layer 2 access "
126 piface->next = hapd->preauth_iface;
127 hapd->preauth_iface = piface;
131 os_free(piface->ifname);
138 void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
140 struct rsn_preauth_interface *piface, *prev;
142 piface = hapd->preauth_iface;
143 hapd->preauth_iface = NULL;
146 piface = piface->next;
147 l2_packet_deinit(prev->l2);
148 os_free(prev->ifname);
154 int rsn_preauth_iface_init(struct hostapd_data *hapd)
156 char *tmp, *start, *end;
158 if (hapd->conf->rsn_preauth_interfaces == NULL)
161 tmp = os_strdup(hapd->conf->rsn_preauth_interfaces);
166 while (*start == ' ')
170 end = os_strchr(start, ' ');
174 if (rsn_preauth_iface_add(hapd, start)) {
175 rsn_preauth_iface_deinit(hapd);
189 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
191 struct hostapd_data *hapd = eloop_ctx;
192 struct sta_info *sta = timeout_ctx;
193 wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for "
194 MACSTR, MAC2STR(sta->addr));
195 ap_free_sta(hapd, sta);
199 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
204 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
205 HOSTAPD_LEVEL_INFO, "pre-authentication %s",
206 success ? "succeeded" : "failed");
208 key = ieee802_1x_get_key(sta->eapol_sm, &len);
211 if (success && key) {
212 if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
214 dot11RSNAConfigPMKLifetime,
215 sta->eapol_sm) == 0) {
216 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
218 "added PMKSA cache entry (pre-auth)");
220 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
222 "failed to add PMKSA cache entry "
228 * Finish STA entry removal from timeout in order to avoid freeing
229 * STA data before the caller has finished processing.
231 eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
235 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
238 struct rsn_preauth_interface *piface;
239 struct l2_ethhdr *ethhdr;
241 piface = hapd->preauth_iface;
243 if (piface == sta->preauth_iface)
245 piface = piface->next;
248 if (piface == NULL) {
249 wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
250 "interface for " MACSTR, MAC2STR(sta->addr));
254 ethhdr = os_malloc(sizeof(*ethhdr) + len);
258 os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
259 os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
260 ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH);
261 os_memcpy(ethhdr + 1, buf, len);
263 if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
264 sizeof(*ethhdr) + len) < 0) {
265 wpa_printf(MSG_ERROR, "Failed to send preauth packet using "
272 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
274 eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
277 #endif /* CONFIG_RSN_PREAUTH */