xref: /freebsd/contrib/wpa/src/ap/preauth_auth.c (revision 884a2a699669ec61e2366e3e358342dbc94be24a)
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 "utils/includes.h"
16 
17 #ifdef CONFIG_RSN_PREAUTH
18 
19 #include "utils/common.h"
20 #include "utils/eloop.h"
21 #include "l2_packet/l2_packet.h"
22 #include "common/wpa_common.h"
23 #include "eapol_auth/eapol_auth_sm.h"
24 #include "eapol_auth/eapol_auth_sm_i.h"
25 #include "hostapd.h"
26 #include "ap_config.h"
27 #include "ieee802_1x.h"
28 #include "sta_info.h"
29 #include "wpa_auth.h"
30 #include "preauth_auth.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 			os_free(tmp);
178 			return -1;
179 		}
180 
181 		if (end)
182 			start = end + 1;
183 		else
184 			break;
185 	}
186 	os_free(tmp);
187 	return 0;
188 }
189 
190 
191 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
192 {
193 	struct hostapd_data *hapd = eloop_ctx;
194 	struct sta_info *sta = timeout_ctx;
195 	wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for "
196 		   MACSTR, MAC2STR(sta->addr));
197 	ap_free_sta(hapd, sta);
198 }
199 
200 
201 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
202 			  int success)
203 {
204 	const u8 *key;
205 	size_t len;
206 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
207 		       HOSTAPD_LEVEL_INFO, "pre-authentication %s",
208 		       success ? "succeeded" : "failed");
209 
210 	key = ieee802_1x_get_key(sta->eapol_sm, &len);
211 	if (len > PMK_LEN)
212 		len = PMK_LEN;
213 	if (success && key) {
214 		if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
215 					       sta->addr,
216 					       dot11RSNAConfigPMKLifetime,
217 					       sta->eapol_sm) == 0) {
218 			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
219 				       HOSTAPD_LEVEL_DEBUG,
220 				       "added PMKSA cache entry (pre-auth)");
221 		} else {
222 			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
223 				       HOSTAPD_LEVEL_DEBUG,
224 				       "failed to add PMKSA cache entry "
225 				       "(pre-auth)");
226 		}
227 	}
228 
229 	/*
230 	 * Finish STA entry removal from timeout in order to avoid freeing
231 	 * STA data before the caller has finished processing.
232 	 */
233 	eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
234 }
235 
236 
237 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
238 		      u8 *buf, size_t len)
239 {
240 	struct rsn_preauth_interface *piface;
241 	struct l2_ethhdr *ethhdr;
242 
243 	piface = hapd->preauth_iface;
244 	while (piface) {
245 		if (piface == sta->preauth_iface)
246 			break;
247 		piface = piface->next;
248 	}
249 
250 	if (piface == NULL) {
251 		wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
252 			   "interface for " MACSTR, MAC2STR(sta->addr));
253 		return;
254 	}
255 
256 	ethhdr = os_malloc(sizeof(*ethhdr) + len);
257 	if (ethhdr == NULL)
258 		return;
259 
260 	os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
261 	os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
262 	ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH);
263 	os_memcpy(ethhdr + 1, buf, len);
264 
265 	if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
266 			   sizeof(*ethhdr) + len) < 0) {
267 		wpa_printf(MSG_ERROR, "Failed to send preauth packet using "
268 			   "l2_packet_send\n");
269 	}
270 	os_free(ethhdr);
271 }
272 
273 
274 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
275 {
276 	eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
277 }
278 
279 #endif /* CONFIG_RSN_PREAUTH */
280