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