Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication
      3  * Copyright (c) 2004-2007, Jouni Malinen <j (at) 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