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 30 static const int dot11RSNAConfigPMKLifetime = 43200; 31 32 struct 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 41 static 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 97 static 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 125 fail2: 126 os_free(piface->ifname); 127 fail1: 128 os_free(piface); 129 return -1; 130 } 131 132 133 void 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 149 int 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 185 static 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 195 void 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 231 void 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 268 void 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