3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-10-05 19:08:52 +02:00

eap: Return specific error when check_settings fails

Change the check_settings eap functions to return a negative errno and
return more granular Dbus error from the Connect method.
This commit is contained in:
Andrew Zaborowski 2018-04-28 04:28:44 +02:00 committed by Denis Kenzior
parent a83419011e
commit b1d4db7cc8
11 changed files with 68 additions and 60 deletions

View File

@ -603,7 +603,7 @@ static void auth_destroyed(void *data)
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_aka_check_settings(struct l_settings *settings, static int eap_aka_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -613,15 +613,15 @@ static bool eap_aka_check_settings(struct l_settings *settings,
auth = iwd_sim_auth_find(false, true); auth = iwd_sim_auth_find(false, true);
if (!auth) { if (!auth) {
l_debug("No SIM driver available for EAP-AKA"); l_debug("No SIM driver available for EAP-AKA");
return false; return -EUNATCH;
} }
if (!iwd_sim_auth_get_nai(auth)) { if (!iwd_sim_auth_get_nai(auth)) {
l_error("SIM driver didn't provide NAI"); l_error("SIM driver didn't provide NAI");
return false; return -ENOENT;
} }
return true; return 0;
} }
static bool eap_aka_common_load_settings(struct eap_state *eap, static bool eap_aka_common_load_settings(struct eap_state *eap,

View File

@ -25,6 +25,7 @@
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#include <ell/ell.h> #include <ell/ell.h>
#include "eap.h" #include "eap.h"
@ -69,7 +70,7 @@ error:
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_gtc_check_settings(struct l_settings *settings, static int eap_gtc_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -80,10 +81,10 @@ static bool eap_gtc_check_settings(struct l_settings *settings,
if (!l_settings_get_value(settings, "Security", setting)) { if (!l_settings_get_value(settings, "Security", setting)) {
l_error("Property %s is missing", setting); l_error("Property %s is missing", setting);
return false; return -ENOENT;
} }
return true; return 0;
} }
static bool eap_gtc_load_settings(struct eap_state *eap, static bool eap_gtc_load_settings(struct eap_state *eap,

View File

@ -86,7 +86,7 @@ err:
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_md5_check_settings(struct l_settings *settings, static int eap_md5_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -97,10 +97,10 @@ static bool eap_md5_check_settings(struct l_settings *settings,
if (!l_settings_get_value(settings, "Security", setting)) { if (!l_settings_get_value(settings, "Security", setting)) {
l_error("Property %s is missing", setting); l_error("Property %s is missing", setting);
return false; return -ENOENT;
} }
return true; return 0;
} }
static bool eap_md5_load_settings(struct eap_state *eap, static bool eap_md5_load_settings(struct eap_state *eap,

View File

@ -641,7 +641,7 @@ static void set_user_name(struct eap_mschapv2_state *state, const char *user)
state->user = l_strdup(user); state->user = l_strdup(user);
} }
static bool eap_mschapv2_check_settings(struct l_settings *settings, static int eap_mschapv2_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -665,7 +665,7 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings,
eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD, eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD,
setting, NULL); setting, NULL);
return true; return 0;
} }
snprintf(setting, sizeof(setting), "%sPassword-Hash", prefix); snprintf(setting, sizeof(setting), "%sPassword-Hash", prefix);
@ -678,7 +678,7 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings,
if (password && password_hash) { if (password && password_hash) {
l_error("Exactly one of (%s, %s) must be present", l_error("Exactly one of (%s, %s) must be present",
setting, setting2); setting, setting2);
return false; return -EEXIST;
} }
if (password_hash) { if (password_hash) {
@ -691,10 +691,10 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings,
if (!tmp || len != 16) { if (!tmp || len != 16) {
l_error("Property %s is not a 16-byte hexstring", l_error("Property %s is not a 16-byte hexstring",
setting); setting);
return false; return -EINVAL;
} }
return true; return 0;
} else if (password) } else if (password)
goto validate; goto validate;
@ -702,7 +702,7 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings,
if (!secret) { if (!secret) {
eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD, eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD,
setting2, identity); setting2, identity);
return true; return 0;
} }
password = secret->value; password = secret->value;
@ -710,13 +710,13 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings,
validate: validate:
if (!l_utf8_validate(password, strlen(password), NULL)) { if (!l_utf8_validate(password, strlen(password), NULL)) {
l_error("Password is not valid UTF-8"); l_error("Password is not valid UTF-8");
return false; return -EINVAL;
} }
if (!mschapv2_nt_password_hash(password, hash)) if (!mschapv2_nt_password_hash(password, hash))
return false; return -EINVAL;
return true; return 0;
} }
static bool eap_mschapv2_load_settings(struct eap_state *eap, static bool eap_mschapv2_load_settings(struct eap_state *eap,

View File

@ -816,7 +816,7 @@ error:
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_peap_check_settings(struct l_settings *settings, static int eap_peap_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -832,7 +832,7 @@ static bool eap_peap_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(path, &size); cert = l_pem_load_certificate(path, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", path); l_error("Failed to load %s", path);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -846,7 +846,7 @@ static bool eap_peap_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(client_cert, &size); cert = l_pem_load_certificate(client_cert, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", client_cert); l_error("Failed to load %s", client_cert);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -858,7 +858,7 @@ static bool eap_peap_check_settings(struct l_settings *settings,
if (path && !client_cert) { if (path && !client_cert) {
l_error("%s present but no client certificate (%s)", l_error("%s present but no client certificate (%s)",
entry, client_cert_entry); entry, client_cert_entry);
return false; return -ENOENT;
} }
snprintf(passphrase_entry, sizeof(passphrase_entry), snprintf(passphrase_entry, sizeof(passphrase_entry),
@ -886,13 +886,13 @@ static bool eap_peap_check_settings(struct l_settings *settings,
if (!encrypted) { if (!encrypted) {
l_error("Error loading client private key %s", l_error("Error loading client private key %s",
path); path);
return false; return -EIO;
} }
if (passphrase) { if (passphrase) {
l_error("Error loading encrypted client " l_error("Error loading encrypted client "
"private key %s", path); "private key %s", path);
return false; return -EACCES;
} }
/* /*
@ -911,13 +911,13 @@ static bool eap_peap_check_settings(struct l_settings *settings,
l_error("%s present but client private " l_error("%s present but client private "
"key %s is not encrypted", "key %s is not encrypted",
passphrase_entry, path); passphrase_entry, path);
return false; return -EIO;
} }
} }
} else if (passphrase) { } else if (passphrase) {
l_error("%s present but no client private key path set (%s)", l_error("%s present but no client private key path set (%s)",
passphrase_entry, entry); passphrase_entry, entry);
return false; return -ENOENT;
} }
snprintf(entry, sizeof(entry), "%sPEAP-Phase2-", prefix); snprintf(entry, sizeof(entry), "%sPEAP-Phase2-", prefix);

View File

@ -609,7 +609,7 @@ static void auth_destroyed(void *data)
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_sim_check_settings(struct l_settings *settings, static int eap_sim_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -619,15 +619,15 @@ static bool eap_sim_check_settings(struct l_settings *settings,
auth = iwd_sim_auth_find(true, false); auth = iwd_sim_auth_find(true, false);
if (!auth) { if (!auth) {
l_debug("No SIM driver available for EAP-SIM"); l_debug("No SIM driver available for EAP-SIM");
return false; return -EUNATCH;
} }
if (!iwd_sim_auth_get_nai(auth)) { if (!iwd_sim_auth_get_nai(auth)) {
l_error("SIM driver didn't provide NAI"); l_error("SIM driver didn't provide NAI");
return false; return -ENOENT;
} }
return true; return 0;
} }
static bool eap_sim_load_settings(struct eap_state *eap, static bool eap_sim_load_settings(struct eap_state *eap,

View File

@ -372,7 +372,7 @@ err:
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_tls_check_settings(struct l_settings *settings, static int eap_tls_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -388,7 +388,7 @@ static bool eap_tls_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(path, &size); cert = l_pem_load_certificate(path, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", path); l_error("Failed to load %s", path);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -402,7 +402,7 @@ static bool eap_tls_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(client_cert, &size); cert = l_pem_load_certificate(client_cert, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", client_cert); l_error("Failed to load %s", client_cert);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -414,7 +414,7 @@ static bool eap_tls_check_settings(struct l_settings *settings,
if (path && !client_cert) { if (path && !client_cert) {
l_error("%s present but no client certificate (%s)", l_error("%s present but no client certificate (%s)",
setting, client_cert_setting); setting, client_cert_setting);
return false; return -ENOENT;
} }
snprintf(passphrase_setting, sizeof(passphrase_setting), snprintf(passphrase_setting, sizeof(passphrase_setting),
@ -442,13 +442,13 @@ static bool eap_tls_check_settings(struct l_settings *settings,
if (!encrypted) { if (!encrypted) {
l_error("Error loading client private key %s", l_error("Error loading client private key %s",
path); path);
return false; return -EIO;
} }
if (passphrase) { if (passphrase) {
l_error("Error loading encrypted client " l_error("Error loading encrypted client "
"private key %s", path); "private key %s", path);
return false; return -EACCES;
} }
/* /*
@ -467,16 +467,16 @@ static bool eap_tls_check_settings(struct l_settings *settings,
l_error("%s present but client private " l_error("%s present but client private "
"key %s is not encrypted", "key %s is not encrypted",
passphrase_setting, path); passphrase_setting, path);
return false; return -ENOENT;
} }
} }
} else if (passphrase) { } else if (passphrase) {
l_error("%s present but no client private key path set (%s)", l_error("%s present but no client private key path set (%s)",
passphrase_setting, setting); passphrase_setting, setting);
return false; return -ENOENT;
} }
return true; return 0;
} }
static bool eap_tls_load_settings(struct eap_state *eap, static bool eap_tls_load_settings(struct eap_state *eap,

View File

@ -632,7 +632,7 @@ err:
eap_method_error(eap); eap_method_error(eap);
} }
static bool eap_ttls_check_settings(struct l_settings *settings, static int eap_ttls_check_settings(struct l_settings *settings,
struct l_queue *secrets, struct l_queue *secrets,
const char *prefix, const char *prefix,
struct l_queue **out_missing) struct l_queue **out_missing)
@ -648,7 +648,7 @@ static bool eap_ttls_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(path, &size); cert = l_pem_load_certificate(path, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", path); l_error("Failed to load %s", path);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -662,7 +662,7 @@ static bool eap_ttls_check_settings(struct l_settings *settings,
cert = l_pem_load_certificate(client_cert, &size); cert = l_pem_load_certificate(client_cert, &size);
if (!cert) { if (!cert) {
l_error("Failed to load %s", client_cert); l_error("Failed to load %s", client_cert);
return false; return -EIO;
} }
l_free(cert); l_free(cert);
@ -674,7 +674,7 @@ static bool eap_ttls_check_settings(struct l_settings *settings,
if (path && !client_cert) { if (path && !client_cert) {
l_error("%s present but no client certificate (%s)", l_error("%s present but no client certificate (%s)",
setting, client_cert_setting); setting, client_cert_setting);
return false; return -ENOENT;
} }
snprintf(passphrase_setting, sizeof(passphrase_setting), snprintf(passphrase_setting, sizeof(passphrase_setting),
@ -702,13 +702,13 @@ static bool eap_ttls_check_settings(struct l_settings *settings,
if (!encrypted) { if (!encrypted) {
l_error("Error loading client private key %s", l_error("Error loading client private key %s",
path); path);
return false; return -EIO;
} }
if (passphrase) { if (passphrase) {
l_error("Error loading encrypted client " l_error("Error loading encrypted client "
"private key %s", path); "private key %s", path);
return false; return -EACCES;
} }
/* /*
@ -727,13 +727,13 @@ static bool eap_ttls_check_settings(struct l_settings *settings,
l_error("%s present but client private " l_error("%s present but client private "
"key %s is not encrypted", "key %s is not encrypted",
passphrase_setting, path); passphrase_setting, path);
return false; return -EIO;
} }
} }
} else if (passphrase) { } else if (passphrase) {
l_error("%s present but no client private key path set (%s)", l_error("%s present but no client private key path set (%s)",
passphrase_setting, setting); passphrase_setting, setting);
return false; return -ENOENT;
} }
snprintf(setting, sizeof(setting), "%sTTLS-Phase2-", prefix); snprintf(setting, sizeof(setting), "%sTTLS-Phase2-", prefix);

View File

@ -390,7 +390,7 @@ void eap_secret_info_free(void *data)
l_free(info); l_free(info);
} }
bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets, int eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
const char *prefix, bool set_key_material, const char *prefix, bool set_key_material,
struct l_queue **out_missing) struct l_queue **out_missing)
{ {
@ -405,7 +405,7 @@ bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
if (!method_name) { if (!method_name) {
l_error("Property %s missing", setting); l_error("Property %s missing", setting);
return false; return -ENOENT;
} }
for (entry = l_queue_get_entries(eap_methods); entry; for (entry = l_queue_get_entries(eap_methods); entry;
@ -419,7 +419,7 @@ bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
if (!entry) { if (!entry) {
l_error("EAP method \"%s\" unsupported", method_name); l_error("EAP method \"%s\" unsupported", method_name);
return false; return -ENOTSUP;
} }
/* Check if selected method is suitable for 802.1x */ /* Check if selected method is suitable for 802.1x */
@ -427,7 +427,7 @@ bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
l_error("EAP method \"%s\" doesn't export key material", l_error("EAP method \"%s\" doesn't export key material",
method_name); method_name);
return false; return -ENOTSUP;
} }
/* method may not store identity in settings file */ /* method may not store identity in settings file */
@ -436,12 +436,12 @@ bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
if (!l_settings_get_value(settings, "Security", setting)) { if (!l_settings_get_value(settings, "Security", setting)) {
l_error("Property %s is missing", setting); l_error("Property %s is missing", setting);
return false; return -ENOENT;
} }
} }
if (!method->check_settings) if (!method->check_settings)
return true; return 0;
return method->check_settings(settings, secrets, prefix, out_missing); return method->check_settings(settings, secrets, prefix, out_missing);
} }

View File

@ -65,7 +65,7 @@ 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 *parameter);
void eap_secret_info_free(void *data); void eap_secret_info_free(void *data);
bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets, int eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
const char *prefix, bool set_key_material, const char *prefix, bool set_key_material,
struct l_queue **out_missing); struct l_queue **out_missing);
bool eap_load_settings(struct eap_state *eap, struct l_settings *settings, bool eap_load_settings(struct eap_state *eap, struct l_settings *settings,
@ -123,7 +123,7 @@ struct eap_method {
bool exports_msk; bool exports_msk;
const char *name; const char *name;
bool (*check_settings)(struct l_settings *settings, int (*check_settings)(struct l_settings *settings,
struct l_queue *secrets, const char *prefix, struct l_queue *secrets, const char *prefix,
struct l_queue **out_missing); struct l_queue **out_missing);

View File

@ -476,7 +476,7 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
if (!network_settings_load(network)) if (!network_settings_load(network))
return -ENOKEY; return -ENOKEY;
if (!eap_check_settings(network->settings, network->secrets, if (eap_check_settings(network->settings, network->secrets,
"EAP-", true, &missing_secrets) || "EAP-", true, &missing_secrets) ||
!l_queue_isempty(missing_secrets) || !l_queue_isempty(missing_secrets) ||
!network_set_8021x_secrets(network)) { !network_set_8021x_secrets(network)) {
@ -892,7 +892,7 @@ static struct l_dbus_message *network_connect_8021x(struct network *network,
struct scan_bss *bss, struct scan_bss *bss,
struct l_dbus_message *message) struct l_dbus_message *message)
{ {
bool r; int r;
struct l_queue *missing_secrets = NULL; struct l_queue *missing_secrets = NULL;
struct l_dbus_message *reply; struct l_dbus_message *reply;
@ -900,8 +900,15 @@ static struct l_dbus_message *network_connect_8021x(struct network *network,
r = eap_check_settings(network->settings, network->secrets, "EAP-", r = eap_check_settings(network->settings, network->secrets, "EAP-",
true, &missing_secrets); true, &missing_secrets);
if (!r) { if (r) {
reply = dbus_error_not_configured(message); if (r == -EUNATCH)
reply = dbus_error_not_available(message);
else if (r == -ENOTSUP)
reply = dbus_error_not_supported(message);
else if (r == -EACCES)
reply = dbus_error_failed(message);
else
reply = dbus_error_not_configured(message);
goto error; goto error;
} }