summaryrefslogtreecommitdiff
path: root/libnm-util/nm-setting-vpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-util/nm-setting-vpn.c')
-rw-r--r--libnm-util/nm-setting-vpn.c183
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,