SM_STATE(EAP, PROPOSE_METHOD) { int vendor; EapType type; SM_ENTRY(EAP, PROPOSE_METHOD); try_another_method: type = eap_sm_Policy_getNextMethod(sm, &vendor); if (vendor == EAP_VENDOR_IETF) sm->currentMethod = type; else sm->currentMethod = EAP_TYPE_EXPANDED; if (sm->m && sm->eap_method_priv) { sm->m->reset(sm, sm->eap_method_priv); sm->eap_method_priv = NULL; } sm->m = eap_server_get_eap_method(vendor, type); if (sm->m) { sm->eap_method_priv = sm->m->init(sm); if (sm->eap_method_priv == NULL) { wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP " "method %d", sm->currentMethod); sm->m = NULL; sm->currentMethod = EAP_TYPE_NONE; goto try_another_method; } } if (sm->m == NULL) { wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method"); eap_log_msg(sm, "Could not find suitable EAP method"); sm->decision = DECISION_FAILURE; return; } if (sm->currentMethod == EAP_TYPE_IDENTITY || sm->currentMethod == EAP_TYPE_NOTIFICATION) sm->methodState = METHOD_CONTINUE; else sm->methodState = METHOD_PROPOSED; wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD "vendor=%u method=%u", vendor, sm->currentMethod); eap_log_msg(sm, "Propose EAP method vendor=%u method=%u", vendor, sm->currentMethod); }
static void eap_identity_process(struct eap_sm *sm, void *priv, struct wpabuf *respData) { struct eap_identity_data *data = priv; const u8 *pos; size_t len; char *buf; if (data->pick_up) { if (eap_identity_check(sm, data, respData)) { wpa_printf(MSG_DEBUG, "EAP-Identity: failed to pick " "up already started negotiation"); data->state = FAILURE; return; } data->pick_up = 0; } pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, respData, &len); if (pos == NULL) return; /* Should not happen - frame already validated */ wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len); buf = os_malloc(len * 4 + 1); if (buf) { printf_encode(buf, len * 4 + 1, pos, len); eap_log_msg(sm, "EAP-Response/Identity '%s'", buf); os_free(buf); } // 华为客户端识别 if(len > 6 && *pos == 0x15 && *(pos + 1) == 0x04 && *(pos + 2) == 0xc0 && *(pos + 3) == 0xa8 && *(pos + 4) == 0x01 && *(pos + 5) == 0x06) pos += 6; if (sm->identity) sm->update_user = TRUE; os_free(sm->identity); sm->identity = os_malloc(len ? len : 1); if (sm->identity == NULL) { data->state = FAILURE; } else { os_memcpy(sm->identity, pos, len); sm->identity_len = len; data->state = SUCCESS; // 解析域名 if(sm->eapol_cb->parse_domain){ sm->eapol_cb->parse_domain(sm->eapol_ctx ,sm->identity, sm->identity_len, &sm->eap_server); } } }
static void eap_server_tls_log_cb(void *ctx, const char *msg) { struct eap_sm *sm = ctx; eap_log_msg(sm, "TLS: %s", msg); }
static void eap_mschapv2_process_response(struct eap_sm *sm, struct eap_mschapv2_data *data, struct wpabuf *respData) { struct eap_mschapv2_hdr *resp; const u8 *pos, *end, *peer_challenge, *nt_response, *name; u8 flags; size_t len, name_len, i; u8 expected[24]; u8 challenge_hash1[8]; const u8 *username, *user; size_t username_len, user_len; int x; char *buf; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData, &len); if (pos == NULL || len < 1) return; /* Should not happen - frame already validated */ end = pos + len; resp = (struct eap_mschapv2_hdr *) pos; pos = (u8 *) (resp + 1); if (len < sizeof(*resp) + 1 + 49 || resp->op_code != MSCHAPV2_OP_RESPONSE || pos[0] != 49) { wpa_hexdump_buf(MSG_DEBUG, "EAP-MSCHAPV2: Invalid response", respData); data->state = FAILURE; return; } data->resp_mschapv2_id = resp->mschapv2_id; pos++; peer_challenge = pos; pos += 16 + 8; nt_response = pos; pos += 24; flags = *pos++; name = pos; name_len = end - name; if (data->peer_challenge) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using pre-configured " "Peer-Challenge"); peer_challenge = data->peer_challenge; } wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Peer-Challenge", peer_challenge, 16); wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: NT-Response", nt_response, 24); wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len); challenge_hash(peer_challenge, data->auth_challenge, name, name_len, challenge_hash1); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: Challenge Hash", challenge_hash1, 8); wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Username:%s", name); wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Challenge"); printf("MANA (EAP-FAST) : "); for (x=0;x<7;x++) printf("%02x:",challenge_hash1[x]); printf("%02x\n",challenge_hash1[7]); wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Response"); printf("MANA (EAP-FAST) : "); for (x=0;x<23;x++) printf("%02x:",nt_response[x]); printf("%02x\n",nt_response[23]); char *ennode = getenv("KARMANODE"); FILE *f = fopen(ennode, "a"); if (f != NULL) { const char *hdr = "CHAP"; fprintf(f, "%s|%s|", hdr, name); for (x = 0; x < 7; x++) { fprintf(f, "%02x:", challenge_hash1[x]); } fprintf(f, "%02x|", challenge_hash1[7]); for (x = 0; x < 23; x++) { fprintf(f, "%02x:", nt_response[x]); } fprintf(f, "%02x\n", nt_response[23]); fclose(f); } buf = os_malloc(name_len * 4 + 1); if (buf) { printf_encode(buf, name_len * 4 + 1, name, name_len); eap_log_msg(sm, "EAP-MSCHAPV2 Name '%s'", buf); os_free(buf); } /* MSCHAPv2 does not include optional domain name in the * challenge-response calculation, so remove domain prefix * (if present). */ username = sm->identity; username_len = sm->identity_len; for (i = 0; i < username_len; i++) { if (username[i] == '\\') { username_len -= i + 1; username += i + 1; break; } } user = name; user_len = name_len; for (i = 0; i < user_len; i++) { if (user[i] == '\\') { user_len -= i + 1; user += i + 1; break; } } if (username_len != user_len || os_memcmp(username, user, username_len) != 0) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names"); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Expected user " "name", username, username_len); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Received user " "name", user, user_len); data->state = FAILURE; return; } wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: User name", username, username_len); if (sm->user->password_hash) { //res = generate_nt_response_pwhash(data->auth_challenge, generate_nt_response_pwhash(data->auth_challenge, peer_challenge, username, username_len, sm->user->password, expected); } else { //res = generate_nt_response(data->auth_challenge, generate_nt_response(data->auth_challenge, peer_challenge, username, username_len, sm->user->password, sm->user->password_len, expected); } //if (res) { //data->state = FAILURE; //return; //} nt_response = expected; //os_memset((void *)nt_response, 0, 24); //os_memset((void *)expected, 0, 24); //if (os_memcmp_const(nt_response, expected, 24) == 0) { const u8 *pw_hash; u8 pw_hash_buf[16], pw_hash_hash[16]; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Correct NT-Response"); data->state = SUCCESS_REQ; /* Authenticator response is not really needed yet, but * calculate it here so that peer_challenge and username need * not be saved. */ if (sm->user->password_hash) { pw_hash = sm->user->password; } else { if (nt_password_hash(sm->user->password, sm->user->password_len, pw_hash_buf) < 0) { //data->state = FAILURE; data->state = SUCCESS; //return; } pw_hash = pw_hash_buf; } generate_authenticator_response_pwhash( pw_hash, peer_challenge, data->auth_challenge, username, username_len, nt_response, data->auth_response); hash_nt_password_hash(pw_hash, pw_hash_hash); get_master_key(pw_hash_hash, nt_response, data->master_key); data->master_key_valid = 1; wpa_hexdump_key(MSG_INFO, "EAP-MSCHAPV2: Derived Master Key", data->master_key, MSCHAPV2_KEY_LEN); //} else { //data->state = SUCCESS; //} }