diff options
Diffstat (limited to 'libnm-core/nm-connection.c')
-rw-r--r-- | libnm-core/nm-connection.c | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 2b52e7a340..9fdee460d6 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -22,11 +22,9 @@ #include <glib-object.h> #include <glib/gi18n.h> -#include <dbus/dbus-glib.h> #include <string.h> #include "nm-connection.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" #include "nm-setting-8021x.h" @@ -310,56 +308,62 @@ _get_type_setting (NMConnection *connection) } static gboolean -validate_permissions_type (GHashTable *hash, GError **error) +validate_permissions_type (GVariant *variant, GError **error) { - GHashTable *s_con; - GValue *permissions; + GVariant *s_con; + GVariant *permissions; + gboolean valid = TRUE; /* Ensure the connection::permissions item (if present) is the correct * type, otherwise the g_object_set() will throw a warning and ignore the * error, leaving us with no permissions. */ - s_con = g_hash_table_lookup (hash, NM_SETTING_CONNECTION_SETTING_NAME); - if (s_con) { - permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS); - if (permissions) { - if ( !G_VALUE_HOLDS (permissions, G_TYPE_STRV) - && !G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) { - g_set_error_literal (error, - NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Wrong permissions property type; should be a list of strings."); - return FALSE; - } + s_con = g_variant_lookup_value (variant, NM_SETTING_CONNECTION_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!s_con) + return TRUE; + + permissions = g_variant_lookup_value (s_con, NM_SETTING_CONNECTION_PERMISSIONS, NULL); + if (permissions) { + if (!g_variant_is_of_type (permissions, G_VARIANT_TYPE_STRING_ARRAY)) { + g_set_error_literal (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Wrong permissions property type; should be a list of strings."); + valid = FALSE; } + g_variant_unref (permissions); } - return TRUE; + + g_variant_unref (s_con); + return valid; } static gboolean -hash_to_connection (NMConnection *connection, GHashTable *new, GError **error) +variant_to_connection (NMConnection *connection, GVariant *new, GError **error) { - GHashTableIter iter; + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + GVariantIter iter; const char *setting_name; - GHashTable *setting_hash; + GVariant *setting_vardict; gboolean changed, valid; - NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); if ((changed = g_hash_table_size (priv->settings) > 0)) g_hash_table_remove_all (priv->settings); - g_hash_table_iter_init (&iter, new); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + g_variant_iter_init (&iter, new); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, &setting_vardict)) { GType type = nm_connection_lookup_setting_type (setting_name); if (type) { - NMSetting *setting = nm_setting_new_from_hash (type, setting_hash); + NMSetting *setting = nm_setting_new_from_variant (type, setting_vardict); if (setting) { _nm_connection_add_setting (connection, setting); changed = TRUE; } } + + g_variant_unref (setting_vardict); } valid = nm_connection_verify (connection, error); @@ -371,7 +375,7 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error) /** * nm_connection_replace_settings: * @connection: a #NMConnection - * @new_settings: (element-type utf8 GLib.HashTable): a #GHashTable of settings + * @new_settings: a #GVariant of type `a{sa{sv}}`, with the new settings * @error: location to store error, or %NULL * * Returns: %TRUE if the settings were valid and added to the connection, %FALSE @@ -379,18 +383,18 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error) **/ gboolean nm_connection_replace_settings (NMConnection *connection, - GHashTable *new_settings, + GVariant *new_settings, GError **error) { gboolean valid = FALSE; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (new_settings != NULL, FALSE); + g_return_val_if_fail (g_variant_is_of_type (new_settings, NM_VARIANT_TYPE_CONNECTION), FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); if (validate_permissions_type (new_settings, error)) - valid = hash_to_connection (connection, new_settings, error); + valid = variant_to_connection (connection, new_settings, error); return valid; } @@ -944,16 +948,16 @@ EXIT: * nm_connection_update_secrets: * @connection: the #NMConnection * @setting_name: the setting object name to which the secrets apply - * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping - * string:#GValue of setting property names and secrets of the given @setting_name + * @secrets: a #GVariant of secrets, in either "connection" format (`a{sa{sv}}`) + * or "setting" format (`a{sv}`) * @error: location to store error, or %NULL * - * Update the specified setting's secrets, given a hash table of secrets - * intended for that setting (deserialized from D-Bus for example). Will also - * extract the given setting's secrets hash if given a hash of hashes, as would - * be returned from nm_connection_to_hash(). If @setting_name is %NULL, expects - * a fully serialized #NMConnection as returned by nm_connection_to_hash() and - * will update all secrets from all settings contained in @secrets. + * Update the specified setting's secrets, given a dictionary of secrets + * intended for that setting (deserialized from D-Bus for example). @secrets + * can be either an `a{sv}` containing secrets only for @setting_name, or else + * an `a{sa{sv}}` containing @setting_name's secrets as one of its items. If + * @setting_name is %NULL, @secrets must be an `a{sa{sv}}`, and all secrets + * it contains will be updated in @connection. * * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update * failed (tried to update secrets for a setting that doesn't exist, etc) @@ -961,38 +965,28 @@ EXIT: gboolean nm_connection_update_secrets (NMConnection *connection, const char *setting_name, - GHashTable *secrets, + GVariant *secrets, GError **error) { NMSetting *setting; gboolean success = TRUE, updated = FALSE; - GHashTable *setting_hash = NULL; - GHashTableIter iter; + GVariant *setting_dict = NULL; + GVariantIter iter; const char *key; - gboolean hashed_connection = FALSE; + gboolean hashed_connection; int success_detail; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); + g_return_val_if_fail ( g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING) + || g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION), FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); /* Empty @secrets means success */ - if (g_hash_table_size (secrets) == 0) + if (g_variant_n_children (secrets) == 0) return TRUE; - /* For backwards compatibility, this function accepts either a hashed - * connection (GHashTable of GHashTables of GValues) or a single hashed - * setting (GHashTable of GValues). - */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) { - if (_nm_setting_lookup_setting_type (key) != G_TYPE_INVALID) { - /* @secrets looks like a hashed connection */ - hashed_connection = TRUE; - break; - } - } + hashed_connection = g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION); if (setting_name) { /* Update just one setting's secrets */ @@ -1006,9 +1000,9 @@ nm_connection_update_secrets (NMConnection *connection, } if (hashed_connection) { - setting_hash = g_hash_table_lookup (secrets, setting_name); - if (!setting_hash) { - /* The hashed connection that didn't contain any secrets for + setting_dict = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) { + /* The hashed connection didn't contain any secrets for * @setting_name; just return success. */ return TRUE; @@ -1017,10 +1011,12 @@ nm_connection_update_secrets (NMConnection *connection, g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); success_detail = _nm_setting_update_secrets (setting, - setting_hash ? setting_hash : secrets, + setting_dict ? setting_dict : secrets, error); g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + g_clear_pointer (&setting_dict, g_variant_unref); + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) return FALSE; if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) @@ -1035,8 +1031,8 @@ nm_connection_update_secrets (NMConnection *connection, } /* check first, whether all the settings exist... */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, NULL)) { setting = nm_connection_get_setting_by_name (connection, key); if (!setting) { g_set_error_literal (error, @@ -1048,15 +1044,17 @@ nm_connection_update_secrets (NMConnection *connection, } /* Update each setting with any secrets from the hashed connection */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &setting_hash)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, &setting_dict)) { /* Update the secrets for this setting */ setting = nm_connection_get_setting_by_name (connection, key); g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); - success_detail = _nm_setting_update_secrets (setting, setting_hash, error); + success_detail = _nm_setting_update_secrets (setting, setting_dict, error); g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + g_variant_unref (setting_dict); + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) { success = FALSE; break; @@ -1196,50 +1194,49 @@ nm_connection_clear_secrets_with_flags (NMConnection *connection, } /** - * nm_connection_to_hash: + * nm_connection_to_variant: * @connection: the #NMConnection * @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL * - * Converts the #NMConnection into a #GHashTable describing the connection, - * suitable for marshalling over D-Bus or serializing. The hash table mapping - * is string:#GHashTable with each element in the returned hash representing - * a #NMSetting object. The keys are setting object names, and the values - * are #GHashTables mapping string:GValue, each of which represents the - * properties of the #NMSetting object. - * - * Returns: (transfer full) (element-type utf8 GLib.HashTable): a new - * #GHashTable describing the connection, its settings, and each setting's - * properties. The caller owns the hash table and must unref the hash table - * with g_hash_table_unref() when it is no longer needed. + * Converts the #NMConnection into a #GVariant describing the connection, + * suitable for marshalling over D-Bus or serializing. The variant is an + * `a{sa{sv}}`, with each element in the outer dictionary representing an + * #NMSetting object, identified by name, and the inner dictionaries as + * with nm_setting_to_variant(). + * + * Returns: (transfer none): a new floating #GVariant describing the connection, + * its settings, and each setting's properties. **/ -GHashTable * -nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) +GVariant * +nm_connection_to_variant (NMConnection *connection, + NMSettingHashFlags flags) { NMConnectionPrivate *priv; + GVariantBuilder builder; GHashTableIter iter; gpointer key, data; - GHashTable *ret, *setting_hash; + GVariant *setting_var, *ret; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - - ret = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); - priv = NM_CONNECTION_GET_PRIVATE (connection); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + /* Add each setting's hash to the main hash */ g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, &key, &data)) { NMSetting *setting = NM_SETTING (data); - setting_hash = nm_setting_to_hash (setting, flags); - if (setting_hash) - g_hash_table_insert (ret, g_strdup (nm_setting_get_name (setting)), setting_hash); + setting_var = nm_setting_to_variant (setting, flags); + if (setting_var) + g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_var); } + ret = g_variant_builder_end (&builder); + /* Don't send empty hashes */ - if (g_hash_table_size (ret) < 1) { - g_hash_table_destroy (ret); + if (g_variant_n_children (ret) == 0) { + g_variant_unref (ret); ret = NULL; } @@ -1434,30 +1431,29 @@ nm_connection_new (void) } /** - * nm_connection_new_from_hash: - * @hash: (element-type utf8 GLib.HashTable): the #GHashTable describing - * the connection + * nm_connection_new_from_variant: + * @hash: the #GVariant describing the connection * @error: on unsuccessful return, an error * - * Creates a new #NMConnection from a hash table describing the connection. See - * nm_connection_to_hash() for a description of the expected hash table. + * Creates a new #NMConnection from a #GVariant describing the connection. See + * nm_connection_to_hash() for a description of the expected variant. * * Returns: the new #NMConnection object, populated with settings created - * from the values in the hash table, or %NULL if the connection failed to + * from the values in the variant, or %NULL if the connection failed to * validate **/ NMConnection * -nm_connection_new_from_hash (GHashTable *hash, GError **error) +nm_connection_new_from_variant (GVariant *variant, GError **error) { NMConnection *connection; - g_return_val_if_fail (hash != NULL, NULL); + g_return_val_if_fail (g_variant_is_of_type (variant, NM_VARIANT_TYPE_CONNECTION), NULL); - if (!validate_permissions_type (hash, error)) + if (!validate_permissions_type (variant, error)) return NULL; connection = nm_connection_new (); - if (!hash_to_connection (connection, hash, error)) { + if (!variant_to_connection (connection, variant, error)) { g_object_unref (connection); return NULL; } |