1203360Sjoerg/* 2203360Sjoerg * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication 3203360Sjoerg * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 4203360Sjoerg * 5203360Sjoerg * This software may be distributed under the terms of the BSD license. 6203360Sjoerg * See README for more details. 7203360Sjoerg */ 8203360Sjoerg 9203360Sjoerg#include "utils/includes.h" 10203360Sjoerg 11203360Sjoerg#ifdef CONFIG_RSN_PREAUTH 12203360Sjoerg 13203360Sjoerg#include "utils/common.h" 14203360Sjoerg#include "utils/eloop.h" 15203360Sjoerg#include "l2_packet/l2_packet.h" 16203360Sjoerg#include "common/wpa_common.h" 17203360Sjoerg#include "eapol_auth/eapol_auth_sm.h" 18203360Sjoerg#include "eapol_auth/eapol_auth_sm_i.h" 19203360Sjoerg#include "hostapd.h" 20203360Sjoerg#include "ap_config.h" 21203360Sjoerg#include "ieee802_1x.h" 22203360Sjoerg#include "sta_info.h" 23203360Sjoerg#include "wpa_auth.h" 24203360Sjoerg#include "preauth_auth.h" 25203360Sjoerg 26203360Sjoerg#ifndef ETH_P_PREAUTH 27203360Sjoerg#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ 28203360Sjoerg#endif /* ETH_P_PREAUTH */ 29203360Sjoerg 30203360Sjoergstatic const int dot11RSNAConfigPMKLifetime = 43200; 31203360Sjoerg 32203360Sjoergstruct rsn_preauth_interface { 33203360Sjoerg struct rsn_preauth_interface *next; 34203360Sjoerg struct hostapd_data *hapd; 35203360Sjoerg struct l2_packet_data *l2; 36203360Sjoerg char *ifname; 37203360Sjoerg int ifindex; 38203360Sjoerg}; 39203360Sjoerg 40203360Sjoerg 41203360Sjoergstatic void rsn_preauth_receive(void *ctx, const u8 *src_addr, 42203360Sjoerg const u8 *buf, size_t len) 43203360Sjoerg{ 44203360Sjoerg struct rsn_preauth_interface *piface = ctx; 45203360Sjoerg struct hostapd_data *hapd = piface->hapd; 46203360Sjoerg struct ieee802_1x_hdr *hdr; 47203360Sjoerg struct sta_info *sta; 48203360Sjoerg struct l2_ethhdr *ethhdr; 49203360Sjoerg 50203360Sjoerg wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet " 51203360Sjoerg "from interface '%s'", piface->ifname); 52203360Sjoerg if (len < sizeof(*ethhdr) + sizeof(*hdr)) { 53203360Sjoerg wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet " 54203360Sjoerg "(len=%lu)", (unsigned long) len); 55203360Sjoerg return; 56203360Sjoerg } 57203360Sjoerg 58203360Sjoerg ethhdr = (struct l2_ethhdr *) buf; 59203360Sjoerg hdr = (struct ieee802_1x_hdr *) (ethhdr + 1); 60203360Sjoerg 61203360Sjoerg if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) { 62203360Sjoerg wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address " 63203360Sjoerg MACSTR, MAC2STR(ethhdr->h_dest)); 64203360Sjoerg return; 65203360Sjoerg } 66203360Sjoerg 67203360Sjoerg sta = ap_get_sta(hapd, ethhdr->h_source); 68203360Sjoerg if (sta && (sta->flags & WLAN_STA_ASSOC)) { 69203360Sjoerg wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association " 70203360Sjoerg "STA " MACSTR, MAC2STR(sta->addr)); 71203360Sjoerg return; 72203360Sjoerg } 73203360Sjoerg if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) { 74203360Sjoerg sta = ap_sta_add(hapd, ethhdr->h_source); 75203360Sjoerg if (sta == NULL) 76203360Sjoerg return; 77203360Sjoerg 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