diff options
Diffstat (limited to 'libnm-util/nm-setting-vpn.c')
-rw-r--r-- | libnm-util/nm-setting-vpn.c | 183 |
1 files changed, 166 insertions, 17 deletions
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 53b609e2d..d3aac0304 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -18,16 +18,19 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include <string.h> +#include <errno.h> +#include <stdlib.h> #include <dbus/dbus-glib.h> #include "nm-setting-vpn.h" #include "nm-param-spec-specialized.h" #include "nm-utils.h" #include "nm-dbus-glib-types.h" +#include "nm-setting-private.h" GQuark nm_setting_vpn_error_quark (void) @@ -158,9 +161,17 @@ nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); } +/** + * nm_setting_vpn_foreach_data_item: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all data items stored in this setting + */ void nm_setting_vpn_foreach_data_item (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); @@ -200,9 +211,17 @@ nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); } +/** + * nm_setting_vpn_foreach_secret: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all secrets stored in this setting. + */ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); @@ -245,34 +264,158 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } static gboolean -update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +update_secret_string (NMSetting *setting, + const char *key, + const char *value, + GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); - char *str; g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - if (!G_VALUE_HOLDS_STRING (value)) { + if (!value || !strlen (value)) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "%s", key); + "Secret %s was empty", key); return FALSE; } - str = g_value_dup_string (value); - if (!str || !strlen (str)) { - g_set_error (error, NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Secret %s was empty", key); - g_free (str); - return FALSE; + g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value)); + return TRUE; +} + +static gboolean +update_secret_hash (NMSetting *setting, + GHashTable *secrets, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + GHashTableIter iter; + const char *name, *value; + + g_return_val_if_fail (secrets != NULL, FALSE); + + /* Make sure the items are valid */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (!name || !strlen (name)) { + g_set_error_literal (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret name was empty"); + return FALSE; + } + + if (!value || !strlen (value)) { + g_set_error (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret %s value was empty", name); + return FALSE; + } + } + + /* Now add the items to the settings' secrets list */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (value == NULL) { + g_warn_if_fail (value != NULL); + continue; + } + if (strlen (value) == 0) { + g_warn_if_fail (strlen (value) > 0); + continue; + } + + g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); + } + + return TRUE; +} + +static gboolean +update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +{ + gboolean success = FALSE; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if (G_VALUE_HOLDS_STRING (value)) { + /* Passing the string properties individually isn't correct, and won't + * produce the correct result, but for some reason that's how it used + * to be done. So even though it's not correct, keep the code around + * for compatibility's sake. + */ + success = update_secret_string (setting, key, g_value_get_string (value), error); + } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { + if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) { + g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET, + "Property %s not a secret property", key); + } else + success = update_secret_hash (setting, g_value_get_boxed (value), error); + } else + g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key); + + return success; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + gboolean success = FALSE; + char *flags_key; + gpointer val; + unsigned long tmp; + + flags_key = g_strdup_printf ("%s-flags", secret_name); + if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { + errno = 0; + tmp = strtoul ((const char *) val, NULL, 10); + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { + *out_flags = (guint32) tmp; + success = TRUE; + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Failed to convert '%s' value '%s' to uint", + flags_key, (const char *) val); + } + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_FOUND, + "Secret flags property '%s' not found", flags_key); } + g_free (flags_key); + return success; +} - g_hash_table_insert (priv->secrets, g_strdup (key), str); +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + g_strdup_printf ("%s-flags", secret_name), + g_strdup_printf ("%u", flags)); return TRUE; } +static GPtrArray * +need_secrets (NMSetting *setting) +{ + /* Assume that VPN connections need secrets since they almost always will */ + return g_ptr_array_sized_new (1); +} + static void destroy_one_secret (gpointer data) { @@ -309,6 +452,8 @@ finalize (GObject *object) static void copy_hash (gpointer key, gpointer value, gpointer user_data) { + g_return_if_fail (value != NULL); + g_return_if_fail (strlen (value)); g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value)); } @@ -386,8 +531,12 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + + parent_class->verify = verify; parent_class->update_one_secret = update_one_secret; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; + parent_class->need_secrets = need_secrets; /* Properties */ /** @@ -395,7 +544,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) * * D-Bus service name of the VPN plugin that this setting uses to connect * to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc - * plugin. + * plugin. **/ g_object_class_install_property (object_class, PROP_SERVICE_TYPE, |