* hostapd / EAP-MSCHAPv2 (draft-kamath-pppext-eap-mschapv2-00.txt) server
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "crypto/ms_funcs.h"
+#include "crypto/random.h"
#include "eap_i.h"
return;
os_free(data->peer_challenge);
- os_free(data);
+ bin_clear_free(data, sizeof(*data));
}
{
struct wpabuf *req;
struct eap_mschapv2_hdr *ms;
- char *name = "hostapd"; /* TODO: make this configurable */
size_t ms_len;
if (!data->auth_challenge_from_tls &&
- os_get_random(data->auth_challenge, CHALLENGE_LEN)) {
+ random_get_bytes(data->auth_challenge, CHALLENGE_LEN)) {
wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to get random "
"data");
data->state = FAILURE;
return NULL;
}
- ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + os_strlen(name);
+ ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + sm->server_id_len;
req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
EAP_CODE_REQUEST, id);
if (req == NULL) {
wpabuf_put(req, CHALLENGE_LEN);
wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge",
data->auth_challenge, CHALLENGE_LEN);
- wpabuf_put_data(req, name, os_strlen(name));
+ wpabuf_put_data(req, sm->server_id, sm->server_id_len);
return req;
}
const u8 *username, *user;
size_t username_len, user_len;
int res;
+ char *buf;
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
&len);
wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);
+ 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). */
}
}
+#ifdef CONFIG_TESTING_OPTIONS
+ {
+ u8 challenge[8];
+
+ if (challenge_hash(peer_challenge, data->auth_challenge,
+ username, username_len, challenge) == 0) {
+ eap_server_mschap_rx_callback(sm, "EAP-MSCHAPV2",
+ username, username_len,
+ challenge, nt_response);
+ }
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
if (username_len != user_len ||
os_memcmp(username, user, username_len) != 0) {
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names");
return;
}
- if (os_memcmp(nt_response, expected, 24) == 0) {
+ if (os_memcmp_const(nt_response, expected, 24) == 0) {
const u8 *pw_hash;
u8 pw_hash_buf[16], pw_hash_hash[16];
if (sm->user->password_hash) {
pw_hash = sm->user->password;
} else {
- nt_password_hash(sm->user->password,
- sm->user->password_len,
- pw_hash_buf);
+ if (nt_password_hash(sm->user->password,
+ sm->user->password_len,
+ pw_hash_buf) < 0) {
+ data->state = FAILURE;
+ 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);
+ if (generate_authenticator_response_pwhash(
+ pw_hash, peer_challenge, data->auth_challenge,
+ username, username_len, nt_response,
+ data->auth_response) < 0 ||
+ hash_nt_password_hash(pw_hash, pw_hash_hash) < 0 ||
+ get_master_key(pw_hash_hash, nt_response,
+ data->master_key)) {
+ data->state = FAILURE;
+ return;
+ }
data->master_key_valid = 1;
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived Master Key",
data->master_key, MSCHAPV2_KEY_LEN);