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.
This commit is contained in:
Andrew Zaborowski 2018-06-14 03:45:23 +02:00 committed by Denis Kenzior
parent 7877be328b
commit b8fde0c166
8 changed files with 42 additions and 52 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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 +