diff options
40 files changed, 4674 insertions, 2374 deletions
@@ -1,3 +1,38 @@ +2007-11-07 Tambet Ingo <tambet@gmail.com> + + Rework NMSetting structures: Move each setting to it's own file. + Convert to GObject. Remove home grown setting types and use GTypes. + Use GObject property introspection for hash conversion, enumerating + properties, etc. + + * libnm-util/nm-setting-connection.[ch] + * libnm-util/nm-setting-ip4-config.[ch] + * libnm-util/nm-setting-ppp.[ch] + * libnm-util/nm-setting-vpn.[ch] + * libnm-util/nm-setting-vpn-properties.[ch] + * libnm-util/nm-setting-wired.[ch] + * libnm-util/nm-setting-wireless.[ch] + * libnm-util/nm-setting-wireless-security.[ch] + + New files, each containing a setting. + + * libnm-util/nm-setting-template.[ch]: A template for creating new + settings. To use it, just replace 'template' with the new setting + name, and you're half-way done. + + * libnm-util/nm-setting.c: Convert to GObject and use GObject + introspection instead of internal types and tables. + + * libnm-util/nm-connection.c: Adapt the new NMSetting work. + + * libnm-util/nm-param-spec-specialized.[ch]: Implement. Handles + GValue types defined by dbus-glib for composed types like collections, + structures and maps. + + * src/*: The API of NMSetting and NMConnection changed a bit: Getting + a setting from connection takes the setting type now. Also, since + the settings are in multiple files, include relevant settings. + 2007-10-31 Saleem Abdulrasool <compnerd@compnerd.org> * configure.in: diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 27eab0def2..9efaa8f5ee 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -11,13 +11,34 @@ libnm_util_la_CPPFLAGS = \ -DGNOME_DISABLE_DEPRECATED \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" +libnm_util_include_HEADERS = \ + nm-connection.h \ + nm-param-spec-specialized.h \ + nm-setting.h \ + nm-setting-connection.h \ + nm-setting-ip4-config.h \ + nm-setting-ppp.h \ + nm-setting-wired.h \ + nm-setting-wireless.h \ + nm-setting-wireless-security.h \ + nm-setting-vpn.h \ + nm-setting-vpn-properties.h \ + nm-utils.h + libnm_util_la_SOURCES= \ nm-connection.c \ - nm-connection.h \ + nm-param-spec-specialized.c \ nm-setting.c \ - nm-setting.h \ + nm-setting-connection.c \ + nm-setting-ip4-config.c \ + nm-setting-ppp.c \ + nm-setting-wired.c \ + nm-setting-wireless.c \ + nm-setting-wireless-security.c \ + nm-setting-vpn.c \ + nm-setting-vpn-properties.c \ nm-utils.c \ - nm-utils.h + $(libnm_util_include_HEADERS) libnm_util_la_LDFLAGS= $(GLIB_LIBS) $(DBUS_LIBS) @@ -25,11 +46,6 @@ libnm_util_la_CFLAGS=-fPIC libnm_util_includedir=$(includedir)/NetworkManager -libnm_util_include_HEADERS = \ - nm-connection.h \ - nm-setting.h \ - nm-utils.h - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index a17c9f287c..0096dbaf99 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -6,6 +6,15 @@ #include "nm-connection.h" #include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ppp.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-vpn.h" +#include "nm-setting-vpn-properties.h" + typedef struct { GHashTable *settings; } NMConnectionPrivate; @@ -22,69 +31,87 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static GHashTable *registered_setting_creators = NULL; +static GHashTable *registered_settings = NULL; static void -register_default_creators (void) +register_default_settings (void) { int i; const struct { const char *name; - NMSettingCreateFn fn; + GType type; } default_map[] = { - { NM_SETTING_CONNECTION, nm_setting_connection_new }, - { NM_SETTING_WIRED, nm_setting_wired_new }, - { NM_SETTING_WIRELESS, nm_setting_wireless_new }, - { NM_SETTING_IP4_CONFIG, nm_setting_ip4_config_new }, - { NM_SETTING_WIRELESS_SECURITY, nm_setting_wireless_security_new }, - { NM_SETTING_PPP, nm_setting_ppp_new }, - { NM_SETTING_VPN, nm_setting_vpn_new }, - { NM_SETTING_VPN_PROPERTIES, nm_setting_vpn_properties_new }, - { NULL, NULL } + { NM_SETTING_CONNECTION_SETTING_NAME, NM_TYPE_SETTING_CONNECTION }, + { NM_SETTING_WIRED_SETTING_NAME, NM_TYPE_SETTING_WIRED }, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG }, + { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY }, + { NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP }, + { NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN }, + { NM_SETTING_VPN_PROPERTIES_SETTING_NAME, NM_TYPE_SETTING_VPN_PROPERTIES }, + { NULL } }; + nm_utils_register_value_transformations (); + for (i = 0; default_map[i].name; i++) - nm_setting_parser_register (default_map[i].name, default_map[i].fn); + nm_setting_register (default_map[i].name, default_map[i].type); } void -nm_setting_parser_register (const char *name, NMSettingCreateFn creator) +nm_setting_register (const char *name, GType type) { g_return_if_fail (name != NULL); - g_return_if_fail (creator != NULL); - - if (!registered_setting_creators) - registered_setting_creators = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, NULL); + g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (type)); + + if (!registered_settings) + registered_settings = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); - if (g_hash_table_lookup (registered_setting_creators, name)) + if (g_hash_table_lookup (registered_settings, name)) g_warning ("Already have a creator function for '%s', overriding", name); - g_hash_table_insert (registered_setting_creators, g_strdup (name), creator); + g_hash_table_insert (registered_settings, g_strdup (name), g_strdup (g_type_name (type))); } void -nm_setting_parser_unregister (const char *name) +nm_setting_unregister (const char *name) +{ + if (registered_settings) + g_hash_table_remove (registered_settings, name); +} + +static GType +nm_connection_lookup_setting_type (const char *name) { - if (registered_setting_creators) - g_hash_table_remove (registered_setting_creators, name); + char *type_name; + GType type; + + type_name = (char *) g_hash_table_lookup (registered_settings, name); + if (type_name) { + type = g_type_from_name (type_name); + if (!type) + g_warning ("Can not get type for '%s'.", type_name); + } else { + type = 0; + g_warning ("Unknown setting '%s'", name); + } + + return type; } NMSetting * nm_connection_create_setting (const char *name) { - NMSettingCreateFn fn; - NMSetting *setting; + GType type; + NMSetting *setting = NULL; g_return_val_if_fail (name != NULL, NULL); - fn = (NMSettingCreateFn) g_hash_table_lookup (registered_setting_creators, name); - if (fn) - setting = fn (); - else { - g_warning ("Unknown setting '%s'", name); - setting = NULL; - } + type = nm_connection_lookup_setting_type (name); + if (type) + setting = (NMSetting *) g_object_new (type, NULL); return setting; } @@ -93,61 +120,60 @@ static void parse_one_setting (gpointer key, gpointer value, gpointer user_data) { NMConnection *connection = (NMConnection *) user_data; - NMSetting *setting; + GType type; + NMSetting *setting = NULL; - setting = nm_connection_create_setting ((char *) key); - if (setting) { - if (nm_setting_populate_from_hash (setting, (GHashTable *) value)) - nm_connection_add_setting (connection, setting); - else - nm_setting_destroy (setting); - } + type = nm_connection_lookup_setting_type ((char *) key); + if (type) + setting = nm_setting_from_hash (type, (GHashTable *) value); + if (setting) + nm_connection_add_setting (connection, setting); } void nm_connection_add_setting (NMConnection *connection, NMSetting *setting) { - NMConnectionPrivate *priv; - g_return_if_fail (NM_IS_CONNECTION (connection)); - g_return_if_fail (setting != NULL); + g_return_if_fail (NM_IS_SETTING (setting)); - priv = NM_CONNECTION_GET_PRIVATE (connection); - g_hash_table_insert (priv->settings, setting->name, setting); + g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings, + g_strdup (G_OBJECT_TYPE_NAME (setting)), setting); } NMSetting * -nm_connection_get_setting (NMConnection *connection, const char *setting_name) +nm_connection_get_setting (NMConnection *connection, GType type) { - NMConnectionPrivate *priv; + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (g_type_is_a (type, NM_TYPE_SETTING), NULL); + + return (NMSetting *) g_hash_table_lookup (NM_CONNECTION_GET_PRIVATE (connection)->settings, + g_type_name (type)); +} + +NMSetting * +nm_connection_get_setting_by_name (NMConnection *connection, const char *name) +{ + GType type; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (setting_name != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); - priv = NM_CONNECTION_GET_PRIVATE (connection); - return (NMSetting *) g_hash_table_lookup (priv->settings, setting_name); + type = nm_connection_lookup_setting_type (name); + + return type ? nm_connection_get_setting (connection, type) : NULL; } gboolean nm_connection_replace_settings (NMConnection *connection, GHashTable *new_settings) { - NMConnectionPrivate *priv; - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (new_settings != NULL, FALSE); - priv = NM_CONNECTION_GET_PRIVATE (connection); - g_hash_table_remove_all (priv->settings); - + g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings); g_hash_table_foreach (new_settings, parse_one_setting, connection); - if (g_hash_table_size (priv->settings) < 1) { - g_warning ("No settings found."); - return FALSE; - } - - if (!nm_settings_verify_all (priv->settings)) { + if (!nm_connection_verify (connection)) { g_warning ("Settings invalid."); return FALSE; } @@ -166,21 +192,15 @@ compare_one_setting (gpointer key, gpointer value, gpointer user_data) NMSetting *setting = (NMSetting *) value; CompareConnectionInfo *info = (CompareConnectionInfo *) user_data; NMSetting *other_setting; - NMConnectionPrivate *other_priv; if (info->failed) return; - other_priv = NM_CONNECTION_GET_PRIVATE (info->other); - other_setting = g_hash_table_lookup (other_priv->settings, setting->name); - if (!other_setting) - goto failed; - - info->failed = nm_setting_compare (setting, other_setting, FALSE) ? FALSE : TRUE; - return; - -failed: - info->failed = TRUE; + other_setting = nm_connection_get_setting (info->other, G_OBJECT_TYPE (setting)); + if (other_setting) + info->failed = nm_setting_compare (setting, other_setting) ? FALSE : TRUE; + else + info->failed = TRUE; } gboolean @@ -210,15 +230,56 @@ nm_connection_compare (NMConnection *connection, NMConnection *other) return info.failed ? FALSE : TRUE; } +typedef struct { + gboolean success; + GSList *all_settings; +} VerifySettingsInfo; + +static void +verify_one_setting (gpointer data, gpointer user_data) +{ + NMSetting *setting = NM_SETTING (data); + VerifySettingsInfo *info = (VerifySettingsInfo *) user_data; + + if (info->success) + info->success = nm_setting_verify (setting, info->all_settings); +} + +static void +hash_values_to_slist (gpointer key, gpointer value, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, value); +} + gboolean nm_connection_verify (NMConnection *connection) { NMConnectionPrivate *priv; + NMSetting *connection_setting; + VerifySettingsInfo info; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); priv = NM_CONNECTION_GET_PRIVATE (connection); - return nm_settings_verify_all (priv->settings); + + /* First, make sure there's at least 'connection' setting */ + connection_setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (!connection_setting) { + g_warning ("'connection' setting not present."); + return FALSE; + } + + /* Now, run the verify function of each setting */ + info.success = TRUE; + info.all_settings = NULL; + 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; } void @@ -232,30 +293,26 @@ nm_connection_update_secrets (NMConnection *connection, g_return_if_fail (setting_name != NULL); g_return_if_fail (secrets != NULL); - setting = nm_connection_get_setting (connection, setting_name); + setting = nm_connection_get_setting (connection, nm_connection_lookup_setting_type (setting_name)); if (!setting) { g_warning ("Unhandled settings object for secrets update."); return; } - if (!nm_setting_update_secrets (setting, secrets)) { - g_warning ("Error updating secrets for setting '%s'", setting_name); - return; - } - + nm_setting_update_secrets (setting, secrets); g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name); } typedef struct NeedSecretsInfo { - GPtrArray * secrets; - char * setting_name; + GPtrArray *secrets; + NMSetting *setting; } NeedSecretsInfo; static void need_secrets_check (gpointer key, gpointer data, gpointer user_data) { - NMSetting *setting = (NMSetting *) data; - NeedSecretsInfo * info = (NeedSecretsInfo *) user_data; + NMSetting *setting = NM_SETTING (data); + NeedSecretsInfo *info = (NeedSecretsInfo *) user_data; // FIXME: allow more than one setting to say it needs secrets if (info->secrets) @@ -263,7 +320,7 @@ need_secrets_check (gpointer key, gpointer data, gpointer user_data) info->secrets = nm_setting_need_secrets (setting); if (info->secrets) - info->setting_name = key; + info->setting = setting; } const char * @@ -282,7 +339,7 @@ nm_connection_need_secrets (NMConnection *connection) // settings name :: [list of secrets key names]. if (info.secrets) { g_ptr_array_free (info.secrets, TRUE); - return info.setting_name; + return nm_setting_get_name (info.setting); } return NULL; @@ -291,9 +348,7 @@ nm_connection_need_secrets (NMConnection *connection) static void clear_setting_secrets (gpointer key, gpointer data, gpointer user_data) { - NMSetting *setting = (NMSetting *) data; - - nm_setting_clear_secrets (setting); + nm_setting_clear_secrets (NM_SETTING (data)); } void @@ -320,8 +375,8 @@ add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) setting_hash = nm_setting_to_hash (setting); if (setting_hash) g_hash_table_insert (connection_hash, - g_strdup (setting->name), - setting_hash); + g_strdup (setting->name), + setting_hash); } GHashTable * @@ -333,8 +388,7 @@ nm_connection_to_hash (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); connection_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_hash_table_destroy); + g_free, (GDestroyNotify) g_hash_table_destroy); priv = NM_CONNECTION_GET_PRIVATE (connection); g_hash_table_foreach (priv->settings, add_one_setting_to_hash, connection_hash); @@ -357,9 +411,8 @@ static void for_each_setting (gpointer key, gpointer value, gpointer user_data) { ForEachValueInfo *info = (ForEachValueInfo *) user_data; - NMSetting *setting = (NMSetting *) value; - nm_setting_enumerate_values (setting, info->func, info->user_data); + nm_setting_enumerate_values (NM_SETTING (value), info->func, info->user_data); } void @@ -388,120 +441,14 @@ nm_connection_for_each_setting_value (NMConnection *connection, g_slice_free (ForEachValueInfo, info); } -static char * -gvalue_to_string (GValue *val) -{ - char *ret; - GType type; - GString *str; - gboolean need_comma = FALSE; - - type = G_VALUE_TYPE (val); - switch (type) { - case G_TYPE_STRING: - ret = g_strdup (g_value_get_string (val)); - break; - case G_TYPE_INT: - ret = g_strdup_printf ("%d", g_value_get_int (val)); - break; - case G_TYPE_UINT: - ret = g_strdup_printf ("%u", g_value_get_uint (val)); - break; - case G_TYPE_BOOLEAN: - ret = g_strdup_printf ("%s", g_value_get_boolean (val) ? "True" : "False"); - break; - case G_TYPE_UCHAR: - ret = g_strdup_printf ("%d", g_value_get_uchar (val)); - break; - case G_TYPE_UINT64: - ret = g_strdup_printf ("%llu", g_value_get_uint64 (val)); - break; - default: - /* These return dynamic values and thus can't be 'case's */ - if (type == DBUS_TYPE_G_UCHAR_ARRAY) - ret = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (val)); - else if (type == dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) { - GSList *iter; - - str = g_string_new ("["); - for (iter = g_value_get_boxed (val); iter; iter = iter->next) { - if (need_comma) - g_string_append (str, ", "); - else - need_comma = TRUE; - - g_string_append (str, (char *) iter->data); - } - g_string_append (str, "]"); - - ret = g_string_free (str, FALSE); - } else if (type == dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_UCHAR_ARRAY)) { - /* Array of arrays of chars, like wireless seen-bssids for example */ - int i; - GPtrArray *ptr_array; - - str = g_string_new ("["); - - ptr_array = (GPtrArray *) g_value_get_boxed (val); - for (i = 0; i < ptr_array->len; i++) { - ret = nm_utils_garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i)); - - if (need_comma) - g_string_append (str, ", "); - else - need_comma = TRUE; - - g_string_append (str, ret); - g_free (ret); - } - - g_string_append (str, "]"); - ret = g_string_free (str, FALSE); - } else if (type == dbus_g_type_get_collection ("GArray", G_TYPE_UINT)) { - GArray *array = g_value_get_boxed (val); - int i; - - str = g_string_new ("["); - - for (i = 0; i < array->len; i++) { - char *s; - - if (need_comma) - g_string_append (str, ", "); - else - need_comma = TRUE; - - s = g_strdup_printf ("%u", g_array_index (array, guint32, i)); - g_string_append (str, s); - g_free (s); - } - - g_string_append (str, "]"); - - ret = g_string_free (str, FALSE); - } else - ret = g_strdup_printf ("Value with type %s", g_type_name (type)); - } - - return ret; -} - -static void -dump_setting_member (gpointer key, gpointer value, gpointer user_data) -{ - char *val_as_str; - - val_as_str = gvalue_to_string ((GValue *) value); - g_message ("\t%s : '%s'", (char *) key, val_as_str ? val_as_str : "(null)"); - g_free (val_as_str); -} - static void dump_setting (gpointer key, gpointer value, gpointer user_data) { - g_message ("Setting '%s'", (char *) key); - g_hash_table_foreach ((GHashTable *) value, dump_setting_member, NULL); - g_message ("-------------------"); + char *str; + + str = nm_setting_to_string (NM_SETTING (value)); + g_print ("%s\n", str); + g_free (str); } void @@ -511,10 +458,7 @@ nm_connection_dump (NMConnection *connection) g_return_if_fail (NM_IS_CONNECTION (connection)); - /* Convert the connection to hash so that we can introspect it */ - hash = nm_connection_to_hash (connection); - g_hash_table_foreach (hash, dump_setting, NULL); - g_hash_table_destroy (hash); + g_hash_table_foreach (NM_CONNECTION_GET_PRIVATE (connection)->settings, dump_setting, NULL); } NMConnection * @@ -522,8 +466,8 @@ nm_connection_new (void) { GObject *object; - if (!registered_setting_creators) - register_default_creators (); + if (!registered_settings) + register_default_settings (); object = g_object_new (NM_TYPE_CONNECTION, NULL); @@ -543,13 +487,7 @@ nm_connection_new_from_hash (GHashTable *hash) priv = NM_CONNECTION_GET_PRIVATE (connection); - if (g_hash_table_size (priv->settings) < 1) { - g_warning ("No settings found."); - g_object_unref (connection); - return NULL; - } - - if (!nm_settings_verify_all (priv->settings)) { + if (!nm_connection_verify (connection)) { g_object_unref (connection); return NULL; } @@ -562,7 +500,7 @@ nm_connection_init (NMConnection *connection) { NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); - priv->settings = g_hash_table_new (g_str_hash, g_str_equal); + priv->settings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } static void diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index fc7658b35e..29bebb92ed 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -1,9 +1,11 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + #ifndef NM_CONNECTION_H #define NM_CONNECTION_H #include <glib.h> #include <glib-object.h> -#include "nm-setting.h" +#include <nm-setting.h> G_BEGIN_DECLS @@ -30,16 +32,19 @@ GType nm_connection_get_type (void); NMConnection *nm_connection_new (void); NMConnection *nm_connection_new_from_hash (GHashTable *hash); void nm_connection_add_setting (NMConnection *connection, - NMSetting *setting); + NMSetting *setting); NMSetting *nm_connection_get_setting (NMConnection *connection, - const char *setting_name); + GType setting_type); + +NMSetting *nm_connection_get_setting_by_name (NMConnection *connection, + const char *name); gboolean nm_connection_replace_settings (NMConnection *connection, - GHashTable *new_settings); + GHashTable *new_settings); gboolean nm_connection_compare (NMConnection *connection, - NMConnection *other); + NMConnection *other); gboolean nm_connection_verify (NMConnection *connection); @@ -52,18 +57,18 @@ void nm_connection_update_secrets (NMConnection *connection, GHashTable *secrets); void nm_connection_for_each_setting_value (NMConnection *connection, - NMSettingValueIterFn func, - gpointer user_data); + NMSettingValueIterFn func, + gpointer user_data); GHashTable *nm_connection_to_hash (NMConnection *connection); void nm_connection_dump (NMConnection *connection); NMSetting *nm_connection_create_setting (const char *name); -void nm_setting_parser_register (const char *name, - NMSettingCreateFn creator); +void nm_setting_register (const char *name, + GType type); -void nm_setting_parser_unregister (const char *name); +void nm_setting_unregister (const char *name); G_END_DECLS diff --git a/libnm-util/nm-param-spec-specialized.c b/libnm-util/nm-param-spec-specialized.c new file mode 100644 index 0000000000..aba86b0b9b --- /dev/null +++ b/libnm-util/nm-param-spec-specialized.c @@ -0,0 +1,710 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-param-spec-specialized.h" + +struct _NMParamSpecSpecialized { + GParamSpec parent; +}; + +#include <string.h> +#include <dbus/dbus-glib.h> + +/***********************************************************/ +/* nm_gvalues_compare */ + +static gint nm_gvalues_compare (const GValue *value1, const GValue *value2); + +static gboolean +type_is_fixed_size (GType type) +{ + switch (type) { + case G_TYPE_CHAR: + case G_TYPE_UCHAR: + case G_TYPE_BOOLEAN: + case G_TYPE_LONG: + case G_TYPE_ULONG: + case G_TYPE_INT: + case G_TYPE_UINT: + case G_TYPE_INT64: + case G_TYPE_UINT64: + case G_TYPE_FLOAT: + case G_TYPE_DOUBLE: + return TRUE; + default: + return FALSE; + } +} + +static gint +nm_gvalues_compare_fixed (const GValue *value1, const GValue *value2) +{ + int ret = 0; + + switch (G_VALUE_TYPE (value1)) { + case G_TYPE_CHAR: { + gchar val1 = g_value_get_char (value1); + gchar val2 = g_value_get_char (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_UCHAR: { + guchar val1 = g_value_get_uchar (value1); + guchar val2 = g_value_get_uchar (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_BOOLEAN: { + gboolean val1 = g_value_get_boolean (value1); + gboolean val2 = g_value_get_boolean (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_LONG: { + glong val1 = g_value_get_long (value1); + glong val2 = g_value_get_long (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_ULONG: { + gulong val1 = g_value_get_ulong (value1); + gulong val2 = g_value_get_ulong (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_INT: { + gint val1 = g_value_get_int (value1); + gint val2 = g_value_get_int (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_UINT: { + guint val1 = g_value_get_uint (value1); + guint val2 = g_value_get_uint (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_INT64: { + gint64 val1 = g_value_get_int64 (value1); + gint64 val2 = g_value_get_int64 (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_UINT64: { + guint64 val1 = g_value_get_uint64 (value1); + guint64 val2 = g_value_get_uint64 (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_FLOAT: { + gfloat val1 = g_value_get_float (value1); + gfloat val2 = g_value_get_float (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + case G_TYPE_DOUBLE: { + gdouble val1 = g_value_get_double (value1); + gdouble val2 = g_value_get_double (value2); + if (val1 != val2) + ret = val1 < val2 ? -1 : val1 > val2; + break; + } + default: + g_warning ("Unhandled fixed size type '%s'", G_VALUE_TYPE_NAME (value1)); + } + + return ret; +} + +static gint +nm_gvalues_compare_string (const GValue *value1, const GValue *value2) +{ + const char *str1 = g_value_get_string (value1); + const char *str2 = g_value_get_string (value2); + + if (str1 == str2) + return 0; + + if (!str1) + return 1; + if (!str2) + return -1; + + return strcmp (str1, str2); +} + +static gint +nm_gvalues_compare_strv (const GValue *value1, const GValue *value2) +{ + char **strv1; + char **strv2; + gint ret; + guint i = 0; + + strv1 = (char **) g_value_get_boxed (value1); + strv2 = (char **) g_value_get_boxed (value2); + + while (strv1[i] && strv2[i]) { + ret = strcmp (strv1[i], strv2[i]); + if (ret) + return ret; + i++; + } + + if (strv1[i] == NULL && strv2[i] == NULL) + return 0; + + if (strv1[i]) + return 1; + + return -1; +} + +static void +nm_gvalue_destroy (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +static GValue * +nm_gvalue_dup (const GValue *value) +{ + GValue *dup; + + dup = g_slice_new0 (GValue); + g_value_init (dup, G_VALUE_TYPE (value)); + g_value_copy (value, dup); + + return dup; +} + +static void +iterate_collection (const GValue *value, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, nm_gvalue_dup (value)); +} + +static gint +nm_gvalues_compare_collection (const GValue *value1, const GValue *value2) +{ + gint ret; + guint len1; + guint len2; + GType value_type = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value1)); + + if (type_is_fixed_size (value_type)) { + gpointer data1 = NULL; + gpointer data2 = NULL; + + dbus_g_type_collection_get_fixed ((GValue *) value1, &data1, &len1); + dbus_g_type_collection_get_fixed ((GValue *) value2, &data2, &len2); + + if (len1 != len2) + ret = len1 < len2 ? -1 : len1 > len2; + else + ret = memcmp (data1, data2, len1); + } else { + GSList *list1 = NULL; + GSList *list2 = NULL; + + dbus_g_type_collection_value_iterate (value1, iterate_collection, &list1); + len1 = g_slist_length (list1); + dbus_g_type_collection_value_iterate (value2, iterate_collection, &list2); + len2 = g_slist_length (list2); + + if (len1 != len2) + ret = len1 < len2 ? -1 : len1 > len2; + else { + GSList *iter1; + GSList *iter2; + + for (iter1 = list1, iter2 = list2, ret = 0; + ret == 0 && iter1 && iter2; + iter1 = iter1->next, iter2 = iter2->next) + ret = nm_gvalues_compare ((GValue *) iter1->data, (GValue *) iter2->data); + } + + g_slist_foreach (list1, (GFunc) nm_gvalue_destroy, NULL); + g_slist_free (list1); + g_slist_foreach (list2, (GFunc) nm_gvalue_destroy, NULL); + g_slist_free (list2); + } + + return ret; +} + +static void +iterate_map (const GValue *key_val, + const GValue *value_val, + gpointer user_data) +{ + GHashTable **hash = (GHashTable **) user_data; + + g_hash_table_insert (*hash, g_value_dup_string (key_val), nm_gvalue_dup (value_val)); +} + +typedef struct { + GHashTable *hash2; + gint ret; +} CompareMapInfo; + +static void +compare_one_map_item (gpointer key, gpointer val, gpointer user_data) +{ + CompareMapInfo *info = (CompareMapInfo *) user_data; + GValue *value2; + + if (info->ret) + return; + + value2 = (GValue *) g_hash_table_lookup (info->hash2, key); + if (value2) + info->ret = nm_gvalues_compare ((GValue *) val, value2); + else + info->ret = 1; +} + +static gint +nm_gvalues_compare_map (const GValue *value1, const GValue *value2) +{ + GHashTable *hash1 = NULL; + GHashTable *hash2 = NULL; + guint len1; + guint len2; + gint ret = 0; + + if (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)) != G_TYPE_STRING) { + g_warning ("Can not compare maps with '%s' for keys", + g_type_name (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)))); + return 0; + } + + hash1 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy); + dbus_g_type_map_value_iterate (value1, iterate_map, &hash1); + len1 = g_hash_table_size (hash1); + + hash2 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy); + dbus_g_type_map_value_iterate (value2, iterate_map, &hash2); + len2 = g_hash_table_size (hash2); + + if (len1 != len2) + ret = len1 < len2 ? -1 : len1 > len2; + else { + CompareMapInfo info; + + info.ret = 0; + info.hash2 = hash2; + g_hash_table_foreach (hash1, compare_one_map_item, &info); + ret = info.ret; + } + + g_hash_table_destroy (hash1); + g_hash_table_destroy (hash2); + + return ret; +} + +static gint +nm_gvalues_compare_struct (const GValue *value1, const GValue *value2) +{ + g_warning ("Not implemented"); + return 0; +} + +gint +nm_gvalues_compare (const GValue *value1, const GValue *value2) +{ + GType type1; + GType type2; + gint ret; + + if (value1 == value2) + return 0; + if (!value1) + return 1; + if (!value2) + return -1; + + type1 = G_VALUE_TYPE (value1); + type2 = G_VALUE_TYPE (value2); + + if (type1 != type2) + return type1 < type2 ? -1 : type1 > type2; + + + if (type_is_fixed_size (type1)) + ret = nm_gvalues_compare_fixed (value1, value2); + else if (type1 == G_TYPE_STRING) + ret = nm_gvalues_compare_string (value1, value2); + else if (G_VALUE_HOLDS_BOXED (value1)) { + gpointer p1 = g_value_get_boxed (value1); + gpointer p2 = g_value_get_boxed (value2); + + if (p1 == p2) + ret = 0; /* Exactly the same values */ + else if (!p1) + ret = 1; /* The comparision functions below don't handle NULLs */ + else if (!p2) + ret = -1; /* The comparision functions below don't handle NULLs */ + else if (type1 == G_TYPE_STRV) + ret = nm_gvalues_compare_strv (value1, value2); + else if (dbus_g_type_is_collection (type1)) + ret = nm_gvalues_compare_collection (value1, value2); + else if (dbus_g_type_is_map (type1)) + ret = nm_gvalues_compare_map (value1, value2); + else if (dbus_g_type_is_struct (type1)) + ret = nm_gvalues_compare_struct (value1, value2); + else if (type1 == G_TYPE_VALUE) + ret = nm_gvalues_compare ((GValue *) g_value_get_boxed (value1), (GValue *) g_value_get_boxed (value2)); + else { + g_warning ("Don't know how to compare boxed types '%s'", g_type_name (type1)); + ret = value1 == value2; + } + } else { + g_warning ("Don't know how to compare types '%s'", g_type_name (type1)); + ret = value1 == value2; + } + + return ret; +} + +/***********************************************************/ + +static void +param_specialized_init (GParamSpec *pspec) +{ +} + +static void +param_specialized_set_default (GParamSpec *pspec, GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static gboolean +param_specialized_validate (GParamSpec *pspec, GValue *value) +{ + NMParamSpecSpecialized *sspec = NM_PARAM_SPEC_SPECIALIZED (pspec); + GType value_type = G_VALUE_TYPE (value); + gboolean changed = FALSE; + + if (!g_value_type_compatible (value_type, G_PARAM_SPEC_VALUE_TYPE (sspec))) { + g_value_reset (value); + changed = TRUE; + } + + return changed; +} + +static gint +param_specialized_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + return nm_gvalues_compare (value1, value2); +} + +GType +nm_param_spec_specialized_get_type (void) +{ + static GType type; + + if (G_UNLIKELY (type) == 0) { + static const GParamSpecTypeInfo pspec_info = { + sizeof (NMParamSpecSpecialized), + 0, + param_specialized_init, + G_TYPE_OBJECT, /* value_type */ + NULL, /* finalize */ + param_specialized_set_default, + param_specialized_validate, + param_specialized_values_cmp, + }; + type = g_param_type_register_static ("NMParamSpecSpecialized", &pspec_info); + } + + return type; +} + +GParamSpec * +nm_param_spec_specialized (const char *name, + const char *nick, + const char *blurb, + GType specialized_type, + GParamFlags flags) +{ + NMParamSpecSpecialized *pspec; + + g_return_val_if_fail (g_type_is_a (specialized_type, G_TYPE_BOXED), NULL); + + pspec = g_param_spec_internal (NM_TYPE_PARAM_SPEC_SPECIALIZED, + name, nick, blurb, flags); + + G_PARAM_SPEC (pspec)->value_type = specialized_type; + + return G_PARAM_SPEC (pspec); +} + +/***********************************************************/ +/* Tests */ + +#if 0 + +static void +compare_ints (void) +{ + GValue value1 = { 0 }; + GValue value2 = { 0 }; + + g_value_init (&value1, G_TYPE_INT); + g_value_init (&value2, G_TYPE_INT); + + g_value_set_int (&value1, 5); + g_value_set_int (&value2, 5); + g_print ("Comparing ints 5 and 5: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_int (&value2, 10); + g_print ("Comparing ints 5 and 10: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_int (&value2, 1); + g_print ("Comparing ints 5 and 1: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static void +compare_strings (void) +{ + GValue value1 = { 0 }; + GValue value2 = { 0 }; + const char *str1 = "hello"; + const char *str2 = "world"; + + g_value_init (&value1, G_TYPE_STRING); + g_value_init (&value2, G_TYPE_STRING); + + g_value_set_string (&value1, str1); + g_value_set_string (&value2, str1); + g_print ("Comparing identical strings: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_string (&value2, str2); + g_print ("Comparing different strings: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static void +compare_strv (void) +{ + GValue value1 = { 0 }; + GValue value2 = { 0 }; + char *strv1[] = { "foo", "bar", "baz", NULL }; + char *strv2[] = { "foo", "bar", "bar", NULL }; + char *strv3[] = { "foo", "bar", NULL }; + char *strv4[] = { "foo", "bar", "baz", "bam", NULL }; + + g_value_init (&value1, G_TYPE_STRV); + g_value_init (&value2, G_TYPE_STRV); + + g_value_set_boxed (&value1, strv1); + g_value_set_boxed (&value2, strv1); + g_print ("Comparing identical strv's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_boxed (&value2, strv2); + g_print ("Comparing different strv's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_boxed (&value2, strv3); + g_print ("Comparing different len (smaller) strv's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_value_set_boxed (&value2, strv4); + g_print ("Comparing different len (longer) strv's: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static void +compare_garrays (void) +{ + GArray *array1; + GArray *array2; + GValue value1 = { 0 }; + GValue value2 = { 0 }; + int i; + + g_value_init (&value1, DBUS_TYPE_G_UINT_ARRAY); + array1 = g_array_new (FALSE, FALSE, sizeof (guint32)); + + g_value_init (&value2, DBUS_TYPE_G_UINT_ARRAY); + array2 = g_array_new (FALSE, FALSE, sizeof (guint32)); + + for (i = 0; i < 5; i++) { + g_array_append_val (array1, i); + g_array_append_val (array2, i); + } + + g_value_set_boxed (&value1, array1); + g_value_set_boxed (&value2, array2); + + g_print ("Comparing identical arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_array_remove_index (array2, 0); + g_value_set_boxed (&value2, array2); + g_print ("Comparing different length arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); + + i = 7; + g_array_prepend_val (array2, i); + g_value_set_boxed (&value2, array2); + g_print ("Comparing different arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static void +compare_ptrarrays (void) +{ + GPtrArray *array1; + GPtrArray *array2; + GValue value1 = { 0 }; + GValue value2 = { 0 }; + + g_value_init (&value1, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)); + array1 = g_ptr_array_new (); + + g_value_init (&value2, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)); + array2 = g_ptr_array_new (); + + g_ptr_array_add (array1, "hello"); + g_ptr_array_add (array1, "world"); + g_value_set_boxed (&value1, array1); + + g_ptr_array_add (array2, "hello"); + g_ptr_array_add (array2, "world"); + g_value_set_boxed (&value2, array2); + + g_print ("Comparing identical ptr arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_ptr_array_add (array2, "boo"); + g_value_set_boxed (&value2, array2); + g_print ("Comparing different len ptr arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_ptr_array_add (array1, "booz"); + g_value_set_boxed (&value1, array1); + g_print ("Comparing different ptr arrays's: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static void +compare_str_hash (void) +{ + GHashTable *hash1; + GHashTable *hash2; + GValue value1 = { 0 }; + GValue value2 = { 0 }; + + g_value_init (&value1, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)); + g_value_init (&value2, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)); + + hash1 = g_hash_table_new (g_str_hash, g_str_equal); + hash2 = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (hash1, "key1", "hello"); + g_hash_table_insert (hash1, "key2", "world"); + + g_hash_table_insert (hash2, "key1", "hello"); + g_hash_table_insert (hash2, "key2", "world"); + + g_value_set_boxed (&value1, hash1); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing identical str hashes: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_hash_table_remove (hash2, "key2"); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing different length str hashes: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_hash_table_insert (hash2, "key2", "moon"); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing different str hashes: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +static GValue * +str_to_gvalue (const char *str) +{ + GValue *value; + + value = g_slice_new0 (GValue); + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, str); + + return value; +} + +static GValue * +int_to_gvalue (int i) +{ + GValue *value; + + value = g_slice_new0 (GValue); + g_value_init (value, G_TYPE_INT); + g_value_set_int (value, i); + + return value; +} + +static void +compare_gvalue_hash (void) +{ + GHashTable *hash1; + GHashTable *hash2; + GValue value1 = { 0 }; + GValue value2 = { 0 }; + + g_value_init (&value1, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); + g_value_init (&value2, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); + + hash1 = g_hash_table_new (g_str_hash, g_str_equal); + hash2 = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (hash1, "key1", str_to_gvalue ("hello")); + g_hash_table_insert (hash1, "key2", int_to_gvalue (5)); + + g_hash_table_insert (hash2, "key1", str_to_gvalue ("hello")); + g_hash_table_insert (hash2, "key2", int_to_gvalue (5)); + + g_value_set_boxed (&value1, hash1); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing identical gvalue hashes: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_hash_table_remove (hash2, "key2"); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing different length str hashes: %d\n", nm_gvalues_compare (&value1, &value2)); + + g_hash_table_insert (hash2, "key2", str_to_gvalue ("moon")); + g_value_set_boxed (&value2, hash2); + g_print ("Comparing different str hashes: %d\n", nm_gvalues_compare (&value1, &value2)); +} + +int +main (int argc, char *argv[]) +{ + DBusGConnection *bus; + + g_type_init (); + bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + + compare_ints (); + compare_strings (); + compare_strv (); + compare_garrays (); + compare_ptrarrays (); + compare_str_hash (); + compare_gvalue_hash (); + + return 0; +} + +#endif diff --git a/libnm-util/nm-param-spec-specialized.h b/libnm-util/nm-param-spec-specialized.h new file mode 100644 index 0000000000..d998cbbd15 --- /dev/null +++ b/libnm-util/nm-param-spec-specialized.h @@ -0,0 +1,23 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_PARAM_SPEC_SPECIALIZED_H +#define NM_PARAM_SPEC_SPECIALIZED_H + +#include <glib-object.h> + +typedef struct _NMParamSpecSpecialized NMParamSpecSpecialized; + +#define NM_TYPE_PARAM_SPEC_SPECIALIZED (nm_param_spec_specialized_get_type ()) + +#define NM_IS_PARAM_SPEC_SPECIALIZED(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), NM_TYPE_PARAM_SPEC_SPECIALIZED)) +#define NM_PARAM_SPEC_SPECIALIZED(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), NM_TYPE_PARAM_SPEC_SPECIALIZED, NMParamSpecSpecialized)) + +GType nm_param_spec_specialized_get_type (void); + +GParamSpec *nm_param_spec_specialized (const char *name, + const char *nick, + const char *blurb, + GType specialized_type, + GParamFlags flags); + +#endif /* NM_PARAM_SPEC_SPECIALIZED_H */ diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c new file mode 100644 index 0000000000..d1dc6cb427 --- /dev/null +++ b/libnm-util/nm-setting-connection.c @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> +#include "nm-setting-connection.h" + +G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_NAME, + PROP_TYPE, + PROP_AUTOCONNECT, + PROP_TIMESTAMP, + + LAST_PROP +}; + +NMSetting *nm_setting_connection_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_CONNECTION, NULL); +} + +static gint +find_setting_by_name (gconstpointer a, gconstpointer b) +{ + NMSetting *setting = NM_SETTING (a); + const char *str = (const char *) b; + + return strcmp (nm_setting_get_name (setting), str); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingConnection *self = NM_SETTING_CONNECTION (setting); + + if (!self->name || !strlen (self->name)) + return FALSE; + + if (!self->type || !strlen (self->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); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_connection_init (NMSettingConnection *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_CONNECTION_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingConnection *self = NM_SETTING_CONNECTION (object); + + g_free (self->name); + g_free (self->type); + + G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingConnection *setting = NM_SETTING_CONNECTION (object); + + switch (prop_id) { + case PROP_NAME: + g_free (setting->name); + setting->name = g_value_dup_string (value); + break; + case PROP_TYPE: + g_free (setting->type); + setting->type = g_value_dup_string (value); + break; + case PROP_AUTOCONNECT: + setting->autoconnect = g_value_get_boolean (value); + break; + case PROP_TIMESTAMP: + setting->timestamp = g_value_get_uint64 (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingConnection *setting = NM_SETTING_CONNECTION (object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, setting->name); + break; + case PROP_TYPE: + g_value_set_string (value, setting->type); + break; + case PROP_AUTOCONNECT: + g_value_set_boolean (value, setting->autoconnect); + break; + case PROP_TIMESTAMP: + g_value_set_uint64 (value, setting->timestamp); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_SETTING_CONNECTION_NAME, + "Name", + "Connection name", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_SETTING_CONNECTION_TYPE, + "Type", + "Connection type", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_AUTOCONNECT, + g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, + "Autoconnect", + "Connection autoconnect", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_TIMESTAMP, + g_param_spec_uint64 (NM_SETTING_CONNECTION_TIMESTAMP, + "Timestamp", + "Connection timestamp", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h new file mode 100644 index 0000000000..3af4cbf002 --- /dev/null +++ b/libnm-util/nm-setting-connection.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_CONNECTION_H +#define NM_SETTING_CONNECTION_H + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_CONNECTION (nm_setting_connection_get_type ()) +#define NM_SETTING_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnection)) +#define NM_SETTING_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) +#define NM_IS_SETTING_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_CONNECTION)) +#define NM_IS_SETTING_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_CONNECTION)) +#define NM_SETTING_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) + +#define NM_SETTING_CONNECTION_SETTING_NAME "connection" + +#define NM_SETTING_CONNECTION_NAME "name" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" + +typedef struct { + NMSetting parent; + + char *name; + char *type; + gboolean autoconnect; + guint64 timestamp; +} NMSettingConnection; + +typedef struct { + NMSettingClass parent; +} NMSettingConnectionClass; + +GType nm_setting_connection_get_type (void); + +NMSetting *nm_setting_connection_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_CONNECTION_H */ diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c new file mode 100644 index 0000000000..17d9855008 --- /dev/null +++ b/libnm-util/nm-setting-ip4-config.c @@ -0,0 +1,214 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <dbus/dbus-glib.h> +#include "nm-setting-ip4-config.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_MANUAL, + PROP_DNS, + PROP_DNS_SEARCH, + PROP_ADDRESSES, + + LAST_PROP +}; + +NMSetting * +nm_setting_ip4_config_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP4_CONFIG, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingIP4Config *self = NM_SETTING_IP4_CONFIG (setting); + + if (self->manual) { + if (!self->addresses) { + g_warning ("address is not provided"); + return FALSE; + } + } + + return TRUE; +} + + +static void +nm_setting_ip4_config_init (NMSettingIP4Config *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_IP4_CONFIG_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingIP4Config *self = NM_SETTING_IP4_CONFIG (object); + + if (self->dns) + g_array_free (self->dns, TRUE); + + nm_utils_slist_free (self->dns_search, g_free); + nm_utils_slist_free (self->addresses, g_free); + + G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object); +} + +static GSList * +ip4_addresses_from_gvalue (const GValue *value) +{ + GPtrArray *ptr_array; + int i; + GSList *list = NULL; + + ptr_array = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; i < ptr_array->len; i++) { + GValueArray *value_array = (GValueArray *) g_ptr_array_index (ptr_array, i); + + if (value_array->n_values == 2 || value_array->n_values == 3) { + NMSettingIP4Address *ip4_addr; + + ip4_addr = g_new0 (NMSettingIP4Address, 1); + ip4_addr->address = g_value_get_uint (g_value_array_get_nth (value_array, 0)); + ip4_addr->netmask = g_value_get_uint (g_value_array_get_nth (value_array, 1)); + + if (value_array->n_values == 3) + ip4_addr->gateway = g_value_get_uint (g_value_array_get_nth (value_array, 2)); + + list = g_slist_prepend (list, ip4_addr); + } else + nm_warning ("Ignoring invalid IP4 address"); + } + + return g_slist_reverse (list); +} + +static void +ip4_addresses_to_gvalue (GSList *list, GValue *value) +{ + GPtrArray *ptr_array; + GSList *iter; + + ptr_array = g_ptr_array_new (); + + for (iter = list; iter; iter = iter->next) { + NMSettingIP4Address *ip4_addr = (NMSettingIP4Address *) iter->data; + GArray *array; + + array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), 3); + g_array_append_val (array, ip4_addr->address); + g_array_append_val (array, ip4_addr->netmask); + + if (ip4_addr->gateway) + g_array_append_val (array, ip4_addr->gateway); + + g_ptr_array_add (ptr_array, array); + } + + g_value_take_boxed (value, ptr_array); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIP4Config *setting = NM_SETTING_IP4_CONFIG (object); + + switch (prop_id) { + case PROP_MANUAL: + setting->manual = g_value_get_boolean (value); + break; + case PROP_DNS: + if (setting->dns) + g_array_free (setting->dns, TRUE); + setting->dns = g_value_dup_boxed (value); + break; + case PROP_DNS_SEARCH: + nm_utils_slist_free (setting->dns_search, g_free); + setting->dns_search = g_value_dup_boxed (value); + break; + case PROP_ADDRESSES: + nm_utils_slist_free (setting->addresses, g_free); + setting->addresses = ip4_addresses_from_gvalue (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingIP4Config *setting = NM_SETTING_IP4_CONFIG (object); + + switch (prop_id) { + case PROP_MANUAL: + g_value_set_boolean (value, setting->manual); + break; + case PROP_DNS: + g_value_set_boxed (value, setting->dns); + break; + case PROP_DNS_SEARCH: + g_value_set_boxed (value, setting->dns_search); + break; + case PROP_ADDRESSES: + ip4_addresses_to_gvalue (setting->addresses, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_MANUAL, + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_MANUAL, + "Manual", + "Do not use DHCP", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DNS, + nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS, + "DNS", + "List of DNS servers", + DBUS_TYPE_G_UINT_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DNS_SEARCH, + nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS_SEARCH, + "DNS search", + "List of DNS search domains", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_ADDRESSES, + nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ADDRESSES, + "Addresses", + "List of NMSettingIP4Addresses", + dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE_ARRAY), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h new file mode 100644 index 0000000000..bebd3baa59 --- /dev/null +++ b/libnm-util/nm-setting-ip4-config.h @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_IP4_CONFIG_H +#define NM_SETTING_IP4_CONFIG_H + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP4_CONFIG (nm_setting_ip4_config_get_type ()) +#define NM_SETTING_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4Config)) +#define NM_SETTING_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IP4CONFIG, NMSettingIP4ConfigClass)) +#define NM_IS_SETTING_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_IS_SETTING_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_SETTING_IP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigClass)) + +#define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4" + +#define NM_SETTING_IP4_CONFIG_MANUAL "manual" +#define NM_SETTING_IP4_CONFIG_DNS "dns" +#define NM_SETTING_IP4_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP4_CONFIG_ADDRESSES "addresses" + +typedef struct { + guint32 address; + guint32 netmask; + guint32 gateway; +} NMSettingIP4Address; + +typedef struct { + NMSetting parent; + + gboolean manual; + GArray *dns; /* array of guint32 */ + GSList *dns_search; /* list of strings */ + GSList *addresses; /* array of NMSettingIP4Address */ +} NMSettingIP4Config; + +typedef struct { + NMSettingClass parent; +} NMSettingIP4ConfigClass; + +GType nm_setting_ip4_config_get_type (void); + +NMSetting *nm_setting_ip4_config_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_IP4_CONFIG_H */ diff --git a/libnm-util/nm-setting-ppp.c b/libnm-util/nm-setting-ppp.c new file mode 100644 index 0000000000..1f358cd534 --- /dev/null +++ b/libnm-util/nm-setting-ppp.c @@ -0,0 +1,326 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-setting-ppp.h" + +G_DEFINE_TYPE (NMSettingPPP, nm_setting_ppp, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_NOAUTH, + PROP_REFUSE_EAP, + PROP_REFUSE_CHAP, + PROP_REFUSE_MSCHAP, + PROP_NOBSDCOMP, + PROP_NODEFLATE, + PROP_REQUIRE_MPPE, + PROP_REQUIRE_MPPE_128, + PROP_MPPE_STATEFUL, + PROP_REQUIRE_MPPC, + PROP_CRTSCTS, + PROP_USEPEERDNS, + PROP_BAUD, + PROP_MRU, + PROP_MTU, + PROP_LCP_ECHO_FAILURE, + PROP_LCP_ECHO_INTERVAL, + + LAST_PROP +}; + +NMSetting * +nm_setting_ppp_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPP, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ +/* NMSettingPPP *self = NM_SETTING_PPP (setting); */ + + /* FIXME: Do we even want this or can we just let pppd evaluate the options? */ + return TRUE; +} + +static void +nm_setting_ppp_init (NMSettingPPP *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_PPP_SETTING_NAME); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingPPP *setting = NM_SETTING_PPP (object); + + switch (prop_id) { + case PROP_NOAUTH: + setting->noauth = g_value_get_boolean (value); + break; + case PROP_REFUSE_EAP: + setting->refuse_eap = g_value_get_boolean (value); + break; + case PROP_REFUSE_CHAP: + setting->refuse_chap = g_value_get_boolean (value); + break; + case PROP_REFUSE_MSCHAP: + setting->refuse_mschap = g_value_get_boolean (value); + break; + case PROP_NOBSDCOMP: + setting->nobsdcomp = g_value_get_boolean (value); + break; + case PROP_NODEFLATE: + setting->nodeflate = g_value_get_boolean (value); + break; + case PROP_REQUIRE_MPPE: + setting->require_mppe = g_value_get_boolean (value); + break; + case PROP_REQUIRE_MPPE_128: + setting->require_mppe_128 = g_value_get_boolean (value); + break; + case PROP_MPPE_STATEFUL: + setting->mppe_stateful = g_value_get_boolean (value); + break; + case PROP_REQUIRE_MPPC: + setting->require_mppc = g_value_get_boolean (value); + break; + case PROP_CRTSCTS: + setting->crtscts = g_value_get_boolean (value); + break; + case PROP_USEPEERDNS: + setting->usepeerdns = g_value_get_boolean (value); + break; + case PROP_BAUD: + setting->baud = g_value_get_uint (value); + break; + case PROP_MRU: + setting->mru = g_value_get_uint (value); + break; + case PROP_MTU: + setting->mtu = g_value_get_uint (value); + break; + case PROP_LCP_ECHO_FAILURE: + setting->lcp_echo_failure = g_value_get_uint (value); + break; + case PROP_LCP_ECHO_INTERVAL: + setting->lcp_echo_interval = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingPPP *setting = NM_SETTING_PPP (object); + + switch (prop_id) { + case PROP_NOAUTH: + g_value_set_boolean (value, setting->noauth); + break; + case PROP_REFUSE_EAP: + g_value_set_boolean (value, setting->refuse_eap); + break; + case PROP_REFUSE_CHAP: + g_value_set_boolean (value, setting->refuse_chap); + break; + case PROP_REFUSE_MSCHAP: + g_value_set_boolean (value, setting->refuse_mschap); + break; + case PROP_NOBSDCOMP: + g_value_set_boolean (value, setting->nobsdcomp); + break; + case PROP_NODEFLATE: + g_value_set_boolean (value, setting->nodeflate); + break; + case PROP_REQUIRE_MPPE: + g_value_set_boolean (value, setting->require_mppe); + break; + case PROP_REQUIRE_MPPE_128: + g_value_set_boolean (value, setting->require_mppe_128); + break; + case PROP_MPPE_STATEFUL: + g_value_set_boolean (value, setting->mppe_stateful); + break; + case PROP_REQUIRE_MPPC: + g_value_set_boolean (value, setting->require_mppc); + break; + case PROP_CRTSCTS: + g_value_set_boolean (value, setting->crtscts); + break; + case PROP_USEPEERDNS: + g_value_set_boolean (value, setting->usepeerdns); + break; + case PROP_BAUD: + g_value_set_uint (value, setting->baud); + break; + case PROP_MRU: + g_value_set_uint (value, setting->mru); + break; + case PROP_MTU: + g_value_set_uint (value, setting->mtu); + break; + case PROP_LCP_ECHO_FAILURE: + g_value_set_uint (value, setting->lcp_echo_failure); + break; + case PROP_LCP_ECHO_INTERVAL: + g_value_set_uint (value, setting->lcp_echo_interval); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_NOAUTH, + g_param_spec_boolean (NM_SETTING_PPP_NOAUTH, + "NoAuth", + "NoAuth", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REFUSE_EAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_EAP, + "Refuse EAP", + "Refuse EAP", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REFUSE_CHAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_CHAP, + "Refuse CHAP", + "Refuse CHAP", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REFUSE_MSCHAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAP, + "Refuse MSCHAP", + "Refuse MSCHAP", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_NOBSDCOMP, + g_param_spec_boolean (NM_SETTING_PPP_NOBSDCOMP, + "No BSD compression", + "No BSD compression", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_NODEFLATE, + g_param_spec_boolean (NM_SETTING_PPP_NODEFLATE, + "No deflate", + "No deflate", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REQUIRE_MPPE, + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE, + "Require MPPE", + "Require MPPE", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REQUIRE_MPPE_128, + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE_128, + "Require MPPE 128", + "Require MPPE 128", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MPPE_STATEFUL, + g_param_spec_boolean (NM_SETTING_PPP_MPPE_STATEFUL, + "MPPE stateful", + "MPPE stateful", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_REQUIRE_MPPC, + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPC, + "Require MPPC", + "Require MPPC", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_CRTSCTS, + g_param_spec_boolean (NM_SETTING_PPP_CRTSCTS, + "CRTSCTS", + "CRTSCTS", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_USEPEERDNS, + g_param_spec_boolean (NM_SETTING_PPP_USEPEERDNS, + "Use peer DNS", + "Use peer DNS", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_BAUD, + g_param_spec_uint (NM_SETTING_PPP_BAUD, + "Baud", + "Baud", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MRU, + g_param_spec_uint (NM_SETTING_PPP_MRU, + "MRU", + "MRU", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_PPP_MTU, + "MTU", + "MTU", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_LCP_ECHO_FAILURE, + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_FAILURE, + "LCP echo failure", + "LCP echo failure", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_LCP_ECHO_INTERVAL, + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_INTERVAL, + "LCP echo interval", + "LCP echo interval", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-ppp.h b/libnm-util/nm-setting-ppp.h new file mode 100644 index 0000000000..c5513e6882 --- /dev/null +++ b/libnm-util/nm-setting-ppp.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_PPP_H +#define NM_SETTING_PPP_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_PPP (nm_setting_ppp_get_type ()) +#define NM_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_PPP, NMSettingPPP)) +#define NM_SETTING_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_PPP, NMSettingPPPClass)) +#define NM_IS_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_PPP)) +#define NM_IS_SETTING_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_PPP)) +#define NM_SETTING_PPP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_PPP, NMSettingPPPClass)) + +#define NM_SETTING_PPP_SETTING_NAME "ppp" + +#define NM_SETTING_PPP_NOAUTH "noauth" +#define NM_SETTING_PPP_REFUSE_EAP "refuse-eap" +#define NM_SETTING_PPP_REFUSE_CHAP "refuse-chap" +#define NM_SETTING_PPP_REFUSE_MSCHAP "refuse-mschap" +#define NM_SETTING_PPP_NOBSDCOMP "nobsdcomp" +#define NM_SETTING_PPP_NODEFLATE "nodeflate" +#define NM_SETTING_PPP_REQUIRE_MPPE "require-mppe" +#define NM_SETTING_PPP_REQUIRE_MPPE_128 "require-mppe-128" +#define NM_SETTING_PPP_MPPE_STATEFUL "mpppe-stateful" +#define NM_SETTING_PPP_REQUIRE_MPPC "require-mppc" +#define NM_SETTING_PPP_CRTSCTS "crtscts" +#define NM_SETTING_PPP_USEPEERDNS "usepeerdns" +#define NM_SETTING_PPP_BAUD "baud" +#define NM_SETTING_PPP_MRU "mru" +#define NM_SETTING_PPP_MTU "mtu" +#define NM_SETTING_PPP_LCP_ECHO_FAILURE "lcp-echo-failure" +#define NM_SETTING_PPP_LCP_ECHO_INTERVAL "lcp-echo-interval" + +typedef struct { + NMSetting parent; + + gboolean noauth; + gboolean refuse_eap; + gboolean refuse_chap; + gboolean refuse_mschap; + gboolean nobsdcomp; + gboolean nodeflate; + gboolean require_mppe; + gboolean require_mppe_128; + gboolean mppe_stateful; + gboolean require_mppc; + gboolean crtscts; + gboolean usepeerdns; + + gint32 baud; + gint32 mru; + gint32 mtu; + gint32 lcp_echo_failure; + gint32 lcp_echo_interval; +} NMSettingPPP; + +typedef struct { + NMSettingClass parent; +} NMSettingPPPClass; + +GType nm_setting_ppp_get_type (void); + +NMSetting *nm_setting_ppp_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_PPP_H */ diff --git a/libnm-util/nm-setting-template.c b/libnm-util/nm-setting-template.c new file mode 100644 index 0000000000..379289bffa --- /dev/null +++ b/libnm-util/nm-setting-template.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-setting-template.h" + +G_DEFINE_TYPE (NMSettingTemplate, nm_setting_template, NM_TYPE_SETTING) + +enum { + PROP_0, + + LAST_PROP +}; + +NMSetting * +nm_setting_template_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_TEMPLATE, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingTemplate *self = NM_SETTING_TEMPLATE (setting); +} + +static void +nm_setting_template_init (NMSettingTemplate *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_TEMPLATE_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingTemplate *self = NM_SETTING_TEMPLATE (object); + + G_OBJECT_CLASS (nm_setting_template_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingTemplate *setting = NM_SETTING_TEMPLATE (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingTemplate *setting = NM_SETTING_TEMPLATE (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_template_class_init (NMSettingTemplateClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ +} diff --git a/libnm-util/nm-setting-template.h b/libnm-util/nm-setting-template.h new file mode 100644 index 0000000000..7e3dde3885 --- /dev/null +++ b/libnm-util/nm-setting-template.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_TEMPLATE_H +#define NM_SETTING_TEMPLATE_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TEMPLATE (nm_setting_template_get_type ()) +#define NM_SETTING_TEMPLATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TEMPLATE, NMSettingTemplate)) +#define NM_SETTING_TEMPLATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_TEMPLATE, NMSettingTemplateClass)) +#define NM_IS_SETTING_TEMPLATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_TEMPLATE)) +#define NM_IS_SETTING_TEMPLATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_TEMPLATE)) +#define NM_SETTING_TEMPLATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_TEMPLATE, NMSettingTemplateClass)) + +#define NM_SETTING_TEMPLATE_SETTING_NAME "template" + +typedef struct { + NMSetting parent; +} NMSettingTemplate; + +typedef struct { + NMSettingClass parent; +} NMSettingTemplateClass; + +GType nm_setting_template_get_type (void); + +NMSetting *nm_setting_template_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_TEMPLATE_H */ diff --git a/libnm-util/nm-setting-vpn-properties.c b/libnm-util/nm-setting-vpn-properties.c new file mode 100644 index 0000000000..20042c71e1 --- /dev/null +++ b/libnm-util/nm-setting-vpn-properties.c @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <dbus/dbus-glib.h> +#include "nm-setting-vpn-properties.h" +#include "nm-param-spec-specialized.h" + +G_DEFINE_TYPE (NMSettingVPNProperties, nm_setting_vpn_properties, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_DATA, + + LAST_PROP +}; + +NMSetting * +nm_setting_vpn_properties_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_VPN_PROPERTIES, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingVPNProperties *self = NM_SETTING_VPN_PROPERTIES (setting); + + if (!self->data) + return FALSE; + + /* FIXME: actually check the data as well */ + + return TRUE; +} + +static void +nm_setting_vpn_properties_init (NMSettingVPNProperties *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_VPN_PROPERTIES_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingVPNProperties *self = NM_SETTING_VPN_PROPERTIES (object); + + g_hash_table_destroy (self->data); + + G_OBJECT_CLASS (nm_setting_vpn_properties_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingVPNProperties *setting = NM_SETTING_VPN_PROPERTIES (object); + + switch (prop_id) { + case PROP_DATA: + if (setting->data) + g_hash_table_destroy (setting->data); + setting->data = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingVPNProperties *setting = NM_SETTING_VPN_PROPERTIES (object); + + switch (prop_id) { + case PROP_DATA: + g_value_set_boxed (value, setting->data); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_vpn_properties_class_init (NMSettingVPNPropertiesClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_DATA, + nm_param_spec_specialized (NM_SETTING_VPN_PROPERTIES_DATA, + "Data", + "VPN Service specific data", + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-vpn-properties.h b/libnm-util/nm-setting-vpn-properties.h new file mode 100644 index 0000000000..8590149563 --- /dev/null +++ b/libnm-util/nm-setting-vpn-properties.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_VPN_PROPERTIES_H +#define NM_SETTING_VPN_PROPERTIES_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_get_type ()) +#define NM_SETTING_VPN_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VPN_PROPERTIES, NMSettingVPNProperties)) +#define NM_SETTING_VPN_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VPN_PROPERTIES, NMSettingVPNPropertiesClass)) +#define NM_IS_SETTING_VPN_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VPN_PROPERTIES)) +#define NM_IS_SETTING_VPN_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_VPN_PROPERTIES)) +#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" +#define NM_SETTING_VPN_PROPERTIES_DATA "data" + +typedef struct { + NMSetting parent; + + GHashTable *data; +} NMSettingVPNProperties; + +typedef struct { + NMSettingClass parent; +} NMSettingVPNPropertiesClass; + +GType nm_setting_vpn_properties_get_type (void); + +NMSetting *nm_setting_vpn_properties_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_VPN_PROPERTIES_H */ diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c new file mode 100644 index 0000000000..e238a46db9 --- /dev/null +++ b/libnm-util/nm-setting-vpn.c @@ -0,0 +1,142 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> +#include <dbus/dbus-glib.h> +#include "nm-setting-vpn.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingVPN, nm_setting_vpn, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_SERVICE_TYPE, + PROP_USER_NAME, + PROP_ROUTES, + + LAST_PROP +}; + +NMSetting * +nm_setting_vpn_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_VPN, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingVPN *self = NM_SETTING_VPN (setting); + + if (!self->service_type || !strlen (self->service_type)) + return FALSE; + + /* default username can be NULL, but can't be zero-length */ + if (self->user_name && !strlen (self->user_name)) + return FALSE; + + return TRUE; +} + +static void +nm_setting_vpn_init (NMSettingVPN *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_VPN_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingVPN *self = NM_SETTING_VPN (object); + + g_free (self->service_type); + g_free (self->user_name); + nm_utils_slist_free (self->routes, g_free); + + G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingVPN *setting = NM_SETTING_VPN (object); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_free (setting->service_type); + setting->service_type = g_value_dup_string (value); + break; + case PROP_USER_NAME: + g_free (setting->user_name); + setting->user_name = g_value_dup_string (value); + break; + case PROP_ROUTES: + nm_utils_slist_free (setting->routes, g_free); + setting->routes = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingVPN *setting = NM_SETTING_VPN (object); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_value_set_string (value, setting->service_type); + break; + case PROP_USER_NAME: + g_value_set_string (value, setting->user_name); + break; + case PROP_ROUTES: + g_value_set_boxed (value, setting->routes); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_SERVICE_TYPE, + g_param_spec_string (NM_SETTING_VPN_SERVICE_TYPE, + "Service type", + "Service type", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_USER_NAME, + g_param_spec_string (NM_SETTING_VPN_USER_NAME, + "User name", + "User name", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_ROUTES, + nm_param_spec_specialized (NM_SETTING_VPN_ROUTES, + "Routes", + "Routes", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h new file mode 100644 index 0000000000..06d8d12bb5 --- /dev/null +++ b/libnm-util/nm-setting-vpn.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_VPN_H +#define NM_SETTING_VPN_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VPN (nm_setting_vpn_get_type ()) +#define NM_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VPN, NMSettingVPN)) +#define NM_SETTING_VPN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VPN, NMSettingVPNClass)) +#define NM_IS_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VPN)) +#define NM_IS_SETTING_VPN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_VPN)) +#define NM_SETTING_VPN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VPN, NMSettingVPNClass)) + +#define NM_SETTING_VPN_SETTING_NAME "vpn" + +#define NM_SETTING_VPN_SERVICE_TYPE "service-type" +#define NM_SETTING_VPN_USER_NAME "user-name" +#define NM_SETTING_VPN_ROUTES "routes" + +typedef struct { + NMSetting parent; + + char *service_type; + char *user_name; + GSList *routes; +} NMSettingVPN; + +typedef struct { + NMSettingClass parent; +} NMSettingVPNClass; + +GType nm_setting_vpn_get_type (void); + +NMSetting *nm_setting_vpn_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_VPN_H */ diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c new file mode 100644 index 0000000000..1cb0da59c9 --- /dev/null +++ b/libnm-util/nm-setting-wired.c @@ -0,0 +1,200 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <dbus/dbus-glib.h> +#include "nm-setting-wired.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_PORT, + PROP_SPEED, + PROP_DUPLEX, + PROP_AUTO_NEGOTIATE, + PROP_MAC_ADDRESS, + PROP_MTU, + + LAST_PROP +}; + +NMSetting * +nm_setting_wired_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRED, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + 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"); + return FALSE; + } + + if (self->duplex && !nm_utils_string_in_list (self->duplex, valid_duplex)) { + g_warning ("Invalid duplex"); + return FALSE; + } + + if (self->mac_address && self->mac_address->len != 6) { + g_warning ("Invalid mac address"); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_wired_init (NMSettingWired *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_WIRED_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingWired *self = NM_SETTING_WIRED (object); + + g_free (self->port); + g_free (self->duplex); + + if (self->mac_address) + g_byte_array_free (self->mac_address, TRUE); + + G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWired *setting = NM_SETTING_WIRED (object); + + switch (prop_id) { + case PROP_PORT: + g_free (setting->port); + setting->port = g_value_dup_string (value); + break; + case PROP_SPEED: + setting->speed = g_value_get_uint (value); + break; + case PROP_DUPLEX: + g_free (setting->port); + setting->duplex = g_value_dup_string (value); + break; + case PROP_AUTO_NEGOTIATE: + setting->auto_negotiate = g_value_get_boolean (value); + break; + case PROP_MAC_ADDRESS: + if (setting->mac_address) + g_byte_array_free (setting->mac_address, TRUE); + setting->mac_address = g_value_dup_boxed (value); + break; + case PROP_MTU: + setting->mtu = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingWired *setting = NM_SETTING_WIRED (object); + + switch (prop_id) { + case PROP_PORT: + g_value_set_string (value, setting->port); + break; + case PROP_SPEED: + g_value_set_uint (value, setting->speed); + break; + case PROP_DUPLEX: + g_value_set_string (value, setting->duplex); + break; + case PROP_AUTO_NEGOTIATE: + g_value_set_boolean (value, setting->auto_negotiate); + break; + case PROP_MAC_ADDRESS: + g_value_set_boxed (value, setting->mac_address); + break; + case PROP_MTU: + g_value_set_uint (value, setting->mtu); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wired_class_init (NMSettingWiredClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_PORT, + g_param_spec_string (NM_SETTING_WIRED_PORT, + "Port", + "Port type", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_SPEED, + g_param_spec_uint (NM_SETTING_WIRED_SPEED, + "Speed", + "Speed", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DUPLEX, + g_param_spec_string (NM_SETTING_WIRED_DUPLEX, + "Duplex", + "Duplex", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_AUTO_NEGOTIATE, + g_param_spec_boolean (NM_SETTING_WIRED_AUTO_NEGOTIATE, + "AutoNegotiate", + "Auto negotiate", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS, + "MAC Address", + "Harware address", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_WIRED_MTU, + "MTU", + "MTU", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} + diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h new file mode 100644 index 0000000000..0cee177539 --- /dev/null +++ b/libnm-util/nm-setting-wired.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_WIRED_H +#define NM_SETTING_WIRED_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRED (nm_setting_wired_get_type ()) +#define NM_SETTING_WIRED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRED, NMSettingWired)) +#define NM_SETTING_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) +#define NM_IS_SETTING_WIRED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRED)) +#define NM_IS_SETTING_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_WIRED)) +#define NM_SETTING_WIRED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) + +#define NM_SETTING_WIRED_SETTING_NAME "802-3-ethernet" + +#define NM_SETTING_WIRED_PORT "port" +#define NM_SETTING_WIRED_SPEED "speed" +#define NM_SETTING_WIRED_DUPLEX "duplex" +#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate" +#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRED_MTU "mtu" + +typedef struct { + NMSetting parent; + + char *port; + guint32 speed; + char *duplex; + gboolean auto_negotiate; + GByteArray *mac_address; + guint32 mtu; +} NMSettingWired; + +typedef struct { + NMSettingClass parent; +} NMSettingWiredClass; + +GType nm_setting_wired_get_type (void); + +NMSetting *nm_setting_wired_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_WIRED_H */ diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c new file mode 100644 index 0000000000..133dde084a --- /dev/null +++ b/libnm-util/nm-setting-wireless-security.c @@ -0,0 +1,982 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> +#include <ctype.h> +#include <dbus/dbus-glib.h> +#include "nm-setting-wireless-security.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_KEY_MGMT, + PROP_WEP_TX_KEYIDX, + PROP_AUTH_ALG, + PROP_PROTO, + PROP_PAIRWISE, + PROP_GROUP, + PROP_EAP, + PROP_IDENTITY, + PROP_ANONYMOUS_IDENTITY, + PROP_CA_CERT, + PROP_CA_PATH, + PROP_CLIENT_CERT, + PROP_PRIVATE_KEY, + PROP_PHASE1_PEAPVER, + PROP_PHASE1_PEAPLABEL, + PROP_PHASE1_FAST_PROVISIONING, + PROP_PHASE2_AUTH, + PROP_PHASE2_AUTHEAP, + PROP_PHASE2_CA_CERT, + PROP_PHASE2_CA_PATH, + PROP_PHASE2_CLIENT_CERT, + PROP_PHASE2_PRIVATE_KEY, + PROP_PHASE2_PRIVATE_KEY_PASSWD, + PROP_NAI, + PROP_WEP_KEY0, + PROP_WEP_KEY1, + PROP_WEP_KEY2, + PROP_WEP_KEY3, + PROP_PSK, + PROP_PASSWORD, + PROP_PIN, + PROP_EAPPSK, + PROP_PRIVATE_KEY_PASSWD, + + LAST_PROP +}; + +NMSetting * +nm_setting_wireless_security_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); + const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL }; + const char *valid_auth_algs[] = { "open", "shared", "leap", NULL }; + const char *valid_protos[] = { "wpa", "rsn", NULL }; + const char *valid_pairwise[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; + const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; + const char *valid_phase1_peapver[] = { "0", "1", NULL }; + + /* Every time a method gets added to the following, add one to EAPMethodNeedSecretsTable */ + const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "psk", "fast", NULL }; + const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL }; + const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL }; + + if (!self->key_mgmt || !nm_utils_string_in_list (self->key_mgmt, valid_key_mgmt)) { + g_warning ("Missing or invalid key management"); + return FALSE; + } + + if (self->wep_tx_keyidx > 3) { + g_warning ("Invalid WEP key index"); + return FALSE; + } + + if (self->auth_alg && !nm_utils_string_in_list (self->auth_alg, valid_auth_algs)) { + g_warning ("Invalid authentication algorithm"); + return FALSE; + } + + if (self->proto && !nm_utils_string_slist_validate (self->proto, valid_protos)) { + g_warning ("Invalid authentication protocol"); + return FALSE; + } + + if (self->pairwise && !nm_utils_string_slist_validate (self->pairwise, valid_pairwise)) { + g_warning ("Invalid pairwise"); + return FALSE; + } + + if (self->group && !nm_utils_string_slist_validate (self->group, valid_groups)) { + g_warning ("Invalid group"); + return FALSE; + } + + if (self->eap && !nm_utils_string_slist_validate (self->eap, valid_eap)) { + g_warning ("Invalid eap"); + return FALSE; + } + + if (self->phase1_peapver && !nm_utils_string_in_list (self->phase1_peapver, valid_phase1_peapver)) { + g_warning ("Invalid phase1 peapver"); + return FALSE; + } + + if (self->phase1_peaplabel && strcmp (self->phase1_peaplabel, "1")) { + g_warning ("Invalid phase1 peaplabel"); + return FALSE; + } + + if (self->phase1_fast_provisioning && strcmp (self->phase1_fast_provisioning, "1")) { + g_warning ("Invalid 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"); + return FALSE; + } + + if (self->phase2_autheap && !nm_utils_string_in_list (self->phase2_autheap, valid_phase2_autheap)) { + g_warning ("Invalid phase2 autheap"); + return FALSE; + } + + /* FIXME: finish */ + + return TRUE; +} + +static gboolean +verify_wep_key (const char *key) +{ + int keylen, i; + + if (!key) + return FALSE; + + keylen = strlen (key); + if (keylen != 10 && keylen != 26) + return FALSE; + + for (i = 0; i < keylen; i++) { + if (!isxdigit (key[i])) + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_wpa_psk (const char *psk) +{ + int psklen, i; + + if (!psk) + return FALSE; + + psklen = strlen (psk); + if (psklen != 64) + return FALSE; + + for (i = 0; i < psklen; i++) { + if (!isxdigit (psk[i])) + return FALSE; + } + + return TRUE; +} + +static void +need_secrets_password (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2) +{ + if (!self->password || !strlen (self->password)) + g_ptr_array_add (secrets, "password"); +} + +static void +need_secrets_eappsk (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2) +{ + if (!self->eappsk || !strlen (self->eappsk)) + g_ptr_array_add (secrets, "eappsk"); +} + +static void +need_secrets_sim (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2) +{ + if (!self->pin || !strlen (self->pin)) + g_ptr_array_add (secrets, "eappsk"); +} + +static void +need_secrets_tls (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2) +{ + if (phase2) { + if (!self->phase2_private_key_passwd || !strlen (self->phase2_private_key_passwd)) + g_ptr_array_add (secrets, "phase2-private-key-passwd"); + } else { + if (!self->private_key_passwd || !strlen (self->private_key_passwd)) + g_ptr_array_add (secrets, "private-key-passwd"); + } +} + +/* Implemented below... */ +static void need_secrets_phase2 (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2); + + +typedef void (*EAPMethodNeedSecretsFunc) (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2); + +typedef struct { + const char *method; + EAPMethodNeedSecretsFunc func; +} EAPMethodNeedSecretsTable; + +static EAPMethodNeedSecretsTable eap_need_secrets_table[] = { + { "leap", need_secrets_password }, + { "md5", need_secrets_password }, + { "pap", need_secrets_password }, + { "chap", need_secrets_password }, + { "mschap", need_secrets_password }, + { "mschapv2", need_secrets_password }, + { "fast", need_secrets_password }, + { "psk", need_secrets_eappsk }, + { "pax", need_secrets_eappsk }, + { "sake", need_secrets_eappsk }, + { "gpsk", need_secrets_eappsk }, + { "tls", need_secrets_tls }, + { "peap", need_secrets_phase2 }, + { "ttls", need_secrets_phase2 }, + { "sim", need_secrets_sim }, + { "gtc", NULL }, // FIXME: implement + { "otp", NULL }, // FIXME: implement + { NULL, NULL } +}; + +static void +need_secrets_phase2 (NMSettingWirelessSecurity *self, + GPtrArray *secrets, + gboolean phase2) +{ + char *method = NULL; + int i; + + g_return_if_fail (phase2 == FALSE); + + /* Check phase2_auth and phase2_autheap */ + method = self->phase2_auth; + if (!method && self->phase2_autheap) + method = self->phase2_autheap; + + if (!method) { + g_warning ("Couldn't find EAP method."); + g_assert_not_reached(); + return; + } + + /* Ask the configured phase2 method if it needs secrets */ + for (i = 0; eap_need_secrets_table[i].method; i++) { + if (eap_need_secrets_table[i].func == NULL) + continue; + if (strcmp (eap_need_secrets_table[i].method, method)) { + (*eap_need_secrets_table[i].func) (self, secrets, TRUE); + break; + } + } +} + + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); + GPtrArray *secrets; + + secrets = g_ptr_array_sized_new (4); + if (!secrets) { + g_warning ("Not enough memory to create required secrets array."); + return NULL; + } + + g_assert (self->key_mgmt); + + /* Static WEP */ + if (strcmp (self->key_mgmt, "none") == 0) { + if (!verify_wep_key (self->wep_key0)) { + g_ptr_array_add (secrets, "wep-key0"); + return secrets; + } + if (self->wep_tx_keyidx == 1 && !verify_wep_key (self->wep_key1)) { + g_ptr_array_add (secrets, "wep-key1"); + return secrets; + } + if (self->wep_tx_keyidx == 2 && !verify_wep_key (self->wep_key2)) { + g_ptr_array_add (secrets, "wep-key2"); + return secrets; + } + if (self->wep_tx_keyidx == 3 && !verify_wep_key (self->wep_key3)) { + g_ptr_array_add (secrets, "wep-key3"); + return secrets; + } + goto no_secrets; + } + + /* WPA-PSK infrastructure and adhoc */ + if ( (strcmp (self->key_mgmt, "wpa-none") == 0) + || (strcmp (self->key_mgmt, "wpa-psk") == 0)) { + if (!verify_wpa_psk (self->psk)) { + g_ptr_array_add (secrets, "psk"); + return secrets; + } + goto no_secrets; + } + + /* LEAP */ + if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) + && self->auth_alg + && (strcmp (self->auth_alg, "leap") == 0) + && (nm_utils_string_list_contains (self->eap, "leap"))) { + if (!self->password || !strlen (self->password)) { + g_ptr_array_add (secrets, "password"); + return secrets; + } + goto no_secrets; + } + + if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) + || (strcmp (self->key_mgmt, "wpa-eap") == 0)) { + GSList *iter; + gboolean eap_method_found = FALSE; + + /* Ask each configured EAP method if it needs secrets */ + for (iter = self->eap; iter && !eap_method_found; iter = g_slist_next (iter)) { + const char *method = (const char *) iter->data; + int i; + + for (i = 0; eap_need_secrets_table[i].method; i++) { + if (eap_need_secrets_table[i].func == NULL) + continue; + if (!strcmp (eap_need_secrets_table[i].method, method)) { + (*eap_need_secrets_table[i].func) (self, secrets, FALSE); + + /* Only break out of the outer loop if this EAP method + * needed secrets. + */ + if (secrets->len > 0) + eap_method_found = TRUE; + break; + } + } + } + + if (secrets->len) + return secrets; + goto no_secrets; + } + + g_assert_not_reached (); + return secrets; + +no_secrets: + if (secrets) + g_ptr_array_free (secrets, TRUE); + return NULL; +} + +static void +nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (object); + + /* Strings first. g_free() already checks for NULLs so we don't have to */ + + g_free (self->key_mgmt); + g_free (self->auth_alg); + g_free (self->identity); + g_free (self->anonymous_identity); + g_free (self->ca_path); + g_free (self->phase1_peapver); + g_free (self->phase1_peaplabel); + g_free (self->phase1_fast_provisioning); + g_free (self->phase2_auth); + g_free (self->phase2_autheap); + g_free (self->phase2_ca_path); + g_free (self->nai); + g_free (self->wep_key0); + g_free (self->wep_key1); + g_free (self->wep_key2); + g_free (self->wep_key3); + g_free (self->psk); + g_free (self->password); + g_free (self->pin); + g_free (self->eappsk); + g_free (self->private_key_passwd); + g_free (self->phase2_private_key_passwd); + + nm_utils_slist_free (self->proto, g_free); + nm_utils_slist_free (self->pairwise, g_free); + nm_utils_slist_free (self->group, g_free); + nm_utils_slist_free (self->eap, g_free); + + if (self->ca_cert) + g_byte_array_free (self->ca_cert, TRUE); + if (self->client_cert) + g_byte_array_free (self->client_cert, TRUE); + if (self->private_key) + g_byte_array_free (self->private_key, TRUE); + if (self->phase2_ca_cert) + g_byte_array_free (self->phase2_ca_cert, TRUE); + if (self->phase2_client_cert) + g_byte_array_free (self->phase2_client_cert, TRUE); + if (self->phase2_private_key) + g_byte_array_free (self->phase2_private_key, TRUE); + + G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); + + switch (prop_id) { + case PROP_KEY_MGMT: + g_free (setting->key_mgmt); + setting->key_mgmt = g_value_dup_string (value); + break; + case PROP_WEP_TX_KEYIDX: + setting->wep_tx_keyidx = g_value_get_uint (value); + break; + case PROP_AUTH_ALG: + g_free (setting->auth_alg); + setting->auth_alg = g_value_dup_string (value); + break; + case PROP_PROTO: + nm_utils_slist_free (setting->proto, g_free); + setting->proto = g_value_dup_boxed (value); + break; + case PROP_PAIRWISE: + nm_utils_slist_free (setting->pairwise, g_free); + setting->pairwise = g_value_dup_boxed (value); + break; + case PROP_GROUP: + nm_utils_slist_free (setting->group, g_free); + setting->group = g_value_dup_boxed (value); + break; + case PROP_EAP: + nm_utils_slist_free (setting->eap, g_free); + setting->eap = g_value_dup_boxed (value); + break; + case PROP_IDENTITY: + g_free (setting->identity); + setting->identity = g_value_dup_string (value); + break; + case PROP_ANONYMOUS_IDENTITY: + g_free (setting->anonymous_identity); + setting->anonymous_identity = g_value_dup_string (value); + break; + case PROP_CA_CERT: + if (setting->ca_cert) + g_byte_array_free (setting->ca_cert, TRUE); + setting->ca_cert = g_value_dup_boxed (value); + break; + case PROP_CA_PATH: + g_free (setting->ca_path); + setting->ca_path = g_value_dup_string (value); + break; + case PROP_CLIENT_CERT: + if (setting->client_cert) + g_byte_array_free (setting->client_cert, TRUE); + setting->client_cert = g_value_dup_boxed (value); + break; + case PROP_PRIVATE_KEY: + if (setting->private_key) + g_byte_array_free (setting->private_key, TRUE); + setting->private_key = g_value_dup_boxed (value); + break; + case PROP_PHASE1_PEAPVER: + g_free (setting->phase1_peapver); + setting->phase1_peapver = g_value_dup_string (value); + break; + case PROP_PHASE1_PEAPLABEL: + g_free (setting->phase1_peaplabel); + setting->phase1_peaplabel = g_value_dup_string (value); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_free (setting->phase1_fast_provisioning); + setting->phase1_fast_provisioning = g_value_dup_string (value); + break; + case PROP_PHASE2_AUTH: + g_free (setting->phase2_auth); + setting->phase2_auth = g_value_dup_string (value); + break; + case PROP_PHASE2_AUTHEAP: + g_free (setting->phase2_autheap); + setting->phase2_autheap = g_value_dup_string (value); + break; + case PROP_PHASE2_CA_CERT: + if (setting->phase2_ca_cert) + g_byte_array_free (setting->phase2_ca_cert, TRUE); + setting->phase2_ca_cert = g_value_dup_boxed (value); + break; + case PROP_PHASE2_CA_PATH: + g_free (setting->phase2_ca_path); + setting->phase2_ca_path = g_value_dup_string (value); + break; + case PROP_PHASE2_CLIENT_CERT: + if (setting->phase2_client_cert) + g_byte_array_free (setting->phase2_client_cert, TRUE); + setting->phase2_client_cert = g_value_dup_boxed (value); + break; + case PROP_PHASE2_PRIVATE_KEY: + if (setting->phase2_private_key) + g_byte_array_free (setting->phase2_private_key, TRUE); + setting->phase2_private_key = g_value_dup_boxed (value); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWD: + g_free (setting->phase2_private_key_passwd); + setting->phase2_private_key_passwd = g_value_dup_string (value); + break; + case PROP_NAI: + g_free (setting->nai); + setting->nai = g_value_dup_string (value); + break; + case PROP_WEP_KEY0: + g_free (setting->wep_key0); + setting->wep_key0 = g_value_dup_string (value); + break; + case PROP_WEP_KEY1: + g_free (setting->wep_key1); + setting->wep_key1 = g_value_dup_string (value); + break; + case PROP_WEP_KEY2: + g_free (setting->wep_key2); + setting->wep_key2 = g_value_dup_string (value); + break; + case PROP_WEP_KEY3: + g_free (setting->wep_key3); + setting->wep_key3 = g_value_dup_string (value); + break; + case PROP_PSK: + g_free (setting->psk); + setting->psk = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (setting->password); + setting->password = g_value_dup_string (value); + break; + case PROP_PIN: + g_free (setting->pin); + setting->pin = g_value_dup_string (value); + break; + case PROP_EAPPSK: + g_free (setting->eappsk); + setting->eappsk = g_value_dup_string (value); + break; + case PROP_PRIVATE_KEY_PASSWD: + g_free (setting->private_key_passwd); + setting->private_key_passwd = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); + + switch (prop_id) { + case PROP_KEY_MGMT: + g_value_set_string (value, setting->key_mgmt); + break; + case PROP_WEP_TX_KEYIDX: + g_value_set_uint (value, setting->wep_tx_keyidx); + break; + case PROP_AUTH_ALG: + g_value_set_string (value, setting->auth_alg); + break; + case PROP_PROTO: + g_value_set_boxed (value, setting->proto); + break; + case PROP_PAIRWISE: + g_value_set_boxed (value, setting->pairwise); + break; + case PROP_GROUP: + g_value_set_boxed (value, setting->group); + break; + case PROP_EAP: + g_value_set_boxed (value, setting->eap); + break; + case PROP_IDENTITY: + g_value_set_string (value, setting->identity); + break; + case PROP_ANONYMOUS_IDENTITY: + g_value_set_string (value, setting->anonymous_identity); + break; + case PROP_CA_CERT: + g_value_set_boxed (value, setting->ca_cert); + break; + case PROP_CA_PATH: + g_value_set_string (value, setting->ca_path); + break; + case PROP_CLIENT_CERT: + g_value_set_boxed (value, setting->client_cert); + break; + case PROP_PRIVATE_KEY: + g_value_set_boxed (value, setting->private_key); + break; + case PROP_PHASE1_PEAPVER: + g_value_set_string (value, setting->phase1_peapver); + break; + case PROP_PHASE1_PEAPLABEL: + g_value_set_string (value, setting->phase1_peaplabel); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_value_set_string (value, setting->phase1_fast_provisioning); + break; + case PROP_PHASE2_AUTH: + g_value_set_string (value, setting->phase2_auth); + break; + case PROP_PHASE2_AUTHEAP: + g_value_set_string (value, setting->phase2_autheap); + break; + case PROP_PHASE2_CA_CERT: + g_value_set_boxed (value, setting->phase2_ca_cert); + break; + case PROP_PHASE2_CA_PATH: + g_value_set_string (value, setting->phase2_ca_path); + break; + case PROP_PHASE2_CLIENT_CERT: + g_value_set_boxed (value, setting->phase2_client_cert); + break; + case PROP_PHASE2_PRIVATE_KEY: + g_value_set_boxed (value, setting->phase2_private_key); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWD: + g_value_set_string (value, setting->phase2_private_key_passwd); + break; + case PROP_NAI: + g_value_set_string (value, setting->nai); + break; + case PROP_WEP_KEY0: + g_value_set_string (value, setting->wep_key0); + break; + case PROP_WEP_KEY1: + g_value_set_string (value, setting->wep_key1); + break; + case PROP_WEP_KEY2: + g_value_set_string (value, setting->wep_key2); + break; + case PROP_WEP_KEY3: + g_value_set_string (value, setting->wep_key3); + break; + case PROP_PSK: + g_value_set_string (value, setting->psk); + break; + case PROP_PASSWORD: + g_value_set_string (value, setting->password); + break; + case PROP_PIN: + g_value_set_string (value, setting->pin); + break; + case PROP_EAPPSK: + g_value_set_string (value, setting->eappsk); + break; + case PROP_PRIVATE_KEY_PASSWD: + g_value_set_string (value, setting->private_key_passwd); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_KEY_MGMT, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "Key management", + "Key management", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_REQUIRED)); + + g_object_class_install_property + (object_class, PROP_WEP_TX_KEYIDX, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + "WEP TX key index", + "WEP TX key index", + 0, 3, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_AUTH_ALG, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "AuthAlg", + "AuthAlg", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PROTO, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PROTO, + "Proto", + "Proto", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PAIRWISE, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, + "Pairwise", + "Pairwise", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_GROUP, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_GROUP, + "Group", + "Group", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_EAP, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_EAP, + "EAP", + "EAP", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_IDENTITY, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_IDENTITY, + "Identity", + "Identity", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_ANONYMOUS_IDENTITY, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_ANONYMOUS_IDENTITY, + "Anonymous identity", + "Anonymous identity", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_CA_CERT, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_CA_CERT, + "CA certificate", + "CA certificate", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_CA_PATH, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_CA_PATH, + "CA path", + "CA path", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_CLIENT_CERT, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_CLIENT_CERT, + "Client certificate", + "Client certificate", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY, + "Private key", + "Private key", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE1_PEAPVER, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPVER, + "Phase1 PEAPVER", + "Phase1 PEAPVER", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE1_PEAPLABEL, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPLABEL, + "Phase1 PEAP label", + "Phase2 PEAP label", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE1_FAST_PROVISIONING, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_FAST_PROVISIONING, + "Phase1 fast provisioning", + "Phase1 fast provisioning", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_AUTH, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTH, + "Phase2 auth", + "Phase2 auth", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_AUTHEAP, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTHEAP, + "Phase2 autheap", + "Phase2 autheap", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_CA_CERT, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_CERT, + "Phase2 CA certificate", + "Phase2 CA certificate", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_CA_PATH, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_PATH, + "Phase2 auth CA path", + "Phase2 auth CA path", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_CLIENT_CERT, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_CLIENT_CERT, + "Phase2 client certificate", + "Phase2 client certificate", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY, + "Phase2 private key", + "Phase2 private key", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWD, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY_PASSWD, + "Phase2 private key password", + "Phase2 private key password", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_NAI, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_NAI, + "NAI", + "NAI", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_WEP_KEY0, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "WEP key0", + "WEP key0", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_WEP_KEY1, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, + "WEP key1", + "WEP key1", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_WEP_KEY2, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, + "WEP key2", + "WEP key2", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_WEP_KEY3, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, + "WEP key3", + "WEP key3", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_PSK, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, + "PSK", + "PSK", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PASSWORD, + "Password", + "Password", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_PIN, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PIN, + "PIN", + "PIN", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_EAPPSK, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_EAPPSK, + "EAPPSK", + "EAPPSK", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY_PASSWD, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY_PASSWD, + "Private key password", + "Private key password", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); +} diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h new file mode 100644 index 0000000000..fa5c0b6847 --- /dev/null +++ b/libnm-util/nm-setting-wireless-security.h @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_WIRELESS_SECURITY_H +#define NM_SETTING_WIRELESS_SECURITY_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_get_type ()) +#define NM_SETTING_WIRELESS_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurity)) +#define NM_SETTING_WIRELESS_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelesSsecurityClass)) +#define NM_IS_SETTING_WIRELESS_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_IS_SETTING_WIRELESS_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_SETTING_WIRELESS_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityClass)) + +#define NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "802-11-wireless-security" + +#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" +#define NM_SETTING_WIRELESS_SECURITY_PROTO "proto" +#define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise" +#define NM_SETTING_WIRELESS_SECURITY_GROUP "group" +#define NM_SETTING_WIRELESS_SECURITY_EAP "eap" +#define NM_SETTING_WIRELESS_SECURITY_IDENTITY "identity" +#define NM_SETTING_WIRELESS_SECURITY_ANONYMOUS_IDENTITY "anonymous-identity" +#define NM_SETTING_WIRELESS_SECURITY_CA_CERT "ca-cert" +#define NM_SETTING_WIRELESS_SECURITY_CA_PATH "ca-path" +#define NM_SETTING_WIRELESS_SECURITY_CLIENT_CERT "client-cert" +#define NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY "private-key" +#define NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPVER "phase1-peapver" +#define NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPLABEL "phase1-peaplabel" +#define NM_SETTING_WIRELESS_SECURITY_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTH "phase2-auth" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTHEAP "phase2-autheap" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_CERT "phase2-ca-cert" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_PATH "phase2-ca-path" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CLIENT_CERT "phase2-client-cert" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY "phase2-private-key" +#define NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY_PASSWD "phase2-private-key-passwd" +#define NM_SETTING_WIRELESS_SECURITY_NAI "nai" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" +#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" +#define NM_SETTING_WIRELESS_SECURITY_PASSWORD "password" +#define NM_SETTING_WIRELESS_SECURITY_PIN "pin" +#define NM_SETTING_WIRELESS_SECURITY_EAPPSK "eappsk" +#define NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY_PASSWD "private-key-passwd" + +typedef struct { + NMSetting parent; + + char *key_mgmt; + guint32 wep_tx_keyidx; + char *auth_alg; + GSList *proto; /* GSList of strings */ + GSList *pairwise; /* GSList of strings */ + GSList *group; /* GSList of strings */ + GSList *eap; /* GSList of strings */ + char *identity; + char *anonymous_identity; + GByteArray *ca_cert; + char *ca_path; + GByteArray *client_cert; + GByteArray *private_key; + char *phase1_peapver; + char *phase1_peaplabel; + char *phase1_fast_provisioning; + char *phase2_auth; + char *phase2_autheap; + GByteArray *phase2_ca_cert; + char *phase2_ca_path; + GByteArray *phase2_client_cert; + GByteArray *phase2_private_key; + char *nai; + char *wep_key0; + char *wep_key1; + char *wep_key2; + char *wep_key3; + char *psk; + char *password; + char *pin; + char *eappsk; + char *private_key_passwd; + char *phase2_private_key_passwd; +} NMSettingWirelessSecurity; + +typedef struct { + NMSettingClass parent; +} NMSettingWirelessSecurityClass; + +GType nm_setting_wireless_security_get_type (void); + +NMSetting *nm_setting_wireless_security_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_WIRELESS_SECURITY_H */ diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c new file mode 100644 index 0000000000..0139f8aa03 --- /dev/null +++ b/libnm-util/nm-setting-wireless.c @@ -0,0 +1,508 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> +#include <netinet/ether.h> +#include <dbus/dbus-glib.h> +#include <iwlib.h> +#include <wireless.h> +#include "NetworkManager.h" + +#include "nm-setting-wireless.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_SSID, + PROP_MODE, + PROP_BAND, + PROP_CHANNEL, + PROP_BSSID, + PROP_RATE, + PROP_TX_POWER, + PROP_MAC_ADDRESS, + PROP_MTU, + PROP_SEEN_BSSIDS, + PROP_SEC, + + LAST_PROP +}; + +static gboolean +match_cipher (const char *cipher, + const char *expected, + guint32 wpa_flags, + guint32 rsn_flags, + guint32 flag) +{ + if (strcmp (cipher, expected) != 0) + return FALSE; + + if (!(wpa_flags & flag) && !(rsn_flags & flag)) + return FALSE; + + return TRUE; +} + +gboolean +nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + guint32 ap_flags, + guint32 ap_wpa, + guint32 ap_rsn, + guint32 ap_mode) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (s_wireless), FALSE); + + if (!s_wireless->security) { + if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + if (strcmp (s_wireless->security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0) + return FALSE; + + if (s_wireless_sec == NULL || !s_wireless_sec->key_mgmt) + return FALSE; + + /* Static WEP */ + if (!strcmp (s_wireless_sec->key_mgmt, "none")) { + if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + /* Adhoc WPA */ + if (!strcmp (s_wireless_sec->key_mgmt, "wpa-none")) { + if (ap_mode != IW_MODE_ADHOC) + return FALSE; + // FIXME: validate ciphers if the BSSID actually puts WPA/RSN IE in + // it's beacon + return TRUE; + } + + /* Stuff after this point requires infrastructure */ + if (ap_mode != IW_MODE_INFRA) + return FALSE; + + /* Dynamic WEP or LEAP */ + if (!strcmp (s_wireless_sec->key_mgmt, "ieee8021x")) { + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + + /* If the AP is advertising a WPA IE, make sure it supports WEP ciphers */ + if (ap_wpa != NM_802_11_AP_SEC_NONE) { + gboolean found = FALSE; + GSList *iter; + + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + + /* quick check; can't use AP if it doesn't support at least one + * WEP cipher in both pairwise and group suites. + */ + if ( !(ap_wpa & (NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104)) + || !(ap_wpa & (NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104))) + return FALSE; + + /* Match at least one pairwise cipher with AP's capability */ + for (iter = s_wireless_sec->pairwise; iter; iter = g_slist_next (iter)) { + if ((found = match_cipher (iter->data, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP40))) + break; + if ((found = match_cipher (iter->data, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP104))) + break; + } + if (!found) + return FALSE; + + /* Match at least one group cipher with AP's capability */ + for (iter = s_wireless_sec->group; iter; iter = g_slist_next (iter)) { + if ((found = match_cipher (iter->data, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = match_cipher (iter->data, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP104))) + break; + } + if (!found) + return FALSE; + } + return TRUE; + } + + /* WPA[2]-PSK and WPA[2] Enterprise */ + if ( !strcmp (s_wireless_sec->key_mgmt, "wpa-psk") + || !strcmp (s_wireless_sec->key_mgmt, "wpa-eap")) { + GSList * elt; + gboolean found = FALSE; + + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + + if (!s_wireless_sec->pairwise || !s_wireless_sec->group) + return FALSE; + + if (!strcmp (s_wireless_sec->key_mgmt, "wpa-psk")) { + if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + return FALSE; + } else if (!strcmp (s_wireless_sec->key_mgmt, "wpa-eap")) { + if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + } + + // FIXME: should handle WPA and RSN separately here to ensure that + // if the Connection only uses WPA we don't match a cipher against + // the AP's RSN IE instead + + /* Match at least one pairwise cipher with AP's capability */ + for (elt = s_wireless_sec->pairwise; elt; elt = g_slist_next (elt)) { + if ((found = match_cipher (elt->data, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_TKIP))) + break; + if ((found = match_cipher (elt->data, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_CCMP))) + break; + } + if (!found) + return FALSE; + + /* Match at least one group cipher with AP's capability */ + for (elt = s_wireless_sec->group; elt; elt = g_slist_next (elt)) { + if ((found = match_cipher (elt->data, "wep40", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = match_cipher (elt->data, "wep104", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP104))) + break; + if ((found = match_cipher (elt->data, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_TKIP))) + break; + if ((found = match_cipher (elt->data, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_CCMP))) + break; + } + if (!found) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +NMSetting * +nm_setting_wireless_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS, NULL); +} + +static gint +find_setting_by_name (gconstpointer a, gconstpointer b) +{ + NMSetting *setting = NM_SETTING (a); + const char *str = (const char *) b; + + return strcmp (nm_setting_get_name (setting), str); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + 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"); + return FALSE; + } + + if (self->mode && !nm_utils_string_in_list (self->mode, valid_modes)) { + g_warning ("Invalid mode. Should be either 'infrastructure' or 'adhoc'"); + return FALSE; + } + + if (self->band && !nm_utils_string_in_list (self->band, valid_bands)) { + g_warning ("Invalid band. Should be either 'a' or 'bg'"); + return FALSE; + } + + if (self->channel && !self->band) { + g_warning ("Channel was provided without band"); + return FALSE; + } + + if (self->channel) { + if (!strcmp (self->band, "a")) { + int i; + int valid_channels[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 0 }; + + for (i = 0; valid_channels[i]; i++) { + if (self->channel == valid_channels[i]) + break; + } + + if (valid_channels[i] == 0) { + g_warning ("Invalid channel"); + return FALSE; + } + } else if (!strcmp (self->band, "bg") && self->channel > 14) { + g_warning ("Invalid channel"); + return FALSE; + } + } + + if (self->bssid && self->bssid->len != 6) { + g_warning ("Invalid bssid"); + return FALSE; + } + + if (self->mac_address && self->mac_address->len != 6) { + g_warning ("Invalid mac address"); + return FALSE; + } + + for (iter = self->seen_bssids; iter; iter = iter->next) { + struct ether_addr addr; + + if (!ether_aton_r (iter->data, &addr)) { + g_warning ("Invalid bssid"); + return FALSE; + } + } + + if (self->security && + all_settings && + !g_slist_find_custom (all_settings, self->security, find_setting_by_name)) { + g_warning ("Invalid or missing security"); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_wireless_init (NMSettingWireless *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_WIRELESS_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingWireless *self = NM_SETTING_WIRELESS (object); + + g_free (self->mode); + g_free (self->band); + g_free (self->security); + + if (self->ssid) + g_byte_array_free (self->ssid, TRUE); + if (self->bssid) + g_byte_array_free (self->bssid, TRUE); + if (self->mac_address) + g_byte_array_free (self->mac_address, TRUE); + + nm_utils_slist_free (self->seen_bssids, g_free); + + G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWireless *setting = NM_SETTING_WIRELESS (object); + + switch (prop_id) { + case PROP_SSID: + if (setting->ssid) + g_byte_array_free (setting->ssid, TRUE); + setting->ssid = g_value_dup_boxed (value); + break; + case PROP_MODE: + g_free (setting->mode); + setting->mode = g_value_dup_string (value); + break; + case PROP_BAND: + g_free (setting->band); + setting->band = g_value_dup_string (value); + break; + case PROP_CHANNEL: + setting->channel = g_value_get_uint (value); + break; + case PROP_BSSID: + if (setting->bssid) + g_byte_array_free (setting->bssid, TRUE); + setting->bssid = g_value_dup_boxed (value); + break; + case PROP_RATE: + setting->rate = g_value_get_uint (value); + break; + case PROP_TX_POWER: + setting->tx_power = g_value_get_uint (value); + break; + case PROP_MAC_ADDRESS: + if (setting->mac_address) + g_byte_array_free (setting->mac_address, TRUE); + setting->mac_address = g_value_dup_boxed (value); + break; + case PROP_MTU: + setting->mtu = g_value_get_uint (value); + break; + case PROP_SEEN_BSSIDS: + nm_utils_slist_free (setting->seen_bssids, g_free); + setting->seen_bssids = g_value_dup_boxed (value); + break; + case PROP_SEC: + g_free (setting->security); + setting->security = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingWireless *setting = NM_SETTING_WIRELESS (object); + + switch (prop_id) { + case PROP_SSID: + g_value_set_boxed (value, setting->ssid); + break; + case PROP_MODE: + g_value_set_string (value, setting->mode); + break; + case PROP_BAND: + g_value_set_string (value, setting->band); + break; + case PROP_CHANNEL: + g_value_set_uint (value, setting->channel); + break; + case PROP_BSSID: + g_value_set_boxed (value, setting->bssid); + break; + case PROP_RATE: + g_value_set_uint (value, setting->rate); + break; + case PROP_TX_POWER: + g_value_set_uint (value, setting->tx_power); + break; + case PROP_MAC_ADDRESS: + g_value_set_boxed (value, setting->mac_address); + break; + case PROP_MTU: + g_value_set_uint (value, setting->mtu); + break; + case PROP_SEEN_BSSIDS: + g_value_set_boxed (value, setting->seen_bssids); + break; + case PROP_SEC: + g_value_set_string (value, setting->security); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_SSID, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SSID, + "SSID", + "SSID", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_string (NM_SETTING_WIRELESS_MODE, + "Mode", + "Mode", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_BAND, + g_param_spec_string (NM_SETTING_WIRELESS_BAND, + "Band", + "Band", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_CHANNEL, + g_param_spec_uint (NM_SETTING_WIRELESS_CHANNEL, + "Channel", + "Channel", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_BSSID, + nm_param_spec_specialized (NM_SETTING_WIRELESS_BSSID, + "BSSID", + "BSSID", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_TX_POWER, + g_param_spec_uint (NM_SETTING_WIRELESS_TX_POWER, + "TX Power", + "TX Power", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS, + "MAC Address", + "Harware address", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_SEEN_BSSIDS, + nm_param_spec_specialized (NM_SETTING_WIRELESS_SEEN_BSSIDS, + "Seen BSSIDS", + "Seen BSSIDs", + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_WIRELESS_MTU, + "MTU", + "MTU", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_SEC, + g_param_spec_string (NM_SETTING_WIRELESS_SEC, + "Security", + "Security", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h new file mode 100644 index 0000000000..83d707b4c7 --- /dev/null +++ b/libnm-util/nm-setting-wireless.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_WIRELESS_H +#define NM_SETTING_WIRELESS_H + +#include <nm-setting.h> +#include <nm-setting-wireless-security.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS (nm_setting_wireless_get_type ()) +#define NM_SETTING_WIRELESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWireless)) +#define NM_SETTING_WIRELESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) +#define NM_IS_SETTING_WIRELESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRELESS)) +#define NM_IS_SETTING_WIRELESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_WIRELESS)) +#define NM_SETTING_WIRELESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) + +#define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless" + +#define NM_SETTING_WIRELESS_SSID "ssid" +#define NM_SETTING_WIRELESS_MODE "mode" +#define NM_SETTING_WIRELESS_BAND "band" +#define NM_SETTING_WIRELESS_CHANNEL "channel" +#define NM_SETTING_WIRELESS_BSSID "bssid" +#define NM_SETTING_WIRELESS_RATE "rate" +#define NM_SETTING_WIRELESS_TX_POWER "tx-power" +#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRELESS_MTU "mtu" +#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" +#define NM_SETTING_WIRELESS_SEC "security" + +typedef struct { + NMSetting parent; + + GByteArray *ssid; + char *mode; + char *band; + guint32 channel; + GByteArray *bssid; + guint32 rate; + guint32 tx_power; + GByteArray *mac_address; + guint32 mtu; + GSList *seen_bssids; + char *security; +} NMSettingWireless; + +typedef struct { + NMSettingClass parent; +} NMSettingWirelessClass; + +GType nm_setting_wireless_get_type (void); + +NMSetting *nm_setting_wireless_new (void); + +gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + guint32 ap_flags, + guint32 ap_wpa, + guint32 ap_rsn, + guint32 ap_mode); + +G_END_DECLS + +#endif /* NM_SETTING_WIRELESS_H */ diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 57589f7bf5..ac4d4cd597 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -1,181 +1,16 @@ /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ -#include <glib-object.h> -#include <dbus/dbus-glib.h> -#include <string.h> -#include <ctype.h> -#include <netinet/ether.h> - #include "nm-setting.h" #include "nm-utils.h" -static GHashTable * nm_setting_hash (NMSetting *setting); -static gboolean nm_setting_populate_from_hash_default (NMSetting *setting, GHashTable *table); -static void default_setting_clear_secrets (NMSetting *setting); -static gboolean default_setting_compare_fn (NMSetting *setting, NMSetting *other, gboolean two_way); - -gboolean -nm_setting_populate_from_hash (NMSetting *setting, GHashTable *hash) -{ - g_return_val_if_fail (setting != NULL, FALSE); - - if (setting->populate_fn) - return setting->populate_fn (setting, hash); - else - return nm_setting_populate_from_hash_default (setting, hash); -} - -gboolean -nm_setting_verify (NMSetting *setting) -{ - g_return_val_if_fail (setting != NULL, FALSE); - - if (setting->verify_fn) - return setting->verify_fn (setting, NULL); - return TRUE; -} - -typedef struct { - gboolean success; - GHashTable *all_settings; -} VerifySettingsInfo; - -static void -verify_one_setting (gpointer key, gpointer value, gpointer user_data) -{ - NMSetting *setting = (NMSetting *) value; - VerifySettingsInfo *info = (VerifySettingsInfo *) user_data; - - if (info->success && setting->verify_fn) { - info->success = setting->verify_fn (setting, info->all_settings); - } -} - -gboolean -nm_settings_verify_all (GHashTable *all_settings) -{ - gpointer p; - VerifySettingsInfo info; - - g_return_val_if_fail (all_settings != NULL, FALSE); - - /* First, make sure there's at least 'connection' setting */ - p = g_hash_table_lookup (all_settings, NM_SETTING_CONNECTION); - if (!p) { - g_warning ("'connection' setting not present."); - return FALSE; - } - - /* Now, run the verify function of each setting */ - info.success = TRUE; - info.all_settings = all_settings; - g_hash_table_foreach (all_settings, verify_one_setting, &info); - - return info.success; -} - -static GHashTable * -default_setting_hash (NMSetting *setting) -{ - return nm_setting_hash (setting); -} - -GHashTable * -nm_setting_to_hash (NMSetting *setting) -{ - g_return_val_if_fail (setting != NULL, NULL); - - if (setting->hash_fn) - return setting->hash_fn (setting); - else - return default_setting_hash (setting); -} - -gboolean -nm_setting_update_secrets (NMSetting *setting, - GHashTable *secrets) -{ - g_return_val_if_fail (setting != NULL, FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); - - if (setting->update_secrets_fn) - return setting->update_secrets_fn (setting, secrets); - return TRUE; -} - -void -nm_setting_clear_secrets (NMSetting *setting) -{ - g_return_if_fail (setting != NULL); - - if (setting->clear_secrets_fn) - setting->clear_secrets_fn (setting); - else - default_setting_clear_secrets (setting); -} - -GPtrArray * -nm_setting_need_secrets (NMSetting *setting) -{ - g_return_val_if_fail (setting != NULL, NULL); - - if (setting->need_secrets_fn) - return setting->need_secrets_fn (setting); - return NULL; -} - -void -nm_setting_destroy (NMSetting *setting) -{ - char *name; - - g_return_if_fail (setting != NULL); - - name = setting->name; - - if (setting->destroy_fn) - setting->destroy_fn (setting); - - g_free (name); -} - -void -nm_setting_enumerate_values (NMSetting *setting, - NMSettingValueIterFn func, - gpointer user_data) -{ - SettingMember *m; - - g_return_if_fail (setting != NULL); - g_return_if_fail (func != NULL); - - m = setting->_members; - while (m->key) { - void *val = G_STRUCT_MEMBER_P (setting, m->offset); - (*func) (setting, m->key, m->type, val, m->secret, user_data); - m++; - }; -} - -gboolean -nm_setting_compare (NMSetting *setting, NMSetting *other, gboolean two_way) -{ - g_return_val_if_fail (setting != NULL, FALSE); - g_return_val_if_fail (other != NULL, FALSE); - - g_return_val_if_fail (setting->name != NULL, FALSE); - g_return_val_if_fail (other->name != NULL, FALSE); +G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) - g_return_val_if_fail (strcmp (setting->name, other->name) == 0, FALSE); +enum { + PROP_0, + PROP_NAME, - if (!setting->compare_fn) - return default_setting_compare_fn (setting, other, two_way); - return setting->compare_fn (setting, other, two_way); -} - -/***********************************************************************/ - -/* Helper functions for converting NMSetting to hash table. */ + PROP_LAST +}; static void destroy_gvalue (gpointer data) @@ -186,1644 +21,417 @@ destroy_gvalue (gpointer data) g_slice_free (GValue, value); } -static GHashTable * -setting_hash_new (void) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - destroy_gvalue); -} - -static GValue * -string_to_gvalue (const char *str) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - - return val; -} - -static GValue * -boolean_to_gvalue (gboolean b) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_BOOLEAN); - g_value_set_boolean (val, b); - - return val; -} - -#if 0 -static GValue * -int_to_gvalue (int i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_INT); - g_value_set_int (val, i); - - return val; -} -#endif - -static GValue * -uint_to_gvalue (guint32 i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UINT); - g_value_set_uint (val, i); - - return val; -} - -static GValue * -uint64_to_gvalue (guint64 i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UINT64); - g_value_set_uint64 (val, i); - - return val; -} - -#if 0 -static GValue * -byte_to_gvalue (guchar c) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UCHAR); - g_value_set_uchar (val, c); - - return val; -} -#endif - -static GValue * -byte_array_to_gvalue (GByteArray *array) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_set_boxed (val, array); - - return val; -} - -static GValue * -uint_array_to_gvalue (GArray *array) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UINT_ARRAY); - g_value_set_boxed (val, array); - - return val; -} - -static GValue * -slist_to_gvalue (GSList *list, GType type) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, dbus_g_type_get_collection ("GSList", type)); - g_value_set_boxed (val, list); - - return val; -} - -static GValue * -ip4_addresses_to_gvalue (GSList *list) -{ - GPtrArray *ptr_array; - GSList *iter; - GValue *val; - - ptr_array = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMSettingIP4Address *ip4_addr = (NMSettingIP4Address *) iter->data; - GArray *array; - - array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), 3); - g_array_append_val (array, ip4_addr->address); - g_array_append_val (array, ip4_addr->netmask); - - if (ip4_addr->gateway) - g_array_append_val (array, ip4_addr->gateway); - - g_ptr_array_add (ptr_array, array); - } - - val = g_slice_new0 (GValue); - g_value_init (val, dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE_ARRAY)); - g_value_set_boxed (val, ptr_array); - - return val; -} - -static GByteArray * -convert_array_to_byte_array (GArray *array) -{ - GByteArray *byte_array; - - byte_array = g_byte_array_sized_new (array->len); - g_byte_array_append (byte_array, (const guint8 *) array->data, array->len); - - return byte_array; -} - -static GSList * -convert_strv_to_slist (char **str) -{ - GSList *list = NULL; - guint i = 0; - - while (str[i]) - list = g_slist_prepend (list, g_strdup (str[i++])); - - return g_slist_reverse (list); -} - -static GSList * -convert_ip4_addresses_to_slist (GPtrArray *array) -{ - int i; - GSList *list = NULL; - - for (i = 0; i < array->len; i++) { - GValueArray *value_array = (GValueArray *) g_ptr_array_index (array, i); - - if (value_array->n_values == 2 || value_array->n_values == 3) { - NMSettingIP4Address *ip4_addr; - - ip4_addr = g_new0 (NMSettingIP4Address, 1); - ip4_addr->address = g_value_get_uint (g_value_array_get_nth (value_array, 0)); - ip4_addr->netmask = g_value_get_uint (g_value_array_get_nth (value_array, 1)); - - if (value_array->n_values == 3) - ip4_addr->gateway = g_value_get_uint (g_value_array_get_nth (value_array, 2)); - - list = g_slist_prepend (list, ip4_addr); - } else - nm_warning ("Ignoring invalid IP4 address"); - } - - return g_slist_reverse (list); -} - -static gboolean -string_in_list (const char *str, const char **valid_strings) -{ - int i; - - for (i = 0; valid_strings[i]; i++) - if (strcmp (str, valid_strings[i]) == 0) - break; - - return valid_strings[i] != NULL; -} - -static gboolean -string_slist_validate (GSList *list, const char **valid_values) +GHashTable * +nm_setting_to_hash (NMSetting *setting) { - GSList *iter; + GHashTable *hash; + GParamSpec **property_specs; + guint n_property_specs; + guint i; - for (iter = list; iter; iter = iter->next) { - if (!string_in_list ((char *) iter->data, valid_values)) - return FALSE; - } + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - return TRUE; -} - -/***********************************************************************/ + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + if (!property_specs) + return NULL; -static gboolean -nm_setting_populate_from_hash_default (NMSetting *setting, GHashTable *table) -{ - SettingMember *m; + hash = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + destroy_gvalue); - g_return_val_if_fail (setting != NULL, FALSE); - g_return_val_if_fail (table != NULL, FALSE); + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; - m = setting->_members; - while (m->key) { - GValue *value; + if (prop_spec->flags & NM_SETTING_PARAM_SERIALIZE) { + GValue *value; - if (m->type == NM_S_TYPE_GVALUE_HASH) { - GHashTable **val = (GHashTable **) G_STRUCT_MEMBER_P (setting, m->offset); - *val = nm_utils_gvalue_hash_dup (table); - break; - } + value = g_slice_new0 (GValue); + g_value_init (value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, value); - value = (GValue *) g_hash_table_lookup (table, m->key); - if (!value && m->required) { - g_warning ("Missing required value '%s'.", m->key); - return FALSE; - } else if (!value) { - goto next; + /* Don't serialize values with default values */ + if (!g_param_value_defaults (prop_spec, value)) + g_hash_table_insert (hash, g_strdup (prop_spec->name), value); + else + destroy_gvalue (value); } - - if ((m->type == NM_S_TYPE_STRING) && G_VALUE_HOLDS_STRING (value)) { - char **val = (char **) G_STRUCT_MEMBER_P (setting, m->offset); - *val = g_strdup (g_value_get_string (value)); - } else if ((m->type == NM_S_TYPE_BOOL) && G_VALUE_HOLDS_BOOLEAN (value)) { - gboolean *val = (gboolean *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = g_value_get_boolean (value); - } else if ((m->type == NM_S_TYPE_UINT32) && G_VALUE_HOLDS_UINT (value)) { - guint32 *val = (guint32 *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = g_value_get_uint (value); - } else if ((m->type == NM_S_TYPE_UINT64) && G_VALUE_HOLDS_UINT64 (value)) { - guint64 *val = (guint64 *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = g_value_get_uint64 (value); - } else if ((m->type == NM_S_TYPE_BYTE_ARRAY) && G_VALUE_HOLDS_BOXED (value)) { - GByteArray **val = (GByteArray **) G_STRUCT_MEMBER_P (setting, m->offset); - *val = convert_array_to_byte_array ((GArray *) g_value_get_boxed (value)); - } else if ((m->type == NM_S_TYPE_STRING_ARRAY) && G_VALUE_HOLDS_BOXED (value)) { - GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset); - *val = convert_strv_to_slist ((char **) g_value_get_boxed (value)); - } else if ((m->type == NM_S_TYPE_UINT_ARRAY) && G_VALUE_HOLDS_BOXED (value)) { - GArray **val = (GArray **) G_STRUCT_MEMBER_P (setting, m->offset); - GArray *tmp = (GArray *) g_value_get_boxed (value); - - *val = g_array_sized_new (FALSE, FALSE, sizeof (guint32), tmp->len); - g_array_append_vals (*val, tmp->data, tmp->len); - } else if ((m->type == NM_S_TYPE_IP4_ADDRESSES) && G_VALUE_HOLDS_BOXED (value)) { - GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset); - *val = convert_ip4_addresses_to_slist ((GPtrArray *) g_value_get_boxed (value)); - } -next: - m++; - }; - - return TRUE; -} - -#define ADD_MEMBER(nmtype, ctype, key, func) \ - case nmtype: { \ - ctype* val = (ctype*) G_STRUCT_MEMBER_P (setting, m->offset); \ - if (*val || (nmtype == NM_S_TYPE_BOOL) || m->required) { \ - g_hash_table_insert (hash, (char *) key, func (*val)); \ - } \ - break; \ } -#define ADD_MEMBER_EXTRA(nmtype, ctype, key, func, extra) \ - case nmtype: { \ - ctype* val = (ctype*) G_STRUCT_MEMBER_P (setting, m->offset); \ - if (*val || (nmtype == NM_S_TYPE_BOOL) || m->required) { \ - g_hash_table_insert (hash, (char *) key, func (*val, extra)); \ - } \ - break; \ - } + g_free (property_specs); -static GHashTable * -nm_setting_hash (NMSetting *setting) -{ - GHashTable *hash; - SettingMember *m; - - g_return_val_if_fail (setting != NULL, NULL); - - hash = setting_hash_new (); - - m = setting->_members; - while (m->key) { - switch (m->type) { - ADD_MEMBER(NM_S_TYPE_STRING, char *, m->key, string_to_gvalue) - ADD_MEMBER(NM_S_TYPE_BOOL, gboolean, m->key, boolean_to_gvalue) - ADD_MEMBER(NM_S_TYPE_UINT32, guint32, m->key, uint_to_gvalue) - ADD_MEMBER(NM_S_TYPE_UINT64, guint64, m->key, uint64_to_gvalue) - ADD_MEMBER(NM_S_TYPE_BYTE_ARRAY, GByteArray *, m->key, byte_array_to_gvalue) - ADD_MEMBER(NM_S_TYPE_UINT_ARRAY, GArray *, m->key, uint_array_to_gvalue) - ADD_MEMBER_EXTRA(NM_S_TYPE_STRING_ARRAY, GSList *, m->key, slist_to_gvalue, G_TYPE_STRING) - ADD_MEMBER(NM_S_TYPE_IP4_ADDRESSES, GSList *, m->key, ip4_addresses_to_gvalue) - default: - break; - } - m++; - } return hash; } -static void -default_setting_clear_secrets (NMSetting *setting) -{ - SettingMember *m; - - g_return_if_fail (setting != NULL); - - m = setting->_members; - while (m->key) { - if (m->secret == FALSE) - goto next; - - switch (m->type) { - case NM_S_TYPE_GVALUE_HASH: { - GHashTable **val = (GHashTable **) G_STRUCT_MEMBER_P (setting, m->offset); - g_hash_table_remove_all (*val); - break; - } - case NM_S_TYPE_STRING: { - char **val = (char **) G_STRUCT_MEMBER_P (setting, m->offset); - g_free (*val); - *val = NULL; - break; - } - case NM_S_TYPE_BOOL: { - gboolean *val = (gboolean *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = FALSE; - break; - } - case NM_S_TYPE_UINT32: { - guint32 *val = (guint32 *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = 0; - break; - } - case NM_S_TYPE_UINT64: { - guint64 *val = (guint64 *) G_STRUCT_MEMBER_P (setting, m->offset); - *val = 0; - break; - } - case NM_S_TYPE_BYTE_ARRAY: { - GByteArray **val = (GByteArray **) G_STRUCT_MEMBER_P (setting, m->offset); - g_byte_array_free (*val, TRUE); - *val = NULL; - break; - } - case NM_S_TYPE_UINT_ARRAY: { - GArray **val = (GArray **) G_STRUCT_MEMBER_P (setting, m->offset); - g_array_free (*val, TRUE); - *val = NULL; - break; - } - case NM_S_TYPE_STRING_ARRAY: { - GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset); - g_slist_foreach (*val, (GFunc) g_free, NULL); - g_slist_free (*val); - *val = NULL; - break; - } - - default: - break; - } - -next: - m++; - } -} - typedef struct { - GHashTable *other; - gboolean failed; -} GValueHashCompareInfo; + GObjectClass *class; + guint n_params; + GParameter *params; +} NMSettingFromHashInfo; static void -compare_one_hash_gvalue (gpointer key, gpointer value, gpointer user_data) -{ - GValueHashCompareInfo *info = (GValueHashCompareInfo *) user_data; - GValue *val = (GValue *) value; - GValue *other_val; - - if (info->failed) +one_property_cb (gpointer key, gpointer val, gpointer user_data) +{ + const char *prop_name = (char *) key; + GValue *src_value = (GValue *) val; + NMSettingFromHashInfo *info = (NMSettingFromHashInfo *) user_data; + GValue *dst_value = &info->params[info->n_params].value; + GParamSpec *param_spec; + + param_spec = g_object_class_find_property (info->class, prop_name); + if (!param_spec || !(param_spec->flags & NM_SETTING_PARAM_SERIALIZE)) { + /* Oh, we're so nice and only warn, maybe it should be a fatal error? */ + nm_warning ("Ignorning invalid property '%s'", prop_name); return; - - other_val = g_hash_table_lookup (info->other, key); - if (!other_val) - goto failed; - - if (G_VALUE_TYPE (val) != G_VALUE_TYPE (other_val)) - goto failed; - - switch (G_VALUE_TYPE (val)) { - case G_TYPE_STRING: { - const char *a_str = g_value_get_string (val); - const char *b_str = g_value_get_string (other_val); - if ((!a_str && b_str) || (a_str && !b_str)) - goto failed; - if (!a_str && !b_str) - break; - if (strcmp (a_str, b_str) != 0) - goto failed; - break; - } - default: - g_warning ("%s: unhandled GValue type %s", __func__, G_VALUE_TYPE_NAME (val)); - goto failed; - break; } - return; -failed: - info->failed = TRUE; -} - -static gboolean -compare_gvalue_hash (GHashTable *a, GHashTable *b) -{ - GValueHashCompareInfo info = { b, FALSE }; - - g_return_val_if_fail (a != NULL, FALSE); - g_return_val_if_fail (b != NULL, FALSE); - - g_hash_table_foreach (a, compare_one_hash_gvalue, &info); - return info.failed ? FALSE : TRUE; -} - -static gboolean -do_one_compare (NMSetting *a, NMSetting *b) -{ - SettingMember *m; - - g_return_val_if_fail (a != NULL, FALSE); - g_return_val_if_fail (b != NULL, FALSE); - - m = a->_members; - while (m->key) { - /* Ignore secrets since they aren't always supposed to be in the setting */ - if (m->secret == FALSE) - goto next; - - switch (m->type) { - case NM_S_TYPE_STRING: { - char **a_val = (char **) G_STRUCT_MEMBER_P (a, m->offset); - char **b_val = (char **) G_STRUCT_MEMBER_P (b, m->offset); - if ((*a_val && !*b_val) || (!*a_val && *b_val)) - return FALSE; - if (*a_val && *b_val && strcmp (*a_val, *b_val)) - return FALSE; - break; - } - case NM_S_TYPE_BOOL: { - gboolean *a_val = (gboolean *) G_STRUCT_MEMBER_P (a, m->offset); - gboolean *b_val = (gboolean *) G_STRUCT_MEMBER_P (b, m->offset); - if (*a_val != *b_val) - return FALSE; - break; - } - case NM_S_TYPE_UINT32: { - guint32 *a_val = (guint32 *) G_STRUCT_MEMBER_P (a, m->offset); - guint32 *b_val = (guint32 *) G_STRUCT_MEMBER_P (b, m->offset); - if (*a_val != *b_val) - return FALSE; - break; - } - case NM_S_TYPE_UINT64: { - guint64 *a_val = (guint64 *) G_STRUCT_MEMBER_P (a, m->offset); - guint64 *b_val = (guint64 *) G_STRUCT_MEMBER_P (b, m->offset); - if (*a_val != *b_val) - return FALSE; - break; - } - case NM_S_TYPE_BYTE_ARRAY: { - GByteArray **a_val = (GByteArray **) G_STRUCT_MEMBER_P (a, m->offset); - GByteArray **b_val = (GByteArray **) G_STRUCT_MEMBER_P (b, m->offset); - if ((*a_val && !*b_val) || (!*a_val && *b_val)) - return FALSE; - if (*a_val && *b_val) { - if ((*a_val)->len != (*b_val)->len) - return FALSE; - if (memcmp ((*a_val)->data, (*b_val)->data, (*a_val)->len)) - return FALSE; - } - break; - } - case NM_S_TYPE_UINT_ARRAY: { - GArray **a_val = (GArray **) G_STRUCT_MEMBER_P (a, m->offset); - GArray **b_val = (GArray **) G_STRUCT_MEMBER_P (b, m->offset); - if ((*a_val && !*b_val) || (!*a_val && *b_val)) - return FALSE; - if (*a_val && *b_val) { - if ((*a_val)->len != (*b_val)->len) - return FALSE; - if (memcmp ((*a_val)->data, (*b_val)->data, (*a_val)->len)) - return FALSE; - } - break; - } - case NM_S_TYPE_STRING_ARRAY: { - GSList **a_val = (GSList **) G_STRUCT_MEMBER_P (a, m->offset); - GSList **b_val = (GSList **) G_STRUCT_MEMBER_P (b, m->offset); - GSList *a_iter; - - for (a_iter = *a_val; a_iter; a_iter = g_slist_next (a_iter)) { - const char *a_str = a_iter->data; - GSList *b_iter; - gboolean found = FALSE; - - for (b_iter = *b_val; b_iter; b_iter = g_slist_next (b_iter)) { - const char *b_str = b_iter->data; - if (!a_str && !b_str) { - found = TRUE; - break; - } - if (a_str && b_str && !strcmp (a_str, b_str)) { - found = TRUE; - break; - } - } - if (!found) - return FALSE; - } - break; - } - case NM_S_TYPE_IP4_ADDRESSES: { - GSList **a_val = (GSList **) G_STRUCT_MEMBER_P (a, m->offset); - GSList **b_val = (GSList **) G_STRUCT_MEMBER_P (b, m->offset); - GSList *a_iter; - - for (a_iter = *a_val; a_iter; a_iter = g_slist_next (a_iter)) { - NMSettingIP4Address *a_addr = (NMSettingIP4Address *) a_iter->data; - GSList *b_iter; - gboolean found = FALSE; - - g_assert (a_addr); - for (b_iter = *b_val; b_iter; b_iter = g_slist_next (b_iter)) { - NMSettingIP4Address *b_addr = (NMSettingIP4Address *) b_iter->data; - - g_assert (b_addr); - if ( (a_addr->address == b_addr->address) - && (a_addr->netmask == b_addr->netmask) - && (a_addr->gateway == b_addr->gateway)) { - found = TRUE; - break; - } - } - if (!found) - return FALSE; - } - break; - } - case NM_S_TYPE_GVALUE_HASH: { - GHashTable **a_val = (GHashTable **) G_STRUCT_MEMBER_P (a, m->offset); - GHashTable **b_val = (GHashTable **) G_STRUCT_MEMBER_P (b, m->offset); - if (!compare_gvalue_hash (*a_val, *b_val)) - return FALSE; - break; - } - - default: - break; - } - -next: - m++; + g_value_init (dst_value, G_VALUE_TYPE (src_value)); + if (g_value_transform (src_value, dst_value)) { + info->params[info->n_params].name = prop_name; + info->n_params++; + } else { + nm_warning ("Ignoring property '%s' with invalid type (%s)", + prop_name, G_VALUE_TYPE_NAME (src_value)); + g_value_unset (dst_value); } - - return TRUE; -} - -static gboolean -default_setting_compare_fn (NMSetting *setting, NMSetting *other, gboolean two_way) -{ - gboolean same; - - same = do_one_compare (setting, other); - - /* compare A to B, then if that is the same compare B to A to ensure - * that keys that are in B but not A will make the comparison fail. - */ - if (two_way && (same == TRUE)) - return do_one_compare (other, setting); - return same; -} - - -/* Connection */ - -static gboolean -setting_connection_verify (NMSetting *setting, GHashTable *all_settings) -{ - NMSettingConnection *self = (NMSettingConnection *) setting; - - if (!self->name || !strlen (self->name)) - return FALSE; - - if (!self->type || !strlen (self->type)) - return FALSE; - - /* Make sure the corresponding 'type' item is present */ - if (all_settings && !g_hash_table_lookup (all_settings, self->type)) - return FALSE; - - return TRUE; -} - -static void -setting_connection_destroy (NMSetting *setting) -{ - NMSettingConnection *self = (NMSettingConnection *) setting; - - g_free (self->name); - g_free (self->type); - - g_slice_free (NMSettingConnection, self); } -static SettingMember con_table[] = { - { "name", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingConnection, name), TRUE, FALSE }, - { "type", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingConnection, type), TRUE, FALSE }, - { "autoconnect", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingConnection, autoconnect), FALSE, FALSE }, - { "timestamp", NM_S_TYPE_UINT64, G_STRUCT_OFFSET (NMSettingConnection, timestamp), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - NMSetting * -nm_setting_connection_new (void) +nm_setting_from_hash (GType setting_type, + GHashTable *hash) { NMSetting *setting; + NMSettingFromHashInfo info; - setting = (NMSetting *) g_slice_new0 (NMSettingConnection); + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL); + g_return_val_if_fail (hash != NULL, NULL); - setting->name = g_strdup (NM_SETTING_CONNECTION); - setting->_members = con_table; - setting->verify_fn = setting_connection_verify; - setting->destroy_fn = setting_connection_destroy; + info.class = g_type_class_ref (setting_type); + info.n_params = 0; + info.params = g_new0 (GParameter, g_hash_table_size (hash)); - return setting; -} + g_hash_table_foreach (hash, one_property_cb, &info); -/* IP4 config */ - -static gboolean -setting_ip4_config_verify (NMSetting *setting, GHashTable *all_settings) -{ - NMSettingIP4Config *self = (NMSettingIP4Config *) setting; - - if (self->manual) { - if (!self->addresses) { - g_warning ("address is not provided"); - return FALSE; - } - } - - return TRUE; -} - -static void -setting_ip4_config_destroy (NMSetting *setting) -{ - NMSettingIP4Config *self = (NMSettingIP4Config *) setting; + setting = (NMSetting *) g_object_newv (setting_type, info.n_params, info.params); - if (self->dns) - g_array_free (self->dns, TRUE); - - if (self->dns_search) { - g_slist_foreach (self->dns_search, (GFunc) g_free, NULL); - g_slist_free (self->dns_search); - } - - if (self->addresses) { - g_slist_foreach (self->addresses, (GFunc) g_free, NULL); - g_slist_free (self->addresses); - } - - g_slice_free (NMSettingIP4Config, self); -} - -static SettingMember ip4_config_table[] = { - { "manual", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingIP4Config, manual), FALSE, FALSE }, - { "dns", NM_S_TYPE_UINT_ARRAY, G_STRUCT_OFFSET (NMSettingIP4Config, dns), FALSE, FALSE }, - { "dns-search", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingIP4Config, dns_search), FALSE, FALSE }, - { "addresses", NM_S_TYPE_IP4_ADDRESSES,G_STRUCT_OFFSET (NMSettingIP4Config, addresses), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_ip4_config_new (void) -{ - NMSetting *setting; - - setting = (NMSetting *) g_slice_new0 (NMSettingIP4Config); - - setting->name = g_strdup (NM_SETTING_IP4_CONFIG); - setting->_members = ip4_config_table; - setting->verify_fn = setting_ip4_config_verify; - setting->destroy_fn = setting_ip4_config_destroy; + g_free (info.params); + g_type_class_unref (info.class); return setting; } -/* Wired device */ - -static gboolean -setting_wired_verify (NMSetting *setting, GHashTable *all_settings) +const char * +nm_setting_get_name (NMSetting *setting) { - NMSettingWired *self = (NMSettingWired *) setting; - const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; - const char *valid_duplex[] = { "half", "full", NULL }; + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - if (self->port && !string_in_list (self->port, valid_ports)) { - g_warning ("Invalid port"); - return FALSE; - } - - if (self->duplex && !string_in_list (self->duplex, valid_duplex)) { - g_warning ("Invalid duplex"); - return FALSE; - } - - if (self->mac_address && self->mac_address->len != 6) { - g_warning ("Invalid mac address"); - return FALSE; - } - - return TRUE; -} - -static void -setting_wired_destroy (NMSetting *setting) -{ - NMSettingWired *self = (NMSettingWired *) setting; - - g_free (self->port); - g_free (self->duplex); - - if (self->mac_address) - g_byte_array_free (self->mac_address, TRUE); - - g_slice_free (NMSettingWired, self); -} - -static SettingMember wired_table[] = { - { "port", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWired, port), FALSE, FALSE }, - { "speed", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWired, speed), FALSE, FALSE }, - { "duplex", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWired, duplex), FALSE, FALSE }, - { "auto-negotiate", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingWired, auto_negotiate), FALSE, FALSE }, - { "mac-address", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWired, mac_address), FALSE, FALSE }, - { "mtu", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWired, mtu), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_wired_new (void) -{ - NMSetting *setting; - NMSettingWired *s_wired; - - s_wired = g_slice_new0 (NMSettingWired); - setting = (NMSetting *) s_wired; - - setting->name = g_strdup (NM_SETTING_WIRED); - setting->_members = wired_table; - setting->verify_fn = setting_wired_verify; - setting->destroy_fn = setting_wired_destroy; - - s_wired->auto_negotiate = TRUE; - - return setting; -} - -/* Wireless device */ - -static gboolean -setting_wireless_verify (NMSetting *setting, GHashTable *all_settings) -{ - NMSettingWireless *self = (NMSettingWireless *) 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"); - return FALSE; - } - - if (self->mode && !string_in_list (self->mode, valid_modes)) { - g_warning ("Invalid mode. Should be either 'infrastructure' or 'adhoc'"); - return FALSE; - } - - if (self->band && !string_in_list (self->band, valid_bands)) { - g_warning ("Invalid band. Should be either 'a' or 'bg'"); - return FALSE; - } - - if (self->channel && !self->band) { - g_warning ("Channel was provided without band"); - return FALSE; - } - - if (self->channel) { - if (!strcmp (self->band, "a")) { - int i; - int valid_channels[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, - 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 0 }; - - for (i = 0; valid_channels[i]; i++) { - if (self->channel == valid_channels[i]) - break; - } - - if (valid_channels[i] == 0) { - g_warning ("Invalid channel"); - return FALSE; - } - } else if (!strcmp (self->band, "bg") && self->channel > 14) { - g_warning ("Invalid channel"); - return FALSE; - } - } - - if (self->bssid && self->bssid->len != 6) { - g_warning ("Invalid bssid"); - return FALSE; - } - - if (self->mac_address && self->mac_address->len != 6) { - g_warning ("Invalid mac address"); - return FALSE; - } - - for (iter = self->seen_bssids; iter; iter = iter->next) { - struct ether_addr addr; - - if (!ether_aton_r (iter->data, &addr)) { - g_warning ("Invalid bssid"); - return FALSE; - } - } - - if ( self->security - && all_settings - && !g_hash_table_lookup (all_settings, self->security)) { - g_warning ("Invalid or missing security"); - return FALSE; - } - - return TRUE; -} - -static void -setting_wireless_destroy (NMSetting *setting) -{ - NMSettingWireless *self = (NMSettingWireless *) setting; - - g_free (self->mode); - g_free (self->band); - g_free (self->security); - - if (self->ssid) - g_byte_array_free (self->ssid, TRUE); - if (self->bssid) - g_byte_array_free (self->bssid, TRUE); - if (self->mac_address) - g_byte_array_free (self->mac_address, TRUE); - - if (self->seen_bssids) { - g_slist_foreach (self->seen_bssids, (GFunc) g_free, NULL); - g_slist_free (self->seen_bssids); - } - - - g_slice_free (NMSettingWireless, self); + return setting->name; } -static SettingMember wireless_table[] = { - { "ssid", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWireless, ssid), TRUE, FALSE }, - { "mode", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWireless, mode), FALSE, FALSE }, - { "band", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWireless, band), FALSE, FALSE }, - { "channel", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWireless, channel), FALSE, FALSE }, - { "bssid", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWireless, bssid), FALSE, FALSE }, - { "rate", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWireless, rate), FALSE, FALSE }, - { "tx-power", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWireless, tx_power), FALSE, FALSE }, - { "mac-address", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWireless, mac_address), FALSE, FALSE }, - { "mtu", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWireless, mtu), FALSE, FALSE }, - { "seen-bssids", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingWireless, seen_bssids), FALSE, FALSE }, - { "security", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWireless, security), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_wireless_new (void) +gboolean +nm_setting_verify (NMSetting *setting, GSList *all_settings) { - NMSetting *setting; + gboolean success = TRUE; - setting = (NMSetting *) g_slice_new0 (NMSettingWireless); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - setting->name = g_strdup (NM_SETTING_WIRELESS); - setting->_members = wireless_table; - setting->verify_fn = setting_wireless_verify; - setting->destroy_fn = setting_wireless_destroy; + if (NM_SETTING_GET_CLASS (setting)->verify) + success = NM_SETTING_GET_CLASS (setting)->verify (setting, all_settings); - return setting; + return success; } -/* Wireless security */ - -static gboolean -setting_wireless_security_verify (NMSetting *setting, GHashTable *all_settings) +gboolean +nm_setting_compare (NMSetting *setting, NMSetting *other) { - NMSettingWirelessSecurity *self = (NMSettingWirelessSecurity *) setting; - const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL }; - const char *valid_auth_algs[] = { "open", "shared", "leap", NULL }; - const char *valid_protos[] = { "wpa", "rsn", NULL }; - const char *valid_pairwise[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; - const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; - const char *valid_phase1_peapver[] = { "0", "1", NULL }; - - /* Every time a method gets added to the following, add one to EAPMethodNeedSecretsTable */ - const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "psk", "fast", NULL }; - const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL }; - const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL }; - - if (!self->key_mgmt || !string_in_list (self->key_mgmt, valid_key_mgmt)) { - g_warning ("Missing or invalid key management"); - return FALSE; - } + GParamSpec **property_specs; + guint n_property_specs; + gboolean different; + guint i; - if (self->wep_tx_keyidx > 3) { - g_warning ("Invalid WEP key index"); - return FALSE; - } + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (NM_IS_SETTING (other), FALSE); - if (self->auth_alg && !string_in_list (self->auth_alg, valid_auth_algs)) { - g_warning ("Invalid authentication algorithm"); + /* First check that both have the same type */ + if (G_OBJECT_TYPE (setting) != G_OBJECT_TYPE (other)) return FALSE; - } - if (self->proto && !string_slist_validate (self->proto, valid_protos)) { - g_warning ("Invalid authentication protocol"); - return FALSE; - } + /* And now all properties */ + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + different = FALSE; - if (self->pairwise && !string_slist_validate (self->pairwise, valid_pairwise)) { - g_warning ("Invalid pairwise"); - return FALSE; - } + for (i = 0; i < n_property_specs && !different; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value1 = { 0 }; + GValue value2 = { 0 }; - if (self->group && !string_slist_validate (self->group, valid_groups)) { - g_warning ("Invalid group"); - return FALSE; - } - - if (self->eap && !string_slist_validate (self->eap, valid_eap)) { - g_warning ("Invalid eap"); - return FALSE; - } - - if (self->phase1_peapver && !string_in_list (self->phase1_peapver, valid_phase1_peapver)) { - g_warning ("Invalid phase1 peapver"); - return FALSE; - } + g_value_init (&value1, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value1); - if (self->phase1_peaplabel && strcmp (self->phase1_peaplabel, "1")) { - g_warning ("Invalid phase1 peaplabel"); - return FALSE; - } - - if (self->phase1_fast_provisioning && strcmp (self->phase1_fast_provisioning, "1")) { - g_warning ("Invalid phase1 fast provisioning"); - return FALSE; - } + g_value_init (&value2, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value2); - if (self->phase2_auth && !string_in_list (self->phase2_auth, valid_phase2_auth)) { - g_warning ("Invalid phase2 authentication"); - return FALSE; - } + different = g_param_values_cmp (prop_spec, &value1, &value2) != 0; - if (self->phase2_autheap && !string_in_list (self->phase2_autheap, valid_phase2_autheap)) { - g_warning ("Invalid phase2 autheap"); - return FALSE; + g_value_unset (&value1); + g_value_unset (&value2); } - /* FIXME: finish */ + g_free (property_specs); - return TRUE; + return different; } -static void -setting_wireless_security_destroy (NMSetting *setting) +void +nm_setting_enumerate_values (NMSetting *setting, + NMSettingValueIterFn func, + gpointer user_data) { - NMSettingWirelessSecurity *self = (NMSettingWirelessSecurity *) setting; - - /* Strings first. g_free() already checks for NULLs so we don't have to */ - - g_free (self->key_mgmt); - g_free (self->auth_alg); - g_free (self->identity); - g_free (self->anonymous_identity); - g_free (self->ca_path); - g_free (self->phase1_peapver); - g_free (self->phase1_peaplabel); - g_free (self->phase1_fast_provisioning); - g_free (self->phase2_auth); - g_free (self->phase2_autheap); - g_free (self->phase2_ca_path); - g_free (self->nai); - g_free (self->wep_key0); - g_free (self->wep_key1); - g_free (self->wep_key2); - g_free (self->wep_key3); - g_free (self->psk); - g_free (self->password); - g_free (self->pin); - g_free (self->eappsk); - g_free (self->private_key_passwd); - g_free (self->phase2_private_key_passwd); - - if (self->proto) { - g_slist_foreach (self->proto, (GFunc) g_free, NULL); - g_slist_free (self->proto); - } + GParamSpec **property_specs; + guint n_property_specs; + int i; - if (self->pairwise) { - g_slist_foreach (self->pairwise, (GFunc) g_free, NULL); - g_slist_free (self->pairwise); - } + g_return_if_fail (NM_IS_SETTING (setting)); + g_return_if_fail (func != NULL); - if (self->group) { - g_slist_foreach (self->group, (GFunc) g_free, NULL); - g_slist_free (self->group); - } + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = { 0 }; - if (self->eap) { - g_slist_foreach (self->eap, (GFunc) g_free, NULL); - g_slist_free (self->eap); + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (prop_spec)); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + func (setting, prop_spec->name, &value, + prop_spec->flags & NM_SETTING_PARAM_SECRET, + user_data); + g_value_unset (&value); } - if (self->ca_cert) - g_byte_array_free (self->ca_cert, TRUE); - if (self->client_cert) - g_byte_array_free (self->client_cert, TRUE); - if (self->private_key) - g_byte_array_free (self->private_key, TRUE); - if (self->phase2_ca_cert) - g_byte_array_free (self->phase2_ca_cert, TRUE); - if (self->phase2_client_cert) - g_byte_array_free (self->phase2_client_cert, TRUE); - if (self->phase2_private_key) - g_byte_array_free (self->phase2_private_key, TRUE); - - g_slice_free (NMSettingWirelessSecurity, self); + g_free (property_specs); } -static gboolean -string_list_contains (GSList *list, const char *string) -{ - GSList *iter; - - g_return_val_if_fail (string != NULL, FALSE); - - for (iter = list; iter; iter = g_slist_next (iter)) - if (!strcmp (iter->data, string)) - return TRUE; - return FALSE; -} - -static gboolean -setting_wireless_security_update_secrets (NMSetting *setting, - GHashTable *secrets) +void +nm_setting_clear_secrets (NMSetting *setting) { - NMSettingWirelessSecurity *self = (NMSettingWirelessSecurity *) setting; - SettingMember *m; + GParamSpec **property_specs; + guint n_property_specs; + guint i; - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); + g_return_if_fail (NM_IS_SETTING (setting)); - m = setting->_members; - while (m->key) { - GValue *value; + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); - if (m->secret == FALSE) - goto next; + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = { 0 }; - value = (GValue *) g_hash_table_lookup (secrets, m->key); - if (value && G_VALUE_HOLDS_STRING (value)) { - char **val = (char **) G_STRUCT_MEMBER_P (setting, m->offset); - g_free (*val); - *val = g_strdup (g_value_get_string (value)); + if (prop_spec->flags & NM_SETTING_PARAM_SECRET) { + g_value_init (&value, prop_spec->value_type); + g_param_value_set_default (prop_spec, &value); + g_object_set_property (G_OBJECT (setting), prop_spec->name, &value); + g_value_unset (&value); } - -next: - m++; } - return TRUE; + g_free (property_specs); } -static gboolean -verify_wep_key (const char *key) +GPtrArray * +nm_setting_need_secrets (NMSetting *setting) { - int keylen, i; - - if (!key) - return FALSE; + GPtrArray *secrets = NULL; - keylen = strlen (key); - if (keylen != 10 && keylen != 26) - return FALSE; + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - for (i = 0; i < keylen; i++) { - if (!isxdigit (key[i])) - return FALSE; - } + if (NM_SETTING_GET_CLASS (setting)->need_secrets) + secrets = NM_SETTING_GET_CLASS (setting)->need_secrets (setting); - return TRUE; + return secrets; } -static gboolean -verify_wpa_psk (const char *psk) +static void +update_one_secret (gpointer key, gpointer val, gpointer user_data) { - int psklen, i; - - if (!psk) - return FALSE; - - psklen = strlen (psk); - if (psklen != 64) - return FALSE; + char *secret_key = (char *) key; + GValue *secret_value = (GValue *) val; + NMSetting *setting = (NMSetting *) user_data; + GParamSpec *prop_spec; + GValue transformed_value = { 0 }; - for (i = 0; i < psklen; i++) { - if (!isxdigit (psk[i])) - return FALSE; + prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), secret_key); + if (!prop_spec) { + nm_warning ("Ignoring invalid secret '%s'.", secret_key); + return; } - return TRUE; -} - -static void -need_secrets_password (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2) -{ - if (!self->password || !strlen (self->password)) - g_ptr_array_add (secrets, "password"); -} + if (!(prop_spec->flags & NM_SETTING_PARAM_SECRET)) { + nm_warning ("Ignoring secret '%s' as it's not marked as a secret.", secret_key); + return; + } -static void -need_secrets_eappsk (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2) -{ - if (!self->eappsk || !strlen (self->eappsk)) - g_ptr_array_add (secrets, "eappsk"); + if (g_value_type_compatible (G_VALUE_TYPE (secret_value), G_PARAM_SPEC_VALUE_TYPE (prop_spec))) + g_object_set_property (G_OBJECT (setting), prop_spec->name, secret_value); + else if (g_value_transform (secret_value, &transformed_value)) { + g_object_set_property (G_OBJECT (setting), prop_spec->name, &transformed_value); + g_value_unset (&transformed_value); + } else + nm_warning ("Ignoring secret property '%s' with invalid type (%s)", + secret_key, G_VALUE_TYPE_NAME (secret_value)); } -static void -need_secrets_sim (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2) +void +nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets) { - if (!self->pin || !strlen (self->pin)) - g_ptr_array_add (secrets, "eappsk"); -} + g_return_if_fail (NM_IS_SETTING (setting)); + g_return_if_fail (secrets != NULL); -static void -need_secrets_tls (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2) -{ - if (phase2) { - if (!self->phase2_private_key_passwd || !strlen (self->phase2_private_key_passwd)) - g_ptr_array_add (secrets, "phase2-private-key-passwd"); - } else { - if (!self->private_key_passwd || !strlen (self->private_key_passwd)) - g_ptr_array_add (secrets, "private-key-passwd"); - } + g_hash_table_foreach (secrets, update_one_secret, setting); } -/* Implemented below... */ -static void need_secrets_phase2 (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2); - - -typedef void (*EAPMethodNeedSecretsFunc) (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2); - -typedef struct { - const char *method; - EAPMethodNeedSecretsFunc func; -} EAPMethodNeedSecretsTable; - -static EAPMethodNeedSecretsTable eap_need_secrets_table[] = { - { "leap", need_secrets_password }, - { "md5", need_secrets_password }, - { "pap", need_secrets_password }, - { "chap", need_secrets_password }, - { "mschap", need_secrets_password }, - { "mschapv2", need_secrets_password }, - { "fast", need_secrets_password }, - { "psk", need_secrets_eappsk }, - { "pax", need_secrets_eappsk }, - { "sake", need_secrets_eappsk }, - { "gpsk", need_secrets_eappsk }, - { "tls", need_secrets_tls }, - { "peap", need_secrets_phase2 }, - { "ttls", need_secrets_phase2 }, - { "sim", need_secrets_sim }, - { "gtc", NULL }, // FIXME: implement - { "otp", NULL }, // FIXME: implement - { NULL, NULL } -}; - -static void -need_secrets_phase2 (NMSettingWirelessSecurity *self, - GPtrArray *secrets, - gboolean phase2) +char * +nm_setting_to_string (NMSetting *setting) { - char *method = NULL; - int i; - - g_return_if_fail (phase2 == FALSE); + GString *string; + GParamSpec **property_specs; + guint n_property_specs; + guint i; - /* Check phase2_auth and phase2_autheap */ - method = self->phase2_auth; - if (!method && self->phase2_autheap) - method = self->phase2_autheap; + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - if (!method) { - g_warning ("Couldn't find EAP method."); - g_assert_not_reached(); - return; - } - - /* Ask the configured phase2 method if it needs secrets */ - for (i = 0; eap_need_secrets_table[i].method; i++) { - if (eap_need_secrets_table[i].func == NULL) - continue; - if (strcmp (eap_need_secrets_table[i].method, method)) { - (*eap_need_secrets_table[i].func) (self, secrets, TRUE); - break; - } - } -} + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + if (!property_specs) + return NULL; + string = g_string_new (setting->name); + g_string_append_c (string, '\n'); -static GPtrArray * -setting_wireless_security_need_secrets (NMSetting *setting) -{ - NMSettingWirelessSecurity *self = (NMSettingWirelessSecurity *) setting; - GPtrArray *secrets; + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = { 0 }; + char *value_str; + gboolean is_serializable; + gboolean is_default; - secrets = g_ptr_array_sized_new (4); - if (!secrets) { - g_warning ("Not enough memory to create required secrets array."); - return NULL; - } + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); - g_assert (self->key_mgmt); + value_str = g_strdup_value_contents (&value); + g_string_append_printf (string, "\t%s : %s", prop_spec->name, value_str); + g_free (value_str); - /* Static WEP */ - if (strcmp (self->key_mgmt, "none") == 0) { - if (!verify_wep_key (self->wep_key0)) { - g_ptr_array_add (secrets, "wep-key0"); - return secrets; - } - if (self->wep_tx_keyidx == 1 && !verify_wep_key (self->wep_key1)) { - g_ptr_array_add (secrets, "wep-key1"); - return secrets; - } - if (self->wep_tx_keyidx == 2 && !verify_wep_key (self->wep_key2)) { - g_ptr_array_add (secrets, "wep-key2"); - return secrets; - } - if (self->wep_tx_keyidx == 3 && !verify_wep_key (self->wep_key3)) { - g_ptr_array_add (secrets, "wep-key3"); - return secrets; - } - goto no_secrets; - } + is_serializable = prop_spec->flags & NM_SETTING_PARAM_SERIALIZE; + is_default = g_param_value_defaults (prop_spec, &value); - /* WPA-PSK infrastructure and adhoc */ - if ( (strcmp (self->key_mgmt, "wpa-none") == 0) - || (strcmp (self->key_mgmt, "wpa-psk") == 0)) { - if (!verify_wpa_psk (self->psk)) { - g_ptr_array_add (secrets, "psk"); - return secrets; - } - goto no_secrets; - } + if (is_serializable || is_default) { + g_string_append (string, " ("); - /* LEAP */ - if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) - && self->auth_alg - && (strcmp (self->auth_alg, "leap") == 0) - && (string_list_contains (self->eap, "leap"))) { - if (!self->password || !strlen (self->password)) { - g_ptr_array_add (secrets, "password"); - return secrets; - } - goto no_secrets; - } + if (is_serializable) + g_string_append_c (string, 's'); + if (is_default) + g_string_append_c (string, 'd'); - if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) - || (strcmp (self->key_mgmt, "wpa-eap") == 0)) { - GSList *iter; - gboolean eap_method_found = FALSE; - - /* Ask each configured EAP method if it needs secrets */ - for (iter = self->eap; iter && !eap_method_found; iter = g_slist_next (iter)) { - const char *method = (const char *) iter->data; - int i; - - for (i = 0; eap_need_secrets_table[i].method; i++) { - if (eap_need_secrets_table[i].func == NULL) - continue; - if (!strcmp (eap_need_secrets_table[i].method, method)) { - (*eap_need_secrets_table[i].func) (self, secrets, FALSE); - - /* Only break out of the outer loop if this EAP method - * needed secrets. - */ - if (secrets->len > 0) - eap_method_found = TRUE; - break; - } - } + g_string_append_c (string, ')'); } - if (secrets->len) - return secrets; - goto no_secrets; + g_string_append_c (string, '\n'); } - g_assert_not_reached (); - return secrets; + g_free (property_specs); + g_string_append_c (string, '\n'); -no_secrets: - if (secrets) - g_ptr_array_free (secrets, TRUE); - return NULL; + return g_string_free (string, FALSE); } -static SettingMember wireless_sec_table[] = { - { "key-mgmt", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, key_mgmt), TRUE, FALSE }, - { "wep-tx-keyidx", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingWirelessSecurity, wep_tx_keyidx), FALSE, FALSE }, - { "auth-alg", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, auth_alg), FALSE, FALSE }, - { "proto", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, proto), FALSE, FALSE }, - { "pairwise", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, pairwise), FALSE, FALSE }, - { "group", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, group), FALSE, FALSE }, - { "eap", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, eap), FALSE, FALSE }, - { "identity", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, identity), FALSE, FALSE }, - { "anonymous-identity", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, anonymous_identity), FALSE, FALSE }, - { "ca-cert", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, ca_cert), FALSE, FALSE }, - { "ca-path", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, ca_path), FALSE, FALSE }, - { "client-cert", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, client_cert), FALSE, FALSE }, - { "private-key", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, private_key), FALSE, FALSE }, - { "phase1-peapver", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase1_peapver), FALSE, FALSE }, - { "phase1-peaplabel", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase1_peaplabel), FALSE, FALSE }, - { "phase1-fast-provisioning", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase1_fast_provisioning), FALSE, FALSE }, - { "phase2-auth", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_auth), FALSE, FALSE }, - { "phase2-autheap", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_autheap), FALSE, FALSE }, - { "phase2-ca-cert", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_ca_cert), FALSE, FALSE }, - { "phase2-ca-path", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_ca_path), FALSE, FALSE }, - { "phase2-client-cert", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_client_cert), FALSE, FALSE }, - { "phase2-private-key", NM_S_TYPE_BYTE_ARRAY, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_private_key), FALSE, FALSE }, - { "nai", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, nai), FALSE, FALSE }, - { "wep-key0", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, wep_key0), FALSE, TRUE }, - { "wep-key1", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, wep_key1), FALSE, TRUE }, - { "wep-key2", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, wep_key2), FALSE, TRUE }, - { "wep-key3", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, wep_key3), FALSE, TRUE }, - { "psk", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, psk), FALSE, TRUE }, - { "password", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, password), FALSE, TRUE }, - { "pin", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, pin), FALSE, TRUE }, - { "eappsk", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, eappsk), FALSE, TRUE }, - { "private-key-passwd", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, private_key_passwd), FALSE, TRUE }, - { "phase2-private-key-passwd", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingWirelessSecurity, phase2_private_key_passwd), FALSE, TRUE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_wireless_security_new (void) -{ - NMSetting *setting; - - setting = (NMSetting *) g_slice_new0 (NMSettingWirelessSecurity); - - setting->name = g_strdup (NM_SETTING_WIRELESS_SECURITY); - setting->_members = wireless_sec_table; - setting->verify_fn = setting_wireless_security_verify; - setting->update_secrets_fn = setting_wireless_security_update_secrets; - setting->need_secrets_fn = setting_wireless_security_need_secrets; - setting->destroy_fn = setting_wireless_security_destroy; - - return setting; -} - -/* PPP */ - -static gboolean -setting_ppp_verify (NMSetting *setting, GHashTable *all_settings) -{ - /* FIXME: Do we even want this or can we just let pppd evaluate the options? */ - return TRUE; -} +/*****************************************************************************/ static void -setting_ppp_destroy (NMSetting *setting) +nm_setting_init (NMSetting *setting) { - NMSettingPPP *self = (NMSettingPPP *) setting; - - g_slice_free (NMSettingPPP, self); } -static SettingMember ppp_table[] = { - { "noauth", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, noauth), FALSE, FALSE }, - { "refuse-eap", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, refuse_eap), FALSE, FALSE }, - { "refuse-chap", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, refuse_chap), FALSE, FALSE }, - { "refuse-mschap", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, refuse_mschap), FALSE, FALSE }, - { "nobsdcomp", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, nobsdcomp), FALSE, FALSE }, - { "nodeflate", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, nodeflate), FALSE, FALSE }, - { "require-mppe", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, require_mppe), FALSE, FALSE }, - { "require-mppe-128", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, require_mppe_128), FALSE, FALSE }, - { "mppe-stateful", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, mppe_stateful), FALSE, FALSE }, - { "require-mppc", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, require_mppc), FALSE, FALSE }, - { "crtscts", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, crtscts), FALSE, FALSE }, - { "usepeerdns", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingPPP, usepeerdns), FALSE, FALSE }, - { "baud", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingPPP, baud), FALSE, FALSE }, - { "mru", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingPPP, mru), FALSE, FALSE }, - { "mtu", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingPPP, mtu), FALSE, FALSE }, - { "lcp-echo-failure", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingPPP, lcp_echo_failure), FALSE, FALSE }, - { "lcp-echo-interval", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingPPP, lcp_echo_interval), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_ppp_new (void) +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) { + GObject *object; NMSetting *setting; - setting = (NMSetting *) g_slice_new0 (NMSettingPPP); - - setting->name = g_strdup (NM_SETTING_PPP); - setting->_members = ppp_table; - setting->verify_fn = setting_ppp_verify; - setting->destroy_fn = setting_ppp_destroy; - - return setting; -} - -/* vpn setting */ - -static gboolean -setting_vpn_verify (NMSetting *setting, GHashTable *all_settings) -{ - NMSettingVPN *self = (NMSettingVPN *) setting; - - if (!self->service_type || !strlen (self->service_type)) - return FALSE; - - /* default username can be NULL, but can't be zero-length */ - if (self->user_name && !strlen (self->user_name)) - return FALSE; - - return TRUE; -} - -static void -setting_vpn_destroy (NMSetting *setting) -{ - NMSettingVPN *self = (NMSettingVPN *) setting; - - g_free (self->service_type); - g_free (self->user_name); + object = G_OBJECT_CLASS (nm_setting_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; - if (self->routes) { - g_slist_foreach (self->routes, (GFunc) g_free, NULL); - g_slist_free (self->routes); + setting = NM_SETTING (object); + if (!setting->name) { + nm_warning ("Setting name is not set."); + g_object_unref (object); + object = NULL; } - g_slice_free (NMSettingVPN, self); + return object; } -static SettingMember vpn_table[] = { - { "service_type", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingVPN, service_type), TRUE, FALSE }, - { "user_name", NM_S_TYPE_STRING, G_STRUCT_OFFSET (NMSettingVPN, user_name), FALSE, FALSE }, - { "routes", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingVPN, routes), FALSE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_vpn_new (void) -{ - NMSetting *setting; - - setting = (NMSetting *) g_slice_new0 (NMSettingVPN); - - setting->name = g_strdup (NM_SETTING_VPN); - setting->_members = vpn_table; - setting->verify_fn = setting_vpn_verify; - setting->destroy_fn = setting_vpn_destroy; - - return setting; -} - -/* vpn-properties setting */ - -static gboolean -setting_vpn_properties_verify (NMSetting *setting, GHashTable *all_settings) -{ - NMSettingVPNProperties *self = (NMSettingVPNProperties *) setting; - - if (!self->data) - return FALSE; - - /* FIXME: actually check the data as well */ - - return TRUE; -} - -static GHashTable * -setting_vpn_properties_hash (NMSetting *setting) +static void +finalize (GObject *object) { - NMSettingVPNProperties *self = (NMSettingVPNProperties *) setting; + NMSetting *self = NM_SETTING (object); - g_return_val_if_fail (self->data != NULL, NULL); + g_free (self->name); - return nm_utils_gvalue_hash_dup (self->data); + G_OBJECT_CLASS (nm_setting_parent_class)->finalize (object); } static void -setting_vpn_properties_destroy (NMSetting *setting) +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) { - NMSettingVPNProperties *self = (NMSettingVPNProperties *) setting; + NMSetting *setting = NM_SETTING (object); - g_hash_table_destroy (self->data); - g_slice_free (NMSettingVPNProperties, self); + switch (prop_id) { + case PROP_NAME: + g_free (setting->name); + setting->name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -property_value_destroy (gpointer data) +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) { - GValue *value = (GValue *) data; + NMSetting *setting = NM_SETTING (object); - g_value_unset (value); - g_slice_free (GValue, data); + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, setting->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -add_one_secret (gpointer key, gpointer value, gpointer user_data) -{ - NMSettingVPNProperties *self = (NMSettingVPNProperties *) user_data; - GValue * new_value; - - if (!value || !G_VALUE_HOLDS_STRING (value)) - return; - - new_value = g_slice_new0 (GValue); - if (!new_value) - return; - - g_value_init (new_value, G_TYPE_STRING); - g_value_copy (value, new_value); - g_hash_table_insert (self->data, g_strdup (key), new_value); -} - -static gboolean -setting_vpn_properties_update_secrets (NMSetting *setting, - GHashTable *secrets) -{ - NMSettingVPNProperties *self = (NMSettingVPNProperties *) setting; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); - - g_hash_table_foreach (secrets, add_one_secret, self); - return TRUE; -} - -static SettingMember vpn_properties_table[] = { - { "data", NM_S_TYPE_GVALUE_HASH, G_STRUCT_OFFSET (NMSettingVPNProperties, data), TRUE, FALSE }, - { NULL, 0, 0 }, -}; - -NMSetting * -nm_setting_vpn_properties_new (void) -{ - NMSetting *setting; - NMSettingVPNProperties *s_vpn_props; - - setting = (NMSetting *) g_slice_new0 (NMSettingVPNProperties); - - setting->name = g_strdup (NM_SETTING_VPN_PROPERTIES); - setting->_members = vpn_properties_table; - setting->verify_fn = setting_vpn_properties_verify; - setting->hash_fn = setting_vpn_properties_hash; - setting->update_secrets_fn = setting_vpn_properties_update_secrets; - setting->destroy_fn = setting_vpn_properties_destroy; - - s_vpn_props = (NMSettingVPNProperties *) setting; - s_vpn_props->data = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - property_value_destroy); - - return setting; +nm_setting_class_init (NMSettingClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_SETTING_NAME, + "Name", + "Setting's name", + NULL, + G_PARAM_READWRITE)); } diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index cfab40b1a3..2279bf5514 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -3,264 +3,74 @@ #ifndef NM_SETTING_H #define NM_SETTING_H -#include <glib.h> +#include <glib/gtypes.h> +#include <glib-object.h> G_BEGIN_DECLS -typedef struct _NMSetting NMSetting; +#define NM_TYPE_SETTING (nm_setting_get_type ()) +#define NM_SETTING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING, NMSetting)) +#define NM_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING, NMSettingClass)) +#define NM_IS_SETTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING)) +#define NM_IS_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING)) +#define NM_SETTING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING, NMSettingClass)) -typedef NMSetting *(*NMSettingCreateFn) (void); -typedef gboolean (*NMSettingPopulateFn) (NMSetting *setting, - GHashTable *hash); -typedef gboolean (*NMSettingVerifyFn) (NMSetting *setting, - GHashTable *all_settings); +#define NM_SETTING_PARAM_SERIALIZE (1 << (0 + G_PARAM_USER_SHIFT)) +#define NM_SETTING_PARAM_REQUIRED (1 << (1 + G_PARAM_USER_SHIFT)) +#define NM_SETTING_PARAM_SECRET (1 << (2 + G_PARAM_USER_SHIFT)) -typedef GHashTable *(*NMSettingToHashFn) (NMSetting *setting); - -typedef gboolean (*NMSettingUpdateSecretsFn) (NMSetting *setting, - GHashTable *secrets); - -typedef GPtrArray *(*NMSettingNeedSecretsFn) (NMSetting *setting); - -typedef void (*NMSettingClearSecretsFn) (NMSetting *setting); - -typedef gboolean (*NMSettingCompareFn) (NMSetting *setting, - NMSetting *other, - gboolean two_way); - -typedef void (*NMSettingDestroyFn) (NMSetting *setting); - -typedef void (*NMSettingValueIterFn) (NMSetting *setting, - const char *key, - guint32 type, - void *value, - gboolean secret, - gpointer user_data); - -#define NM_S_TYPE_STRING 1 -#define NM_S_TYPE_UINT32 2 -#define NM_S_TYPE_BOOL 3 -#define NM_S_TYPE_BYTE_ARRAY 4 -#define NM_S_TYPE_STRING_ARRAY 5 -#define NM_S_TYPE_GVALUE_HASH 6 -#define NM_S_TYPE_UINT64 7 -#define NM_S_TYPE_UINT_ARRAY 8 - -#define NM_S_TYPE_IP4_ADDRESSES 9 - - -typedef struct SettingMember { - const char *key; - guint32 type; - gulong offset; - gboolean required; - gboolean secret; -} SettingMember; - -struct _NMSetting { - char *name; - SettingMember *_members; /* Private */ - - NMSettingPopulateFn populate_fn; - NMSettingVerifyFn verify_fn; - NMSettingToHashFn hash_fn; - NMSettingUpdateSecretsFn update_secrets_fn; - NMSettingNeedSecretsFn need_secrets_fn; - NMSettingClearSecretsFn clear_secrets_fn; - NMSettingCompareFn compare_fn; - NMSettingDestroyFn destroy_fn; -}; - -gboolean nm_settings_verify_all (GHashTable *all_settings); - -gboolean nm_setting_populate_from_hash (NMSetting *setting, GHashTable *hash); -gboolean nm_setting_verify (NMSetting *setting); -gboolean nm_setting_compare (NMSetting *setting, NMSetting *other, gboolean two_way); -GHashTable *nm_setting_to_hash (NMSetting *setting); -gboolean nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets); -GPtrArray * nm_setting_need_secrets (NMSetting *setting); -void nm_setting_clear_secrets (NMSetting *setting); -void nm_setting_destroy (NMSetting *setting); -void nm_setting_enumerate_values (NMSetting *setting, - NMSettingValueIterFn func, - gpointer user_data); - -/* Default, built-in settings */ - -/* Connection */ - -#define NM_SETTING_CONNECTION "connection" +#define NM_SETTING_NAME "name" typedef struct { - NMSetting parent; + GObject parent; char *name; - char *type; - gboolean autoconnect; - guint64 timestamp; -} NMSettingConnection; - -NMSetting *nm_setting_connection_new (void); - -/* IP4 config */ - -#define NM_SETTING_IP4_CONFIG "ipv4" +} NMSetting; typedef struct { - guint32 address; - guint32 netmask; - guint32 gateway; -} NMSettingIP4Address; + GObjectClass parent; -typedef struct { - NMSetting parent; + /* Virtual functions */ + gboolean (*verify) (NMSetting *setting, + GSList *all_settings); - gboolean manual; - GArray *dns; - GSList *dns_search; /* GSList of strings */ - GSList *addresses; /* GSList of NMSettingIP4Address */ -} NMSettingIP4Config; + GPtrArray *(*need_secrets) (NMSetting *setting); +} NMSettingClass; -NMSetting *nm_setting_ip4_config_new (void); +typedef void (*NMSettingValueIterFn) (NMSetting *setting, + const char *key, + const GValue *value, + gboolean secret, + gpointer user_data); -/* Wired device */ -#define NM_SETTING_WIRED "802-3-ethernet" +GType nm_setting_get_type (void); -typedef struct { - NMSetting parent; +GHashTable *nm_setting_to_hash (NMSetting *setting); +NMSetting *nm_setting_from_hash (GType setting_type, + GHashTable *hash); - char *port; - guint32 speed; - char *duplex; - gboolean auto_negotiate; - GByteArray *mac_address; - guint32 mtu; -} NMSettingWired; +const char *nm_setting_get_name (NMSetting *setting); -NMSetting *nm_setting_wired_new (void); +gboolean nm_setting_verify (NMSetting *setting, + GSList *all_settings); -/* Wireless device */ - -#define NM_SETTING_WIRELESS "802-11-wireless" - -typedef struct { - NMSetting parent; +gboolean nm_setting_compare (NMSetting *setting, + NMSetting *other); - GByteArray *ssid; - char *mode; - char *band; - guint32 channel; - GByteArray *bssid; - guint32 rate; - guint32 tx_power; - GByteArray *mac_address; - guint32 mtu; - GSList *seen_bssids; - char *security; -} NMSettingWireless; - -NMSetting *nm_setting_wireless_new (void); - -/* Wireless security */ - -#define NM_SETTING_WIRELESS_SECURITY "802-11-wireless-security" - -typedef struct { - NMSetting parent; - - char *key_mgmt; - guint32 wep_tx_keyidx; - char *auth_alg; - GSList *proto; /* GSList of strings */ - GSList *pairwise; /* GSList of strings */ - GSList *group; /* GSList of strings */ - GSList *eap; /* GSList of strings */ - char *identity; - char *anonymous_identity; - GByteArray *ca_cert; - char *ca_path; - GByteArray *client_cert; - GByteArray *private_key; - char *phase1_peapver; - char *phase1_peaplabel; - char *phase1_fast_provisioning; - char *phase2_auth; - char *phase2_autheap; - GByteArray *phase2_ca_cert; - char *phase2_ca_path; - GByteArray *phase2_client_cert; - GByteArray *phase2_private_key; - char *nai; - char *wep_key0; - char *wep_key1; - char *wep_key2; - char *wep_key3; - char *psk; - char *password; - char *pin; - char *eappsk; - char *private_key_passwd; - char *phase2_private_key_passwd; -} NMSettingWirelessSecurity; - -NMSetting *nm_setting_wireless_security_new (void); - -/* PPP */ - -#define NM_SETTING_PPP "ppp" - -typedef struct { - NMSetting parent; - - gboolean noauth; - gboolean refuse_eap; - gboolean refuse_chap; - gboolean refuse_mschap; - gboolean nobsdcomp; - gboolean nodeflate; - gboolean require_mppe; - gboolean require_mppe_128; - gboolean mppe_stateful; - gboolean require_mppc; - gboolean crtscts; - gboolean usepeerdns; - - gint32 baud; - gint32 mru; - gint32 mtu; - gint32 lcp_echo_failure; - gint32 lcp_echo_interval; -} NMSettingPPP; - -NMSetting *nm_setting_ppp_new (void); - -/* VPN */ - -#define NM_SETTING_VPN "vpn" - -typedef struct { - NMSetting parent; - - char *service_type; - char *user_name; - GSList *routes; -} NMSettingVPN; - -NMSetting *nm_setting_vpn_new (void); - -/* VPN properties */ - -#define NM_SETTING_VPN_PROPERTIES "vpn-properties" - -typedef struct { - NMSetting parent; +void nm_setting_enumerate_values (NMSetting *setting, + NMSettingValueIterFn func, + gpointer user_data); - GHashTable *data; -} NMSettingVPNProperties; +char *nm_setting_to_string (NMSetting *setting); -NMSetting *nm_setting_vpn_properties_new (void); +/* Secrets */ +void nm_setting_clear_secrets (NMSetting *setting); +GPtrArray *nm_setting_need_secrets (NMSetting *setting); +void nm_setting_update_secrets (NMSetting *setting, + GHashTable *secrets); G_END_DECLS #endif /* NM_SETTING_H */ + diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 9a3474adb5..4910e9054b 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + /* NetworkManager -- Network link manager * * Ray Strode <rstrode@redhat.com> @@ -28,7 +30,7 @@ #include <glib.h> #include <glib-object.h> -#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> #include "nm-utils.h" #include "NetworkManager.h" @@ -377,6 +379,86 @@ nm_utils_garray_to_string (GArray *array) return g_string_free (str, FALSE); } +void +nm_utils_slist_free (GSList *list, GDestroyNotify elem_destroy_fn) +{ + if (!list) + return; + + if (elem_destroy_fn) + g_slist_foreach (list, (GFunc) elem_destroy_fn, NULL); + + g_slist_free (list); +} + +gboolean +nm_utils_string_in_list (const char *str, const char **valid_strings) +{ + int i; + + for (i = 0; valid_strings[i]; i++) + if (strcmp (str, valid_strings[i]) == 0) + break; + + return valid_strings[i] != NULL; +} + +gboolean +nm_utils_string_list_contains (GSList *list, const char *string) +{ + GSList *iter; + + g_return_val_if_fail (string != NULL, FALSE); + + for (iter = list; iter; iter = g_slist_next (iter)) + if (!strcmp (iter->data, string)) + return TRUE; + return FALSE; +} + +gboolean +nm_utils_string_slist_validate (GSList *list, const char **valid_values) +{ + GSList *iter; + + for (iter = list; iter; iter = iter->next) { + if (!nm_utils_string_in_list ((char *) iter->data, valid_values)) + return FALSE; + } + + return TRUE; +} + +static void +nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value) +{ + char **str; + GSList *list = NULL; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); + + str = (char **) g_value_get_boxed (src_value); + + while (str[i]) + list = g_slist_prepend (list, g_strdup (str[i++])); + + g_value_set_boxed (dest_value, g_slist_reverse (list)); +} + +void +nm_utils_register_value_transformations (void) +{ + static gboolean registered = FALSE; + + if (G_UNLIKELY (!registered)) { + g_value_register_transform_func (G_TYPE_STRV, + dbus_g_type_get_collection ("GSList", G_TYPE_STRING), + nm_utils_convert_strv_to_slist); + registered = TRUE; + } +} + static gboolean device_supports_ap_ciphers (guint32 dev_caps, guint32 ap_flags, @@ -545,174 +627,3 @@ nm_utils_security_valid (NMUtilsSecurityType type, return good; } - - -static gboolean -match_cipher (const char *cipher, - const char *expected, - guint32 wpa_flags, - guint32 rsn_flags, - guint32 flag) -{ - if (strcmp (cipher, expected) != 0) - return FALSE; - - if (!(wpa_flags & flag) && !(rsn_flags & flag)) - return FALSE; - - return TRUE; -} - -gboolean -nm_utils_ap_security_compatible (NMConnection *connection, - guint32 ap_flags, - guint32 ap_wpa, - guint32 ap_rsn, - guint32 ap_mode) -{ - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wireless_sec; - - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); - if (!s_wireless) - return FALSE; - - if (!s_wireless->security) { - if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) - || (ap_wpa != NM_802_11_AP_SEC_NONE) - || (ap_rsn != NM_802_11_AP_SEC_NONE)) - return FALSE; - return TRUE; - } - - if (strcmp (s_wireless->security, NM_SETTING_WIRELESS_SECURITY) != 0) - return FALSE; - - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS_SECURITY); - if (s_wireless_sec == NULL || !s_wireless_sec->key_mgmt) - return FALSE; - - /* Static WEP */ - if (!strcmp (s_wireless_sec->key_mgmt, "none")) { - if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) - || (ap_wpa != NM_802_11_AP_SEC_NONE) - || (ap_rsn != NM_802_11_AP_SEC_NONE)) - return FALSE; - return TRUE; - } - - /* Adhoc WPA */ - if (!strcmp (s_wireless_sec->key_mgmt, "wpa-none")) { - if (ap_mode != IW_MODE_ADHOC) - return FALSE; - // FIXME: validate ciphers if the BSSID actually puts WPA/RSN IE in - // it's beacon - return TRUE; - } - - /* Stuff after this point requires infrastructure */ - if (ap_mode != IW_MODE_INFRA) - return FALSE; - - /* Dynamic WEP or LEAP */ - if (!strcmp (s_wireless_sec->key_mgmt, "ieee8021x")) { - if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) - return FALSE; - - /* If the AP is advertising a WPA IE, make sure it supports WEP ciphers */ - if (ap_wpa != NM_802_11_AP_SEC_NONE) { - gboolean found = FALSE; - GSList *iter; - - if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) - return FALSE; - - /* quick check; can't use AP if it doesn't support at least one - * WEP cipher in both pairwise and group suites. - */ - if ( !(ap_wpa & (NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104)) - || !(ap_wpa & (NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104))) - return FALSE; - - /* Match at least one pairwise cipher with AP's capability */ - for (iter = s_wireless_sec->pairwise; iter; iter = g_slist_next (iter)) { - if ((found = match_cipher (iter->data, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP40))) - break; - if ((found = match_cipher (iter->data, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP104))) - break; - } - if (!found) - return FALSE; - - /* Match at least one group cipher with AP's capability */ - for (iter = s_wireless_sec->group; iter; iter = g_slist_next (iter)) { - if ((found = match_cipher (iter->data, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP40))) - break; - if ((found = match_cipher (iter->data, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP104))) - break; - } - if (!found) - return FALSE; - } - return TRUE; - } - - /* WPA[2]-PSK and WPA[2] Enterprise */ - if ( !strcmp (s_wireless_sec->key_mgmt, "wpa-psk") - || !strcmp (s_wireless_sec->key_mgmt, "wpa-eap")) { - GSList * elt; - gboolean found = FALSE; - - if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) - return FALSE; - - if (!s_wireless_sec->pairwise || !s_wireless_sec->group) - return FALSE; - - if (!strcmp (s_wireless_sec->key_mgmt, "wpa-psk")) { - if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) - && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) - return FALSE; - } else if (!strcmp (s_wireless_sec->key_mgmt, "wpa-eap")) { - if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X) - && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) - return FALSE; - } - - // FIXME: should handle WPA and RSN separately here to ensure that - // if the Connection only uses WPA we don't match a cipher against - // the AP's RSN IE instead - - /* Match at least one pairwise cipher with AP's capability */ - for (elt = s_wireless_sec->pairwise; elt; elt = g_slist_next (elt)) { - if ((found = match_cipher (elt->data, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_TKIP))) - break; - if ((found = match_cipher (elt->data, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_CCMP))) - break; - } - if (!found) - return FALSE; - - /* Match at least one group cipher with AP's capability */ - for (elt = s_wireless_sec->group; elt; elt = g_slist_next (elt)) { - if ((found = match_cipher (elt->data, "wep40", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP40))) - break; - if ((found = match_cipher (elt->data, "wep104", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP104))) - break; - if ((found = match_cipher (elt->data, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_TKIP))) - break; - if ((found = match_cipher (elt->data, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_CCMP))) - break; - } - if (!found) - return FALSE; - - return TRUE; - } - - return FALSE; -} - diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index 831b36e170..a96a0981aa 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -140,6 +140,19 @@ char *nm_utils_ssid_to_utf8 (const char *ssid, guint32 len); GHashTable *nm_utils_gvalue_hash_dup (GHashTable *hash); char *nm_utils_garray_to_string (GArray *array); +void nm_utils_slist_free (GSList *list, + GDestroyNotify elem_destroy_fn); + +gboolean nm_utils_string_in_list (const char *str, + const char **valid_strings); + +gboolean nm_utils_string_list_contains (GSList *list, + const char *string); + +gboolean nm_utils_string_slist_validate (GSList *list, + const char **valid_values); + +void nm_utils_register_value_transformations (void); typedef enum { NMU_SEC_INVALID = 0, diff --git a/src/NetworkManagerAP.c b/src/NetworkManagerAP.c index 655453a22e..a246a62ea8 100644 --- a/src/NetworkManagerAP.c +++ b/src/NetworkManagerAP.c @@ -27,6 +27,7 @@ #include <wireless.h> #include "wpa.h" #include "nm-properties-changed-signal.h" +#include "nm-setting-wireless.h" #include "nm-access-point-glue.h" @@ -546,7 +547,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection) g_return_val_if_fail (connection != NULL, NULL); - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); g_return_val_if_fail (s_wireless != NULL, NULL); g_return_val_if_fail (s_wireless->ssid != NULL, NULL); g_return_val_if_fail (s_wireless->ssid->len > 0, NULL); @@ -581,7 +582,8 @@ nm_ap_new_fake_from_connection (NMConnection *connection) nm_ap_set_freq (ap, freq); } - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS_SECURITY); + s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS_SECURITY)); if (!s_wireless_sec) goto done; @@ -1188,13 +1190,14 @@ nm_ap_check_compatible (NMAccessPoint *self, { NMAccessPointPrivate *priv; NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wireless_sec; g_return_val_if_fail (NM_IS_AP (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); priv = NM_AP_GET_PRIVATE (self); - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, "802-11-wireless"); + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); if (s_wireless == NULL) return FALSE; @@ -1232,11 +1235,15 @@ nm_ap_check_compatible (NMAccessPoint *self, return FALSE; } - return nm_utils_ap_security_compatible (connection, - nm_ap_get_flags (self), - nm_ap_get_wpa_flags (self), - nm_ap_get_rsn_flags (self), - nm_ap_get_mode (self)); + s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS_SECURITY); + + return nm_setting_wireless_ap_security_compatible (s_wireless, + s_wireless_sec, + nm_ap_get_flags (self), + nm_ap_get_wpa_flags (self), + nm_ap_get_rsn_flags (self), + nm_ap_get_mode (self)); } static gboolean diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 1f05193159..04d06cf370 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -38,7 +38,7 @@ #include "nm-device-802-11-wireless.h" #include "nm-device-802-3-ethernet.h" #include "nm-dbus-manager.h" -#include "nm-setting.h" +#include "nm-setting-connection.h" struct NMPolicy { NMManager *manager; @@ -66,7 +66,7 @@ get_connection_name (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_SETTING_CONNECTION); + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_return_val_if_fail (s_con != NULL, NULL); return s_con->name; @@ -345,8 +345,8 @@ nm_policy_device_change_check (gpointer user_data) same_activating = TRUE; if (!same_activating && !old_has_link && (old_mode != IW_MODE_ADHOC)) { - NMSettingConnection * new_sc = (NMSettingConnection *) nm_connection_get_setting (connection, NM_SETTING_CONNECTION); - NMSettingConnection * old_sc = (NMSettingConnection *) nm_connection_get_setting (old_connection, NM_SETTING_CONNECTION); + NMSettingConnection * new_sc = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + NMSettingConnection * old_sc = (NMSettingConnection *) nm_connection_get_setting (old_connection, NM_TYPE_SETTING_CONNECTION); nm_info ("SWITCH: found better connection '%s/%s'" " than current connection '%s/%s'. " diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index d399e222cc..025fa7ed4e 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -24,6 +24,7 @@ #include "nm-activation-request.h" #include "nm-marshal.h" #include "nm-utils.h" +#include "nm-setting-wireless.h" #include "nm-manager.h" /* FIXME! */ @@ -195,13 +196,12 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) * yes, replace the setting object in the connection. If not, just try * updating the secrets. */ - setting = nm_setting_wireless_security_new (); - nm_setting_populate_from_hash (setting, secrets); - if (nm_setting_verify (setting)) + setting = nm_setting_from_hash (NM_TYPE_SETTING_WIRELESS, secrets); + if (nm_setting_verify (setting, NULL)) nm_connection_add_setting (priv->connection, setting); else { nm_connection_update_secrets (priv->connection, info->setting_name, secrets); - nm_setting_destroy (setting); + g_object_unref (setting); } g_signal_emit (info->req, diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index acab00423d..473b912fc7 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -44,6 +44,8 @@ #include "nm-supplicant-interface.h" #include "nm-supplicant-config.h" #include "nm-properties-changed-signal.h" +#include "nm-setting-connection.h" +#include "nm-setting-wireless.h" static gboolean impl_device_get_access_points (NMDevice80211Wireless *device, GPtrArray **aps, @@ -750,15 +752,15 @@ find_best_connection (gpointer data, gpointer user_data) if (info->found) return; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_SETTING_CONNECTION); + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); if (s_con == NULL) return; - if (strcmp (s_con->type, NM_SETTING_WIRELESS)) + if (strcmp (s_con->type, NM_SETTING_WIRELESS_SETTING_NAME)) return; if (!s_con->autoconnect) return; - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (s_wireless == NULL) return; @@ -1588,7 +1590,8 @@ ap_auth_enforced (NMConnection *connection, /* No way to tell if the key is wrong with Open System * auth mode in WEP. Auth is not enforced like Shared Key. */ - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS_SECURITY); + s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS_SECURITY); if (s_wireless_sec && (!s_wireless_sec->auth_alg || !strcmp (s_wireless_sec->auth_alg, "open"))) @@ -2323,7 +2326,7 @@ build_supplicant_config (NMDevice80211Wireless *self, g_return_val_if_fail (self != NULL, NULL); - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, "802-11-wireless"); + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); g_return_val_if_fail (s_wireless != NULL, NULL); config = nm_supplicant_config_new (); @@ -2337,7 +2340,8 @@ build_supplicant_config (NMDevice80211Wireless *self, goto error; } - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, "802-11-wireless-security"); + s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS_SECURITY); if (s_wireless_sec) { DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG); const char *con_path = dbus_g_proxy_get_path (proxy); @@ -2461,7 +2465,7 @@ real_connection_secrets_updated (NMDevice *dev, if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH) return; - if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY) != 0) { + if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0) { nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); return; } @@ -2501,7 +2505,7 @@ real_act_stage2_config (NMDevice *dev) connection = nm_act_request_get_connection (req); g_assert (connection); - s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, NM_SETTING_CONNECTION); + s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_connection); /* If we need secrets, get them */ @@ -2527,7 +2531,8 @@ real_act_stage2_config (NMDevice *dev) g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); return NM_ACT_STAGE_RETURN_POSTPONE; } else { - NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); + NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS); if (s_wireless->security) { nm_info ("Activation (%s/wireless): connection '%s' has security" diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index 7b4a8b5fb4..6124ad6575 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + /* NetworkManager -- Network link manager * * Dan Williams <dcbw@redhat.com> @@ -33,6 +35,9 @@ #include "NetworkManagerUtils.h" #include "nm-supplicant-manager.h" #include "nm-netlink-monitor.h" +#include "NetworkManagerSystem.h" +#include "nm-setting-connection.h" +#include "nm-setting-wired.h" #include "nm-utils.h" #include "nm-device-802-3-ethernet-glue.h" @@ -107,8 +112,8 @@ constructor (GType type, guint32 caps; object = G_OBJECT_CLASS (nm_device_802_3_ethernet_parent_class)->constructor (type, - n_construct_params, - construct_params); + n_construct_params, + construct_params); if (!object) return NULL; @@ -123,11 +128,12 @@ constructor (GType type, NMNetlinkMonitor * monitor = nm_netlink_monitor_get (); priv->link_connected_id = g_signal_connect (monitor, "interface-connected", - G_CALLBACK (nm_device_802_3_ethernet_link_activated), - dev); + G_CALLBACK (nm_device_802_3_ethernet_link_activated), + dev); priv->link_disconnected_id = g_signal_connect (monitor, "interface-disconnected", - G_CALLBACK (nm_device_802_3_ethernet_link_deactivated), - dev); + G_CALLBACK (nm_device_802_3_ethernet_link_deactivated), + dev); + g_object_unref (monitor); } else { priv->link_connected_id = 0; @@ -292,8 +298,6 @@ real_set_hw_address (NMDevice *dev) nm_dev_sock_close (sk); } - - static guint32 real_get_generic_capabilities (NMDevice *dev) { @@ -350,15 +354,15 @@ find_best_connection (gpointer data, gpointer user_data) if (info->found) return; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_SETTING_CONNECTION); + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); if (s_con == NULL) return; - if (strcmp (s_con->type, NM_SETTING_WIRED)) + if (strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME)) return; if (!s_con->autoconnect) return; - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_SETTING_WIRED); + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (s_wired == NULL) return; @@ -390,7 +394,6 @@ real_get_best_connection (NMDevice *dev, return find_info.found; } - static void nm_device_802_3_ethernet_dispose (GObject *object) { diff --git a/src/nm-device.c b/src/nm-device.c index 8fcaee7816..74f14c326b 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -38,6 +38,7 @@ #include "nm-utils.h" #include "autoip.h" #include "nm-netlink.h" +#include "nm-setting-ip4-config.h" #define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config" @@ -192,8 +193,11 @@ constructor (GType type, nm_info ("(%s): exporting device as %s", nm_device_get_iface (dev), nm_device_get_dbus_path (dev)); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (manager), - nm_device_get_dbus_path (dev), - object); + nm_device_get_dbus_path (dev), + object); + + g_object_unref (manager); + priv->initialized = TRUE; return object; @@ -557,7 +561,7 @@ real_act_stage3_ip_config_start (NMDevice *self) req = nm_device_get_act_request (self); setting = (NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req), - NM_SETTING_IP4_CONFIG); + NM_TYPE_SETTING_IP4_CONFIG); /* If we did not receive IP4 configuration information, default to DHCP */ if (!setting || setting->manual == FALSE) { @@ -741,7 +745,7 @@ real_act_stage4_get_ip4_config (NMDevice *self, req = nm_device_get_act_request (self); merge_ip4_config (real_config, (NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req), - NM_SETTING_IP4_CONFIG)); + NM_TYPE_SETTING_IP4_CONFIG)); *config = real_config; ret = NM_ACT_STAGE_RETURN_SUCCESS; diff --git a/src/nm-manager.c b/src/nm-manager.c index 20c27f0c33..5744b4deca 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -10,6 +10,8 @@ #include "nm-device-802-11-wireless.h" #include "NetworkManagerSystem.h" #include "nm-properties-changed-signal.h" +#include "nm-setting-connection.h" +#include "nm-setting-wireless.h" #include "nm-marshal.h" static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); @@ -947,7 +949,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, NMSettingWireless *s_wireless; GSList *seen_iter; - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (!s_wireless || !s_wireless->seen_bssids) goto next; g_assert (s_wireless->ssid); @@ -1557,9 +1559,9 @@ connection_sort (gconstpointer pa, gconstpointer pb) NMConnection *b = NM_CONNECTION (pb); NMSettingConnection *con_b; - con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_SETTING_CONNECTION); + con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); g_assert (con_a); - con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_SETTING_CONNECTION); + con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); g_assert (con_b); if (con_a->autoconnect != con_b->autoconnect) { diff --git a/src/ppp-manager/Makefile.am b/src/ppp-manager/Makefile.am index 020dd090ac..5290f4dd08 100644 --- a/src/ppp-manager/Makefile.am +++ b/src/ppp-manager/Makefile.am @@ -13,10 +13,10 @@ libppp_manager_la_SOURCES = \ nm-ppp-status.h libppp_manager_la_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(HAL_CFLAGS) \ - -DG_DISABLE_DEPRECATED \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ + $(DBUS_CFLAGS) \ + $(HAL_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ -DLIBDIR=\"$(libdir)\" libppp_manager_la_LIBADD = \ @@ -24,18 +24,20 @@ libppp_manager_la_LIBADD = \ $(GLIB_LIBS) \ $(top_builddir)/src/marshallers/libmarshallers.la -nm_pppd_plugindir = $(libdir) -nm_pppd_plugin_PROGRAMS = nm-pppd-plugin.so +lib_LTLIBRARIES = nm-pppd-plugin.la -nm_pppd_plugin_so_SOURCES = \ - nm-pppd-plugin.c \ - nm-pppd-plugin.h \ +nm_pppd_plugin_la_SOURCES = \ + nm-pppd-plugin.c \ + nm-pppd-plugin.h \ nm-ppp-status.h -nm_pppd_plugin_so_CPPFLAGS = $(DBUS_CFLAGS) $(GLIB_CFLAGS) -fPIC +nm_pppd_plugin_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) -nm_pppd_plugin_so_LDFLAGS = -shared -nm_pppd_plugin_so_LDADD = \ +nm_pppd_plugin_la_LDFLAGS = -module -avoid-version + +nm_pppd_plugin_la_LIBADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(top_builddir)/libnm-util/libnm-util.la diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 8b4c332fd9..4e2790ace4 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -5,7 +5,7 @@ #include <glib-object.h> #include "nm-ppp-status.h" -#include "nm-setting.h" +#include "nm-setting-ppp.h" #include "nm-ip4-config.h" #include "nm-pppd-plugin.h" diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h index e8997f6201..9b6c660f6e 100644 --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -23,8 +23,8 @@ #define NM_SUPPLICANT_CONFIG_H #include <glib-object.h> +#include <nm-setting-wireless.h> #include "nm-supplicant-types.h" -#include "nm-setting.h" G_BEGIN_DECLS diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index d5675d6b10..c82acbea28 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -30,6 +30,8 @@ #include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" +#include "nm-setting-connection.h" +#include "nm-setting-vpn.h" #include "nm-dbus-manager.h" #include "nm-manager.h" #include "NetworkManagerSystem.h" @@ -142,7 +144,7 @@ nm_vpn_connection_get_service (NMVPNConnection *connection) NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMSettingVPN *setting; - setting = (NMSettingVPN *) nm_connection_get_setting (priv->connection, NM_SETTING_VPN); + setting = (NMSettingVPN *) nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_VPN); return setting->service_type; } @@ -152,7 +154,7 @@ nm_vpn_connection_get_routes (NMVPNConnection *connection) NMSettingVPN *setting; setting = (NMSettingVPN *) nm_connection_get_setting (NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection, - NM_SETTING_VPN); + NM_TYPE_SETTING_VPN); return setting->routes; } @@ -445,7 +447,7 @@ nm_vpn_connection_get_name (NMVPNConnection *connection) g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - setting = (NMSettingConnection *) nm_connection_get_setting (priv->connection, NM_SETTING_CONNECTION); + setting = (NMSettingConnection *) nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_CONNECTION); return setting->name; } diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 9e918caa10..02a03ea797 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -5,6 +5,7 @@ #include "nm-vpn-manager.h" #include "nm-vpn-service.h" #include "nm-vpn-connection.h" +#include "nm-setting-vpn.h" #include "nm-manager.h" #include "nm-dbus-manager.h" #include "NetworkManagerVPN.h" @@ -80,7 +81,7 @@ nm_vpn_manager_connect (NMVPNManager *manager, if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) return NULL; - vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_SETTING_VPN); + vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); if (!vpn_setting) return NULL; |