Include sta_flags.h explicitly, not via sta_info.h
[libeap.git] / hostapd / preauth.c
1 /*
2  * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication
3  * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #ifdef CONFIG_RSN_PREAUTH
18
19 #include "hostapd.h"
20 #include "config.h"
21 #include "l2_packet/l2_packet.h"
22 #include "ieee802_1x.h"
23 #include "eloop.h"
24 #include "sta_flags.h"
25 #include "sta_info.h"
26 #include "common/wpa_common.h"
27 #include "eapol_sm.h"
28 #include "wpa.h"
29 #include "preauth.h"
30
31 #ifndef ETH_P_PREAUTH
32 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
33 #endif /* ETH_P_PREAUTH */
34
35 static const int dot11RSNAConfigPMKLifetime = 43200;
36
37 struct rsn_preauth_interface {
38         struct rsn_preauth_interface *next;
39         struct hostapd_data *hapd;
40         struct l2_packet_data *l2;
41         char *ifname;
42         int ifindex;
43 };
44
45
46 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
47                                 const u8 *buf, size_t len)
48 {
49         struct rsn_preauth_interface *piface = ctx;
50         struct hostapd_data *hapd = piface->hapd;
51         struct ieee802_1x_hdr *hdr;
52         struct sta_info *sta;
53         struct l2_ethhdr *ethhdr;
54
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);
60                 return;
61         }
62
63         ethhdr = (struct l2_ethhdr *) buf;
64         hdr = (struct ieee802_1x_hdr *) (ethhdr + 1);
65
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));
69                 return;
70         }
71
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));
76                 return;
77         }
78         if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
79                 sta = ap_sta_add(hapd, ethhdr->h_source);
80                 if (sta == NULL)
81                         return;
82                 sta->flags = WLAN_STA_PREAUTH;
83
84                 ieee802_1x_new_station(hapd, sta);
85                 if (sta->eapol_sm == NULL) {
86                         ap_free_sta(hapd, sta);
87                         sta = NULL;
88                 } else {
89                         sta->eapol_sm->radius_identifier = -1;
90                         sta->eapol_sm->portValid = TRUE;
91                         sta->eapol_sm->flags |= EAPOL_SM_PREAUTH;
92                 }
93         }
94         if (sta == NULL)
95                 return;
96         sta->preauth_iface = piface;
97         ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
98                            len - sizeof(*ethhdr));
99 }
100
101
102 static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
103 {
104         struct rsn_preauth_interface *piface;
105
106         wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
107
108         piface = os_zalloc(sizeof(*piface));
109         if (piface == NULL)
110                 return -1;
111         piface->hapd = hapd;
112
113         piface->ifname = os_strdup(ifname);
114         if (piface->ifname == NULL) {
115                 goto fail1;
116         }
117
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 "
122                            "to ETH_P_PREAUTH");
123                 goto fail2;
124         }
125
126         piface->next = hapd->preauth_iface;
127         hapd->preauth_iface = piface;
128         return 0;
129
130 fail2:
131         os_free(piface->ifname);
132 fail1:
133         os_free(piface);
134         return -1;
135 }
136
137
138 void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
139 {
140         struct rsn_preauth_interface *piface, *prev;
141
142         piface = hapd->preauth_iface;
143         hapd->preauth_iface = NULL;
144         while (piface) {
145                 prev = piface;
146                 piface = piface->next;
147                 l2_packet_deinit(prev->l2);
148                 os_free(prev->ifname);
149                 os_free(prev);
150         }
151 }
152
153
154 int rsn_preauth_iface_init(struct hostapd_data *hapd)
155 {
156         char *tmp, *start, *end;
157
158         if (hapd->conf->rsn_preauth_interfaces == NULL)
159                 return 0;
160
161         tmp = os_strdup(hapd->conf->rsn_preauth_interfaces);
162         if (tmp == NULL)
163                 return -1;
164         start = tmp;
165         for (;;) {
166                 while (*start == ' ')
167                         start++;
168                 if (*start == '\0')
169                         break;
170                 end = os_strchr(start, ' ');
171                 if (end)
172                         *end = '\0';
173
174                 if (rsn_preauth_iface_add(hapd, start)) {
175                         rsn_preauth_iface_deinit(hapd);
176                         return -1;
177                 }
178
179                 if (end)
180                         start = end + 1;
181                 else
182                         break;
183         }
184         os_free(tmp);
185         return 0;
186 }
187
188
189 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
190 {
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);
196 }
197
198
199 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
200                           int success)
201 {
202         const u8 *key;
203         size_t len;
204         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
205                        HOSTAPD_LEVEL_INFO, "pre-authentication %s",
206                        success ? "succeeded" : "failed");
207
208         key = ieee802_1x_get_key(sta->eapol_sm, &len);
209         if (len > PMK_LEN)
210                 len = PMK_LEN;
211         if (success && key) {
212                 if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
213                                                sta->addr,
214                                                dot11RSNAConfigPMKLifetime,
215                                                sta->eapol_sm) == 0) {
216                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
217                                        HOSTAPD_LEVEL_DEBUG,
218                                        "added PMKSA cache entry (pre-auth)");
219                 } else {
220                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
221                                        HOSTAPD_LEVEL_DEBUG,
222                                        "failed to add PMKSA cache entry "
223                                        "(pre-auth)");
224                 }
225         }
226
227         /*
228          * Finish STA entry removal from timeout in order to avoid freeing
229          * STA data before the caller has finished processing.
230          */
231         eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
232 }
233
234
235 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
236                       u8 *buf, size_t len)
237 {
238         struct rsn_preauth_interface *piface;
239         struct l2_ethhdr *ethhdr;
240
241         piface = hapd->preauth_iface;
242         while (piface) {
243                 if (piface == sta->preauth_iface)
244                         break;
245                 piface = piface->next;
246         }
247
248         if (piface == NULL) {
249                 wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
250                            "interface for " MACSTR, MAC2STR(sta->addr));
251                 return;
252         }
253
254         ethhdr = os_malloc(sizeof(*ethhdr) + len);
255         if (ethhdr == NULL)
256                 return;
257
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);
262
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 "
266                            "l2_packet_send\n");
267         }
268         os_free(ethhdr);
269 }
270
271
272 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
273 {
274         eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
275 }
276
277 #endif /* CONFIG_RSN_PREAUTH */