00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "wpa.h"
00020 #include "drivers/driver.h"
00021 #include "eloop.h"
00022 #include "l2_packet/l2_packet.h"
00023 #include "eapol_supp/eapol_supp_sm.h"
00024 #include "preauth.h"
00025 #include "pmksa_cache.h"
00026 #include "wpa_i.h"
00027 #include "ieee802_11_defs.h"
00028
00029
00030 #if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
00031
00032 #define PMKID_CANDIDATE_PRIO_SCAN 1000
00033
00034
00035 struct rsn_pmksa_candidate {
00036 struct rsn_pmksa_candidate *next;
00037 u8 bssid[ETH_ALEN];
00038 int priority;
00039 };
00040
00041
00047 void pmksa_candidate_free(struct wpa_sm *sm)
00048 {
00049 struct rsn_pmksa_candidate *entry, *prev;
00050
00051 if (sm == NULL)
00052 return;
00053
00054 entry = sm->pmksa_candidates;
00055 sm->pmksa_candidates = NULL;
00056 while (entry) {
00057 prev = entry;
00058 entry = entry->next;
00059 os_free(prev);
00060 }
00061 }
00062
00063
00064 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
00065 const u8 *buf, size_t len)
00066 {
00067 struct wpa_sm *sm = ctx;
00068
00069 wpa_printf(MSG_DEBUG, "RX pre-auth from " MACSTR, MAC2STR(src_addr));
00070 wpa_hexdump(MSG_MSGDUMP, "RX pre-auth", buf, len);
00071
00072 if (sm->preauth_eapol == NULL ||
00073 is_zero_ether_addr(sm->preauth_bssid) ||
00074 os_memcmp(sm->preauth_bssid, src_addr, ETH_ALEN) != 0) {
00075 wpa_printf(MSG_WARNING, "RSN pre-auth frame received from "
00076 "unexpected source " MACSTR " - dropped",
00077 MAC2STR(src_addr));
00078 return;
00079 }
00080
00081 eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len);
00082 }
00083
00084
00085 static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success,
00086 void *ctx)
00087 {
00088 struct wpa_sm *sm = ctx;
00089 u8 pmk[PMK_LEN];
00090
00091 if (success) {
00092 int res, pmk_len;
00093 pmk_len = PMK_LEN;
00094 res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
00095 if (res) {
00096
00097
00098
00099
00100 res = eapol_sm_get_key(eapol, pmk, 16);
00101 pmk_len = 16;
00102 }
00103 if (res == 0) {
00104 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth",
00105 pmk, pmk_len);
00106 sm->pmk_len = pmk_len;
00107 pmksa_cache_add(sm->pmksa, pmk, pmk_len,
00108 sm->preauth_bssid, sm->own_addr,
00109 sm->network_ctx,
00110 WPA_KEY_MGMT_IEEE8021X);
00111 } else {
00112 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
00113 "RSN: failed to get master session key from "
00114 "pre-auth EAPOL state machines");
00115 success = 0;
00116 }
00117 }
00118
00119 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
00120 MACSTR " %s", MAC2STR(sm->preauth_bssid),
00121 success ? "completed successfully" : "failed");
00122
00123 rsn_preauth_deinit(sm);
00124 rsn_preauth_candidate_process(sm);
00125 }
00126
00127
00128 static void rsn_preauth_timeout(void *eloop_ctx, void *timeout_ctx)
00129 {
00130 struct wpa_sm *sm = eloop_ctx;
00131
00132 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
00133 MACSTR " timed out", MAC2STR(sm->preauth_bssid));
00134 rsn_preauth_deinit(sm);
00135 rsn_preauth_candidate_process(sm);
00136 }
00137
00138
00139 static int rsn_preauth_eapol_send(void *ctx, int type, const u8 *buf,
00140 size_t len)
00141 {
00142 struct wpa_sm *sm = ctx;
00143 u8 *msg;
00144 size_t msglen;
00145 int res;
00146
00147
00148
00149
00150 if (sm->l2_preauth == NULL)
00151 return -1;
00152
00153 msg = wpa_sm_alloc_eapol(sm, type, buf, len, &msglen, NULL);
00154 if (msg == NULL)
00155 return -1;
00156
00157 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL (preauth)", msg, msglen);
00158 res = l2_packet_send(sm->l2_preauth, sm->preauth_bssid,
00159 ETH_P_RSN_PREAUTH, msg, msglen);
00160 os_free(msg);
00161 return res;
00162 }
00163
00164
00180 int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
00181 struct eap_peer_config *eap_conf)
00182 {
00183 struct eapol_config eapol_conf;
00184 struct eapol_ctx *ctx;
00185
00186 if (sm->preauth_eapol)
00187 return -1;
00188
00189 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
00190 "RSN: starting pre-authentication with " MACSTR, MAC2STR(dst));
00191
00192 sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr,
00193 ETH_P_RSN_PREAUTH,
00194 rsn_preauth_receive, sm, 0);
00195 if (sm->l2_preauth == NULL) {
00196 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet "
00197 "processing for pre-authentication");
00198 return -2;
00199 }
00200
00201 if (sm->bridge_ifname) {
00202 sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname,
00203 sm->own_addr,
00204 ETH_P_RSN_PREAUTH,
00205 rsn_preauth_receive, sm, 0);
00206 if (sm->l2_preauth_br == NULL) {
00207 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 "
00208 "packet processing (bridge) for "
00209 "pre-authentication");
00210 return -2;
00211 }
00212 }
00213
00214 ctx = os_zalloc(sizeof(*ctx));
00215 if (ctx == NULL) {
00216 wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context.");
00217 return -4;
00218 }
00219 ctx->ctx = sm->ctx->ctx;
00220 ctx->msg_ctx = sm->ctx->ctx;
00221 ctx->preauth = 1;
00222 ctx->cb = rsn_preauth_eapol_cb;
00223 ctx->cb_ctx = sm;
00224 ctx->scard_ctx = sm->scard_ctx;
00225 ctx->eapol_send = rsn_preauth_eapol_send;
00226 ctx->eapol_send_ctx = sm;
00227 ctx->set_config_blob = sm->ctx->set_config_blob;
00228 ctx->get_config_blob = sm->ctx->get_config_blob;
00229
00230 sm->preauth_eapol = eapol_sm_init(ctx);
00231 if (sm->preauth_eapol == NULL) {
00232 os_free(ctx);
00233 wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL "
00234 "state machines for pre-authentication");
00235 return -3;
00236 }
00237 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
00238 eapol_conf.accept_802_1x_keys = 0;
00239 eapol_conf.required_keys = 0;
00240 eapol_conf.fast_reauth = sm->fast_reauth;
00241 eapol_conf.workaround = sm->eap_workaround;
00242 eapol_sm_notify_config(sm->preauth_eapol, eap_conf, &eapol_conf);
00243
00244
00245
00246
00247
00248
00249 eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6);
00250 os_memcpy(sm->preauth_bssid, dst, ETH_ALEN);
00251
00252 eapol_sm_notify_portValid(sm->preauth_eapol, TRUE);
00253
00254 eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE);
00255
00256 eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0,
00257 rsn_preauth_timeout, sm, NULL);
00258
00259 return 0;
00260 }
00261
00262
00271 void rsn_preauth_deinit(struct wpa_sm *sm)
00272 {
00273 if (sm == NULL || !sm->preauth_eapol)
00274 return;
00275
00276 eloop_cancel_timeout(rsn_preauth_timeout, sm, NULL);
00277 eapol_sm_deinit(sm->preauth_eapol);
00278 sm->preauth_eapol = NULL;
00279 os_memset(sm->preauth_bssid, 0, ETH_ALEN);
00280
00281 l2_packet_deinit(sm->l2_preauth);
00282 sm->l2_preauth = NULL;
00283 if (sm->l2_preauth_br) {
00284 l2_packet_deinit(sm->l2_preauth_br);
00285 sm->l2_preauth_br = NULL;
00286 }
00287 }
00288
00289
00299 void rsn_preauth_candidate_process(struct wpa_sm *sm)
00300 {
00301 struct rsn_pmksa_candidate *candidate;
00302
00303 if (sm->pmksa_candidates == NULL)
00304 return;
00305
00306
00307
00308 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: processing PMKSA candidate "
00309 "list");
00310 if (sm->preauth_eapol ||
00311 sm->proto != WPA_PROTO_RSN ||
00312 wpa_sm_get_state(sm) != WPA_COMPLETED ||
00313 (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
00314 sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256)) {
00315 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
00316 "state for new pre-authentication");
00317 return;
00318 }
00319
00320 while (sm->pmksa_candidates) {
00321 struct rsn_pmksa_cache_entry *p = NULL;
00322 candidate = sm->pmksa_candidates;
00323 p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL);
00324 if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 &&
00325 (p == NULL || p->opportunistic)) {
00326 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA "
00327 "candidate " MACSTR
00328 " selected for pre-authentication",
00329 MAC2STR(candidate->bssid));
00330 sm->pmksa_candidates = candidate->next;
00331 rsn_preauth_init(sm, candidate->bssid,
00332 sm->eap_conf_ctx);
00333 os_free(candidate);
00334 return;
00335 }
00336 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA candidate "
00337 MACSTR " does not need pre-authentication anymore",
00338 MAC2STR(candidate->bssid));
00339
00340
00341 if (p) {
00342 wpa_sm_add_pmkid(sm, candidate->bssid, p->pmkid);
00343 }
00344
00345 sm->pmksa_candidates = candidate->next;
00346 os_free(candidate);
00347 }
00348 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: no more pending PMKSA "
00349 "candidates");
00350 }
00351
00352
00365 void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
00366 int prio, int preauth)
00367 {
00368 struct rsn_pmksa_candidate *cand, *prev, *pos;
00369
00370 if (sm->network_ctx && sm->proactive_key_caching)
00371 pmksa_cache_get_opportunistic(sm->pmksa, sm->network_ctx,
00372 bssid);
00373
00374 if (!preauth) {
00375 wpa_printf(MSG_DEBUG, "RSN: Ignored PMKID candidate without "
00376 "preauth flag");
00377 return;
00378 }
00379
00380
00381
00382 prev = NULL;
00383 cand = sm->pmksa_candidates;
00384 while (cand) {
00385 if (os_memcmp(cand->bssid, bssid, ETH_ALEN) == 0) {
00386 if (prev)
00387 prev->next = cand->next;
00388 else
00389 sm->pmksa_candidates = cand->next;
00390 break;
00391 }
00392 prev = cand;
00393 cand = cand->next;
00394 }
00395
00396 if (cand) {
00397 if (prio < PMKID_CANDIDATE_PRIO_SCAN)
00398 cand->priority = prio;
00399 } else {
00400 cand = os_zalloc(sizeof(*cand));
00401 if (cand == NULL)
00402 return;
00403 os_memcpy(cand->bssid, bssid, ETH_ALEN);
00404 cand->priority = prio;
00405 }
00406
00407
00408
00409 prev = NULL;
00410 pos = sm->pmksa_candidates;
00411 while (pos) {
00412 if (cand->priority <= pos->priority)
00413 break;
00414 prev = pos;
00415 pos = pos->next;
00416 }
00417 cand->next = pos;
00418 if (prev)
00419 prev->next = cand;
00420 else
00421 sm->pmksa_candidates = cand;
00422
00423 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: added PMKSA cache "
00424 "candidate " MACSTR " prio %d", MAC2STR(bssid), prio);
00425 rsn_preauth_candidate_process(sm);
00426 }
00427
00428
00429
00430
00440 void rsn_preauth_scan_results(struct wpa_sm *sm,
00441 struct wpa_scan_results *results)
00442 {
00443 struct wpa_scan_res *r;
00444 struct wpa_ie_data ie;
00445 int i;
00446 struct rsn_pmksa_cache_entry *pmksa;
00447
00448 if (sm->ssid_len == 0)
00449 return;
00450
00451
00452
00453
00454
00455 pmksa_candidate_free(sm);
00456
00457 for (i = results->num - 1; i >= 0; i--) {
00458 const u8 *ssid, *rsn;
00459
00460 r = results->res[i];
00461
00462 ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
00463 if (ssid == NULL || ssid[1] != sm->ssid_len ||
00464 os_memcmp(ssid + 2, sm->ssid, ssid[1]) != 0)
00465 continue;
00466
00467 if (os_memcmp(r->bssid, sm->bssid, ETH_ALEN) == 0)
00468 continue;
00469
00470 rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
00471 if (rsn == NULL || wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
00472 continue;
00473
00474 pmksa = pmksa_cache_get(sm->pmksa, r->bssid, NULL);
00475 if (pmksa &&
00476 (!pmksa->opportunistic ||
00477 !(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
00478 continue;
00479
00480
00481
00482
00483
00484 pmksa_candidate_add(sm, r->bssid,
00485 PMKID_CANDIDATE_PRIO_SCAN,
00486 ie.capabilities & WPA_CAPABILITY_PREAUTH);
00487 }
00488 }
00489
00490
00491 #ifdef CONFIG_CTRL_IFACE
00492
00505 int rsn_preauth_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
00506 int verbose)
00507 {
00508 char *pos = buf, *end = buf + buflen;
00509 int res, ret;
00510
00511 if (sm->preauth_eapol) {
00512 ret = os_snprintf(pos, end - pos, "Pre-authentication "
00513 "EAPOL state machines:\n");
00514 if (ret < 0 || ret >= end - pos)
00515 return pos - buf;
00516 pos += ret;
00517 res = eapol_sm_get_status(sm->preauth_eapol,
00518 pos, end - pos, verbose);
00519 if (res >= 0)
00520 pos += res;
00521 }
00522
00523 return pos - buf;
00524 }
00525 #endif
00526
00527
00533 int rsn_preauth_in_progress(struct wpa_sm *sm)
00534 {
00535 return sm->preauth_eapol != NULL;
00536 }
00537
00538 #endif
00539