00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "wpa.h"
00019 #include "eloop.h"
00020 #include "l2_packet/l2_packet.h"
00021 #include "eapol_supp/eapol_supp_sm.h"
00022 #include "preauth.h"
00023 #include "pmksa_cache.h"
00024 #include "wpa_i.h"
00025 #include "common/ieee802_11_defs.h"
00026
00027
00028 #if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
00029
00030 #define PMKID_CANDIDATE_PRIO_SCAN 1000
00031
00032
00033 struct rsn_pmksa_candidate {
00034 struct dl_list list;
00035 u8 bssid[ETH_ALEN];
00036 int priority;
00037 };
00038
00039
00044 void pmksa_candidate_free(struct wpa_sm *sm)
00045 {
00046 struct rsn_pmksa_candidate *entry, *n;
00047
00048 if (sm == NULL)
00049 return;
00050
00051 dl_list_for_each_safe(entry, n, &sm->pmksa_candidates,
00052 struct rsn_pmksa_candidate, list)
00053 os_free(entry);
00054 }
00055
00056
00057 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
00058 const u8 *buf, size_t len)
00059 {
00060 struct wpa_sm *sm = ctx;
00061
00062 wpa_printf(MSG_DEBUG, "RX pre-auth from " MACSTR, MAC2STR(src_addr));
00063 wpa_hexdump(MSG_MSGDUMP, "RX pre-auth", buf, len);
00064
00065 if (sm->preauth_eapol == NULL ||
00066 is_zero_ether_addr(sm->preauth_bssid) ||
00067 os_memcmp(sm->preauth_bssid, src_addr, ETH_ALEN) != 0) {
00068 wpa_printf(MSG_WARNING, "RSN pre-auth frame received from "
00069 "unexpected source " MACSTR " - dropped",
00070 MAC2STR(src_addr));
00071 return;
00072 }
00073
00074 eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len);
00075 }
00076
00077
00078 static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success,
00079 void *ctx)
00080 {
00081 struct wpa_sm *sm = ctx;
00082 u8 pmk[PMK_LEN];
00083
00084 if (success) {
00085 int res, pmk_len;
00086 pmk_len = PMK_LEN;
00087 res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
00088 if (res) {
00089
00090
00091
00092
00093 res = eapol_sm_get_key(eapol, pmk, 16);
00094 pmk_len = 16;
00095 }
00096 if (res == 0) {
00097 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth",
00098 pmk, pmk_len);
00099 sm->pmk_len = pmk_len;
00100 pmksa_cache_add(sm->pmksa, pmk, pmk_len,
00101 sm->preauth_bssid, sm->own_addr,
00102 sm->network_ctx,
00103 WPA_KEY_MGMT_IEEE8021X);
00104 } else {
00105 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
00106 "RSN: failed to get master session key from "
00107 "pre-auth EAPOL state machines");
00108 success = 0;
00109 }
00110 }
00111
00112 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
00113 MACSTR " %s", MAC2STR(sm->preauth_bssid),
00114 success ? "completed successfully" : "failed");
00115
00116 rsn_preauth_deinit(sm);
00117 rsn_preauth_candidate_process(sm);
00118 }
00119
00120
00121 static void rsn_preauth_timeout(void *eloop_ctx, void *timeout_ctx)
00122 {
00123 struct wpa_sm *sm = eloop_ctx;
00124
00125 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
00126 MACSTR " timed out", MAC2STR(sm->preauth_bssid));
00127 rsn_preauth_deinit(sm);
00128 rsn_preauth_candidate_process(sm);
00129 }
00130
00131
00132 static int rsn_preauth_eapol_send(void *ctx, int type, const u8 *buf,
00133 size_t len)
00134 {
00135 struct wpa_sm *sm = ctx;
00136 u8 *msg;
00137 size_t msglen;
00138 int res;
00139
00140
00141
00142
00143 if (sm->l2_preauth == NULL)
00144 return -1;
00145
00146 msg = wpa_sm_alloc_eapol(sm, type, buf, len, &msglen, NULL);
00147 if (msg == NULL)
00148 return -1;
00149
00150 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL (preauth)", msg, msglen);
00151 res = l2_packet_send(sm->l2_preauth, sm->preauth_bssid,
00152 ETH_P_RSN_PREAUTH, msg, msglen);
00153 os_free(msg);
00154 return res;
00155 }
00156
00157
00172 int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
00173 struct eap_peer_config *eap_conf)
00174 {
00175 struct eapol_config eapol_conf;
00176 struct eapol_ctx *ctx;
00177
00178 if (sm->preauth_eapol)
00179 return -1;
00180
00181 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
00182 "RSN: starting pre-authentication with " MACSTR, MAC2STR(dst));
00183
00184 sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr,
00185 ETH_P_RSN_PREAUTH,
00186 rsn_preauth_receive, sm, 0);
00187 if (sm->l2_preauth == NULL) {
00188 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet "
00189 "processing for pre-authentication");
00190 return -2;
00191 }
00192
00193 if (sm->bridge_ifname) {
00194 sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname,
00195 sm->own_addr,
00196 ETH_P_RSN_PREAUTH,
00197 rsn_preauth_receive, sm, 0);
00198 if (sm->l2_preauth_br == NULL) {
00199 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 "
00200 "packet processing (bridge) for "
00201 "pre-authentication");
00202 return -2;
00203 }
00204 }
00205
00206 ctx = os_zalloc(sizeof(*ctx));
00207 if (ctx == NULL) {
00208 wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context.");
00209 return -4;
00210 }
00211 ctx->ctx = sm->ctx->ctx;
00212 ctx->msg_ctx = sm->ctx->ctx;
00213 ctx->preauth = 1;
00214 ctx->cb = rsn_preauth_eapol_cb;
00215 ctx->cb_ctx = sm;
00216 ctx->scard_ctx = sm->scard_ctx;
00217 ctx->eapol_send = rsn_preauth_eapol_send;
00218 ctx->eapol_send_ctx = sm;
00219 ctx->set_config_blob = sm->ctx->set_config_blob;
00220 ctx->get_config_blob = sm->ctx->get_config_blob;
00221
00222 sm->preauth_eapol = eapol_sm_init(ctx);
00223 if (sm->preauth_eapol == NULL) {
00224 os_free(ctx);
00225 wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL "
00226 "state machines for pre-authentication");
00227 return -3;
00228 }
00229 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
00230 eapol_conf.accept_802_1x_keys = 0;
00231 eapol_conf.required_keys = 0;
00232 eapol_conf.fast_reauth = sm->fast_reauth;
00233 eapol_conf.workaround = sm->eap_workaround;
00234 eapol_sm_notify_config(sm->preauth_eapol, eap_conf, &eapol_conf);
00235
00236
00237
00238
00239
00240
00241 eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6);
00242 os_memcpy(sm->preauth_bssid, dst, ETH_ALEN);
00243
00244 eapol_sm_notify_portValid(sm->preauth_eapol, TRUE);
00245
00246 eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE);
00247
00248 eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0,
00249 rsn_preauth_timeout, sm, NULL);
00250
00251 return 0;
00252 }
00253
00254
00262 void rsn_preauth_deinit(struct wpa_sm *sm)
00263 {
00264 if (sm == NULL || !sm->preauth_eapol)
00265 return;
00266
00267 eloop_cancel_timeout(rsn_preauth_timeout, sm, NULL);
00268 eapol_sm_deinit(sm->preauth_eapol);
00269 sm->preauth_eapol = NULL;
00270 os_memset(sm->preauth_bssid, 0, ETH_ALEN);
00271
00272 l2_packet_deinit(sm->l2_preauth);
00273 sm->l2_preauth = NULL;
00274 if (sm->l2_preauth_br) {
00275 l2_packet_deinit(sm->l2_preauth_br);
00276 sm->l2_preauth_br = NULL;
00277 }
00278 }
00279
00280
00289 void rsn_preauth_candidate_process(struct wpa_sm *sm)
00290 {
00291 struct rsn_pmksa_candidate *candidate, *n;
00292
00293 if (dl_list_empty(&sm->pmksa_candidates))
00294 return;
00295
00296
00297
00298 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: processing PMKSA candidate "
00299 "list");
00300 if (sm->preauth_eapol ||
00301 sm->proto != WPA_PROTO_RSN ||
00302 wpa_sm_get_state(sm) != WPA_COMPLETED ||
00303 (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
00304 sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256)) {
00305 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
00306 "state for new pre-authentication");
00307 return;
00308 }
00309
00310 dl_list_for_each_safe(candidate, n, &sm->pmksa_candidates,
00311 struct rsn_pmksa_candidate, list) {
00312 struct rsn_pmksa_cache_entry *p = NULL;
00313 p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL);
00314 if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 &&
00315 (p == NULL || p->opportunistic)) {
00316 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA "
00317 "candidate " MACSTR
00318 " selected for pre-authentication",
00319 MAC2STR(candidate->bssid));
00320 dl_list_del(&candidate->list);
00321 rsn_preauth_init(sm, candidate->bssid,
00322 sm->eap_conf_ctx);
00323 os_free(candidate);
00324 return;
00325 }
00326 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA candidate "
00327 MACSTR " does not need pre-authentication anymore",
00328 MAC2STR(candidate->bssid));
00329
00330
00331 if (p) {
00332 wpa_sm_add_pmkid(sm, candidate->bssid, p->pmkid);
00333 }
00334
00335 dl_list_del(&candidate->list);
00336 os_free(candidate);
00337 }
00338 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: no more pending PMKSA "
00339 "candidates");
00340 }
00341
00342
00354 void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
00355 int prio, int preauth)
00356 {
00357 struct rsn_pmksa_candidate *cand, *pos;
00358
00359 if (sm->network_ctx && sm->proactive_key_caching)
00360 pmksa_cache_get_opportunistic(sm->pmksa, sm->network_ctx,
00361 bssid);
00362
00363 if (!preauth) {
00364 wpa_printf(MSG_DEBUG, "RSN: Ignored PMKID candidate without "
00365 "preauth flag");
00366 return;
00367 }
00368
00369
00370
00371 cand = NULL;
00372 dl_list_for_each(pos, &sm->pmksa_candidates,
00373 struct rsn_pmksa_candidate, list) {
00374 if (os_memcmp(pos->bssid, bssid, ETH_ALEN) == 0) {
00375 cand = pos;
00376 break;
00377 }
00378 }
00379
00380 if (cand) {
00381 if (prio < PMKID_CANDIDATE_PRIO_SCAN)
00382 cand->priority = prio;
00383 } else {
00384 cand = os_zalloc(sizeof(*cand));
00385 if (cand == NULL)
00386 return;
00387 os_memcpy(cand->bssid, bssid, ETH_ALEN);
00388 cand->priority = prio;
00389 }
00390
00391
00392
00393 dl_list_for_each(pos, &sm->pmksa_candidates,
00394 struct rsn_pmksa_candidate, list) {
00395 if (cand->priority <= pos->priority) {
00396 dl_list_add(pos->list.prev, &cand->list);
00397 cand = NULL;
00398 break;
00399 }
00400 }
00401 if (cand)
00402 dl_list_add_tail(&sm->pmksa_candidates, &cand->list);
00403
00404 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: added PMKSA cache "
00405 "candidate " MACSTR " prio %d", MAC2STR(bssid), prio);
00406 rsn_preauth_candidate_process(sm);
00407 }
00408
00409
00410
00411
00421 int rsn_preauth_scan_results(struct wpa_sm *sm)
00422 {
00423 if (sm->ssid_len == 0)
00424 return -1;
00425
00426
00427
00428
00429
00430 pmksa_candidate_free(sm);
00431
00432 return 0;
00433 }
00434
00435
00443 void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
00444 const u8 *ssid, const u8 *rsn)
00445 {
00446 struct wpa_ie_data ie;
00447 struct rsn_pmksa_cache_entry *pmksa;
00448
00449 if (ssid[1] != sm->ssid_len ||
00450 os_memcmp(ssid + 2, sm->ssid, sm->ssid_len) != 0)
00451 return;
00452
00453 if (os_memcmp(bssid, sm->bssid, ETH_ALEN) == 0)
00454 return;
00455
00456 if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
00457 return;
00458
00459 pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL);
00460 if (pmksa && (!pmksa->opportunistic ||
00461 !(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
00462 return;
00463
00464
00465 pmksa_candidate_add(sm, bssid, PMKID_CANDIDATE_PRIO_SCAN,
00466 ie.capabilities & WPA_CAPABILITY_PREAUTH);
00467 }
00468
00469
00470 #ifdef CONFIG_CTRL_IFACE
00471
00483 int rsn_preauth_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
00484 int verbose)
00485 {
00486 char *pos = buf, *end = buf + buflen;
00487 int res, ret;
00488
00489 if (sm->preauth_eapol) {
00490 ret = os_snprintf(pos, end - pos, "Pre-authentication "
00491 "EAPOL state machines:\n");
00492 if (ret < 0 || ret >= end - pos)
00493 return pos - buf;
00494 pos += ret;
00495 res = eapol_sm_get_status(sm->preauth_eapol,
00496 pos, end - pos, verbose);
00497 if (res >= 0)
00498 pos += res;
00499 }
00500
00501 return pos - buf;
00502 }
00503 #endif
00504
00505
00510 int rsn_preauth_in_progress(struct wpa_sm *sm)
00511 {
00512 return sm->preauth_eapol != NULL;
00513 }
00514
00515 #endif