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