struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, u8 code, u8 identifier) { if (type == EAP_UNAUTH_TLS_TYPE) return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, code, identifier); return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, identifier); }
static struct wpabuf * eap_peap_build_phase2_soh(struct eap_sm *sm, struct eap_peap_data *data, u8 id) { struct wpabuf *buf1, *buf, *encr_req; const u8 *req; size_t req_len; buf1 = tncs_build_soh_request(); if (buf1 == NULL) return NULL; buf = eap_msg_alloc(EAP_VENDOR_MICROSOFT, 0x21, wpabuf_len(buf1), EAP_CODE_REQUEST, id); if (buf == NULL) { wpabuf_free(buf1); return NULL; } wpabuf_put_buf(buf, buf1); wpabuf_free(buf1); req = wpabuf_head(buf); req_len = wpabuf_len(buf); wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 SOH data", req, req_len); req += sizeof(struct eap_hdr); req_len -= sizeof(struct eap_hdr); encr_req = eap_server_tls_encrypt(sm, &data->ssl, req, req_len); wpabuf_free(buf); return encr_req; }
static u8 * eap_gtc_buildReq(struct eap_sm *sm, void *priv, int id, size_t *reqDataLen) { struct eap_gtc_data *data = priv; struct eap_hdr *req; u8 *pos; char *msg = "Password"; size_t msg_len; msg_len = strlen(msg); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqDataLen, msg_len, EAP_CODE_REQUEST, id, &pos); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } memcpy(pos, msg, msg_len); data->state = CONTINUE; (void)sm; return (u8 *) req; }
static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier, size_t *respDataLen) { struct eap_hdr *resp; u8 *rpos, *start; size_t len; wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4"); len = 1 + 2 + eap_gpsk_mic_len(data->vendor, data->specifier); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len, EAP_CODE_RESPONSE, identifier, &rpos); if (resp == NULL) return NULL; *rpos++ = EAP_GPSK_OPCODE_GPSK_4; start = rpos; /* No PD_Payload_3 */ WPA_PUT_BE16(rpos, 0); rpos += 2; if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, start, rpos - start, rpos) < 0) { eap_gpsk_state(data, FAILURE); os_free(resp); return NULL; } return (u8 *) resp; }
static struct wpabuf * eap_tnc_build_msg(struct eap_tnc_data *data, u8 id) { struct wpabuf *req; u8 flags; size_t send_len, plen; wpa_printf(MSG_DEBUG, "EAP-TNC: Generating Request"); flags = EAP_TNC_VERSION; send_len = wpabuf_len(data->out_buf) - data->out_used; if (1 + send_len > data->fragment_size) { send_len = data->fragment_size - 1; flags |= EAP_TNC_FLAGS_MORE_FRAGMENTS; if (data->out_used == 0) { flags |= EAP_TNC_FLAGS_LENGTH_INCLUDED; send_len -= 4; } } plen = 1 + send_len; if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED) plen += 4; req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, plen, EAP_CODE_REQUEST, id); if (req == NULL) return NULL; wpabuf_put_u8(req, flags); /* Flags */ if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED) wpabuf_put_be32(req, wpabuf_len(data->out_buf)); wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used, send_len); data->out_used += send_len; if (data->out_used == wpabuf_len(data->out_buf)) { wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes " "(message sent completely)", (unsigned long) send_len); wpabuf_free(data->out_buf); data->out_buf = NULL; data->out_used = 0; if (data->was_fail) eap_tnc_set_state(data, FAIL); else if (data->was_done) eap_tnc_set_state(data, DONE); } else { wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes " "(%lu more to send)", (unsigned long) send_len, (unsigned long) wpabuf_len(data->out_buf) - data->out_used); if (data->state == FAIL) data->was_fail = 1; else if (data->state == DONE) data->was_done = 1; eap_tnc_set_state(data, WAIT_FRAG_ACK); } return req; }
static u8 * eap_md5_buildReq(struct eap_sm *sm, void *priv, int id, size_t *reqDataLen) { struct eap_md5_data *data = priv; struct eap_hdr *req; u8 *pos; (void)sm; if (hostapd_get_rand(data->challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data"); data->state = FAILURE; return NULL; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqDataLen, 1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id, &pos); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } *pos++ = CHALLENGE_LEN; memcpy(pos, data->challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN); data->state = CONTINUE; return (u8 *) req; }
/** * eap_tlv_build_result - Build EAP-TLV Result message * @id: EAP identifier for the header * @status: Status (EAP_TLV_RESULT_SUCCESS or EAP_TLV_RESULT_FAILURE) * Returns: Buffer to the allocated EAP-TLV Result message or %NULL on failure * * This funtion builds an EAP-TLV Result message. The caller is responsible for * freeing the returned buffer. */ static struct wpabuf * eap_tlv_build_result(struct eap_sm *sm, struct eap_peap_data *data, int crypto_tlv_used, int id, u16 status) { struct wpabuf *msg; size_t len; if (data->crypto_binding == NO_BINDING) crypto_tlv_used = 0; len = 6; if (crypto_tlv_used) len += 60; /* Cryptobinding TLV */ msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, len, EAP_CODE_RESPONSE, id); if (msg == NULL) return NULL; wpabuf_put_u8(msg, 0x80); /* Mandatory */ wpabuf_put_u8(msg, EAP_TLV_RESULT_TLV); wpabuf_put_be16(msg, 2); /* Length */ wpabuf_put_be16(msg, status); /* Status */ if (crypto_tlv_used && eap_tlv_add_cryptobinding(sm, data, msg)) { wpabuf_free(msg); return NULL; } return msg; }
static struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id) { struct eap_gtc_data *data = priv; struct wpabuf *req; char *msg; size_t msg_len; msg = data->prefix ? "CHALLENGE=Password" : "Password"; msg_len = os_strlen(msg); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } wpabuf_put_data(req, msg, msg_len); data->state = CONTINUE; return req; }
static struct wpabuf * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier) { struct wpabuf *resp; u8 *rpos, *start; size_t mlen; wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4"); mlen = eap_gpsk_mic_len(data->vendor, data->specifier); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, 1 + 2 + mlen, EAP_CODE_RESPONSE, identifier); if (resp == NULL) return NULL; wpabuf_put_u8(resp, EAP_GPSK_OPCODE_GPSK_4); start = wpabuf_put(resp, 0); /* No PD_Payload_3 */ wpabuf_put_be16(resp, 0); rpos = wpabuf_put(resp, mlen); if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, start, rpos - start, rpos) < 0) { eap_gpsk_state(data, FAILURE); wpabuf_free(resp); return NULL; } return resp; }
static struct wpabuf * eap_pwd_build_id_req(struct eap_sm *sm, struct eap_pwd_data *data, u8 id) { struct wpabuf *req; wpa_printf(MSG_DEBUG, "EAP-pwd: ID/Request"); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, sizeof(struct eap_pwd_hdr) + sizeof(struct eap_pwd_id) + data->id_server_len, EAP_CODE_REQUEST, id); if (req == NULL) { eap_pwd_state(data, FAILURE); return NULL; } /* an lfsr is good enough to generate unpredictable tokens */ data->token = os_random(); wpabuf_put_u8(req, EAP_PWD_OPCODE_ID_EXCH); wpabuf_put_be16(req, data->group_num); wpabuf_put_u8(req, EAP_PWD_DEFAULT_RAND_FUNC); wpabuf_put_u8(req, EAP_PWD_DEFAULT_PRF); wpabuf_put_data(req, &data->token, sizeof(data->token)); wpabuf_put_u8(req, EAP_PWD_PREP_NONE); wpabuf_put_data(req, data->id_server, data->id_server_len); return req; }
static struct wpabuf * eap_mschapv2_build_failure_req( struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id) { struct wpabuf *req; struct eap_mschapv2_hdr *ms; char *message = "E=691 R=0 C=00000000000000000000000000000000 V=3 " "M=FAILED"; size_t ms_len; ms_len = sizeof(*ms) + os_strlen(message); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory" " for request"); data->state = FAILURE; return NULL; } ms = wpabuf_put(req, sizeof(*ms)); ms->op_code = MSCHAPV2_OP_FAILURE; ms->mschapv2_id = data->resp_mschapv2_id; WPA_PUT_BE16(ms->ms_length, ms_len); wpabuf_put_data(req, message, os_strlen(message)); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Failure Request Message", (u8 *) message, os_strlen(message)); return req; }
static struct wpabuf * eap_md5_buildReq(struct eap_sm *sm, void *priv, u8 id) { struct eap_md5_data *data = priv; struct wpabuf *req; if (os_get_random(data->challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data"); data->state = FAILURE; return NULL; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } wpabuf_put_u8(req, CHALLENGE_LEN); wpabuf_put_data(req, data->challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", data->challenge, CHALLENGE_LEN); data->state = CONTINUE; return req; }
/** * eap_peer_tls_phase2_nak - Generate EAP-Nak for Phase 2 * @types: Buffer for returning allocated list of allowed EAP methods * @num_types: Buffer for returning number of allocated EAP methods * @hdr: EAP-Request header (and the following EAP type octet) * @resp: Buffer for returning the EAP-Nak message * Returns: 0 on success, -1 on failure */ int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types, struct eap_hdr *hdr, struct wpabuf **resp) { u8 *pos = (u8 *) (hdr + 1); size_t i; /* TODO: add support for expanded Nak */ wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos); wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types", (u8 *) types, num_types * sizeof(struct eap_method_type)); *resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types, EAP_CODE_RESPONSE, hdr->identifier); if (*resp == NULL) return -1; for (i = 0; i < num_types; i++) { if (types[i].vendor == EAP_VENDOR_IETF && types[i].method < 256) wpabuf_put_u8(*resp, types[i].method); } eap_update_len(*resp); return 0; }
static struct wpabuf * eap_identity_buildReq(struct eap_sm *sm, void *priv, u8 id) { struct eap_identity_data *data = priv; struct wpabuf *req; const char *req_data; size_t req_data_len; if (sm->eapol_cb->get_eap_req_id_text) { req_data = sm->eapol_cb->get_eap_req_id_text(sm->eapol_ctx, &req_data_len); } else { req_data = NULL; req_data_len = 0; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req_data_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-Identity: Failed to allocate " "memory for request"); data->state = FAILURE; return NULL; } wpabuf_put_data(req, req_data, req_data_len); return req; }
static struct wpabuf * eap_psk_build_1(struct eap_sm *sm, struct eap_psk_data *data, u8 id) { struct wpabuf *req; struct eap_psk_hdr_1 *psk; wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)"); if (random_get_bytes(data->rand_s, EAP_PSK_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data"); data->state = FAILURE; return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)", data->rand_s, EAP_PSK_RAND_LEN); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, sizeof(*psk) + data->id_s_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } psk = wpabuf_put(req, sizeof(*psk)); psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */ os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); wpabuf_put_data(req, data->id_s, data->id_s_len); return req; }
static u8 * eap_mschapv2_build_failure_req(struct eap_sm *sm, struct eap_mschapv2_data *data, int id, size_t *reqDataLen) { struct eap_hdr *req; struct eap_mschapv2_hdr *ms; u8 *pos; char *message = "E=691 R=0 C=00000000000000000000000000000000 V=3 " "M=FAILED"; size_t ms_len; ms_len = sizeof(*ms) + strlen(message); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen, ms_len, EAP_CODE_REQUEST, id, &pos); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory" " for request"); data->state = FAILURE; return NULL; } ms = (struct eap_mschapv2_hdr *) pos; ms->op_code = MSCHAPV2_OP_FAILURE; ms->mschapv2_id = data->resp_mschapv2_id; WPA_PUT_BE16(ms->ms_length, ms_len); memcpy((u8 *) (ms + 1), message, strlen(message)); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Failure Request Message", (u8 *) message, strlen(message)); return (u8 *) req; }
u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len) { struct eap_hdr *hdr; u8 *pos; hdr = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, resp_len, 10, EAP_CODE_RESPONSE, id, &pos); if (hdr == NULL) return NULL; *pos++ = 0x80; /* Mandatory */ *pos++ = EAP_TLV_NAK_TLV; /* Length */ *pos++ = 0; *pos++ = 6; /* Vendor-Id */ *pos++ = 0; *pos++ = 0; *pos++ = 0; *pos++ = 0; /* NAK-Type */ WPA_PUT_BE16(pos, nak_type); return (u8 *) hdr; }
static struct wpabuf *eap_wsc_build_msg(struct eap_wsc_data *data, struct eap_method_ret *ret, u8 id) { struct wpabuf *resp; u8 flags; size_t send_len, plen; ret->ignore = FALSE; wpa_printf(MSG_DEBUG, "EAP-WSC: Generating Response"); ret->allowNotifications = TRUE; flags = 0; send_len = wpabuf_len(data->out_buf) - data->out_used; if (2 + send_len > data->fragment_size) { send_len = data->fragment_size - 2; flags |= WSC_FLAGS_MF; if (data->out_used == 0) { flags |= WSC_FLAGS_LF; send_len -= 2; } } plen = 2 + send_len; if (flags & WSC_FLAGS_LF) { plen += 2; } resp = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, plen, EAP_CODE_RESPONSE, id); if (resp == NULL) { return NULL; } wpabuf_put_u8(resp, data->out_op_code); /* Op-Code */ wpabuf_put_u8(resp, flags); /* Flags */ if (flags & WSC_FLAGS_LF) { wpabuf_put_be16(resp, wpabuf_len(data->out_buf)); } wpabuf_put_data(resp, wpabuf_head_u8(data->out_buf) + data->out_used, send_len); data->out_used += send_len; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; if (data->out_used == wpabuf_len(data->out_buf)) { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(message sent completely)", (unsigned long)send_len); wpabuf_free(data->out_buf); data->out_buf = NULL; data->out_used = 0; if ((data->state == FAIL && data->out_op_code == WSC_ACK) || data->out_op_code == WSC_NACK || data->out_op_code == WSC_Done) { eap_wsc_state(data, FAIL); ret->methodState = METHOD_DONE; } else { eap_wsc_state(data, MESG); } } else { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(%lu more to send)", (unsigned long)send_len, (unsigned long)wpabuf_len(data->out_buf) - data->out_used); eap_wsc_state(data, WAIT_FRAG_ACK); } return resp; }
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; }
struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, int eap_type, int version, u8 id) { struct wpabuf *req; u8 flags; size_t send_len, plen; wpa_printf(MSG_DEBUG, "SSL: Generating Request"); if (data->tls_out == NULL) { wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); return NULL; } flags = version; send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; if (1 + send_len > data->tls_out_limit) { send_len = data->tls_out_limit - 1; flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; if (data->tls_out_pos == 0) { flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; send_len -= 4; } } plen = 1 + send_len; if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) plen += 4; req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, plen, EAP_CODE_REQUEST, id); if (req == NULL) return NULL; wpabuf_put_u8(req, flags); /* Flags */ if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) wpabuf_put_be32(req, wpabuf_len(data->tls_out)); wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, send_len); data->tls_out_pos += send_len; if (data->tls_out_pos == wpabuf_len(data->tls_out)) { wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " "(message sent completely)", (unsigned long) send_len); wpabuf_free(data->tls_out); data->tls_out = NULL; data->tls_out_pos = 0; data->state = MSG; } else { wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " "(%lu more to send)", (unsigned long) send_len, (unsigned long) wpabuf_len(data->tls_out) - data->tls_out_pos); data->state = WAIT_FRAG_ACK; } return req; }
/** * eap_mschapv2_process - Process an EAP-MSCHAPv2 failure message * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @data: Pointer to private EAP method data from eap_mschapv2_init() * @ret: Return values from EAP request validation and processing * @req: Pointer to EAP-MSCHAPv2 header from the request * @req_len: Length of the EAP-MSCHAPv2 data * @id: EAP identifier used in th erequest * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if * no reply available */ static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, size_t req_len, u8 id) { struct wpabuf *resp; const u8 *msdata = (const u8 *) (req + 1); char *buf; size_t len = req_len - sizeof(*req); int retry = 0; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received failure"); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Failure data", msdata, len); /* * eap_mschapv2_failure_txt() expects a nul terminated string, so we * must allocate a large enough temporary buffer to create that since * the received message does not include nul termination. */ buf = os_malloc(len + 1); if (buf) { os_memcpy(buf, msdata, len); buf[len] = '\0'; retry = eap_mschapv2_failure_txt(sm, data, buf); os_free(buf); } ret->ignore = FALSE; ret->methodState = METHOD_DONE; ret->decision = DECISION_FAIL; ret->allowNotifications = FALSE; if (data->prev_error == ERROR_PASSWD_EXPIRED && data->passwd_change_version == 3) { struct eap_peer_config *config = eap_get_config(sm); if (config && config->new_password) return eap_mschapv2_change_password(sm, data, ret, req, id); if (config && config->pending_req_new_password) return NULL; } else if (retry && data->prev_error == ERROR_AUTHENTICATION_FAILURE) { /* TODO: could try to retry authentication, e.g, after having * changed the username/password. In this case, EAP MS-CHAP-v2 * Failure Response would not be sent here. */ return NULL; } /* Note: Only op_code of the EAP-MSCHAPV2 header is included in failure * message. */ resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; wpabuf_put_u8(resp, MSCHAPV2_OP_FAILURE); /* op_code */ return resp; }
static struct wpabuf * eap_tnc_build_msg(struct eap_tnc_data *data, struct eap_method_ret *ret, u8 id) { struct wpabuf *resp; u8 flags; size_t send_len, plen; ret->ignore = FALSE; wpa_printf(MSG_DEBUG, "EAP-TNC: Generating Response"); ret->allowNotifications = TRUE; flags = EAP_TNC_VERSION; send_len = wpabuf_len(data->out_buf) - data->out_used; if (1 + send_len > data->fragment_size) { send_len = data->fragment_size - 1; flags |= EAP_TNC_FLAGS_MORE_FRAGMENTS; if (data->out_used == 0) { flags |= EAP_TNC_FLAGS_LENGTH_INCLUDED; send_len -= 4; } } plen = 1 + send_len; if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED) plen += 4; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, plen, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; wpabuf_put_u8(resp, flags); /* Flags */ if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED) wpabuf_put_be32(resp, wpabuf_len(data->out_buf)); wpabuf_put_data(resp, wpabuf_head_u8(data->out_buf) + data->out_used, send_len); data->out_used += send_len; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; if (data->out_used == wpabuf_len(data->out_buf)) { wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes " "(message sent completely)", (unsigned long) send_len); wpabuf_free(data->out_buf); data->out_buf = NULL; data->out_used = 0; } else { wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes " "(%lu more to send)", (unsigned long) send_len, (unsigned long) wpabuf_len(data->out_buf) - data->out_used); data->state = WAIT_FRAG_ACK; } return resp; }
static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, int peap_version, u8 id, int ret, u8 **out_data, size_t *out_len) { size_t len; u8 *pos, *flags; int more_fragments, length_included; wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total " "%lu bytes)", (unsigned long) data->tls_out_len - data->tls_out_pos, (unsigned long) data->tls_out_len); len = data->tls_out_len - data->tls_out_pos; if (len > data->tls_out_limit) { more_fragments = 1; len = data->tls_out_limit; wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments " "will follow", (unsigned long) len); } else more_fragments = 0; length_included = data->tls_out_pos == 0 && (data->tls_out_len > data->tls_out_limit || data->include_tls_length); *out_data = (u8 *) eap_msg_alloc(EAP_VENDOR_IETF, eap_type, out_len, 1 + length_included * 4 + len, EAP_CODE_RESPONSE, id, &pos); if (*out_data == NULL) return -1; flags = pos++; *flags = peap_version; if (more_fragments) *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; if (length_included) { *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; WPA_PUT_BE32(pos, data->tls_out_len); pos += 4; } os_memcpy(pos, &data->tls_out[data->tls_out_pos], len); data->tls_out_pos += len; if (!more_fragments) { data->tls_out_len = 0; data->tls_out_pos = 0; os_free(data->tls_out); data->tls_out = NULL; } return ret; }
/** * eap_mschapv2_process - Process an EAP-MSCHAPv2 success message * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @data: Pointer to private EAP method data from eap_mschapv2_init() * @ret: Return values from EAP request validation and processing * @req: Pointer to EAP-MSCHAPv2 header from the request * @req_len: Length of the EAP-MSCHAPv2 data * @id: EAP identifier used in th erequest * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if * no reply available */ static struct wpabuf * eap_mschapv2_success(struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, size_t req_len, u8 id) { struct wpabuf *resp; const u8 *pos; size_t len; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received success"); len = req_len - sizeof(*req); pos = (const u8 *) (req + 1); /*if (!data->auth_response_valid || mschapv2_verify_auth_response(data->auth_response, pos, len)) { wpa_printf(MSG_WARNING, "EAP-MSCHAPV2: Invalid authenticator " "response in success request"); ret->methodState = METHOD_DONE; ret->decision = DECISION_FAIL; return NULL; }*/ // Skip this check :). pos += 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN; len -= 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN; while (len > 0 && *pos == ' ') { pos++; len--; } wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Success message", pos, len); wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Authentication succeeded"); /* Note: Only op_code of the EAP-MSCHAPV2 header is included in success * message. */ resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1, EAP_CODE_RESPONSE, id); if (resp == NULL) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Failed to allocate " "buffer for success response"); ret->ignore = TRUE; return NULL; } wpabuf_put_u8(resp, MSCHAPV2_OP_SUCCESS); /* op_code */ ret->methodState = METHOD_DONE; ret->decision = DECISION_UNCOND_SUCC; ret->allowNotifications = FALSE; data->success = 1; if (data->prev_error == ERROR_PASSWD_EXPIRED) eap_mschapv2_password_changed(sm, data); return resp; }
static struct wpabuf * eap_wsc_build_msg(struct eap_wsc_data *data, u8 id) { struct wpabuf *req; u8 flags; size_t send_len, plen; flags = 0; send_len = wpabuf_len(data->out_buf) - data->out_used; if (2 + send_len > data->fragment_size) { send_len = data->fragment_size - 2; flags |= WSC_FLAGS_MF; if (data->out_used == 0) { flags |= WSC_FLAGS_LF; send_len -= 2; } } plen = 2 + send_len; if (flags & WSC_FLAGS_LF) plen += 2; req = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, plen, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for " "request"); return NULL; } wpabuf_put_u8(req, data->out_op_code); /* Op-Code */ wpabuf_put_u8(req, flags); /* Flags */ if (flags & WSC_FLAGS_LF) wpabuf_put_be16(req, wpabuf_len(data->out_buf)); wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used, send_len); data->out_used += send_len; if (data->out_used == wpabuf_len(data->out_buf)) { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(message sent completely)", (unsigned long) send_len); wpabuf_free(data->out_buf); data->out_buf = NULL; data->out_used = 0; eap_wsc_state(data, MESG); } else { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(%lu more to send)", (unsigned long) send_len, (unsigned long) wpabuf_len(data->out_buf) - data->out_used); eap_wsc_state(data, WAIT_FRAG_ACK); } return req; }
struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) { struct wpabuf *req; req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_REQUEST, id); if (req == NULL) return NULL; wpa_printf(MSG_DEBUG, "SSL: Building ACK"); wpabuf_put_u8(req, version); /* Flags */ return req; }
static u8 * eap_leap_process_success(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t *respDataLen) { struct eap_leap_data *data = priv; const struct eap_hdr *req; struct eap_hdr *resp; u8 *pos; const u8 *identity; size_t identity_len; wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Success"); identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) return NULL; if (data->state != LEAP_WAIT_SUCCESS) { wpa_printf(MSG_INFO, "EAP-LEAP: EAP-Success received in " "unexpected state (%d) - ignored", data->state); ret->ignore = TRUE; return NULL; } req = (const struct eap_hdr *) reqData; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP, respDataLen, 3 + LEAP_CHALLENGE_LEN + identity_len, EAP_CODE_REQUEST, req->identifier, &pos); if (resp == NULL) return NULL; *pos++ = LEAP_VERSION; *pos++ = 0; /* unused */ *pos++ = LEAP_CHALLENGE_LEN; if (hostapd_get_rand(pos, LEAP_CHALLENGE_LEN)) { wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data " "for challenge"); os_free(resp); ret->ignore = TRUE; return NULL; } os_memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos, LEAP_CHALLENGE_LEN); pos += LEAP_CHALLENGE_LEN; os_memcpy(pos, identity, identity_len); data->state = LEAP_WAIT_RESPONSE; return (u8 *) resp; }
/** * eap_peer_tls_build_ack - Build a TLS ACK frame * @id: EAP identifier for the response * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) * @peap_version: Version number for EAP-PEAP/TTLS * Returns: Pointer to the allocated ACK frame or %NULL on failure */ struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type, int peap_version) { struct wpabuf *resp; resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)", (int) eap_type, id, peap_version); wpabuf_put_u8(resp, peap_version); /* Flags */ return resp; }
u8 * eap_tls_build_ack(struct eap_ssl_data *data, size_t *respDataLen, u8 id, EapType eap_type, int peap_version) { struct eap_hdr *resp; u8 *pos; resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, respDataLen, 1, EAP_CODE_RESPONSE, id, &pos); if (resp == NULL) return NULL; wpa_printf(MSG_DEBUG, "SSL: Building ACK"); *pos = peap_version; /* Flags */ return (u8 *) resp; }
static struct wpabuf * eap_tnc_build_frag_ack(u8 id, u8 code) { struct wpabuf *msg; msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 0, code, id); if (msg == NULL) { wpa_printf(MSG_ERROR, "EAP-TNC: Failed to allocate memory " "for fragment ack"); return NULL; } wpa_printf(MSG_DEBUG, "EAP-TNC: Send fragment ack"); return msg; }