Lines Matching defs:sm
40 static bool eap_sm_allowMethod(struct eap_sm *sm, int vendor,
42 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id);
43 static void eap_sm_processIdentity(struct eap_sm *sm,
45 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req);
47 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req);
52 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
57 static bool eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
59 return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
63 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
66 sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
70 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var)
72 return sm->eapol_cb->get_int(sm->eapol_ctx, var);
76 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var,
79 sm->eapol_cb->set_int(sm->eapol_ctx, var, value);
83 static struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm)
85 return sm->eapol_cb->get_eapReqData(sm->eapol_ctx);
89 static void eap_notify_status(struct eap_sm *sm, const char *status,
94 if (sm->eapol_cb->notify_status)
95 sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
99 static void eap_report_error(struct eap_sm *sm, int error_code)
102 if (sm->eapol_cb->notify_eap_error)
103 sm->eapol_cb->notify_eap_error(sm->eapol_ctx, error_code);
107 static void eap_sm_free_key(struct eap_sm *sm)
109 if (sm->eapKeyData) {
110 bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen);
111 sm->eapKeyData = NULL;
116 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
118 ext_password_free(sm->ext_pw_buf);
119 sm->ext_pw_buf = NULL;
121 if (sm->m == NULL || sm->eap_method_priv == NULL)
125 "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt);
126 sm->m->deinit(sm, sm->eap_method_priv);
127 sm->eap_method_priv = NULL;
128 sm->m = NULL;
134 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
140 static int eap_config_allowed_method(struct eap_sm *sm,
162 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
167 int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method)
169 return eap_config_allowed_method(sm, eap_get_config(sm), vendor,
175 static int eap_sm_append_3gpp_realm(struct eap_sm *sm, char *imsi,
219 if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
220 sm->m->has_reauth_data(sm, sm->eap_method_priv) &&
221 !sm->prev_failure &&
222 sm->last_config == eap_get_config(sm)) {
225 sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
227 sm->last_config = eap_get_config(sm);
228 eap_deinit_prev_method(sm, "INITIALIZE");
230 sm->selectedMethod = EAP_TYPE_NONE;
231 sm->methodState = METHOD_NONE;
232 sm->allowNotifications = true;
233 sm->decision = DECISION_FAIL;
234 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
235 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
236 eapol_set_bool(sm, EAPOL_eapSuccess, false);
237 eapol_set_bool(sm, EAPOL_eapFail, false);
238 eap_sm_free_key(sm);
239 os_free(sm->eapSessionId);
240 sm->eapSessionId = NULL;
241 sm->eapKeyAvailable = false;
242 eapol_set_bool(sm, EAPOL_eapRestart, false);
243 sm->lastId = -1; /* new session - make sure this does not match with
253 eapol_set_bool(sm, EAPOL_eapResp, false);
254 eapol_set_bool(sm, EAPOL_eapNoResp, false);
262 sm->ignore = 0;
263 sm->num_rounds = 0;
264 sm->num_rounds_short = 0;
265 sm->prev_failure = 0;
266 sm->expected_failure = 0;
267 sm->reauthInit = false;
268 sm->erp_seq = (u32) -1;
269 sm->use_machine_cred = 0;
270 sm->eap_fast_mschapv2 = false;
282 sm->num_rounds = 0;
283 sm->num_rounds_short = 0;
289 eapol_set_int(sm, EAPOL_idleWhile, 0);
313 eapReqData = eapol_get_eapReqData(sm);
315 eap_sm_parseEapReq(sm, eapReqData);
316 sm->num_rounds++;
318 sm->num_rounds_short++;
320 sm->num_rounds_short = 0;
336 if (sm->reqMethod == EAP_TYPE_EXPANDED)
337 method = sm->reqVendorMethod;
339 method = sm->reqMethod;
341 eap_method = eap_peer_get_eap_method(sm->reqVendor, method);
343 if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
345 sm->reqVendor, method);
346 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
348 sm->reqVendor, method);
349 eap_notify_status(sm, "refuse proposed method",
354 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
355 "vendor=%u method=%u", sm->reqVendor, method);
357 eap_notify_status(sm, "accept proposed method",
367 if (sm->fast_reauth &&
368 sm->m && sm->m->vendor == sm->reqVendor &&
369 sm->m->method == method &&
370 sm->m->has_reauth_data &&
371 sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
376 eap_deinit_prev_method(sm, "GET_METHOD");
380 sm->selectedMethod = sm->reqMethod;
381 if (sm->m == NULL)
382 sm->m = eap_method;
383 if (!sm->m) {
386 sm->reqVendor, method);
390 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
394 sm->reqVendor, method, sm->m->name);
396 sm->eap_method_priv = sm->m->init_for_reauth(
397 sm, sm->eap_method_priv);
399 sm->waiting_ext_cert_check = 0;
400 sm->ext_cert_check = 0;
401 sm->eap_method_priv = sm->m->init(sm);
404 if (sm->eap_method_priv == NULL) {
405 struct eap_peer_config *config = eap_get_config(sm);
406 wpa_msg(sm->msg_ctx, MSG_INFO,
409 sm->reqVendor, method, sm->m->name);
410 sm->m = NULL;
411 sm->methodState = METHOD_NONE;
412 sm->selectedMethod = EAP_TYPE_NONE;
413 if (sm->reqMethod == EAP_TYPE_TLS && config &&
429 sm->methodState = METHOD_INIT;
430 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD
432 sm->reqVendor, method, sm->m->name);
436 wpabuf_free(sm->eapRespData);
437 sm->eapRespData = NULL;
438 sm->eapRespData = eap_sm_buildNak(sm, sm->reqId);
444 static char * eap_get_realm(struct eap_sm *sm, struct eap_peer_config *config)
490 sm->eapol_cb->get_imsi &&
491 (eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
493 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
495 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
502 mnc_len = sm->eapol_cb->get_imsi(sm->eapol_ctx, config->sim_num,
508 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len,
527 static char * eap_home_realm(struct eap_sm *sm)
529 return eap_get_realm(sm, eap_get_config(sm));
534 eap_erp_get_key(struct eap_sm *sm, const char *realm)
538 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) {
554 eap_erp_get_key_nai(struct eap_sm *sm, const char *nai)
558 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) {
574 static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm)
578 while ((erp = eap_erp_get_key(sm, realm)) != NULL) {
586 int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 next_seq_num)
591 home_realm = eap_home_realm(sm);
597 erp = eap_erp_get_key(sm, home_realm);
620 int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
631 home_realm = eap_get_realm(sm, config);
633 home_realm = eap_home_realm(sm);
639 erp = eap_erp_get_key(sm, home_realm);
671 void eap_peer_erp_free_keys(struct eap_sm *sm)
676 dl_list_for_each_safe(erp, tmp, &sm->erp_keys, struct eap_erp_key, list)
685 void eap_peer_erp_init(struct eap_sm *sm, u8 *ext_session_id,
701 realm = eap_home_realm(sm);
706 eap_erp_remove_keys_realm(sm, realm);
727 emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len);
742 session_id = sm->eapSessionId;
743 session_id_len = sm->eapSessionIdLen;
787 dl_list_add(&sm->erp_keys, &erp->list);
802 struct wpabuf * eap_peer_build_erp_reauth_start(struct eap_sm *sm, u8 eap_id)
809 realm = eap_home_realm(sm);
813 erp = eap_erp_get_key(sm, realm);
850 sm->erp_seq = erp->next_seq;
859 static int eap_peer_erp_reauth_start(struct eap_sm *sm, u8 eap_id)
863 msg = eap_peer_build_erp_reauth_start(sm, eap_id);
868 wpabuf_free(sm->eapRespData);
869 sm->eapRespData = msg;
870 sm->reauthInit = true;
887 if (sm->m == NULL) {
892 eapReqData = eapol_get_eapReqData(sm);
893 if (sm->m->vendor == EAP_VENDOR_IETF && sm->m->method == EAP_TYPE_LEAP)
913 ret.ignore = sm->ignore;
914 ret.methodState = sm->methodState;
915 ret.decision = sm->decision;
916 ret.allowNotifications = sm->allowNotifications;
917 wpabuf_free(sm->eapRespData);
918 sm->eapRespData = NULL;
919 sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
926 sm->eapRespData);
928 sm->ignore = ret.ignore;
929 if (sm->ignore)
931 sm->methodState = ret.methodState;
932 sm->decision = ret.decision;
933 sm->allowNotifications = ret.allowNotifications;
935 if (sm->m->isKeyAvailable && sm->m->getKey &&
936 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
937 eap_sm_free_key(sm);
938 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
939 &sm->eapKeyDataLen);
940 os_free(sm->eapSessionId);
941 sm->eapSessionId = NULL;
942 if (sm->m->getSessionId) {
943 sm->eapSessionId = sm->m->getSessionId(
944 sm, sm->eap_method_priv,
945 &sm->eapSessionIdLen);
947 sm->eapSessionId, sm->eapSessionIdLen);
960 wpabuf_free(sm->lastRespData);
961 if (sm->eapRespData) {
962 if (wpabuf_len(sm->eapRespData) >= 20)
963 sm->num_rounds_short = 0;
964 if (sm->workaround)
965 os_memcpy(sm->last_sha1, sm->req_sha1, 20);
966 sm->lastId = sm->reqId;
967 sm->lastRespData = wpabuf_dup(sm->eapRespData);
968 eapol_set_bool(sm, EAPOL_eapResp, true);
971 sm->lastRespData = NULL;
973 eapol_set_bool(sm, EAPOL_eapReq, false);
974 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
975 sm->reauthInit = false;
986 eapol_set_bool(sm, EAPOL_eapReq, false);
987 eapol_set_bool(sm, EAPOL_eapNoResp, true);
999 eapReqData = eapol_get_eapReqData(sm);
1002 eap_sm_processIdentity(sm, eapReqData);
1003 wpabuf_free(sm->eapRespData);
1004 sm->eapRespData = NULL;
1005 sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0);
1017 eapReqData = eapol_get_eapReqData(sm);
1020 eap_sm_processNotify(sm, eapReqData);
1021 wpabuf_free(sm->eapRespData);
1022 sm->eapRespData = NULL;
1023 sm->eapRespData = eap_sm_buildNotify(sm->reqId);
1033 wpabuf_free(sm->eapRespData);
1034 if (sm->lastRespData)
1035 sm->eapRespData = wpabuf_dup(sm->lastRespData);
1037 sm->eapRespData = NULL;
1048 struct eap_peer_config *config = eap_get_config(sm);
1051 if (sm->eapKeyData != NULL)
1052 sm->eapKeyAvailable = true;
1053 eapol_set_bool(sm, EAPOL_eapSuccess, true);
1060 eapol_set_bool(sm, EAPOL_eapReq, false);
1068 eapol_set_bool(sm, EAPOL_eapNoResp, true);
1070 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1073 if (!config || !sm->m) {
1087 if (config->erp && sm->m->get_emsk && sm->eapSessionId &&
1088 sm->m->isKeyAvailable &&
1089 sm->m->isKeyAvailable(sm, sm->eap_method_priv))
1090 eap_peer_erp_init(sm, NULL, 0, NULL, 0);
1101 eapol_set_bool(sm, EAPOL_eapFail, true);
1108 eapol_set_bool(sm, EAPOL_eapReq, false);
1115 eapol_set_bool(sm, EAPOL_eapNoResp, true);
1117 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
1120 sm->prev_failure = 1;
1124 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
1136 if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
1154 static void eap_peer_sm_step_idle(struct eap_sm *sm)
1161 if (eapol_get_bool(sm, EAPOL_eapReq))
1163 else if ((eapol_get_bool(sm, EAPOL_altAccept) &&
1164 sm->decision != DECISION_FAIL) ||
1165 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
1166 sm->decision == DECISION_UNCOND_SUCC))
1168 else if (eapol_get_bool(sm, EAPOL_altReject) ||
1169 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
1170 sm->decision != DECISION_UNCOND_SUCC) ||
1171 (eapol_get_bool(sm, EAPOL_altAccept) &&
1172 sm->methodState != METHOD_CONT &&
1173 sm->decision == DECISION_FAIL))
1175 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
1176 sm->leap_done && sm->decision != DECISION_FAIL &&
1177 sm->methodState == METHOD_DONE)
1179 else if (sm->selectedMethod == EAP_TYPE_PEAP &&
1180 sm->peap_done && sm->decision != DECISION_FAIL &&
1181 sm->methodState == METHOD_DONE)
1186 static int eap_peer_req_is_duplicate(struct eap_sm *sm)
1190 duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
1191 if (sm->workaround && duplicate &&
1192 os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) {
1212 static int eap_peer_sm_allow_canned(struct eap_sm *sm)
1214 struct eap_peer_config *config = eap_get_config(sm);
1221 static void eap_peer_sm_step_received(struct eap_sm *sm)
1223 int duplicate = eap_peer_req_is_duplicate(sm);
1230 if (sm->rxSuccess && sm->decision != DECISION_FAIL &&
1231 (sm->reqId == sm->lastId ||
1232 eap_success_workaround(sm, sm->reqId, sm->lastId)))
1234 else if (sm->workaround && sm->lastId == -1 && sm->rxSuccess &&
1235 !sm->rxFailure && !sm->rxReq && eap_peer_sm_allow_canned(sm))
1237 else if (sm->workaround && sm->lastId == -1 && sm->rxFailure &&
1238 !sm->rxReq && sm->methodState != METHOD_CONT &&
1239 eap_peer_sm_allow_canned(sm))
1241 else if (sm->workaround && sm->rxSuccess && !sm->rxFailure &&
1242 !sm->rxReq && sm->methodState != METHOD_CONT &&
1243 eap_peer_sm_allow_canned(sm))
1245 else if (sm->methodState != METHOD_CONT &&
1246 ((sm->rxFailure &&
1247 sm->decision != DECISION_UNCOND_SUCC) ||
1248 (sm->rxSuccess && sm->decision == DECISION_FAIL &&
1249 (sm->selectedMethod != EAP_TYPE_LEAP ||
1250 sm->methodState != METHOD_MAY_CONT))) &&
1251 (sm->reqId == sm->lastId ||
1252 eap_success_workaround(sm, sm->reqId, sm->lastId)))
1254 else if (sm->rxReq && duplicate)
1256 else if (sm->rxReq && !duplicate &&
1257 sm->reqMethod == EAP_TYPE_NOTIFICATION &&
1258 sm->allowNotifications)
1260 else if (sm->rxReq && !duplicate &&
1261 sm->selectedMethod == EAP_TYPE_NONE &&
1262 sm->reqMethod == EAP_TYPE_IDENTITY)
1264 else if (sm->rxReq && !duplicate &&
1265 sm->selectedMethod == EAP_TYPE_NONE &&
1266 sm->reqMethod != EAP_TYPE_IDENTITY &&
1267 sm->reqMethod != EAP_TYPE_NOTIFICATION)
1269 else if (sm->rxReq && !duplicate &&
1270 sm->reqMethod == sm->selectedMethod &&
1271 sm->methodState != METHOD_DONE)
1273 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
1274 (sm->rxSuccess || sm->rxResp))
1276 else if (sm->reauthInit)
1283 static void eap_peer_sm_step_local(struct eap_sm *sm)
1285 switch (sm->EAP_state) {
1290 if (eapol_get_bool(sm, EAPOL_portEnabled) &&
1291 !sm->force_disabled)
1295 eap_peer_sm_step_idle(sm);
1298 eap_peer_sm_step_received(sm);
1301 if (sm->selectedMethod == sm->reqMethod)
1315 if (sm->ignore)
1317 else if (sm->methodState == METHOD_DONE &&
1318 sm->decision == DECISION_FAIL && !sm->eapRespData)
1349 if (eapol_get_bool(sm, EAPOL_eapRestart) &&
1350 eapol_get_bool(sm, EAPOL_portEnabled))
1352 else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled)
1354 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
1363 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
1364 wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d "
1367 sm->num_rounds++;
1370 } else if (sm->num_rounds_short > EAP_MAX_AUTH_ROUNDS_SHORT) {
1371 if (sm->num_rounds_short == EAP_MAX_AUTH_ROUNDS_SHORT + 1) {
1372 wpa_msg(sm->msg_ctx, MSG_INFO,
1375 sm->num_rounds_short++;
1380 eap_peer_sm_step_local(sm);
1385 static bool eap_sm_allowMethod(struct eap_sm *sm, int vendor,
1388 if (!eap_allowed_method(sm, vendor, method)) {
1402 struct eap_sm *sm, int id, const struct eap_method *methods,
1421 if (sm->reqVendor == m->vendor &&
1422 sm->reqVendorMethod == m->method)
1424 if (eap_allowed_method(sm, m->vendor, m->method)) {
1448 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id)
1457 "vendor=%u method=%u not allowed)", sm->reqMethod,
1458 sm->reqVendor, sm->reqVendorMethod);
1462 if (sm->reqMethod == EAP_TYPE_EXPANDED)
1463 return eap_sm_build_expanded_nak(sm, id, methods, count);
1474 if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod)
1476 if (eap_allowed_method(sm, m->vendor, m->method)) {
1497 static void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req)
1502 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
1504 eap_notify_status(sm, "started", "");
1549 static int eap_sm_imsi_identity(struct eap_sm *sm,
1559 if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) {
1572 mnc_len = scard_get_mnc_len(sm->scard_ctx);
1581 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len,
1629 static int eap_sm_set_scard_pin(struct eap_sm *sm,
1632 if (scard_set_pin(sm->scard_ctx, conf->cert.pin)) {
1641 eap_sm_request_pin(sm);
1648 static int eap_sm_get_scard_identity(struct eap_sm *sm,
1651 if (eap_sm_set_scard_pin(sm, conf))
1654 return eap_sm_imsi_identity(sm, conf);
1662 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1671 struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
1673 struct eap_peer_config *config = eap_get_config(sm);
1685 if (sm->m && sm->m->get_identity &&
1686 (identity = sm->m->get_identity(sm, sm->eap_method_priv,
1695 } else if (sm->use_machine_cred) {
1734 if (eap_sm_get_scard_identity(sm, config) < 0)
1741 } else if (eap_sm_set_scard_pin(sm, config) < 0) {
1750 eap_sm_request_identity(sm);
1761 os_free(sm->identity);
1762 sm->identity = os_memdup(identity, identity_len);
1763 sm->identity_len = identity_len;
1771 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req)
1790 wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",
1804 static void eap_peer_initiate(struct eap_sm *sm, const struct eap_hdr *hdr,
1844 if (eap_peer_erp_reauth_start(sm, hdr->identifier) == 0)
1851 eapol_set_bool(sm, EAPOL_eapTriggerStart, true);
1855 void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, size_t len)
1895 if (seq != sm->erp_seq) {
1926 erp = eap_erp_get_key_nai(sm, nai);
1975 eapol_set_bool(sm, EAPOL_eapFail, true);
1976 eapol_set_bool(sm, EAPOL_eapReq, false);
1977 eapol_set_bool(sm, EAPOL_eapNoResp, true);
1978 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
1980 sm->prev_failure = 1;
1987 eap_sm_free_key(sm);
1988 sm->eapKeyDataLen = 0;
1989 sm->eapKeyData = os_malloc(erp->rRK_len);
1990 if (!sm->eapKeyData)
1992 sm->eapKeyDataLen = erp->rRK_len;
1999 sm->eapKeyData, erp->rRK_len) < 0) {
2001 eap_sm_free_key(sm);
2005 sm->eapKeyData, sm->eapKeyDataLen);
2006 sm->eapKeyAvailable = true;
2007 eapol_set_bool(sm, EAPOL_eapSuccess, true);
2008 eapol_set_bool(sm, EAPOL_eapReq, false);
2009 eapol_set_bool(sm, EAPOL_eapNoResp, true);
2010 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
2016 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
2022 sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = false;
2023 sm->reqId = 0;
2024 sm->reqMethod = EAP_TYPE_NONE;
2025 sm->reqVendor = EAP_VENDOR_IETF;
2026 sm->reqVendorMethod = EAP_TYPE_NONE;
2041 sm->reqId = hdr->identifier;
2043 if (sm->workaround) {
2046 sha1_vector(1, addr, &plen, sm->req_sha1);
2056 sm->rxReq = true;
2058 sm->reqMethod = *pos++;
2059 if (sm->reqMethod == EAP_TYPE_EXPANDED) {
2066 sm->reqVendor = WPA_GET_BE24(pos);
2068 sm->reqVendorMethod = WPA_GET_BE32(pos);
2072 sm->reqId, sm->reqMethod, sm->reqVendor,
2073 sm->reqVendorMethod);
2076 if (sm->selectedMethod == EAP_TYPE_LEAP) {
2087 sm->rxResp = true;
2089 sm->reqMethod = *pos;
2092 sm->reqMethod, sm->reqId);
2099 eap_notify_status(sm, "completion", "success");
2100 sm->rxSuccess = true;
2104 eap_notify_status(sm, "completion", "failure");
2107 if (sm->m && sm->m->get_error_code) {
2110 error_code = sm->m->get_error_code(sm->eap_method_priv);
2112 eap_report_error(sm, error_code);
2114 sm->rxFailure = true;
2117 eap_peer_initiate(sm, hdr, plen);
2120 eap_peer_finish(sm, hdr, plen);
2133 struct eap_sm *sm = ctx;
2138 eap_notify_status(sm, "remote certificate verification",
2140 if (sm->ext_cert_check) {
2141 sm->waiting_ext_cert_check = 1;
2142 eap_sm_request(sm, WPA_CTRL_REQ_EXT_CERT_CHECK,
2147 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR
2153 eap_notify_status(sm, "remote certificate verification",
2157 if (!sm->eapol_cb->notify_cert)
2170 sm->eapol_cb->notify_cert(sm->eapol_ctx, &data->peer_cert,
2175 eap_notify_status(sm, "local TLS alert",
2178 eap_notify_status(sm, "remote TLS alert",
2184 eap_notify_status(sm, "unsafe server renegotiation", "failure");
2210 struct eap_sm *sm;
2213 sm = os_zalloc(sizeof(*sm));
2214 if (sm == NULL)
2216 sm->eapol_ctx = eapol_ctx;
2217 sm->eapol_cb = eapol_cb;
2218 sm->msg_ctx = msg_ctx;
2219 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
2220 sm->wps = conf->wps;
2221 dl_list_init(&sm->erp_keys);
2238 tlsconf.cb_ctx = sm;
2240 sm->ssl_ctx = tls_init(&tlsconf);
2241 if (sm->ssl_ctx == NULL) {
2244 os_free(sm);
2248 sm->ssl_ctx2 = tls_init(&tlsconf);
2249 if (sm->ssl_ctx2 == NULL) {
2255 return sm;
2261 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2266 void eap_peer_sm_deinit(struct eap_sm *sm)
2268 if (sm == NULL)
2270 eap_deinit_prev_method(sm, "EAP deinit");
2271 eap_sm_abort(sm);
2272 if (sm->ssl_ctx2)
2273 tls_deinit(sm->ssl_ctx2);
2274 tls_deinit(sm->ssl_ctx);
2275 eap_peer_erp_free_keys(sm);
2276 os_free(sm->identity);
2277 os_free(sm);
2283 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2290 int eap_peer_sm_step(struct eap_sm *sm)
2294 sm->changed = false;
2296 if (sm->changed)
2298 } while (sm->changed);
2305 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2310 void eap_sm_abort(struct eap_sm *sm)
2312 wpabuf_free(sm->lastRespData);
2313 sm->lastRespData = NULL;
2314 wpabuf_free(sm->eapRespData);
2315 sm->eapRespData = NULL;
2316 eap_sm_free_key(sm);
2317 os_free(sm->eapSessionId);
2318 sm->eapSessionId = NULL;
2323 eapol_set_bool(sm, EAPOL_eapSuccess, false);
2404 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2415 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose)
2419 if (sm == NULL)
2424 eap_sm_state_txt(sm->EAP_state));
2428 if (sm->selectedMethod != EAP_TYPE_NONE) {
2430 if (sm->m) {
2431 name = sm->m->name;
2435 sm->selectedMethod);
2443 sm->selectedMethod, name);
2448 if (sm->m && sm->m->get_status) {
2449 len += sm->m->get_status(sm, sm->eap_method_priv,
2461 sm->reqMethod,
2462 eap_sm_method_state_txt(sm->methodState),
2463 eap_sm_decision_txt(sm->decision),
2464 sm->ClientTimeout);
2475 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
2483 if (sm == NULL)
2485 config = eap_get_config(sm);
2534 if (sm->eapol_cb->eap_param_needed)
2535 sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt);
2540 const char * eap_sm_get_method_name(struct eap_sm *sm)
2542 if (sm->m == NULL)
2544 return sm->m->name;
2550 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2557 void eap_sm_request_identity(struct eap_sm *sm)
2559 eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0);
2565 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2572 void eap_sm_request_password(struct eap_sm *sm)
2574 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0);
2580 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2587 void eap_sm_request_new_password(struct eap_sm *sm)
2589 eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0);
2595 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2602 void eap_sm_request_pin(struct eap_sm *sm)
2604 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0);
2610 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2618 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len)
2620 eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len);
2626 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2633 void eap_sm_request_passphrase(struct eap_sm *sm)
2635 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0);
2641 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2644 void eap_sm_request_sim(struct eap_sm *sm, const char *req)
2646 eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req));
2652 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2657 void eap_sm_notify_ctrl_attached(struct eap_sm *sm)
2659 struct eap_peer_config *config = eap_get_config(sm);
2669 eap_sm_request_identity(sm);
2671 eap_sm_request_password(sm);
2673 eap_sm_request_new_password(sm);
2675 eap_sm_request_otp(sm, NULL, 0);
2677 eap_sm_request_pin(sm);
2679 eap_sm_request_passphrase(sm);
2763 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2766 void eap_set_fast_reauth(struct eap_sm *sm, int enabled)
2768 sm->fast_reauth = enabled;
2774 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2777 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
2779 sm->workaround = workaround;
2785 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2793 struct eap_peer_config * eap_get_config(struct eap_sm *sm)
2795 return sm->eapol_cb->get_config(sm->eapol_ctx);
2801 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2805 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
2807 struct eap_peer_config *config = eap_get_config(sm);
2812 if (sm->use_machine_cred) {
2822 static int eap_get_ext_password(struct eap_sm *sm,
2829 if (sm->use_machine_cred) {
2845 ext_password_free(sm->ext_pw_buf);
2846 sm->ext_pw_buf = ext_password_get(sm->ext_pw, name);
2849 return sm->ext_pw_buf == NULL ? -1 : 0;
2855 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2859 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
2861 struct eap_peer_config *config = eap_get_config(sm);
2866 if ((sm->use_machine_cred &&
2868 (!sm->use_machine_cred &&
2870 if (eap_get_ext_password(sm, config) < 0)
2872 *len = wpabuf_len(sm->ext_pw_buf);
2873 return wpabuf_head(sm->ext_pw_buf);
2876 if (sm->use_machine_cred) {
2888 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2895 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
2897 struct eap_peer_config *config = eap_get_config(sm);
2902 if ((sm->use_machine_cred &&
2904 (!sm->use_machine_cred &&
2906 if (eap_get_ext_password(sm, config) < 0)
2910 *len = wpabuf_len(sm->ext_pw_buf);
2911 return wpabuf_head(sm->ext_pw_buf);
2914 if (sm->use_machine_cred) {
2931 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2935 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len)
2937 struct eap_peer_config *config = eap_get_config(sm);
2947 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2951 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len)
2953 struct eap_peer_config *config = eap_get_config(sm);
2963 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2969 void eap_clear_config_otp(struct eap_sm *sm)
2971 struct eap_peer_config *config = eap_get_config(sm);
2983 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2986 const char * eap_get_config_phase1(struct eap_sm *sm)
2988 struct eap_peer_config *config = eap_get_config(sm);
2997 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3000 const char * eap_get_config_phase2(struct eap_sm *sm)
3002 struct eap_peer_config *config = eap_get_config(sm);
3009 int eap_get_config_fragment_size(struct eap_sm *sm)
3011 struct eap_peer_config *config = eap_get_config(sm);
3020 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3023 int eap_key_available(struct eap_sm *sm)
3025 return sm ? sm->eapKeyAvailable : 0;
3031 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3038 void eap_notify_success(struct eap_sm *sm)
3040 if (sm) {
3041 sm->decision = DECISION_COND_SUCC;
3042 sm->EAP_state = EAP_SUCCESS;
3049 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3054 void eap_notify_lower_layer_success(struct eap_sm *sm)
3056 if (sm == NULL)
3059 if (eapol_get_bool(sm, EAPOL_eapSuccess) ||
3060 sm->decision == DECISION_FAIL ||
3061 (sm->methodState != METHOD_MAY_CONT &&
3062 sm->methodState != METHOD_DONE))
3065 if (sm->eapKeyData != NULL)
3066 sm->eapKeyAvailable = true;
3067 eapol_set_bool(sm, EAPOL_eapSuccess, true);
3068 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
3076 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3084 const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len)
3086 if (sm == NULL || sm->eapSessionId == NULL) {
3091 *len = sm->eapSessionIdLen;
3092 return sm->eapSessionId;
3098 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3107 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len)
3109 if (sm == NULL || sm->eapKeyData == NULL) {
3114 *len = sm->eapKeyDataLen;
3115 return sm->eapKeyData;
3121 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3129 struct wpabuf * eap_get_eapRespData(struct eap_sm *sm)
3133 if (sm == NULL || sm->eapRespData == NULL)
3136 resp = sm->eapRespData;
3137 sm->eapRespData = NULL;
3145 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3151 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx)
3153 if (sm)
3154 sm->scard_ctx = ctx;
3160 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3166 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
3169 sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
3176 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3180 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
3184 return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
3193 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3199 void eap_set_force_disabled(struct eap_sm *sm, int disabled)
3201 sm->force_disabled = disabled;
3207 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3210 void eap_set_external_sim(struct eap_sm *sm, int external_sim)
3212 sm->external_sim = external_sim;
3218 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3225 void eap_notify_pending(struct eap_sm *sm)
3227 sm->eapol_cb->notify_pending(sm->eapol_ctx);
3233 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3235 void eap_invalidate_cached_session(struct eap_sm *sm)
3237 if (sm)
3238 eap_deinit_prev_method(sm, "invalidate");
3268 void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext)
3270 ext_password_free(sm->ext_pw_buf);
3271 sm->ext_pw_buf = NULL;
3272 sm->ext_pw = ext;
3278 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3282 void eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len)
3284 if (sm->eapol_cb->set_anon_id)
3285 sm->eapol_cb->set_anon_id(sm->eapol_ctx, id, len);
3289 int eap_peer_was_failure_expected(struct eap_sm *sm)
3291 return sm->expected_failure;