static u8 * eap_otp_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, size_t *respDataLen) { const struct eap_hdr *req; struct eap_hdr *resp; const u8 *pos, *password; u8 *rpos; size_t password_len, len; int otp; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, reqDataLen, &len); if (pos == NULL) { ret->ignore = TRUE; return NULL; } req = (const struct eap_hdr *) reqData; wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message", pos, len); password = eap_get_config_otp(sm, &password_len); if (password) otp = 1; else { password = eap_get_config_password(sm, &password_len); otp = 0; } if (password == NULL) { wpa_printf(MSG_INFO, "EAP-OTP: Password not configured"); eap_sm_request_otp(sm, (const char *) pos, len); ret->ignore = TRUE; return NULL; } ret->ignore = FALSE; ret->methodState = METHOD_DONE; ret->decision = DECISION_COND_SUCC; ret->allowNotifications = FALSE; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, respDataLen, password_len, EAP_CODE_RESPONSE, req->identifier, &rpos); if (resp == NULL) return NULL; os_memcpy(rpos, password, password_len); wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response", password, password_len); if (otp) { wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password"); eap_clear_config_otp(sm); } return (u8 *) resp; }
void eap_sm_notify_ctrl_attached(struct eap_sm *sm) { struct wpa_ssid *config = eap_get_config(sm); if (config == NULL) return; /* Re-send any pending requests for user data since a new control * interface was added. This handles cases where the EAP authentication * starts immediately after system startup when the user interface is * not yet running. */ if (config->pending_req_identity) eap_sm_request_identity(sm, config); if (config->pending_req_password) eap_sm_request_password(sm, config); if (config->pending_req_otp) eap_sm_request_otp(sm, config, NULL, 0); if (config->pending_req_pin) eap_sm_request_pin(sm, config); }
static struct wpabuf * eap_gtc_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const struct wpabuf *reqData) { struct eap_gtc_data *data = priv; struct wpabuf *resp; const u8 *pos, *password, *identity; size_t password_len, identity_len, len, plen; int otp; u8 id; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqData, &len); if (pos == NULL) { ret->ignore = TRUE; return NULL; } id = eap_get_id(reqData); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len); if (data->prefix && (len < 10 || os_memcmp(pos, "CHALLENGE=", 10) != 0)) { wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with " "expected prefix"); wpa_printf(MSG_DEBUG, "Unrecoverable error - Restarting\n"); /* Send an empty response in order to allow tunneled * acknowledgement of the failure. This will also cover the * error case which seems to use EAP-MSCHAPv2 like error * reporting with EAP-GTC inside EAP-FAST tunnel. */ resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, 0, EAP_CODE_RESPONSE, id); return resp; } password = eap_get_config_otp(sm, &password_len); if (password) otp = 1; else { password = eap_get_config_password(sm, &password_len); otp = 0; } if (password == NULL) { wpa_printf(MSG_INFO, "EAP-GTC: Password not configured"); eap_sm_request_otp(sm, (const char *) pos, len); ret->ignore = TRUE; return NULL; } ret->ignore = FALSE; ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE; ret->decision = DECISION_COND_SUCC; ret->allowNotifications = FALSE; plen = password_len; identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) return NULL; if (data->prefix) plen += 9 + identity_len + 1; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, plen, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; if (data->prefix) { wpabuf_put_data(resp, "RESPONSE=", 9); wpabuf_put_data(resp, identity, identity_len); wpabuf_put_u8(resp, '\0'); } wpabuf_put_data(resp, password, password_len); wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", wpabuf_head_u8(resp) + sizeof(struct eap_hdr) + 1, plen); if (otp) { wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password"); eap_clear_config_otp(sm); } return resp; }
static u8 * eap_gtc_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, size_t *respDataLen) { struct eap_gtc_data *data = priv; struct wpa_ssid *config = eap_get_config(sm); const struct eap_hdr *req; struct eap_hdr *resp; const u8 *pos, *password; u8 *rpos; size_t password_len, len; pos = eap_hdr_validate(EAP_TYPE_GTC, reqData, reqDataLen, &len); if (pos == NULL) { ret->ignore = TRUE; return NULL; } req = (const struct eap_hdr *) reqData; wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len); if (data->prefix && (len < 10 || memcmp(pos, "CHALLENGE=", 10) != 0)) { wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with " "expected prefix"); /* Send an empty response in order to allow tunneled * acknowledgement of the failure. This will also cover the * error case which seems to use EAP-MSCHAPv2 like error * reporting with EAP-GTC inside EAP-FAST tunnel. */ *respDataLen = sizeof(struct eap_hdr) + 1; resp = malloc(*respDataLen); if (resp == NULL) return NULL; resp->code = EAP_CODE_RESPONSE; resp->identifier = req->identifier; resp->length = host_to_be16(*respDataLen); rpos = (u8 *) (resp + 1); *rpos++ = EAP_TYPE_GTC; return (u8 *) resp; } if (config == NULL || (config->password == NULL && config->otp == NULL)) { wpa_printf(MSG_INFO, "EAP-GTC: Password not configured"); eap_sm_request_otp(sm, config, (const char *) pos, len); ret->ignore = TRUE; return NULL; } if (config->otp) { password = config->otp; password_len = config->otp_len; } else { password = config->password; password_len = config->password_len; } ret->ignore = FALSE; ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE; ret->decision = DECISION_COND_SUCC; ret->allowNotifications = FALSE; *respDataLen = sizeof(struct eap_hdr) + 1 + password_len; if (data->prefix) { *respDataLen += 9 + config->identity_len + 1; } resp = malloc(*respDataLen); if (resp == NULL) return NULL; resp->code = EAP_CODE_RESPONSE; resp->identifier = req->identifier; resp->length = host_to_be16(*respDataLen); rpos = (u8 *) (resp + 1); *rpos++ = EAP_TYPE_GTC; if (data->prefix) { memcpy(rpos, "RESPONSE=", 9); rpos += 9; memcpy(rpos, config->identity, config->identity_len); rpos += config->identity_len; *rpos++ = '\0'; } memcpy(rpos, password, password_len); wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", (u8 *) (resp + 1) + 1, *respDataLen - sizeof(struct eap_hdr) - 1); if (config->otp) { wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password"); memset(config->otp, 0, config->otp_len); free(config->otp); config->otp = NULL; config->otp_len = 0; } return (u8 *) resp; }