2 * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication
3 * Copyright (c) 2004-2006, 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
20 #include "l2_packet.h"
21 #include "ieee802_1x.h"
24 #include "wpa_common.h"
30 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
31 #endif /* ETH_P_PREAUTH */
33 static const int dot11RSNAConfigPMKLifetime
= 43200;
35 struct rsn_preauth_interface
{
36 struct rsn_preauth_interface
*next
;
37 struct hostapd_data
*hapd
;
38 struct l2_packet_data
*l2
;
44 static void rsn_preauth_receive(void *ctx
, const u8
*src_addr
,
45 const u8
*buf
, size_t len
)
47 struct rsn_preauth_interface
*piface
= ctx
;
48 struct hostapd_data
*hapd
= piface
->hapd
;
49 struct ieee802_1x_hdr
*hdr
;
51 struct l2_ethhdr
*ethhdr
;
53 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN: receive pre-auth packet "
54 "from interface '%s'\n", piface
->ifname
);
55 if (len
< sizeof(*ethhdr
) + sizeof(*hdr
)) {
56 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN: too short pre-auth "
57 "packet (len=%lu)\n", (unsigned long) len
);
61 ethhdr
= (struct l2_ethhdr
*) buf
;
62 hdr
= (struct ieee802_1x_hdr
*) (ethhdr
+ 1);
64 if (memcmp(ethhdr
->h_dest
, hapd
->own_addr
, ETH_ALEN
) != 0) {
65 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN: pre-auth for "
66 "foreign address " MACSTR
"\n",
67 MAC2STR(ethhdr
->h_dest
));
71 sta
= ap_get_sta(hapd
, ethhdr
->h_source
);
72 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
73 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN: pre-auth for "
74 "already association STA " MACSTR
"\n",
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 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN pre-auth interface '%s'\n",
109 piface
= wpa_zalloc(sizeof(*piface
));
114 piface
->ifname
= strdup(ifname
);
115 if (piface
->ifname
== NULL
) {
119 piface
->l2
= l2_packet_init(piface
->ifname
, NULL
, ETH_P_PREAUTH
,
120 rsn_preauth_receive
, piface
, 1);
121 if (piface
->l2
== NULL
) {
122 printf("Failed to open register layer 2 access to "
127 piface
->next
= hapd
->preauth_iface
;
128 hapd
->preauth_iface
= piface
;
132 free(piface
->ifname
);
139 void rsn_preauth_iface_deinit(struct hostapd_data
*hapd
)
141 struct rsn_preauth_interface
*piface
, *prev
;
143 piface
= hapd
->preauth_iface
;
144 hapd
->preauth_iface
= NULL
;
147 piface
= piface
->next
;
148 l2_packet_deinit(prev
->l2
);
155 int rsn_preauth_iface_init(struct hostapd_data
*hapd
)
157 char *tmp
, *start
, *end
;
159 if (hapd
->conf
->rsn_preauth_interfaces
== NULL
)
162 tmp
= strdup(hapd
->conf
->rsn_preauth_interfaces
);
167 while (*start
== ' ')
171 end
= strchr(start
, ' ');
175 if (rsn_preauth_iface_add(hapd
, start
)) {
176 rsn_preauth_iface_deinit(hapd
);
190 static void rsn_preauth_finished_cb(void *eloop_ctx
, void *timeout_ctx
)
192 struct hostapd_data
*hapd
= eloop_ctx
;
193 struct sta_info
*sta
= timeout_ctx
;
194 wpa_printf(MSG_DEBUG
, "RSN: Removing pre-authentication STA entry for "
195 MACSTR
, MAC2STR(sta
->addr
));
196 ap_free_sta(hapd
, sta
);
200 void rsn_preauth_finished(struct hostapd_data
*hapd
, struct sta_info
*sta
,
205 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
206 HOSTAPD_LEVEL_INFO
, "pre-authentication %s",
207 success
? "succeeded" : "failed");
209 key
= ieee802_1x_get_key_crypt(sta
->eapol_sm
, &len
);
210 if (success
&& key
) {
211 if (wpa_auth_pmksa_add_preauth(hapd
->wpa_auth
, key
, len
,
213 dot11RSNAConfigPMKLifetime
,
214 sta
->eapol_sm
) == 0) {
215 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
217 "added PMKSA cache entry (pre-auth)");
219 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
221 "failed to add PMKSA cache entry "
227 * Finish STA entry removal from timeout in order to avoid freeing
228 * STA data before the caller has finished processing.
230 eloop_register_timeout(0, 0, rsn_preauth_finished_cb
, hapd
, sta
);
234 void rsn_preauth_send(struct hostapd_data
*hapd
, struct sta_info
*sta
,
237 struct rsn_preauth_interface
*piface
;
238 struct l2_ethhdr
*ethhdr
;
240 piface
= hapd
->preauth_iface
;
242 if (piface
== sta
->preauth_iface
)
244 piface
= piface
->next
;
247 if (piface
== NULL
) {
248 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "RSN: Could not find "
249 "pre-authentication interface for " MACSTR
"\n",
254 ethhdr
= malloc(sizeof(*ethhdr
) + len
);
258 memcpy(ethhdr
->h_dest
, sta
->addr
, ETH_ALEN
);
259 memcpy(ethhdr
->h_source
, hapd
->own_addr
, ETH_ALEN
);
260 ethhdr
->h_proto
= htons(ETH_P_PREAUTH
);
261 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 printf("Failed to send preauth packet using l2_packet_send\n");
271 void rsn_preauth_free_station(struct hostapd_data
*hapd
, struct sta_info
*sta
)
273 eloop_cancel_timeout(rsn_preauth_finished_cb
, hapd
, sta
);
276 #endif /* CONFIG_RSN_PREAUTH */