X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=libeap%2Fsrc%2Feap_peer%2Feap_mschapv2.c;fp=libeap%2Fsrc%2Feap_peer%2Feap_mschapv2.c;h=ce2227d388ef4140d4172cf3683a48f925c92cc1;hp=cd410d91b5df8b02702b5060da5ff7a2e71222ce;hb=f3746d009c6d7f50025af1f58a85e5fee9680be6;hpb=244f18d04aaf29e68495b5ffeb40ef5cca50942f diff --git a/libeap/src/eap_peer/eap_mschapv2.c b/libeap/src/eap_peer/eap_mschapv2.c index cd410d9..ce2227d 100644 --- a/libeap/src/eap_peer/eap_mschapv2.c +++ b/libeap/src/eap_peer/eap_mschapv2.c @@ -2,14 +2,8 @@ * EAP peer method: EAP-MSCHAPV2 (draft-kamath-pppext-eap-mschapv2-00.txt) * Copyright (c) 2004-2008, Jouni Malinen * - * 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. * * This file implements EAP peer part of EAP-MSCHAPV2 method (EAP type 26). * draft-kamath-pppext-eap-mschapv2-00.txt defines the Microsoft EAP CHAP @@ -23,6 +17,7 @@ #include "common.h" #include "crypto/ms_funcs.h" +#include "crypto/random.h" #include "common/wpa_ctrl.h" #include "mschapv2.h" #include "eap_i.h" @@ -145,7 +140,7 @@ static void eap_mschapv2_deinit(struct eap_sm *sm, void *priv) os_free(data->peer_challenge); os_free(data->auth_challenge); wpabuf_free(data->prev_challenge); - os_free(data); + bin_clear_free(data, sizeof(*data)); } @@ -199,7 +194,7 @@ static struct wpabuf * eap_mschapv2_challenge_reply( "in Phase 1"); peer_challenge = data->peer_challenge; os_memset(r->peer_challenge, 0, MSCHAPV2_CHAL_LEN); - } else if (os_get_random(peer_challenge, MSCHAPV2_CHAL_LEN)) { + } else if (random_get_bytes(peer_challenge, MSCHAPV2_CHAL_LEN)) { wpabuf_free(resp); return NULL; } @@ -308,16 +303,23 @@ static void eap_mschapv2_password_changed(struct eap_sm *sm, WPA_EVENT_PASSWORD_CHANGED "EAP-MSCHAPV2: Password changed successfully"); data->prev_error = 0; - os_free(config->password); - if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) { + bin_clear_free(config->password, config->password_len); + if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { + /* TODO: update external storage */ + } else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) { config->password = os_malloc(16); config->password_len = 16; - if (config->password) { - nt_password_hash(config->new_password, - config->new_password_len, - config->password); + if (config->password && + nt_password_hash(config->new_password, + config->new_password_len, + config->password)) { + bin_clear_free(config->password, + config->password_len); + config->password = NULL; + config->password_len = 0; } - os_free(config->new_password); + bin_clear_free(config->new_password, + config->new_password_len); } else { config->password = config->new_password; config->password_len = config->new_password_len; @@ -470,6 +472,13 @@ static int eap_mschapv2_failure_txt(struct eap_sm *sm, pos += 2; msg = pos; } + if (data->prev_error == ERROR_AUTHENTICATION_FAILURE && retry && + config && config->phase2 && + os_strstr(config->phase2, "mschapv2_retry=0")) { + wpa_printf(MSG_DEBUG, + "EAP-MSCHAPV2: mark password retry disabled based on local configuration"); + retry = 0; + } wpa_msg(sm->msg_ctx, MSG_WARNING, "EAP-MSCHAPV2: failure message: '%s' (retry %sallowed, error " "%d)", @@ -502,6 +511,11 @@ static struct wpabuf * eap_mschapv2_change_password( struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id) { +#ifdef CONFIG_NO_RC4 + wpa_printf(MSG_ERROR, + "EAP-MSCHAPV2: RC4 not support in the build - cannot change password"); + return NULL; +#else /* CONFIG_NO_RC4 */ struct wpabuf *resp; int ms_len; const u8 *username, *password, *new_password; @@ -552,19 +566,21 @@ static struct wpabuf * eap_mschapv2_change_password( /* Encrypted-Hash */ if (pwhash) { u8 new_password_hash[16]; - nt_password_hash(new_password, new_password_len, - new_password_hash); + if (nt_password_hash(new_password, new_password_len, + new_password_hash)) + goto fail; nt_password_hash_encrypted_with_block(password, new_password_hash, cp->encr_hash); } else { - old_nt_password_hash_encrypted_with_new_nt_password_hash( - new_password, new_password_len, - password, password_len, cp->encr_hash); + if (old_nt_password_hash_encrypted_with_new_nt_password_hash( + new_password, new_password_len, + password, password_len, cp->encr_hash)) + goto fail; } /* Peer-Challenge */ - if (os_get_random(cp->peer_challenge, MSCHAPV2_CHAL_LEN)) + if (random_get_bytes(cp->peer_challenge, MSCHAPV2_CHAL_LEN)) goto fail; /* Reserved, must be zero */ @@ -597,9 +613,13 @@ static struct wpabuf * eap_mschapv2_change_password( /* Likewise, generate master_key here since we have the needed data * available. */ - nt_password_hash(new_password, new_password_len, password_hash); - hash_nt_password_hash(password_hash, password_hash_hash); - get_master_key(password_hash_hash, cp->nt_response, data->master_key); + if (nt_password_hash(new_password, new_password_len, password_hash) || + hash_nt_password_hash(password_hash, password_hash_hash) || + get_master_key(password_hash_hash, cp->nt_response, + data->master_key)) { + data->auth_response_valid = 0; + goto fail; + } data->master_key_valid = 1; /* Flags */ @@ -613,6 +633,7 @@ static struct wpabuf * eap_mschapv2_change_password( fail: wpabuf_free(resp); return NULL; +#endif /* CONFIG_NO_RC4 */ } @@ -647,10 +668,8 @@ static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm, * must allocate a large enough temporary buffer to create that since * the received message does not include nul termination. */ - buf = os_malloc(len + 1); + buf = dup_binstr(msdata, len); if (buf) { - os_memcpy(buf, msdata, len); - buf[len] = '\0'; retry = eap_mschapv2_failure_txt(sm, data, buf); os_free(buf); } @@ -861,7 +880,6 @@ static u8 * eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len) int eap_peer_mschapv2_register(void) { struct eap_method *eap; - int ret; eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, @@ -875,8 +893,5 @@ int eap_peer_mschapv2_register(void) eap->isKeyAvailable = eap_mschapv2_isKeyAvailable; eap->getKey = eap_mschapv2_getKey; - ret = eap_peer_method_register(eap); - if (ret) - eap_peer_method_free(eap); - return ret; + return eap_peer_method_register(eap); }