Merge driver ops set_wps_beacon_ie and set_wps_probe_resp_ie
[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 "common.h"
20 #include "hostapd.h"
21 #include "config.h"
22 #include "l2_packet/l2_packet.h"
23 #include "ieee802_1x.h"
24 #include "eloop.h"
25 #include "sta_info.h"
26 #include "common/wpa_common.h"
27 #include "eapol_auth/eapol_auth_sm.h"
28 #include "eapol_auth/eapol_auth_sm_i.h"
29 #include "wpa.h"
30 #include "preauth.h"
31
32 #ifndef ETH_P_PREAUTH
33 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
34 #endif /* ETH_P_PREAUTH */
35
36 static const int dot11RSNAConfigPMKLifetime = 43200;
37
38 struct rsn_preauth_interface {
39         struct rsn_preauth_interface *next;
40         struct hostapd_data *hapd;
41         struct l2_packet_data *l2;
42         char *ifname;
43         int ifindex;
44 };
45
46
47 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
48                                 const u8 *buf, size_t len)
49 {
50         struct rsn_preauth_interface *piface = ctx;
51         struct hostapd_data *hapd = piface->hapd;
52         struct ieee802_1x_hdr *hdr;
53         struct sta_info *sta;
54         struct l2_ethhdr *ethhdr;
55
56         wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet "
57                    "from interface '%s'", piface->ifname);
58         if (len < sizeof(*ethhdr) + sizeof(*hdr)) {
59                 wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet "
60                            "(len=%lu)", (unsigned long) len);
61                 return;
62         }
63
64         ethhdr = (struct l2_ethhdr *) buf;
65         hdr = (struct ieee802_1x_hdr *) (ethhdr + 1);
66
67         if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) {
68                 wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address "
69                            MACSTR, MAC2STR(ethhdr->h_dest));
70                 return;
71         }
72
73         sta = ap_get_sta(hapd, ethhdr->h_source);
74         if (sta && (sta->flags & WLAN_STA_ASSOC)) {
75                 wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association "
76                            "STA " MACSTR, MAC2STR(sta->addr));
77                 return;
78         }
79         if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
80                 sta = ap_sta_add(hapd, ethhdr->h_source);
81                 if (sta == NULL)
82                         return;
83                 sta->flags = WLAN_STA_PREAUTH;
84
85                 ieee802_1x_new_station(hapd, sta);
86                 if (sta->eapol_sm == NULL) {
87                         ap_free_sta(hapd, sta);
88                         sta = NULL;
89                 } else {
90                         sta->eapol_sm->radius_identifier = -1;
91                         sta->eapol_sm->portValid = TRUE;
92                         sta->eapol_sm->flags |= EAPOL_SM_PREAUTH;
93                 }
94         }
95         if (sta == NULL)
96                 return;
97         sta->preauth_iface = piface;
98         ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
99                            len - sizeof(*ethhdr));
100 }
101
102
103 static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
104 {
105         struct rsn_preauth_interface *piface;
106
107         wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
108
109         piface = os_zalloc(sizeof(*piface));
110         if (piface == NULL)
111                 return -1;
112         piface->hapd = hapd;
113
114         piface->ifname = os_strdup(ifname);
115         if (piface->ifname == NULL) {
116                 goto fail1;
117         }
118
119         piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH,
120                                     rsn_preauth_receive, piface, 1);
121         if (piface->l2 == NULL) {
122                 wpa_printf(MSG_ERROR, "Failed to open register layer 2 access "
123                            "to ETH_P_PREAUTH");
124                 goto fail2;
125         }
126
127         piface->next = hapd->preauth_iface;
128         hapd->preauth_iface = piface;
129         return 0;
130
131 fail2:
132         os_free(piface->ifname);
133 fail1:
134         os_free(piface);
135         return -1;
136 }
137
138
139 void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
140 {
141         struct rsn_preauth_interface *piface, *prev;
142
143         piface = hapd->preauth_iface;
144         hapd->preauth_iface = NULL;
145         while (piface) {
146                 prev = piface;
147                 piface = piface->next;
148                 l2_packet_deinit(prev->l2);
149                 os_free(prev->ifname);
150                 os_free(prev);
151         }
152 }
153
154
155 int rsn_preauth_iface_init(struct hostapd_data *hapd)
156 {
157         char *tmp, *start, *end;
158
159         if (hapd->conf->rsn_preauth_interfaces == NULL)
160                 return 0;
161
162         tmp = os_strdup(hapd->conf->rsn_preauth_interfaces);
163         if (tmp == NULL)
164                 return -1;
165         start = tmp;
166         for (;;) {
167                 while (*start == ' ')
168                         start++;
169                 if (*start == '\0')
170                         break;
171                 end = os_strchr(start, ' ');
172                 if (end)
173                         *end = '\0';
174
175                 if (rsn_preauth_iface_add(hapd, start)) {
176                         rsn_preauth_iface_deinit(hapd);
177                         return -1;
178                 }
179
180                 if (end)
181                         start = end + 1;
182                 else
183                         break;
184         }
185         os_free(tmp);
186         return 0;
187 }
188
189
190 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
191 {
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);
197 }
198
199
200 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
201                           int success)
202 {
203         const u8 *key;
204         size_t len;
205         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
206                        HOSTAPD_LEVEL_INFO, "pre-authentication %s",
207                        success ? "succeeded" : "failed");
208
209         key = ieee802_1x_get_key(sta->eapol_sm, &len);
210         if (len > PMK_LEN)
211                 len = PMK_LEN;
212         if (success && key) {
213                 if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
214                                                sta->addr,
215                                                dot11RSNAConfigPMKLifetime,
216                                                sta->eapol_sm) == 0) {
217                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
218                                        HOSTAPD_LEVEL_DEBUG,
219                                        "added PMKSA cache entry (pre-auth)");
220                 } else {
221                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
222                                        HOSTAPD_LEVEL_DEBUG,
223                                        "failed to add PMKSA cache entry "
224                                        "(pre-auth)");
225                 }
226         }
227
228         /*
229          * Finish STA entry removal from timeout in order to avoid freeing
230          * STA data before the caller has finished processing.
231          */
232         eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
233 }
234
235
236 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
237                       u8 *buf, size_t len)
238 {
239         struct rsn_preauth_interface *piface;
240         struct l2_ethhdr *ethhdr;
241
242         piface = hapd->preauth_iface;
243         while (piface) {
244                 if (piface == sta->preauth_iface)
245                         break;
246                 piface = piface->next;
247         }
248
249         if (piface == NULL) {
250                 wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
251                            "interface for " MACSTR, MAC2STR(sta->addr));
252                 return;
253         }
254
255         ethhdr = os_malloc(sizeof(*ethhdr) + len);
256         if (ethhdr == NULL)
257                 return;
258
259         os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
260         os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
261         ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH);
262         os_memcpy(ethhdr + 1, buf, len);
263
264         if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
265                            sizeof(*ethhdr) + len) < 0) {
266                 wpa_printf(MSG_ERROR, "Failed to send preauth packet using "
267                            "l2_packet_send\n");
268         }
269         os_free(ethhdr);
270 }
271
272
273 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
274 {
275         eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
276 }
277
278 #endif /* CONFIG_RSN_PREAUTH */