From b1d4db7cc82e80a57f82ec4550ab5a63a5535f08 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Sat, 28 Apr 2018 04:28:44 +0200 Subject: [PATCH] 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. --- src/eap-aka.c | 8 ++++---- src/eap-gtc.c | 7 ++++--- src/eap-md5.c | 6 +++--- src/eap-mschapv2.c | 18 +++++++++--------- src/eap-peap.c | 16 ++++++++-------- src/eap-sim.c | 8 ++++---- src/eap-tls.c | 18 +++++++++--------- src/eap-ttls.c | 16 ++++++++-------- src/eap.c | 12 ++++++------ src/eap.h | 4 ++-- src/network.c | 15 +++++++++++---- 11 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/eap-aka.c b/src/eap-aka.c index 8e90c1ce..0798009b 100644 --- a/src/eap-aka.c +++ b/src/eap-aka.c @@ -603,7 +603,7 @@ static void auth_destroyed(void *data) 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, const char *prefix, 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); if (!auth) { l_debug("No SIM driver available for EAP-AKA"); - return false; + return -EUNATCH; } if (!iwd_sim_auth_get_nai(auth)) { 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, diff --git a/src/eap-gtc.c b/src/eap-gtc.c index 2d6f88f0..1a242886 100644 --- a/src/eap-gtc.c +++ b/src/eap-gtc.c @@ -25,6 +25,7 @@ #endif #include +#include #include #include "eap.h" @@ -69,7 +70,7 @@ error: 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, const char *prefix, 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)) { 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, diff --git a/src/eap-md5.c b/src/eap-md5.c index 103ac015..4d9d16e6 100644 --- a/src/eap-md5.c +++ b/src/eap-md5.c @@ -86,7 +86,7 @@ err: 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, const char *prefix, 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)) { 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, diff --git a/src/eap-mschapv2.c b/src/eap-mschapv2.c index 688e17f0..7cb50e5f 100644 --- a/src/eap-mschapv2.c +++ b/src/eap-mschapv2.c @@ -641,7 +641,7 @@ 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, +static int eap_mschapv2_check_settings(struct l_settings *settings, struct l_queue *secrets, const char *prefix, 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, setting, NULL); - return true; + return 0; } 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) { l_error("Exactly one of (%s, %s) must be present", setting, setting2); - return false; + return -EEXIST; } if (password_hash) { @@ -691,10 +691,10 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings, if (!tmp || len != 16) { l_error("Property %s is not a 16-byte hexstring", setting); - return false; + return -EINVAL; } - return true; + return 0; } else if (password) goto validate; @@ -702,7 +702,7 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings, if (!secret) { eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD, setting2, identity); - return true; + return 0; } password = secret->value; @@ -710,13 +710,13 @@ static bool eap_mschapv2_check_settings(struct l_settings *settings, validate: if (!l_utf8_validate(password, strlen(password), NULL)) { l_error("Password is not valid UTF-8"); - return false; + return -EINVAL; } 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, diff --git a/src/eap-peap.c b/src/eap-peap.c index 6a6d24a1..cf9e196f 100644 --- a/src/eap-peap.c +++ b/src/eap-peap.c @@ -816,7 +816,7 @@ error: 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, const char *prefix, 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); if (!cert) { l_error("Failed to load %s", path); - return false; + return -EIO; } 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); if (!cert) { l_error("Failed to load %s", client_cert); - return false; + return -EIO; } l_free(cert); @@ -858,7 +858,7 @@ static bool eap_peap_check_settings(struct l_settings *settings, if (path && !client_cert) { l_error("%s present but no client certificate (%s)", entry, client_cert_entry); - return false; + return -ENOENT; } snprintf(passphrase_entry, sizeof(passphrase_entry), @@ -886,13 +886,13 @@ static bool eap_peap_check_settings(struct l_settings *settings, if (!encrypted) { l_error("Error loading client private key %s", path); - return false; + return -EIO; } if (passphrase) { l_error("Error loading encrypted client " "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 " "key %s is not encrypted", passphrase_entry, path); - return false; + return -EIO; } } } else if (passphrase) { l_error("%s present but no client private key path set (%s)", passphrase_entry, entry); - return false; + return -ENOENT; } snprintf(entry, sizeof(entry), "%sPEAP-Phase2-", prefix); diff --git a/src/eap-sim.c b/src/eap-sim.c index 72d38741..39a810b8 100644 --- a/src/eap-sim.c +++ b/src/eap-sim.c @@ -609,7 +609,7 @@ static void auth_destroyed(void *data) 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, const char *prefix, 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); if (!auth) { l_debug("No SIM driver available for EAP-SIM"); - return false; + return -EUNATCH; } if (!iwd_sim_auth_get_nai(auth)) { 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, diff --git a/src/eap-tls.c b/src/eap-tls.c index 4a8fe5c1..14ada014 100644 --- a/src/eap-tls.c +++ b/src/eap-tls.c @@ -372,7 +372,7 @@ err: 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, const char *prefix, 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); if (!cert) { l_error("Failed to load %s", path); - return false; + return -EIO; } 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); if (!cert) { l_error("Failed to load %s", client_cert); - return false; + return -EIO; } l_free(cert); @@ -414,7 +414,7 @@ static bool eap_tls_check_settings(struct l_settings *settings, if (path && !client_cert) { l_error("%s present but no client certificate (%s)", setting, client_cert_setting); - return false; + return -ENOENT; } snprintf(passphrase_setting, sizeof(passphrase_setting), @@ -442,13 +442,13 @@ static bool eap_tls_check_settings(struct l_settings *settings, if (!encrypted) { l_error("Error loading client private key %s", path); - return false; + return -EIO; } if (passphrase) { l_error("Error loading encrypted client " "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 " "key %s is not encrypted", passphrase_setting, path); - return false; + return -ENOENT; } } } else if (passphrase) { l_error("%s present but no client private key path set (%s)", passphrase_setting, setting); - return false; + return -ENOENT; } - return true; + return 0; } static bool eap_tls_load_settings(struct eap_state *eap, diff --git a/src/eap-ttls.c b/src/eap-ttls.c index 1c7d66fc..41c2fe0f 100644 --- a/src/eap-ttls.c +++ b/src/eap-ttls.c @@ -632,7 +632,7 @@ err: 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, const char *prefix, 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); if (!cert) { l_error("Failed to load %s", path); - return false; + return -EIO; } 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); if (!cert) { l_error("Failed to load %s", client_cert); - return false; + return -EIO; } l_free(cert); @@ -674,7 +674,7 @@ static bool eap_ttls_check_settings(struct l_settings *settings, if (path && !client_cert) { l_error("%s present but no client certificate (%s)", setting, client_cert_setting); - return false; + return -ENOENT; } snprintf(passphrase_setting, sizeof(passphrase_setting), @@ -702,13 +702,13 @@ static bool eap_ttls_check_settings(struct l_settings *settings, if (!encrypted) { l_error("Error loading client private key %s", path); - return false; + return -EIO; } if (passphrase) { l_error("Error loading encrypted client " "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 " "key %s is not encrypted", passphrase_setting, path); - return false; + return -EIO; } } } else if (passphrase) { l_error("%s present but no client private key path set (%s)", passphrase_setting, setting); - return false; + return -ENOENT; } snprintf(setting, sizeof(setting), "%sTTLS-Phase2-", prefix); diff --git a/src/eap.c b/src/eap.c index 3117c052..da08b4b3 100644 --- a/src/eap.c +++ b/src/eap.c @@ -390,7 +390,7 @@ void eap_secret_info_free(void *data) 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, struct l_queue **out_missing) { @@ -405,7 +405,7 @@ bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets, if (!method_name) { l_error("Property %s missing", setting); - return false; + return -ENOENT; } 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) { l_error("EAP method \"%s\" unsupported", method_name); - return false; + return -ENOTSUP; } /* 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", method_name); - return false; + return -ENOTSUP; } /* 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)) { l_error("Property %s is missing", setting); - return false; + return -ENOENT; } } if (!method->check_settings) - return true; + return 0; return method->check_settings(settings, secrets, prefix, out_missing); } diff --git a/src/eap.h b/src/eap.h index 33aaba8f..fedfdb0d 100644 --- a/src/eap.h +++ b/src/eap.h @@ -65,7 +65,7 @@ void eap_append_secret(struct l_queue **out_missing, enum eap_secret_type type, const char *id, const char *parameter); 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, struct l_queue **out_missing); bool eap_load_settings(struct eap_state *eap, struct l_settings *settings, @@ -123,7 +123,7 @@ struct eap_method { bool exports_msk; 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 **out_missing); diff --git a/src/network.c b/src/network.c index 2acded00..42a78dd9 100644 --- a/src/network.c +++ b/src/network.c @@ -476,7 +476,7 @@ int network_autoconnect(struct network *network, struct scan_bss *bss) if (!network_settings_load(network)) return -ENOKEY; - if (!eap_check_settings(network->settings, network->secrets, + if (eap_check_settings(network->settings, network->secrets, "EAP-", true, &missing_secrets) || !l_queue_isempty(missing_secrets) || !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 l_dbus_message *message) { - bool r; + int r; struct l_queue *missing_secrets = NULL; 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-", true, &missing_secrets); - if (!r) { - reply = dbus_error_not_configured(message); + if (r) { + 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; }