summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--libnm-util/Makefile.am32
-rw-r--r--libnm-util/nm-connection.c378
-rw-r--r--libnm-util/nm-connection.h25
-rw-r--r--libnm-util/nm-param-spec-specialized.c710
-rw-r--r--libnm-util/nm-param-spec-specialized.h23
-rw-r--r--libnm-util/nm-setting-connection.c165
-rw-r--r--libnm-util/nm-setting-connection.h43
-rw-r--r--libnm-util/nm-setting-ip4-config.c214
-rw-r--r--libnm-util/nm-setting-ip4-config.h49
-rw-r--r--libnm-util/nm-setting-ppp.c326
-rw-r--r--libnm-util/nm-setting-ppp.h70
-rw-r--r--libnm-util/nm-setting-template.c78
-rw-r--r--libnm-util/nm-setting-template.h33
-rw-r--r--libnm-util/nm-setting-vpn-properties.c105
-rw-r--r--libnm-util/nm-setting-vpn-properties.h36
-rw-r--r--libnm-util/nm-setting-vpn.c142
-rw-r--r--libnm-util/nm-setting-vpn.h41
-rw-r--r--libnm-util/nm-setting-wired.c200
-rw-r--r--libnm-util/nm-setting-wired.h47
-rw-r--r--libnm-util/nm-setting-wireless-security.c982
-rw-r--r--libnm-util/nm-setting-wireless-security.h101
-rw-r--r--libnm-util/nm-setting-wireless.c508
-rw-r--r--libnm-util/nm-setting-wireless.h65
-rw-r--r--libnm-util/nm-setting.c1944
-rw-r--r--libnm-util/nm-setting.h278
-rw-r--r--libnm-util/nm-utils.c255
-rw-r--r--libnm-util/nm-utils.h13
-rw-r--r--src/NetworkManagerAP.c23
-rw-r--r--src/NetworkManagerPolicy.c8
-rw-r--r--src/nm-activation-request.c8
-rw-r--r--src/nm-device-802-11-wireless.c23
-rw-r--r--src/nm-device-802-3-ethernet.c27
-rw-r--r--src/nm-device.c12
-rw-r--r--src/nm-manager.c8
-rw-r--r--src/ppp-manager/Makefile.am26
-rw-r--r--src/ppp-manager/nm-ppp-manager.h2
-rw-r--r--src/supplicant-manager/nm-supplicant-config.h2
-rw-r--r--src/vpn-manager/nm-vpn-connection.c8
-rw-r--r--src/vpn-manager/nm-vpn-manager.c3
40 files changed, 4674 insertions, 2374 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c59c2803c..222b3bc32c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;