1 /* 2 * WPA Supplicant - RSN pre-authentication 3 * Copyright (c) 2003-2006, 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 "includes.h" 16 17 #include "common.h" 18 #include "wpa.h" 19 #include "driver.h" 20 #include "eloop.h" 21 #include "config.h" 22 #include "l2_packet.h" 23 #include "eapol_sm.h" 24 #include "preauth.h" 25 #include "pmksa_cache.h" 26 #include "wpa_i.h" 27 28 29 #define PMKID_CANDIDATE_PRIO_SCAN 1000 30 31 32 struct rsn_pmksa_candidate { 33 struct rsn_pmksa_candidate *next; 34 u8 bssid[ETH_ALEN]; 35 int priority; 36 }; 37 38 39 /** 40 * pmksa_candidate_free - Free all entries in PMKSA candidate list 41 * @sm: Pointer to WPA state machine data from wpa_sm_init() 42 */ 43 void pmksa_candidate_free(struct wpa_sm *sm) 44 { 45 struct rsn_pmksa_candidate *entry, *prev; 46 47 if (sm == NULL) 48 return; 49 50 entry = sm->pmksa_candidates; 51 sm->pmksa_candidates = NULL; 52 while (entry) { 53 prev = entry; 54 entry = entry->next; 55 os_free(prev); 56 } 57 } 58 59 60 #if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2) 61 62 static void rsn_preauth_receive(void *ctx, const u8 *src_addr, 63 const u8 *buf, size_t len) 64 { 65 struct wpa_sm *sm = ctx; 66 67 wpa_printf(MSG_DEBUG, "RX pre-auth from " MACSTR, MAC2STR(src_addr)); 68 wpa_hexdump(MSG_MSGDUMP, "RX pre-auth", buf, len); 69 70 if (sm->preauth_eapol == NULL || 71 os_memcmp(sm->preauth_bssid, "\x00\x00\x00\x00\x00\x00", 72 ETH_ALEN) == 0 || 73 os_memcmp(sm->preauth_bssid, src_addr, ETH_ALEN) != 0) { 74 wpa_printf(MSG_WARNING, "RSN pre-auth frame received from " 75 "unexpected source " MACSTR " - dropped", 76 MAC2STR(src_addr)); 77 return; 78 } 79 80 eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len); 81 } 82 83 84 static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success, 85 void *ctx) 86 { 87 struct wpa_sm *sm = ctx; 88 u8 pmk[PMK_LEN]; 89 90 if (success) { 91 int res, pmk_len; 92 pmk_len = PMK_LEN; 93 res = eapol_sm_get_key(eapol, pmk, PMK_LEN); 94 if (res) { 95 /* 96 * EAP-LEAP is an exception from other EAP methods: it 97 * uses only 16-byte PMK. 98 */ 99 res = eapol_sm_get_key(eapol, pmk, 16); 100 pmk_len = 16; 101 } 102 if (res == 0) { 103 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth", 104 pmk, pmk_len); 105 sm->pmk_len = pmk_len; 106 pmksa_cache_add(sm->pmksa, pmk, pmk_len, 107 sm->preauth_bssid, sm->own_addr, 108 sm->cur_ssid); 109 } else { 110 wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: failed to get " 111 "master session key from pre-auth EAPOL state " 112 "machines"); 113 success = 0; 114 } 115 } 116 117 wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: pre-authentication with " MACSTR 118 " %s", MAC2STR(sm->preauth_bssid), 119 success ? "completed successfully" : "failed"); 120 121 rsn_preauth_deinit(sm); 122 rsn_preauth_candidate_process(sm); 123 } 124 125 126 static void rsn_preauth_timeout(void *eloop_ctx, void *timeout_ctx) 127 { 128 struct wpa_sm *sm = eloop_ctx; 129 130 wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: pre-authentication with " MACSTR 131 " timed out", MAC2STR(sm->preauth_bssid)); 132 rsn_preauth_deinit(sm); 133 rsn_preauth_candidate_process(sm); 134 } 135 136 137 static int rsn_preauth_eapol_send(void *ctx, int type, const u8 *buf, 138 size_t len) 139 { 140 struct wpa_sm *sm = ctx; 141 u8 *msg; 142 size_t msglen; 143 int res; 144 145 /* TODO: could add l2_packet_sendmsg that allows fragments to avoid 146 * extra copy here */ 147 148 if (sm->l2_preauth == NULL) 149 return -1; 150 151 msg = wpa_sm_alloc_eapol(sm, type, buf, len, &msglen, NULL); 152 if (msg == NULL) 153 return -1; 154 155 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL (preauth)", msg, msglen); 156 res = l2_packet_send(sm->l2_preauth, sm->preauth_bssid, 157 ETH_P_RSN_PREAUTH, msg, msglen); 158 os_free(msg); 159 return res; 160 } 161 162 163 /** 164 * rsn_preauth_init - Start new RSN pre-authentication 165 * @sm: Pointer to WPA state machine data from wpa_sm_init() 166 * @dst: Authenticator address (BSSID) with which to preauthenticate 167 * @config: Current network configuration 168 * Returns: 0 on success, -1 on another pre-authentication is in progress, 169 * -2 on layer 2 packet initialization failure, -3 on EAPOL state machine 170 * initialization failure, -4 on memory allocation failure 171 * 172 * This function request an RSN pre-authentication with a given destination 173 * address. This is usually called for PMKSA candidates found from scan results 174 * or from driver reports. In addition, ctrl_iface PREAUTH command can trigger 175 * pre-authentication. 176 */ 177 int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst, struct wpa_ssid *config) 178 { 179 struct eapol_config eapol_conf; 180 struct eapol_ctx *ctx; 181 182 if (sm->preauth_eapol) 183 return -1; 184 185 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: starting pre-authentication " 186 "with " MACSTR, MAC2STR(dst)); 187 188 sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr, 189 ETH_P_RSN_PREAUTH, 190 rsn_preauth_receive, sm, 0); 191 if (sm->l2_preauth == NULL) { 192 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet " 193 "processing for pre-authentication"); 194 return -2; 195 } 196 197 if (sm->bridge_ifname) { 198 sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname, 199 sm->own_addr, 200 ETH_P_RSN_PREAUTH, 201 rsn_preauth_receive, sm, 0); 202 if (sm->l2_preauth_br == NULL) { 203 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 " 204 "packet processing (bridge) for " 205 "pre-authentication"); 206 return -2; 207 } 208 } 209 210 ctx = os_zalloc(sizeof(*ctx)); 211 if (ctx == NULL) { 212 wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context."); 213 return -4; 214 } 215 ctx->ctx = sm->ctx->ctx; 216 ctx->msg_ctx = sm->ctx->ctx; 217 ctx->preauth = 1; 218 ctx->cb = rsn_preauth_eapol_cb; 219 ctx->cb_ctx = sm; 220 ctx->scard_ctx = sm->scard_ctx; 221 ctx->eapol_send = rsn_preauth_eapol_send; 222 ctx->eapol_send_ctx = sm; 223 ctx->set_config_blob = sm->ctx->set_config_blob; 224 ctx->get_config_blob = sm->ctx->get_config_blob; 225 226 sm->preauth_eapol = eapol_sm_init(ctx); 227 if (sm->preauth_eapol == NULL) { 228 os_free(ctx); 229 wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL " 230 "state machines for pre-authentication"); 231 return -3; 232 } 233 os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 234 eapol_conf.accept_802_1x_keys = 0; 235 eapol_conf.required_keys = 0; 236 eapol_conf.fast_reauth = sm->fast_reauth; 237 if (config) 238 eapol_conf.workaround = config->eap_workaround; 239 eapol_sm_notify_config(sm->preauth_eapol, config, &eapol_conf); 240 /* 241 * Use a shorter startPeriod with preauthentication since the first 242 * preauth EAPOL-Start frame may end up being dropped due to race 243 * condition in the AP between the data receive and key configuration 244 * after the 4-Way Handshake. 245 */ 246 eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6); 247 os_memcpy(sm->preauth_bssid, dst, ETH_ALEN); 248 249 eapol_sm_notify_portValid(sm->preauth_eapol, TRUE); 250 /* 802.1X::portControl = Auto */ 251 eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE); 252 253 eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0, 254 rsn_preauth_timeout, sm, NULL); 255 256 return 0; 257 } 258 259 260 /** 261 * rsn_preauth_deinit - Abort RSN pre-authentication 262 * @sm: Pointer to WPA state machine data from wpa_sm_init() 263 * 264 * This function aborts the current RSN pre-authentication (if one is started) 265 * and frees resources allocated for it. 266 */ 267 void rsn_preauth_deinit(struct wpa_sm *sm) 268 { 269 if (sm == NULL || !sm->preauth_eapol) 270 return; 271 272 eloop_cancel_timeout(rsn_preauth_timeout, sm, NULL); 273 eapol_sm_deinit(sm->preauth_eapol); 274 sm->preauth_eapol = NULL; 275 os_memset(sm->preauth_bssid, 0, ETH_ALEN); 276 277 l2_packet_deinit(sm->l2_preauth); 278 sm->l2_preauth = NULL; 279 if (sm->l2_preauth_br) { 280 l2_packet_deinit(sm->l2_preauth_br); 281 sm->l2_preauth_br = NULL; 282 } 283 } 284 285 286 /** 287 * rsn_preauth_candidate_process - Process PMKSA candidates 288 * @sm: Pointer to WPA state machine data from wpa_sm_init() 289 * 290 * Go through the PMKSA candidates and start pre-authentication if a candidate 291 * without an existing PMKSA cache entry is found. Processed candidates will be 292 * removed from the list. 293 */ 294 void rsn_preauth_candidate_process(struct wpa_sm *sm) 295 { 296 struct rsn_pmksa_candidate *candidate; 297 298 if (sm->pmksa_candidates == NULL) 299 return; 300 301 /* TODO: drop priority for old candidate entries */ 302 303 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: processing PMKSA candidate " 304 "list"); 305 if (sm->preauth_eapol || 306 sm->proto != WPA_PROTO_RSN || 307 wpa_sm_get_state(sm) != WPA_COMPLETED || 308 sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X) { 309 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: not in suitable state " 310 "for new pre-authentication"); 311 return; /* invalid state for new pre-auth */ 312 } 313 314 while (sm->pmksa_candidates) { 315 struct rsn_pmksa_cache_entry *p = NULL; 316 candidate = sm->pmksa_candidates; 317 p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL); 318 if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 && 319 (p == NULL || p->opportunistic)) { 320 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: PMKSA " 321 "candidate " MACSTR 322 " selected for pre-authentication", 323 MAC2STR(candidate->bssid)); 324 sm->pmksa_candidates = candidate->next; 325 rsn_preauth_init(sm, candidate->bssid, sm->cur_ssid); 326 os_free(candidate); 327 return; 328 } 329 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: PMKSA candidate " 330 MACSTR " does not need pre-authentication anymore", 331 MAC2STR(candidate->bssid)); 332 /* Some drivers (e.g., NDIS) expect to get notified about the 333 * PMKIDs again, so report the existing data now. */ 334 if (p) { 335 wpa_sm_add_pmkid(sm, candidate->bssid, p->pmkid); 336 } 337 338 sm->pmksa_candidates = candidate->next; 339 os_free(candidate); 340 } 341 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: no more pending PMKSA " 342 "candidates"); 343 } 344 345 346 /** 347 * pmksa_candidate_add - Add a new PMKSA candidate 348 * @sm: Pointer to WPA state machine data from wpa_sm_init() 349 * @bssid: BSSID (authenticator address) of the candidate 350 * @prio: Priority (the smaller number, the higher priority) 351 * @preauth: Whether the candidate AP advertises support for pre-authentication 352 * 353 * This function is used to add PMKSA candidates for RSN pre-authentication. It 354 * is called from scan result processing and from driver events for PMKSA 355 * candidates, i.e., EVENT_PMKID_CANDIDATE events to wpa_supplicant_event(). 356 */ 357 void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid, 358 int prio, int preauth) 359 { 360 struct rsn_pmksa_candidate *cand, *prev, *pos; 361 362 if (sm->cur_ssid && sm->cur_ssid->proactive_key_caching) 363 pmksa_cache_get_opportunistic(sm->pmksa, sm->cur_ssid, bssid); 364 365 if (!preauth) { 366 wpa_printf(MSG_DEBUG, "RSN: Ignored PMKID candidate without " 367 "preauth flag"); 368 return; 369 } 370 371 /* If BSSID already on candidate list, update the priority of the old 372 * entry. Do not override priority based on normal scan results. */ 373 prev = NULL; 374 cand = sm->pmksa_candidates; 375 while (cand) { 376 if (os_memcmp(cand->bssid, bssid, ETH_ALEN) == 0) { 377 if (prev) 378 prev->next = cand->next; 379 else 380 sm->pmksa_candidates = cand->next; 381 break; 382 } 383 prev = cand; 384 cand = cand->next; 385 } 386 387 if (cand) { 388 if (prio < PMKID_CANDIDATE_PRIO_SCAN) 389 cand->priority = prio; 390 } else { 391 cand = os_zalloc(sizeof(*cand)); 392 if (cand == NULL) 393 return; 394 os_memcpy(cand->bssid, bssid, ETH_ALEN); 395 cand->priority = prio; 396 } 397 398 /* Add candidate to the list; order by increasing priority value. i.e., 399 * highest priority (smallest value) first. */ 400 prev = NULL; 401 pos = sm->pmksa_candidates; 402 while (pos) { 403 if (cand->priority <= pos->priority) 404 break; 405 prev = pos; 406 pos = pos->next; 407 } 408 cand->next = pos; 409 if (prev) 410 prev->next = cand; 411 else 412 sm->pmksa_candidates = cand; 413 414 wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: added PMKSA cache " 415 "candidate " MACSTR " prio %d", MAC2STR(bssid), prio); 416 rsn_preauth_candidate_process(sm); 417 } 418 419 420 /* TODO: schedule periodic scans if current AP supports preauth */ 421 422 /** 423 * rsn_preauth_scan_results - Process scan results to find PMKSA candidates 424 * @sm: Pointer to WPA state machine data from wpa_sm_init() 425 * @results: Scan results 426 * @count: Number of BSSes in scan results 427 * 428 * This functions goes through the scan results and adds all suitable APs 429 * (Authenticators) into PMKSA candidate list. 430 */ 431 void rsn_preauth_scan_results(struct wpa_sm *sm, 432 struct wpa_scan_result *results, int count) 433 { 434 struct wpa_scan_result *r; 435 struct wpa_ie_data ie; 436 int i; 437 struct rsn_pmksa_cache_entry *pmksa; 438 439 if (sm->cur_ssid == NULL) 440 return; 441 442 /* 443 * TODO: is it ok to free all candidates? What about the entries 444 * received from EVENT_PMKID_CANDIDATE? 445 */ 446 pmksa_candidate_free(sm); 447 448 for (i = count - 1; i >= 0; i--) { 449 r = &results[i]; 450 if (r->ssid_len != sm->cur_ssid->ssid_len || 451 os_memcmp(r->ssid, sm->cur_ssid->ssid, 452 r->ssid_len) != 0) 453 continue; 454 455 if (os_memcmp(r->bssid, sm->bssid, ETH_ALEN) == 0) 456 continue; 457 458 if (r->rsn_ie_len == 0 || 459 wpa_parse_wpa_ie(r->rsn_ie, r->rsn_ie_len, &ie)) 460 continue; 461 462 pmksa = pmksa_cache_get(sm->pmksa, r->bssid, NULL); 463 if (pmksa && 464 (!pmksa->opportunistic || 465 !(ie.capabilities & WPA_CAPABILITY_PREAUTH))) 466 continue; 467 468 /* 469 * Give less priority to candidates found from normal 470 * scan results. 471 */ 472 pmksa_candidate_add(sm, r->bssid, 473 PMKID_CANDIDATE_PRIO_SCAN, 474 ie.capabilities & WPA_CAPABILITY_PREAUTH); 475 } 476 } 477 478 479 #ifdef CONFIG_CTRL_IFACE 480 /** 481 * rsn_preauth_get_status - Get pre-authentication status 482 * @sm: Pointer to WPA state machine data from wpa_sm_init() 483 * @buf: Buffer for status information 484 * @buflen: Maximum buffer length 485 * @verbose: Whether to include verbose status information 486 * Returns: Number of bytes written to buf. 487 * 488 * Query WPA2 pre-authentication for status information. This function fills in 489 * a text area with current status information. If the buffer (buf) is not 490 * large enough, status information will be truncated to fit the buffer. 491 */ 492 int rsn_preauth_get_status(struct wpa_sm *sm, char *buf, size_t buflen, 493 int verbose) 494 { 495 char *pos = buf, *end = buf + buflen; 496 int res, ret; 497 498 if (sm->preauth_eapol) { 499 ret = os_snprintf(pos, end - pos, "Pre-authentication " 500 "EAPOL state machines:\n"); 501 if (ret < 0 || ret >= end - pos) 502 return pos - buf; 503 pos += ret; 504 res = eapol_sm_get_status(sm->preauth_eapol, 505 pos, end - pos, verbose); 506 if (res >= 0) 507 pos += res; 508 } 509 510 return pos - buf; 511 } 512 #endif /* CONFIG_CTRL_IFACE */ 513 514 515 /** 516 * rsn_preauth_in_progress - Verify whether pre-authentication is in progress 517 * @sm: Pointer to WPA state machine data from wpa_sm_init() 518 */ 519 int rsn_preauth_in_progress(struct wpa_sm *sm) 520 { 521 return sm->preauth_eapol != NULL; 522 } 523 524 #endif /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */ 525