3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-22 14:49:24 +01:00

eap-mschapv2: Implement .check_settings

Move the settings validation from .load_settings plus allow the
username/password to be supplied in the secrets l_queue instead of
in the l_settings.
This commit is contained in:
Andrew Zaborowski 2018-04-18 07:03:24 +02:00 committed by Denis Kenzior
parent 9134743a97
commit 3b2b194170

View File

@ -641,6 +641,84 @@ static void set_user_name(struct eap_mschapv2_state *state, const char *user)
state->user = l_strdup(user);
}
static bool eap_mschapv2_check_settings(struct l_settings *settings,
struct l_queue *secrets,
const char *prefix,
struct l_queue **out_missing)
{
const char *identity, *password = NULL, *password_hash;
const struct eap_secret_info *secret;
char setting[64], setting2[64];
uint8_t hash[16];
snprintf(setting, sizeof(setting), "%sIdentity", prefix);
identity = l_settings_get_value(settings, "Security", setting);
if (!identity) {
secret = l_queue_find(secrets, eap_secret_info_match, setting);
if (secret) {
identity = secret->value;
password = secret->value + strlen(secret->value);
goto validate;
}
eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD,
setting, NULL);
return true;
}
snprintf(setting, sizeof(setting), "%sPassword-Hash", prefix);
password_hash = l_settings_get_value(settings, "Security",
setting);
snprintf(setting2, sizeof(setting2), "%sPassword", prefix);
password = l_settings_get_value(settings, "Security", setting2);
if (password && password_hash) {
l_error("Exactly one of (%s, %s) must be present",
setting, setting2);
return false;
}
if (password_hash) {
unsigned char *tmp;
size_t len;
tmp = l_util_from_hexstring(password, &len);
l_free(tmp);
if (!tmp || len != 16) {
l_error("Property %s is not a 16-byte hexstring",
setting);
return false;
}
return true;
} else if (password)
goto validate;
secret = l_queue_find(secrets, eap_secret_info_match, setting2);
if (!secret) {
eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD,
setting2, identity);
return true;
}
password = secret->value;
validate:
if (!l_utf8_validate(password, strlen(password), NULL)) {
l_error("Password is not valid UTF-8");
return false;
}
if (!mschapv2_nt_password_hash(password, hash))
return false;
return true;
}
static bool eap_mschapv2_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
@ -655,9 +733,6 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
set_user_name(state,
l_settings_get_value(settings, "Security", setting));
if (!state->user)
goto err;
state->user_len = strlen(state->user);
/* Either read the password-hash from hexdump or password and hash it */
@ -668,31 +743,18 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
size_t len;
tmp = l_util_from_hexstring(password, &len);
if (len != 16) {
l_error("Read an impossible password hash");
l_free(tmp);
goto err;
}
memcpy(state->password_hash, tmp, 16);
l_free(tmp);
} else {
snprintf(setting, sizeof(setting), "%sPassword", prefix);
password = l_settings_get_value(settings, "Security",
setting);
if (!password || !set_password_from_string(state, password))
goto err;
set_password_from_string(state, password);
}
eap_set_data(eap, state);
return true;
err:
l_free(state->user);
l_free(state);
return false;
}
static struct eap_method eap_mschapv2 = {
@ -702,6 +764,7 @@ static struct eap_method eap_mschapv2 = {
.free = eap_mschapv2_free,
.handle_request = eap_mschapv2_handle_request,
.check_settings = eap_mschapv2_check_settings,
.load_settings = eap_mschapv2_load_settings,
};