From b8fde0c166bcd6e11af72c557630b297d54b46fe Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Thu, 14 Jun 2018 03:45:23 +0200 Subject: [PATCH] eap: Accept a second id parameter in eap_append_secret Accept two setting IDs in eap_append_secret, first for the username and second for the password in case of the EAP_SECRET_REMOTE_USER_PASSWORD EAP secret type. In all other cases only the first setting is used. Until now for EAP_SECRET_REMOTE_USER_PASSWORD secrets we'd generate the two setting names by adding different suffixes to the ID parameter. Using the two different setting names automatically fixes the issues with using the EAP Identity returned by the agent in EAP-MSCHAPv2 and EAP-PWD. --- src/eap-mschapv2.c | 54 ++++++++++++++++------------------------------ src/eap-peap.c | 2 +- src/eap-pwd.c | 14 ++++++------ src/eap-tls.c | 2 +- src/eap-ttls.c | 2 +- src/eap.c | 4 +++- src/eap.h | 3 ++- src/network.c | 13 ++++++----- 8 files changed, 42 insertions(+), 52 deletions(-) diff --git a/src/eap-mschapv2.c b/src/eap-mschapv2.c index ea64d46a..59b27d38 100644 --- a/src/eap-mschapv2.c +++ b/src/eap-mschapv2.c @@ -670,6 +670,9 @@ static int eap_mschapv2_check_settings(struct l_settings *settings, snprintf(setting, sizeof(setting), "%sIdentity", prefix); identity = l_settings_get_value(settings, "Security", setting); + snprintf(setting2, sizeof(setting2), "%sPassword", prefix); + password = l_settings_get_value(settings, "Security", setting2); + if (!identity) { secret = l_queue_find(secrets, eap_secret_info_match, setting); if (secret) { @@ -680,7 +683,7 @@ static int eap_mschapv2_check_settings(struct l_settings *settings, } eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD, - setting, NULL); + setting, setting2, NULL); return 0; } @@ -688,9 +691,6 @@ static int eap_mschapv2_check_settings(struct l_settings *settings, 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); @@ -717,7 +717,7 @@ static int eap_mschapv2_check_settings(struct l_settings *settings, secret = l_queue_find(secrets, eap_secret_info_match, setting2); if (!secret) { eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD, - setting2, identity); + setting2, NULL, identity); return 0; } @@ -740,53 +740,37 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap, const char *prefix) { struct eap_mschapv2_state *state; - const char *identity, *password = NULL; + const char *identity, *password; char setting[64]; state = l_new(struct eap_mschapv2_state, 1); snprintf(setting, sizeof(setting), "%sIdentity", prefix); identity = l_settings_get_value(settings, "Security", setting); - - if (!identity) { - snprintf(setting, sizeof(setting), "%sIdentity-User", prefix); - identity = l_settings_get_value(settings, "Security", setting); - if (!identity) - goto error; - - snprintf(setting, sizeof(setting), "%sIdentity-Password", - prefix); - password = l_settings_get_value(settings, "Security", setting); - if (!password) - goto error; - - set_password_from_string(state, password); - } + if (!identity) + goto error; set_user_name(state, identity); state->user_len = strlen(state->user); /* Either read the password-hash from hexdump or password and hash it */ + snprintf(setting, sizeof(setting), "%sPassword", prefix); + password = l_settings_get_value(settings, "Security", setting); + if (password) + set_password_from_string(state, password); + if (!password) { + unsigned char *tmp; + size_t len; + snprintf(setting, sizeof(setting), "%sPassword-Hash", prefix); password = l_settings_get_value(settings, "Security", setting); - if (password) { - unsigned char *tmp; - size_t len; - - tmp = l_util_from_hexstring(password, &len); - memcpy(state->password_hash, tmp, 16); - l_free(tmp); - } - } - - if (!password) { - snprintf(setting, sizeof(setting), "%sPassword", prefix); - password = l_settings_get_value(settings, "Security", setting); if (!password) goto error; - set_password_from_string(state, password); + tmp = l_util_from_hexstring(password, &len); + memcpy(state->password_hash, tmp, 16); + l_free(tmp); } eap_set_data(eap, state); diff --git a/src/eap-peap.c b/src/eap-peap.c index c3d79dec..4957a173 100644 --- a/src/eap-peap.c +++ b/src/eap-peap.c @@ -928,7 +928,7 @@ static int eap_peap_check_settings(struct l_settings *settings, */ eap_append_secret(out_missing, EAP_SECRET_LOCAL_PKEY_PASSPHRASE, - passphrase_entry, path); + passphrase_entry, NULL, path); } else { memset(priv_key, 0, size); l_free(priv_key); diff --git a/src/eap-pwd.c b/src/eap-pwd.c index 03127d72..f5cfcec3 100644 --- a/src/eap-pwd.c +++ b/src/eap-pwd.c @@ -723,31 +723,31 @@ static int eap_pwd_check_settings(struct l_settings *settings, { const char *identity, *password = NULL; const struct eap_secret_info *secret; - char setting[64]; + char setting[64], setting2[64]; snprintf(setting, sizeof(setting), "%sIdentity", prefix); identity = l_settings_get_value(settings, "Security", setting); + snprintf(setting2, sizeof(setting2), "%sPWD-Password", prefix); + password = l_settings_get_value(settings, "Security", setting2); + if (!identity) { secret = l_queue_find(secrets, eap_secret_info_match, setting); if (!secret) { eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD, - setting, NULL); + setting, setting2, NULL); } return 0; } - snprintf(setting, sizeof(setting), "%sPWD-Password", prefix); - password = l_settings_get_value(settings, "Security", setting); - if (!password) { - secret = l_queue_find(secrets, eap_secret_info_match, setting); + secret = l_queue_find(secrets, eap_secret_info_match, setting2); if (!secret) { eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD, - setting, identity); + setting2, NULL, identity); } } diff --git a/src/eap-tls.c b/src/eap-tls.c index f6ecd76f..0fdaf57a 100644 --- a/src/eap-tls.c +++ b/src/eap-tls.c @@ -473,7 +473,7 @@ static int eap_tls_check_settings(struct l_settings *settings, */ eap_append_secret(out_missing, EAP_SECRET_LOCAL_PKEY_PASSPHRASE, - passphrase_setting, path); + passphrase_setting, NULL, path); } else { memset(priv_key, 0, size); l_free(priv_key); diff --git a/src/eap-ttls.c b/src/eap-ttls.c index 6e70a024..bb8586df 100644 --- a/src/eap-ttls.c +++ b/src/eap-ttls.c @@ -740,7 +740,7 @@ static int eap_ttls_check_settings(struct l_settings *settings, */ eap_append_secret(out_missing, EAP_SECRET_LOCAL_PKEY_PASSPHRASE, - passphrase_setting, path); + passphrase_setting, NULL, path); } else { memset(priv_key, 0, size); l_free(priv_key); diff --git a/src/eap.c b/src/eap.c index 8ed0b0b2..9e685ec9 100644 --- a/src/eap.c +++ b/src/eap.c @@ -377,7 +377,7 @@ bool eap_secret_info_match(const void *a, const void *b) } void eap_append_secret(struct l_queue **out_missing, enum eap_secret_type type, - const char *id, const char *parameter) + const char *id, const char *id2, const char *parameter) { struct eap_secret_info *info; @@ -386,6 +386,7 @@ void eap_append_secret(struct l_queue **out_missing, enum eap_secret_type type, info = l_new(struct eap_secret_info, 1); info->id = l_strdup(id); + info->id2 = l_strdup(id2); info->type = type; info->parameter = l_strdup(parameter); l_queue_push_tail(*out_missing, info); @@ -409,6 +410,7 @@ void eap_secret_info_free(void *data) } l_free(info->id); + l_free(info->id2); l_free(info); } diff --git a/src/eap.h b/src/eap.h index 03b6f9ed..2682bad2 100644 --- a/src/eap.h +++ b/src/eap.h @@ -41,6 +41,7 @@ enum eap_secret_type { struct eap_secret_info { char *id; + char *id2; enum eap_secret_type type; char *parameter; char *value; @@ -62,7 +63,7 @@ void eap_free(struct eap_state *eap); bool eap_secret_info_match(const void *a, const void *b); void eap_append_secret(struct l_queue **out_missing, enum eap_secret_type type, - const char *id, const char *parameter); + const char *id, const char *id2, const char *parameter); void eap_secret_info_free(void *data); int eap_check_settings(struct l_settings *settings, struct l_queue *secrets, diff --git a/src/network.c b/src/network.c index 7f12a8ec..d0095d1c 100644 --- a/src/network.c +++ b/src/network.c @@ -385,15 +385,18 @@ static bool network_set_8021x_secrets(struct network *network) break; case EAP_SECRET_REMOTE_USER_PASSWORD: - setting = alloca(strlen(secret->id) + 10); - - sprintf(setting, "%s-User", secret->id); if (!l_settings_set_string(network->settings, - "Security", setting, + "Security", secret->id, secret->value)) return false; - sprintf(setting, "%s-Password", secret->id); + if (secret->id2) + setting = secret->id2; + else { + setting = alloca(strlen(secret->id) + 10); + sprintf(setting, "%s-Password", secret->id); + } + if (!l_settings_set_string(network->settings, "Security", setting, secret->value + 1 +