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