diff --git a/ChangeLog b/ChangeLog index 436e12772..4f3afa6fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-06-12 Dan Williams + + Add a GError argument to nm_connection_verify() and nm_setting_verify(), + and add error enums to each NMSetting subclass. Each NMSetting subclass now + returns a descriptive GError when verification fails. + 2008-06-11 Dan Williams Patch from Tambet Ingo diff --git a/callouts/nm-dispatcher-action.c b/callouts/nm-dispatcher-action.c index 8da80fee3..0aae1b3a9 100644 --- a/callouts/nm-dispatcher-action.c +++ b/callouts/nm-dispatcher-action.c @@ -311,10 +311,15 @@ nm_dispatcher_action (Handler *h, if (!d->persist) d->quit_timeout = g_timeout_add (10000, quit_timeout_cb, NULL); - connection = nm_connection_new_from_hash (connection_hash); + connection = nm_connection_new_from_hash (connection_hash, error); if (connection) { - if (!nm_connection_verify (connection)) - g_warning ("Connection was invalid!"); + g_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark ((*error)->domain)), + (*error)->message, (*error)->code); + /* Don't fail on this error yet */ + g_error_free (*error); + *error = NULL; } value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE); diff --git a/libnm-glib/nm-dbus-connection.c b/libnm-glib/nm-dbus-connection.c index ba649d9e0..b3442478e 100644 --- a/libnm-glib/nm-dbus-connection.c +++ b/libnm-glib/nm-dbus-connection.c @@ -121,7 +121,7 @@ constructor (GType type, NMConnection *wrapped; const char *service; GHashTable *settings = NULL; - GError *err = NULL; + GError *error = NULL; object = G_OBJECT_CLASS (nm_dbus_connection_parent_class)->constructor (type, n_construct_params, construct_params); @@ -146,17 +146,21 @@ constructor (GType type, priv->path, NM_DBUS_IFACE_SETTINGS_CONNECTION); - if (!org_freedesktop_NetworkManagerSettings_Connection_get_settings (priv->proxy, &settings, &err)) { - nm_warning ("Can not retrieve settings: %s", err->message); - g_error_free (err); + if (!org_freedesktop_NetworkManagerSettings_Connection_get_settings (priv->proxy, &settings, &error)) { + nm_warning ("Can not retrieve settings: %s", error->message); + g_error_free (error); goto err; } - wrapped = nm_connection_new_from_hash (settings); + wrapped = nm_connection_new_from_hash (settings, &error); g_hash_table_destroy (settings); if (!wrapped) { - nm_warning ("Invalid settings"); + nm_warning ("Invalid connection: '%s' / '%s' invalid: %d", + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, + error->code); + g_error_free (error); goto err; } diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c index eabac2b80..05e7bf3e8 100644 --- a/libnm-glib/nm-vpn-plugin.c +++ b/libnm-glib/nm-vpn-plugin.c @@ -321,14 +321,22 @@ nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin, static gboolean impl_vpn_plugin_connect (NMVPNPlugin *plugin, GHashTable *properties, - GError **err) + GError **error) { NMConnection *connection; - gboolean success; + gboolean success = FALSE; - connection = nm_connection_new_from_hash (properties); - success = nm_vpn_plugin_connect (plugin, connection, err); - g_object_unref (connection); + connection = nm_connection_new_from_hash (properties, error); + if (!connection) { + nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark ((*error)->domain)), + (*error)->message, + (*error)->code); + } else { + success = nm_vpn_plugin_connect (plugin, connection, error); + g_object_unref (connection); + } return success; } @@ -344,17 +352,20 @@ impl_vpn_plugin_need_secrets (NMVPNPlugin *plugin, char *sn = NULL; GError *ns_err = NULL; gboolean needed = FALSE; + GError *cnfh_err = NULL; g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE); g_return_val_if_fail (properties != NULL, FALSE); - connection = nm_connection_new_from_hash (properties); + connection = nm_connection_new_from_hash (properties, &cnfh_err); if (!connection) { g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, - "%s", - "The connection information was invalid."); + "The connection was invalid: '%s' / '%s' invalid: %d.", + g_type_name (nm_connection_lookup_setting_type_by_quark (cnfh_err->domain)), + cnfh_err->message, cnfh_err->code); + g_error_free (cnfh_err); return FALSE; } diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index bc1e091f8..082dd7db6 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -59,44 +59,98 @@ static struct SettingInfo { const char *name; GType type; guint32 priority; + GQuark error_quark; } default_map[DEFAULT_MAP_SIZE] = { { NULL } }; static void -register_one_setting (int i, const char *name, GType type, guint32 priority) +register_one_setting (const char *name, GType type, GQuark error_quark, guint32 priority) { - g_return_if_fail (i >= 0); + static guint32 i = 0; + g_return_if_fail (i < DEFAULT_MAP_SIZE); g_return_if_fail (default_map[i].name == NULL); default_map[i].name = name; default_map[i].type = type; + default_map[i].error_quark = error_quark; default_map[i].priority = priority; + i++; + nm_setting_register (name, type); } static void register_default_settings (void) { - int i = 0; - nm_utils_register_value_transformations (); if (G_LIKELY (default_map[0].name)) return; - register_one_setting (i++, NM_SETTING_CONNECTION_SETTING_NAME, NM_TYPE_SETTING_CONNECTION, 0); - register_one_setting (i++, NM_SETTING_WIRED_SETTING_NAME, NM_TYPE_SETTING_WIRED, 1); - register_one_setting (i++, NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS, 1); - register_one_setting (i++, NM_SETTING_GSM_SETTING_NAME, NM_TYPE_SETTING_GSM, 1); - register_one_setting (i++, NM_SETTING_CDMA_SETTING_NAME, NM_TYPE_SETTING_CDMA, 1); - register_one_setting (i++, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY, 2); - register_one_setting (i++, NM_SETTING_SERIAL_SETTING_NAME, NM_TYPE_SETTING_SERIAL, 2); - register_one_setting (i++, NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP, 3); - register_one_setting (i++, NM_SETTING_PPPOE_SETTING_NAME, NM_TYPE_SETTING_PPPOE, 3); - register_one_setting (i++, NM_SETTING_802_1X_SETTING_NAME, NM_TYPE_SETTING_802_1X, 3); - register_one_setting (i++, NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN, 4); - register_one_setting (i++, NM_SETTING_VPN_PROPERTIES_SETTING_NAME, NM_TYPE_SETTING_VPN_PROPERTIES, 5); - register_one_setting (i++, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG, 6); + register_one_setting (NM_SETTING_CONNECTION_SETTING_NAME, + NM_TYPE_SETTING_CONNECTION, + NM_SETTING_CONNECTION_ERROR, + 0); + + register_one_setting (NM_SETTING_WIRED_SETTING_NAME, + NM_TYPE_SETTING_WIRED, + NM_SETTING_WIRED_ERROR, + 1); + + register_one_setting (NM_SETTING_WIRELESS_SETTING_NAME, + NM_TYPE_SETTING_WIRELESS, + NM_SETTING_WIRELESS_ERROR, + 1); + + register_one_setting (NM_SETTING_GSM_SETTING_NAME, + NM_TYPE_SETTING_GSM, + NM_SETTING_GSM_ERROR, + 1); + + register_one_setting (NM_SETTING_CDMA_SETTING_NAME, + NM_TYPE_SETTING_CDMA, + NM_SETTING_CDMA_ERROR, + 1); + + register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_TYPE_SETTING_WIRELESS_SECURITY, + NM_SETTING_WIRELESS_SECURITY_ERROR, + 2); + + register_one_setting (NM_SETTING_SERIAL_SETTING_NAME, + NM_TYPE_SETTING_SERIAL, + NM_SETTING_SERIAL_ERROR, + 2); + + register_one_setting (NM_SETTING_PPP_SETTING_NAME, + NM_TYPE_SETTING_PPP, + NM_SETTING_PPP_ERROR, + 3); + + register_one_setting (NM_SETTING_PPPOE_SETTING_NAME, + NM_TYPE_SETTING_PPPOE, + NM_SETTING_PPPOE_ERROR, + 3); + + register_one_setting (NM_SETTING_802_1X_SETTING_NAME, + NM_TYPE_SETTING_802_1X, + NM_SETTING_802_1X_ERROR, + 3); + + register_one_setting (NM_SETTING_VPN_SETTING_NAME, + NM_TYPE_SETTING_VPN, + NM_SETTING_VPN_ERROR, + 4); + + register_one_setting (NM_SETTING_VPN_PROPERTIES_SETTING_NAME, + NM_TYPE_SETTING_VPN_PROPERTIES, + NM_SETTING_VPN_PROPERTIES_ERROR, + 5); + + register_one_setting (NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_TYPE_SETTING_IP4_CONFIG, + NM_SETTING_IP4_CONFIG_ERROR, + 6); } static guint32 @@ -118,10 +172,11 @@ nm_setting_register (const char *name, GType type) g_return_if_fail (name != NULL); g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (type)); - if (!registered_settings) + if (G_UNLIKELY (!registered_settings)) { registered_settings = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + } if (g_hash_table_lookup (registered_settings, name)) g_warning ("Already have a creator function for '%s', overriding", name); @@ -155,6 +210,19 @@ nm_connection_lookup_setting_type (const char *name) return type; } +GType +nm_connection_lookup_setting_type_by_quark (GQuark error_quark) +{ + int i; + + for (i = 0; default_map[i].name; i++) { + if (default_map[i].error_quark == error_quark) + return default_map[i].type; + } + + return G_TYPE_INVALID; +} + NMSetting * nm_connection_create_setting (const char *name) { @@ -230,14 +298,21 @@ gboolean nm_connection_replace_settings (NMConnection *connection, GHashTable *new_settings) { + GError *error = NULL; + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (new_settings != NULL, FALSE); g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings); g_hash_table_foreach (new_settings, parse_one_setting, connection); - if (!nm_connection_verify (connection)) { - g_warning ("Settings invalid."); + if (!nm_connection_verify (connection, &error)) { + g_warning ("%s: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, + error->code); + g_error_free (error); return FALSE; } @@ -299,6 +374,7 @@ nm_connection_compare (NMConnection *connection, typedef struct { gboolean success; GSList *all_settings; + GError **error; } VerifySettingsInfo; static void @@ -308,7 +384,7 @@ verify_one_setting (gpointer data, gpointer user_data) VerifySettingsInfo *info = (VerifySettingsInfo *) user_data; if (info->success) - info->success = nm_setting_verify (setting, info->all_settings); + info->success = nm_setting_verify (setting, info->all_settings, info->error); } static void @@ -320,13 +396,15 @@ hash_values_to_slist (gpointer key, gpointer value, gpointer user_data) } gboolean -nm_connection_verify (NMConnection *connection) +nm_connection_verify (NMConnection *connection, GError **error) { NMConnectionPrivate *priv; NMSetting *connection_setting; VerifySettingsInfo info; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + if (error) + g_return_val_if_fail (*error == NULL, FALSE); priv = NM_CONNECTION_GET_PRIVATE (connection); @@ -338,13 +416,13 @@ nm_connection_verify (NMConnection *connection) } /* Now, run the verify function of each setting */ + memset (&info, 0, sizeof (info)); info.success = TRUE; - info.all_settings = NULL; + info.error = error; g_hash_table_foreach (priv->settings, hash_values_to_slist, &info.all_settings); g_slist_foreach (info.all_settings, verify_one_setting, &info); g_slist_free (info.all_settings); - return info.success; } @@ -601,7 +679,7 @@ nm_connection_new (void) } NMConnection * -nm_connection_new_from_hash (GHashTable *hash) +nm_connection_new_from_hash (GHashTable *hash, GError **error) { NMConnection *connection; NMConnectionPrivate *priv; @@ -613,7 +691,7 @@ nm_connection_new_from_hash (GHashTable *hash) priv = NM_CONNECTION_GET_PRIVATE (connection); - if (!nm_connection_verify (connection)) { + if (!nm_connection_verify (connection, error)) { g_object_unref (connection); return NULL; } diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index e24b42d36..a4d134f9e 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -39,7 +39,9 @@ typedef struct { GType nm_connection_get_type (void); NMConnection *nm_connection_new (void); -NMConnection *nm_connection_new_from_hash (GHashTable *hash); + +NMConnection *nm_connection_new_from_hash (GHashTable *hash, GError **error); + void nm_connection_add_setting (NMConnection *connection, NMSetting *setting); @@ -60,7 +62,7 @@ gboolean nm_connection_compare (NMConnection *connection, NMConnection *other, NMSettingCompareFlags flags); -gboolean nm_connection_verify (NMConnection *connection); +gboolean nm_connection_verify (NMConnection *connection, GError **error); const char * nm_connection_need_secrets (NMConnection *connection, GPtrArray **hints); @@ -97,6 +99,8 @@ void nm_setting_unregister (const char *name); GType nm_connection_lookup_setting_type (const char *name); +GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); + G_END_DECLS #endif /* NM_CONNECTION_H */ diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index 3205a36c3..7380f173c 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -9,6 +9,40 @@ #include "nm-dbus-glib-types.h" #include "crypto.h" +GQuark +nm_setting_802_1x_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-802-1x-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_802_1x_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_802_1X_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, "MissingProperty"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSetting8021xError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING) enum { @@ -188,16 +222,34 @@ need_secrets_tls (NMSetting8021x *self, } static gboolean -verify_tls (NMSetting8021x *self, gboolean phase2) +verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) { if (phase2) { - if (!self->phase2_client_cert || !self->phase2_client_cert->len) { - g_warning ("%s: phase2 client certificate invalid", __func__); + if (!self->phase2_client_cert) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } else if (!self->phase2_client_cert->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); return FALSE; } } else { - if (!self->client_cert || !self->client_cert->len) { - g_warning ("%s: client certificate invalid", __func__); + if (!self->client_cert) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } else if (!self->client_cert->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_CLIENT_CERT); return FALSE; } } @@ -206,15 +258,57 @@ verify_tls (NMSetting8021x *self, gboolean phase2) } static gboolean -verify_ttls (NMSetting8021x *self, gboolean phase2) +verify_ttls (NMSetting8021x *self, gboolean phase2, GError **error) { - if (!self->identity && !self->anonymous_identity) { - g_warning ("%s: missing identity or anonymous identity", __func__); + if ( (!self->identity || !strlen (self->identity)) + && (!self->anonymous_identity || !strlen (self->anonymous_identity))) { + if (!self->identity) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_IDENTITY); + } else if (!strlen (self->identity)) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_IDENTITY); + } else if (!self->anonymous_identity) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } else { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } return FALSE; } - if (!self->phase2_auth && !self->phase2_autheap) { - g_warning ("%s: missing phase2 auth method", __func__); + if ( (!self->phase2_auth || !strlen (self->phase2_auth)) + && (!self->phase2_autheap || !strlen (self->phase2_autheap))) { + if (!self->phase2_auth) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!strlen (self->phase2_auth)) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!self->phase2_autheap) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + } else { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + } return FALSE; } @@ -222,9 +316,21 @@ verify_ttls (NMSetting8021x *self, gboolean phase2) } static gboolean -verify_identity (NMSetting8021x *self, gboolean phase2) +verify_identity (NMSetting8021x *self, gboolean phase2, GError **error) { - return self->identity ? TRUE : FALSE; + if (!self->identity) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_IDENTITY); + } else if (!strlen (self->identity)) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_IDENTITY); + } + + return TRUE; } /* Implemented below... */ @@ -238,7 +344,8 @@ typedef void (*EAPMethodNeedSecretsFunc) (NMSetting8021x *self, gboolean phase2); typedef gboolean (*EAPMethodValidateFunc)(NMSetting8021x *self, - gboolean phase2); + gboolean phase2, + GError **error); typedef struct { const char *method; @@ -336,7 +443,7 @@ need_secrets (NMSetting *setting) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSetting8021x *self = NM_SETTING_802_1X (setting); const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "fast", NULL }; @@ -345,13 +452,22 @@ verify (NMSetting *setting, GSList *all_settings) const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL }; GSList *iter; + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + if (!self->eap) { - g_warning ("Missing eap method"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_EAP); return FALSE; } if (!nm_utils_string_slist_validate (self->eap, valid_eap)) { - g_warning ("Invalid eap"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_EAP); return FALSE; } @@ -364,7 +480,7 @@ verify (NMSetting *setting, GSList *all_settings) if (eap_methods_table[i].v_func == NULL) continue; if (!strcmp (eap_methods_table[i].method, method)) { - if (!(*eap_methods_table[i].v_func) (self, FALSE)) + if (!(*eap_methods_table[i].v_func) (self, FALSE, error)) return FALSE; break; } @@ -372,27 +488,42 @@ verify (NMSetting *setting, GSList *all_settings) } if (self->phase1_peapver && !nm_utils_string_in_list (self->phase1_peapver, valid_phase1_peapver)) { - g_warning ("Invalid phase1 peapver"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE1_PEAPVER); return FALSE; } if (self->phase1_peaplabel && strcmp (self->phase1_peaplabel, "1")) { - g_warning ("Invalid phase1 peaplabel"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE1_PEAPLABEL); return FALSE; } if (self->phase1_fast_provisioning && strcmp (self->phase1_fast_provisioning, "1")) { - g_warning ("Invalid phase1 fast provisioning"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING); return FALSE; } if (self->phase2_auth && !nm_utils_string_in_list (self->phase2_auth, valid_phase2_auth)) { - g_warning ("Invalid phase2 authentication"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTH); return FALSE; } if (self->phase2_autheap && !nm_utils_string_in_list (self->phase2_autheap, valid_phase2_autheap)) { - g_warning ("Invalid phase2 autheap"); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_AUTHEAP); return FALSE; } diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index babf93f7c..06c884e5c 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_802_1X_SETTING_NAME "802-1x" +typedef enum +{ + NM_SETTING_802_1X_ERROR_UNKNOWN = 0, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY +} NMSetting8021xError; + +#define NM_TYPE_SETTING_802_1X_ERROR (nm_setting_802_1x_error_get_type ()) +GType nm_setting_802_1x_error_get_type (void); + +#define NM_SETTING_802_1X_ERROR nm_setting_802_1x_error_quark () +GQuark nm_setting_802_1x_error_quark (void); + + #define NM_SETTING_802_1X_EAP "eap" #define NM_SETTING_802_1X_IDENTITY "identity" #define NM_SETTING_802_1X_ANONYMOUS_IDENTITY "anonymous-identity" diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index d7a932a12..49b574bd5 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -5,6 +5,42 @@ #include "nm-setting-serial.h" #include "nm-utils.h" +GQuark +nm_setting_cdma_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-cdma-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_cdma_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_CDMA_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_CDMA_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_CDMA_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required serial setting is missing */ + ENUM_ENTRY (NM_SETTING_CDMA_ERROR_MISSING_SERIAL_SETTING, "MissingSerialSetting"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingCdmaError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING) enum { @@ -32,19 +68,31 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingCdma *self = NM_SETTING_CDMA (setting); /* Serial connections require a PPP setting */ if (all_settings && !g_slist_find_custom (all_settings, NM_SETTING_SERIAL_SETTING_NAME, find_setting_by_name)) { - g_warning ("Missing serial setting"); + g_set_error (error, + NM_SETTING_CDMA_ERROR, + NM_SETTING_CDMA_ERROR_MISSING_SERIAL_SETTING, + NULL); return FALSE; } - if (!self->number || strlen (self->number) < 1) { - nm_warning ("Missing phone number"); + if (!self->number) { + g_set_error (error, + NM_SETTING_CDMA_ERROR, + NM_SETTING_CDMA_ERROR_MISSING_PROPERTY, + NM_SETTING_CDMA_NUMBER); + return FALSE; + } else if (!strlen (self->number)) { + g_set_error (error, + NM_SETTING_CDMA_ERROR, + NM_SETTING_CDMA_ERROR_INVALID_PROPERTY, + NM_SETTING_CDMA_NUMBER); return FALSE; } diff --git a/libnm-util/nm-setting-cdma.h b/libnm-util/nm-setting-cdma.h index c9e0bae62..90422d838 100644 --- a/libnm-util/nm-setting-cdma.h +++ b/libnm-util/nm-setting-cdma.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_CDMA_SETTING_NAME "cdma" +typedef enum +{ + NM_SETTING_CDMA_ERROR_UNKNOWN = 0, + NM_SETTING_CDMA_ERROR_INVALID_PROPERTY, + NM_SETTING_CDMA_ERROR_MISSING_PROPERTY, + NM_SETTING_CDMA_ERROR_MISSING_SERIAL_SETTING +} NMSettingCdmaError; + +#define NM_TYPE_SETTING_CDMA_ERROR (nm_setting_cdma_error_get_type ()) +GType nm_setting_cdma_error_get_type (void); + +#define NM_SETTING_CDMA_ERROR nm_setting_cdma_error_quark () +GQuark nm_setting_cdma_error_quark (void); + #define NM_SETTING_CDMA_NUMBER "number" #define NM_SETTING_CDMA_USERNAME "username" #define NM_SETTING_CDMA_PASSWORD "password" diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 2c460e9fa..4b8511646 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -3,6 +3,42 @@ #include #include "nm-setting-connection.h" +GQuark +nm_setting_connection_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-connection-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_connection_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_CONNECTION_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The setting specified by the 'type' field was not found. */ + ENUM_ENTRY (NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND, "TypeSettingNotFound"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingConnectionError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) enum { @@ -30,19 +66,44 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingConnection *self = NM_SETTING_CONNECTION (setting); - if (!self->id || !strlen (self->id)) + if (!self->id) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + NM_SETTING_CONNECTION_ID); return FALSE; + } else if (!strlen (self->id)) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_ID); + return FALSE; + } - if (!self->type || !strlen (self->type)) + if (!self->type) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + NM_SETTING_CONNECTION_TYPE); return FALSE; + } else if (!strlen (self->type)) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_TYPE); + return FALSE; + } /* Make sure the corresponding 'type' item is present */ if (all_settings && !g_slist_find_custom (all_settings, self->type, find_setting_by_name)) { - g_warning ("Required setting '%s' not found.", self->type); + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND, + NM_SETTING_CONNECTION_TYPE); return FALSE; } diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index cae8010a2..d665579d6 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_CONNECTION_SETTING_NAME "connection" +typedef enum +{ + NM_SETTING_CONNECTION_ERROR_UNKNOWN = 0, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND +} NMSettingConnectionError; + +#define NM_TYPE_SETTING_CONNECTION_ERROR (nm_setting_connection_error_get_type ()) +GType nm_setting_connection_error_get_type (void); + +#define NM_SETTING_CONNECTION_ERROR nm_setting_connection_error_quark () +GQuark nm_setting_connection_error_quark (void); + #define NM_SETTING_CONNECTION_ID "id" #define NM_SETTING_CONNECTION_TYPE "type" #define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index 5bd2150d4..c454b7395 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -5,6 +5,42 @@ #include "nm-setting-serial.h" #include "nm-utils.h" +GQuark +nm_setting_gsm_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-gsm-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_gsm_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_GSM_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_GSM_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_GSM_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required serial setting is missing */ + ENUM_ENTRY (NM_SETTING_GSM_ERROR_MISSING_SERIAL_SETTING, "MissingSerialSetting"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingGsmError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING) enum { @@ -38,24 +74,39 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingGsm *self = NM_SETTING_GSM (setting); /* Serial connections require a PPP setting */ if (all_settings && !g_slist_find_custom (all_settings, NM_SETTING_SERIAL_SETTING_NAME, find_setting_by_name)) { - g_warning ("Missing serial setting"); + g_set_error (error, + NM_SETTING_GSM_ERROR, + NM_SETTING_GSM_ERROR_MISSING_SERIAL_SETTING, + NULL); return FALSE; } - if (!self->number || strlen (self->number) < 1) { - nm_warning ("Missing phone number"); + if (!self->number) { + g_set_error (error, + NM_SETTING_GSM_ERROR, + NM_SETTING_GSM_ERROR_MISSING_PROPERTY, + NM_SETTING_GSM_NUMBER); + return FALSE; + } else if (!strlen (self->number)) { + g_set_error (error, + NM_SETTING_GSM_ERROR, + NM_SETTING_GSM_ERROR_INVALID_PROPERTY, + NM_SETTING_GSM_NUMBER); return FALSE; } if (self->apn && (strlen (self->apn) < 1 || strchr (self->apn, '"'))) { - nm_warning ("Invalid APN"); + g_set_error (error, + NM_SETTING_GSM_ERROR, + NM_SETTING_GSM_ERROR_INVALID_PROPERTY, + NM_SETTING_GSM_APN); return FALSE; } diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h index d7d3f0d92..39cffd69c 100644 --- a/libnm-util/nm-setting-gsm.h +++ b/libnm-util/nm-setting-gsm.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_GSM_SETTING_NAME "gsm" +typedef enum +{ + NM_SETTING_GSM_ERROR_UNKNOWN = 0, + NM_SETTING_GSM_ERROR_INVALID_PROPERTY, + NM_SETTING_GSM_ERROR_MISSING_PROPERTY, + NM_SETTING_GSM_ERROR_MISSING_SERIAL_SETTING +} NMSettingGsmError; + +#define NM_TYPE_SETTING_GSM_ERROR (nm_setting_gsm_error_get_type ()) +GType nm_setting_gsm_error_get_type (void); + +#define NM_SETTING_GSM_ERROR nm_setting_gsm_error_quark () +GQuark nm_setting_gsm_error_quark (void); + #define NM_SETTING_GSM_NUMBER "number" #define NM_SETTING_GSM_USERNAME "username" #define NM_SETTING_GSM_PASSWORD "password" diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index 906b25cae..b8bfae94f 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -8,6 +8,42 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" +GQuark +nm_setting_ip4_config_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-ip4-config-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_ip4_config_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_IP4_CONFIG_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The specified property was not allowed in combination with the current 'method' */ + ENUM_ENTRY (NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, "NotAllowedForMethod"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingIP4ConfigError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING) enum { @@ -29,38 +65,58 @@ nm_setting_ip4_config_new (void) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingIP4Config *self = NM_SETTING_IP4_CONFIG (setting); - if (!self->method) + if (!self->method) { + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP4_CONFIG_METHOD); return FALSE; + } if (!strcmp (self->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { if (!self->addresses) { - g_warning ("address is not provided"); + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP4_CONFIG_ADDRESSES); return FALSE; } } else if ( !strcmp (self->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP) || !strcmp (self->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { if (self->dns && self->dns->len) { - g_warning ("may not specify DNS when using autoip/shared"); + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP4_CONFIG_DNS); return FALSE; } if (g_slist_length (self->dns_search)) { - g_warning ("may not specify DNS searches when using autoip/shared"); + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); return FALSE; } if (g_slist_length (self->addresses)) { - g_warning ("may not specify IP addresses when using autoip/shared"); + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP4_CONFIG_ADDRESSES); return FALSE; } } else if (!strcmp (self->method, NM_SETTING_IP4_CONFIG_METHOD_DHCP)) { /* nothing to do */ } else { - g_warning ("invalid IP4 config method '%s'", self->method); + g_set_error (error, + NM_SETTING_IP4_CONFIG_ERROR, + NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY, + NM_SETTING_IP4_CONFIG_METHOD); return FALSE; } diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index a6097944d..14cd1e7d7 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4" +typedef enum +{ + NM_SETTING_IP4_CONFIG_ERROR_UNKNOWN = 0, + NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY, + NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD +} NMSettingIP4ConfigError; + +#define NM_TYPE_SETTING_IP4_CONFIG_ERROR (nm_setting_ip4_config_error_get_type ()) +GType nm_setting_ip4_config_error_get_type (void); + +#define NM_SETTING_IP4_CONFIG_ERROR nm_setting_ip4_config_error_quark () +GQuark nm_setting_ip4_config_error_quark (void); + #define NM_SETTING_IP4_CONFIG_METHOD "method" #define NM_SETTING_IP4_CONFIG_DNS "dns" #define NM_SETTING_IP4_CONFIG_DNS_SEARCH "dns-search" diff --git a/libnm-util/nm-setting-ppp.c b/libnm-util/nm-setting-ppp.c index 706540a5c..1bf7f5058 100644 --- a/libnm-util/nm-setting-ppp.c +++ b/libnm-util/nm-setting-ppp.c @@ -2,6 +2,42 @@ #include "nm-setting-ppp.h" +GQuark +nm_setting_ppp_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-ppp-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_ppp_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_PPP_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_PPP_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_PPP_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The 'require-mppe' option is not allowed in conjunction with 'noauth'. */ + ENUM_ENTRY (NM_SETTING_PPP_ERROR_REQUIRE_MPPE_NOT_ALLOWED, "RequireMPPENotAllowed"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingPPPError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingPPP, nm_setting_ppp, NM_TYPE_SETTING) enum { @@ -35,13 +71,16 @@ nm_setting_ppp_new (void) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingPPP *self = NM_SETTING_PPP (setting); if (self->noauth) { if (self->require_mppe) { - g_warning ("Option 'noauth' incompatible with 'require-mppe'"); + g_set_error (error, + NM_SETTING_PPP_ERROR, + NM_SETTING_PPP_ERROR_REQUIRE_MPPE_NOT_ALLOWED, + NM_SETTING_PPP_REQUIRE_MPPE); return FALSE; } } diff --git a/libnm-util/nm-setting-ppp.h b/libnm-util/nm-setting-ppp.h index 3c5b1e874..b1d7307ef 100644 --- a/libnm-util/nm-setting-ppp.h +++ b/libnm-util/nm-setting-ppp.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_PPP_SETTING_NAME "ppp" +typedef enum +{ + NM_SETTING_PPP_ERROR_UNKNOWN = 0, + NM_SETTING_PPP_ERROR_INVALID_PROPERTY, + NM_SETTING_PPP_ERROR_MISSING_PROPERTY, + NM_SETTING_PPP_ERROR_REQUIRE_MPPE_NOT_ALLOWED +} NMSettingPPPError; + +#define NM_TYPE_SETTING_PPP_ERROR (nm_setting_ppp_error_get_type ()) +GType nm_setting_ppp_error_get_type (void); + +#define NM_SETTING_PPP_ERROR nm_setting_ppp_error_quark () +GQuark nm_setting_ppp_error_quark (void); + #define NM_SETTING_PPP_NOAUTH "noauth" #define NM_SETTING_PPP_REFUSE_EAP "refuse-eap" #define NM_SETTING_PPP_REFUSE_PAP "refuse-pap" diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index d3f99e62a..1b2b9457b 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -4,6 +4,42 @@ #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" +GQuark +nm_setting_pppoe_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-pppoe-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_pppoe_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_PPPOE_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_PPPOE_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required PPP setting is missing */ + ENUM_ENTRY (NM_SETTING_PPPOE_ERROR_MISSING_PPP_SETTING, "MissingPPPSetting"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingPPPOEError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingPPPOE, nm_setting_pppoe, NM_TYPE_SETTING) enum { @@ -31,22 +67,37 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingPPPOE *self = NM_SETTING_PPPOE (setting); - if (!self->username || !strlen (self->username)) { - g_warning ("Missing or empty username"); + if (!self->username) { + g_set_error (error, + NM_SETTING_PPPOE_ERROR, + NM_SETTING_PPPOE_ERROR_MISSING_PROPERTY, + NM_SETTING_PPPOE_USERNAME); + return FALSE; + } else if (!strlen (self->username)) { + g_set_error (error, + NM_SETTING_PPPOE_ERROR, + NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY, + NM_SETTING_PPPOE_USERNAME); return FALSE; } if (self->service && !strlen (self->service)) { - g_warning ("Empty service"); + g_set_error (error, + NM_SETTING_PPPOE_ERROR, + NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY, + NM_SETTING_PPPOE_SERVICE); return FALSE; } if (!g_slist_find_custom (all_settings, NM_SETTING_PPP_SETTING_NAME, find_setting_by_name)) { - g_warning ("Invalid or missing PPP setting"); + g_set_error (error, + NM_SETTING_PPPOE_ERROR, + NM_SETTING_PPPOE_ERROR_MISSING_PPP_SETTING, + NULL); return FALSE; } diff --git a/libnm-util/nm-setting-pppoe.h b/libnm-util/nm-setting-pppoe.h index c20472bfe..b4db850f4 100644 --- a/libnm-util/nm-setting-pppoe.h +++ b/libnm-util/nm-setting-pppoe.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_PPPOE_SETTING_NAME "pppoe" +typedef enum +{ + NM_SETTING_PPPOE_ERROR_UNKNOWN = 0, + NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY, + NM_SETTING_PPPOE_ERROR_MISSING_PROPERTY, + NM_SETTING_PPPOE_ERROR_MISSING_PPP_SETTING +} NMSettingPPPOEError; + +#define NM_TYPE_SETTING_PPPOE_ERROR (nm_setting_pppoe_error_get_type ()) +GType nm_setting_pppoe_error_get_type (void); + +#define NM_SETTING_PPPOE_ERROR nm_setting_pppoe_error_quark () +GQuark nm_setting_pppoe_error_quark (void); + #define NM_SETTING_PPPOE_SERVICE "service" #define NM_SETTING_PPPOE_USERNAME "username" #define NM_SETTING_PPPOE_PASSWORD "password" diff --git a/libnm-util/nm-setting-serial.c b/libnm-util/nm-setting-serial.c index a5417c4f7..b05084534 100644 --- a/libnm-util/nm-setting-serial.c +++ b/libnm-util/nm-setting-serial.c @@ -5,6 +5,42 @@ #include "nm-setting-serial.h" #include "nm-setting-ppp.h" +GQuark +nm_setting_serial_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-serial-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_serial_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_SERIAL_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_SERIAL_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_SERIAL_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required PPP setting is missing */ + ENUM_ENTRY (NM_SETTING_SERIAL_ERROR_MISSING_PPP_SETTING, "MissingPPPSetting"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingSerialError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING) enum { @@ -34,12 +70,15 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { /* Serial connections require a PPP setting */ if (all_settings && !g_slist_find_custom (all_settings, NM_SETTING_PPP_SETTING_NAME, find_setting_by_name)) { - g_warning ("Missing PPP setting"); + g_set_error (error, + NM_SETTING_SERIAL_ERROR, + NM_SETTING_SERIAL_ERROR_MISSING_PPP_SETTING, + NULL); return FALSE; } diff --git a/libnm-util/nm-setting-serial.h b/libnm-util/nm-setting-serial.h index 42d43631d..9b2a3e2af 100644 --- a/libnm-util/nm-setting-serial.h +++ b/libnm-util/nm-setting-serial.h @@ -16,6 +16,20 @@ G_BEGIN_DECLS #define NM_SETTING_SERIAL_SETTING_NAME "serial" +typedef enum +{ + NM_SETTING_SERIAL_ERROR_UNKNOWN = 0, + NM_SETTING_SERIAL_ERROR_INVALID_PROPERTY, + NM_SETTING_SERIAL_ERROR_MISSING_PROPERTY, + NM_SETTING_SERIAL_ERROR_MISSING_PPP_SETTING +} NMSettingSerialError; + +#define NM_TYPE_SETTING_SERIAL_ERROR (nm_setting_serial_error_get_type ()) +GType nm_setting_serial_error_get_type (void); + +#define NM_SETTING_SERIAL_ERROR nm_setting_serial_error_quark () +GQuark nm_setting_serial_error_quark (void); + #define NM_SETTING_SERIAL_BAUD "baud" #define NM_SETTING_SERIAL_BITS "bits" #define NM_SETTING_SERIAL_PARITY "parity" diff --git a/libnm-util/nm-setting-vpn-properties.c b/libnm-util/nm-setting-vpn-properties.c index 2fa880b51..0307995dd 100644 --- a/libnm-util/nm-setting-vpn-properties.c +++ b/libnm-util/nm-setting-vpn-properties.c @@ -5,6 +5,40 @@ #include "nm-param-spec-specialized.h" #include "nm-dbus-glib-types.h" +GQuark +nm_setting_vpn_properties_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-vpn-properties-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_vpn_properties_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_VPN_PROPERTIES_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_VPN_PROPERTIES_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_VPN_PROPERTIES_ERROR_MISSING_PROPERTY, "MissingProperty"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingVPNPropertiesError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingVPNProperties, nm_setting_vpn_properties, NM_TYPE_SETTING) enum { @@ -21,7 +55,7 @@ nm_setting_vpn_properties_new (void) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingVPNProperties *self = NM_SETTING_VPN_PROPERTIES (setting); diff --git a/libnm-util/nm-setting-vpn-properties.h b/libnm-util/nm-setting-vpn-properties.h index 61a684c24..5e4ac55b4 100644 --- a/libnm-util/nm-setting-vpn-properties.h +++ b/libnm-util/nm-setting-vpn-properties.h @@ -15,6 +15,20 @@ G_BEGIN_DECLS #define NM_SETTING_VPN_PROPERTIES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VPN_PROPERTIES, NMSettingVPNPropertiesClass)) #define NM_SETTING_VPN_PROPERTIES_SETTING_NAME "vpn-properties" + +typedef enum +{ + NM_SETTING_VPN_PROPERTIES_ERROR_UNKNOWN = 0, + NM_SETTING_VPN_PROPERTIES_ERROR_INVALID_PROPERTY, + NM_SETTING_VPN_PROPERTIES_ERROR_MISSING_PROPERTY, +} NMSettingVPNPropertiesError; + +#define NM_TYPE_SETTING_VPN_PROPERTIES_ERROR (nm_setting_vpn_properties_error_get_type ()) +GType nm_setting_vpn_properties_error_get_type (void); + +#define NM_SETTING_VPN_PROPERTIES_ERROR nm_setting_vpn_properties_error_quark () +GQuark nm_setting_vpn_properties_error_quark (void); + #define NM_SETTING_VPN_PROPERTIES_DATA "data" typedef struct { diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index df962bd7e..f91f39a2b 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -7,6 +7,40 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" +GQuark +nm_setting_vpn_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-vpn-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_vpn_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_VPN_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_VPN_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_VPN_ERROR_MISSING_PROPERTY, "MissingProperty"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingVpnError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingVPN, nm_setting_vpn, NM_TYPE_SETTING) enum { @@ -25,16 +59,34 @@ nm_setting_vpn_new (void) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingVPN *self = NM_SETTING_VPN (setting); - if (!self->service_type || !strlen (self->service_type)) + if (!self->service_type) { + g_set_error (error, + NM_SETTING_VPN_ERROR, + NM_SETTING_VPN_ERROR_MISSING_PROPERTY, + NM_SETTING_VPN_SERVICE_TYPE); return FALSE; + } + + if (!strlen (self->service_type)) { + g_set_error (error, + NM_SETTING_VPN_ERROR, + NM_SETTING_VPN_ERROR_INVALID_PROPERTY, + NM_SETTING_VPN_SERVICE_TYPE); + return FALSE; + } /* default username can be NULL, but can't be zero-length */ - if (self->user_name && !strlen (self->user_name)) + if (self->user_name && !strlen (self->user_name)) { + g_set_error (error, + NM_SETTING_VPN_ERROR, + NM_SETTING_VPN_ERROR_INVALID_PROPERTY, + NM_SETTING_VPN_USER_NAME); return FALSE; + } return TRUE; } diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index 06d8d12bb..221d3ff08 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -16,6 +16,19 @@ G_BEGIN_DECLS #define NM_SETTING_VPN_SETTING_NAME "vpn" +typedef enum +{ + NM_SETTING_VPN_ERROR_UNKNOWN = 0, + NM_SETTING_VPN_ERROR_INVALID_PROPERTY, + NM_SETTING_VPN_ERROR_MISSING_PROPERTY, +} NMSettingVpnError; + +#define NM_TYPE_SETTING_VPN_ERROR (nm_setting_vpn_error_get_type ()) +GType nm_setting_vpn_error_get_type (void); + +#define NM_SETTING_VPN_ERROR nm_setting_vpn_error_quark () +GQuark nm_setting_vpn_error_quark (void); + #define NM_SETTING_VPN_SERVICE_TYPE "service-type" #define NM_SETTING_VPN_USER_NAME "user-name" #define NM_SETTING_VPN_ROUTES "routes" diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 1db21f529..f8f8b1f64 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -6,6 +6,40 @@ #include "nm-param-spec-specialized.h" #include "nm-utils.h" +GQuark +nm_setting_wired_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-wired-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_wired_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_WIRED_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_WIRED_ERROR_MISSING_PROPERTY, "MissingProperty"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingWiredError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) enum { @@ -27,24 +61,33 @@ nm_setting_wired_new (void) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWired *self = NM_SETTING_WIRED (setting); const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; const char *valid_duplex[] = { "half", "full", NULL }; if (self->port && !nm_utils_string_in_list (self->port, valid_ports)) { - g_warning ("Invalid port"); + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_PORT); return FALSE; } if (self->duplex && !nm_utils_string_in_list (self->duplex, valid_duplex)) { - g_warning ("Invalid duplex"); + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_DUPLEX); return FALSE; } if (self->mac_address && self->mac_address->len != ETH_ALEN) { - g_warning ("Invalid mac address"); + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_MAC_ADDRESS); return FALSE; } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index 0cee17753..a5f3df83b 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -16,6 +16,19 @@ G_BEGIN_DECLS #define NM_SETTING_WIRED_SETTING_NAME "802-3-ethernet" +typedef enum +{ + NM_SETTING_WIRED_ERROR_UNKNOWN = 0, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_ERROR_MISSING_PROPERTY +} NMSettingWiredError; + +#define NM_TYPE_SETTING_WIRED_ERROR (nm_setting_wired_error_get_type ()) +GType nm_setting_wired_error_get_type (void); + +#define NM_SETTING_WIRED_ERROR nm_setting_wired_error_quark () +GQuark nm_setting_wired_error_quark (void); + #define NM_SETTING_WIRED_PORT "port" #define NM_SETTING_WIRED_SPEED "speed" #define NM_SETTING_WIRED_DUPLEX "duplex" diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index 7415db125..7331394ff 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -9,6 +9,48 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" +GQuark +nm_setting_wireless_security_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-wireless-security-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_wireless_security_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required 802.1x setting is missing */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING, "Missing8021xSetting"), + /* The LEAP authentication algorithm requires use of 802.1x key management. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, "LEAPRequires8021x"), + /* The LEAP authentication algorithm requires a username. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, "LEAPRequiresUsername"), + /* Shared Key authentication can only be used with WEP encryption. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP, "SharedKeyRequiresWEP"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingWirelessSecurityError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING) enum { @@ -158,7 +200,7 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL }; @@ -167,19 +209,36 @@ verify (NMSetting *setting, GSList *all_settings) const char *valid_pairwise[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; - if (!self->key_mgmt || !nm_utils_string_in_list (self->key_mgmt, valid_key_mgmt)) { - g_warning ("Missing or invalid key management"); + if (!self->key_mgmt) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (!nm_utils_string_in_list (self->key_mgmt, valid_key_mgmt)) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } if (self->auth_alg && !strcmp (self->auth_alg, "leap")) { /* LEAP must use ieee8021x key management */ if (strcmp (self->key_mgmt, "ieee8021x")) { - g_warning ("LEAP requires IEEE8021X key management."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } if (!self->leap_username) { - g_warning ("LEAP requires a username."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); return FALSE; } } else { @@ -187,58 +246,99 @@ verify (NMSetting *setting, GSList *all_settings) || (strcmp (self->key_mgmt, "wpa-eap") == 0)) { /* Need an 802.1x setting too */ if (!g_slist_find_custom (all_settings, NM_SETTING_802_1X_SETTING_NAME, find_setting_by_name)) { - g_warning ("Invalid or missing 802.1x setting"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING, + NULL); return FALSE; } } } + if (self->leap_username && !strlen (self->leap_username)) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + if (self->wep_tx_keyidx > 3) { - g_warning ("Invalid WEP key index"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); return FALSE; } if (self->wep_key0 && !strlen (self->wep_key0)) { - g_warning ("Invalid zero-length WEP key #0."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); return FALSE; } if (self->wep_key1 && !strlen (self->wep_key1)) { - g_warning ("Invalid zero-length WEP key #1."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); return FALSE; } if (self->wep_key2 && !strlen (self->wep_key2)) { - g_warning ("Invalid zero-length WEP key #2."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); return FALSE; } if (self->wep_key3 && !strlen (self->wep_key3)) { - g_warning ("Invalid zero-length WEP key #3."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); return FALSE; } if (self->auth_alg && !nm_utils_string_in_list (self->auth_alg, valid_auth_algs)) { - g_warning ("Invalid authentication algorithm"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } if (self->proto && !nm_utils_string_slist_validate (self->proto, valid_protos)) { - g_warning ("Invalid authentication protocol"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_PROTO); return FALSE; } if (self->pairwise && !nm_utils_string_slist_validate (self->pairwise, valid_pairwise)) { - g_warning ("Invalid pairwise"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } if (self->group && !nm_utils_string_slist_validate (self->group, valid_groups)) { - g_warning ("Invalid group"); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_GROUP); return FALSE; } /* Shared Key auth can only be used with WEP */ if (self->auth_alg && !strcmp (self->auth_alg, "shared")) { if (self->key_mgmt && strcmp (self->key_mgmt, "none")) { - g_warning ("Shared Key authentication can only be used with WEP."); + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } } diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h index 037500308..a9b88067e 100644 --- a/libnm-util/nm-setting-wireless-security.h +++ b/libnm-util/nm-setting-wireless-security.h @@ -16,6 +16,23 @@ G_BEGIN_DECLS #define NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "802-11-wireless-security" +typedef enum +{ + NM_SETTING_WIRELESS_SECURITY_ERROR_UNKNOWN = 0, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY, + NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, + NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP +} NMSettingWirelessSecurityError; + +#define NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR (nm_setting_wireless_security_error_get_type ()) +GType nm_setting_wireless_security_error_get_type (void); + +#define NM_SETTING_WIRELESS_SECURITY_ERROR nm_setting_wireless_security_error_quark () +GQuark nm_setting_wireless_security_error_quark (void); + #define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt" #define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx" #define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg" diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index bc39cf401..2eebc928c 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -12,6 +12,44 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" +GQuark +nm_setting_wireless_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-wireless-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_wireless_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The required security setting is missing */ + ENUM_ENTRY (NM_SETTING_WIRELESS_ERROR_MISSING_SECURITY_SETTING, "MissingSecuritySetting"), + /* The 'channel' property requires a valid 'band' */ + ENUM_ENTRY (NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND, "ChannelRequiresBand"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingWirelessError", values); + } + return etype; +} + + G_DEFINE_TYPE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING) enum { @@ -208,30 +246,50 @@ find_setting_by_name (gconstpointer a, gconstpointer b) } static gboolean -verify (NMSetting *setting, GSList *all_settings) +verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWireless *self = NM_SETTING_WIRELESS (setting); const char *valid_modes[] = { "infrastructure", "adhoc", NULL }; const char *valid_bands[] = { "a", "bg", NULL }; GSList *iter; - if (!self->ssid || self->ssid->len < 1 || self->ssid->len > 32) { - g_warning ("Invalid or missing ssid"); + if (!self->ssid) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY, + NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + if (!self->ssid->len || self->ssid->len > 32) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SSID); return FALSE; } if (self->mode && !nm_utils_string_in_list (self->mode, valid_modes)) { - g_warning ("Invalid mode. Should be either 'infrastructure' or 'adhoc'"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_MODE); return FALSE; } if (self->band && !nm_utils_string_in_list (self->band, valid_bands)) { - g_warning ("Invalid band. Should be either 'a' or 'bg'"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_BAND); return FALSE; } if (self->channel && !self->band) { - g_warning ("Channel was provided without band"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND, + NM_SETTING_WIRELESS_BAND); return FALSE; } @@ -250,22 +308,34 @@ verify (NMSetting *setting, GSList *all_settings) } if (valid_channels[i] == 0) { - g_warning ("Invalid channel"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_CHANNEL); return FALSE; } } else if (!strcmp (self->band, "bg") && self->channel > 14) { - g_warning ("Invalid channel"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_CHANNEL); return FALSE; } } - if (self->bssid && self->bssid->len != 6) { - g_warning ("Invalid bssid"); + if (self->bssid && self->bssid->len != ETH_ALEN) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_BSSID); return FALSE; } - if (self->mac_address && self->mac_address->len != 6) { - g_warning ("Invalid mac address"); + if (self->mac_address && self->mac_address->len != ETH_ALEN) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_MAC_ADDRESS); return FALSE; } @@ -273,14 +343,20 @@ verify (NMSetting *setting, GSList *all_settings) struct ether_addr addr; if (!ether_aton_r (iter->data, &addr)) { - g_warning ("Invalid bssid"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_SEEN_BSSIDS); return FALSE; } } if ( self->security && !g_slist_find_custom (all_settings, self->security, find_setting_by_name)) { - g_warning ("Invalid or missing security"); + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_MISSING_SECURITY_SETTING, + NULL); return FALSE; } diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index 83d707b4c..712c14305 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -17,6 +17,21 @@ G_BEGIN_DECLS #define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless" +typedef enum +{ + NM_SETTING_WIRELESS_ERROR_UNKNOWN = 0, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY, + NM_SETTING_WIRELESS_ERROR_MISSING_SECURITY_SETTING, + NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND +} NMSettingWirelessError; + +#define NM_TYPE_SETTING_WIRELESS_ERROR (nm_setting_wireless_error_get_type ()) +GType nm_setting_wireless_error_get_type (void); + +#define NM_SETTING_WIRELESS_ERROR nm_setting_wireless_error_quark () +GQuark nm_setting_wireless_error_quark (void); + #define NM_SETTING_WIRELESS_SSID "ssid" #define NM_SETTING_WIRELESS_MODE "mode" #define NM_SETTING_WIRELESS_BAND "band" diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 5f7747893..2fa2650fb 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -168,16 +168,16 @@ nm_setting_get_name (NMSetting *setting) } gboolean -nm_setting_verify (NMSetting *setting, GSList *all_settings) +nm_setting_verify (NMSetting *setting, GSList *all_settings, GError **error) { - gboolean success = TRUE; - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + if (error) + g_return_val_if_fail (*error == NULL, FALSE); if (NM_SETTING_GET_CLASS (setting)->verify) - success = NM_SETTING_GET_CLASS (setting)->verify (setting, all_settings); + return NM_SETTING_GET_CLASS (setting)->verify (setting, all_settings, error); - return success; + return TRUE; } gboolean diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index cd25dddc6..53eba688c 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -33,7 +33,8 @@ typedef struct { /* Virtual functions */ gboolean (*verify) (NMSetting *setting, - GSList *all_settings); + GSList *all_settings, + GError **error); GPtrArray *(*need_secrets) (NMSetting *setting); @@ -60,7 +61,8 @@ NMSetting *nm_setting_duplicate (NMSetting *setting); const char *nm_setting_get_name (NMSetting *setting); gboolean nm_setting_verify (NMSetting *setting, - GSList *all_settings); + GSList *all_settings, + GError **error); typedef enum { diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 187303e99..ef197cc51 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -411,7 +411,7 @@ update_one_setting (const char* key, if (s_8021x) all_settings = g_slist_append (all_settings, s_8021x); - if (!nm_setting_verify (setting, all_settings)) { + if (!nm_setting_verify (setting, all_settings, NULL)) { /* Just try updating secrets */ g_object_unref (setting); setting = NULL; diff --git a/src/nm-manager.c b/src/nm-manager.c index 0ab356fe9..cef870c0a 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -664,10 +664,17 @@ connection_get_settings_cb (DBusGProxy *proxy, if (connection == NULL) { const char *path = dbus_g_proxy_get_path (proxy); NMManagerPrivate *priv; + GError *error = NULL; - connection = nm_connection_new_from_hash (settings); - if (connection == NULL) + connection = nm_connection_new_from_hash (settings, &error); + if (connection == NULL) { + nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); goto out; + } scope = get_scope_for_proxy (proxy); @@ -782,13 +789,19 @@ connection_updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_da NMConnection *old_connection; GHashTable *hash; gboolean valid = FALSE; + GError *error = NULL; old_connection = get_connection_for_proxy (manager, proxy, &hash); g_return_if_fail (old_connection != NULL); - new_connection = nm_connection_new_from_hash (settings); + new_connection = nm_connection_new_from_hash (settings, &error); if (!new_connection) { /* New connection invalid, remove existing connection */ + nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); remove_connection (manager, old_connection, hash); return; } diff --git a/system-settings/plugins/ifcfg-fedora/reader.c b/system-settings/plugins/ifcfg-fedora/reader.c index 2ae4e89c7..1c022ced9 100644 --- a/system-settings/plugins/ifcfg-fedora/reader.c +++ b/system-settings/plugins/ifcfg-fedora/reader.c @@ -678,11 +678,8 @@ wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err } nm_connection_add_setting (connection, con_setting); - if (!nm_connection_verify (connection)) { - g_set_error (error, ifcfg_plugin_error_quark (), 0, - "Connection from %s was invalid.", file); + if (!nm_connection_verify (connection, error)) goto error; - } return connection; @@ -758,11 +755,8 @@ wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **error) nm_connection_add_setting (connection, wired_setting); - if (!nm_connection_verify (connection)) { - g_set_error (error, ifcfg_plugin_error_quark (), 0, - "Connection from %s was invalid.", file); + if (!nm_connection_verify (connection, error)) goto error; - } return connection; @@ -919,11 +913,9 @@ connection_from_file (const char *filename, nm_connection_add_setting (connection, s_ip4); } - if (!nm_connection_verify (connection)) { + if (!nm_connection_verify (connection, error)) { g_object_unref (connection); connection = NULL; - g_set_error (error, ifcfg_plugin_error_quark (), 0, - "Connection was invalid"); } *keyfile = get_keys_file_path (filename); diff --git a/system-settings/plugins/ifcfg-suse/parser.c b/system-settings/plugins/ifcfg-suse/parser.c index 59de19fe4..cff74d8bb 100644 --- a/system-settings/plugins/ifcfg-suse/parser.c +++ b/system-settings/plugins/ifcfg-suse/parser.c @@ -648,6 +648,7 @@ parse_ifcfg (const char *iface, NMDeviceType type) { shvarFile *file; NMConnection *connection; + GError *error = NULL; g_return_val_if_fail (iface != NULL, NULL); @@ -670,7 +671,12 @@ parse_ifcfg (const char *iface, NMDeviceType type) svCloseFile (file); - if (!nm_connection_verify (connection)) { + if (!nm_connection_verify (connection, &error)) { + g_warning ("%s: Invalid connection for %s: '%s' / '%s' invalid: %d", + __func__, iface, + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); g_object_unref (connection); connection = NULL; } diff --git a/system-settings/src/dbus-settings.c b/system-settings/src/dbus-settings.c index 969697c7e..06c94e1f3 100644 --- a/system-settings/src/dbus-settings.c +++ b/system-settings/src/dbus-settings.c @@ -431,7 +431,7 @@ impl_settings_add_connection (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMConnection *connection; - GError *err = NULL; + GError *err = NULL, *cnfh_error = NULL; if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) { dbus_g_method_return_error (context, err); @@ -439,7 +439,7 @@ impl_settings_add_connection (NMSysconfigSettings *self, return FALSE; } - connection = nm_connection_new_from_hash (hash); + connection = nm_connection_new_from_hash (hash, &cnfh_error); if (connection) { GSList *iter; @@ -465,7 +465,10 @@ impl_settings_add_connection (NMSysconfigSettings *self, /* Invalid connection hash */ err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, - "%s", "Invalid connection"); + "Invalid connection: '%s' / '%s' invalid: %d", + g_type_name (nm_connection_lookup_setting_type_by_quark (cnfh_error->domain)), + cnfh_error->message, cnfh_error->code); + g_error_free (cnfh_error); dbus_g_method_return_error (context, err); g_error_free (err); return FALSE;