summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2014-09-26 13:55:48 +0200
committerJiří Klimeš <jklimes@redhat.com>2014-09-26 13:55:48 +0200
commitdf230fc2c635e2b47788f008737a9e84b415f5e6 (patch)
tree8ce2a6563ec9530225aa0e09268bce80a6a9ed05
parentc9b9229c2e7de2bbb12e493a868921b7a788ee92 (diff)
parent502eb2daf9f3e390547aac38c42b24ea1ae75df7 (diff)
downloadNetworkManager-df230fc2c635e2b47788f008737a9e84b415f5e6.tar.gz
merge: secret handling enhancements (bgo #728920)
https://bugzilla.gnome.org/show_bug.cgi?id=728920
-rw-r--r--introspection/nm-settings-connection.xml8
-rw-r--r--src/settings/nm-settings-connection.c146
2 files changed, 141 insertions, 13 deletions
diff --git a/introspection/nm-settings-connection.xml b/introspection/nm-settings-connection.xml
index b5bd2cd0e0..b02762d6be 100644
--- a/introspection/nm-settings-connection.xml
+++ b/introspection/nm-settings-connection.xml
@@ -93,6 +93,14 @@
</arg>
</method>
+ <method name="ClearSecrets">
+ <tp:docstring>
+ Clear the secrets belonging to this network connection profile.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_clear_secrets"/>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+
<method name="Save">
<tp:docstring>
Saves a "dirty" connection (that had previously been
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 9fa2801dd3..6b0d38c738 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -15,8 +15,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * (C) Copyright 2008 Novell, Inc.
- * (C) Copyright 2008 - 2013 Red Hat, Inc.
+ * Copyright 2008 Novell, Inc.
+ * Copyright 2008 - 2014 Red Hat, Inc.
*/
#include "config.h"
@@ -66,6 +66,9 @@ static void impl_settings_connection_get_secrets (NMSettingsConnection *connecti
const gchar *setting_name,
DBusGMethodInvocation *context);
+static void impl_settings_connection_clear_secrets (NMSettingsConnection *connection,
+ DBusGMethodInvocation *context);
+
#include "nm-settings-connection-glue.h"
static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface);
@@ -1209,6 +1212,54 @@ typedef struct {
} UpdateInfo;
static void
+has_some_secrets_cb (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
+{
+ GParamSpec *pspec;
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), key);
+ if (pspec) {
+ if ( (flags & NM_SETTING_PARAM_SECRET)
+ && !g_param_value_defaults (pspec, (GValue *)value))
+ *((gboolean *) user_data) = TRUE;
+ }
+}
+
+static gboolean
+any_secrets_present (NMConnection *connection)
+{
+ gboolean has_secrets = FALSE;
+
+ nm_connection_for_each_setting_value (connection, has_some_secrets_cb, &has_secrets);
+ return has_secrets;
+}
+
+static void
+cached_secrets_to_connection (NMSettingsConnection *self, NMConnection *connection)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ GVariant *secrets_dict;
+
+ if (priv->agent_secrets) {
+ secrets_dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
+ if (secrets_dict) {
+ (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL);
+ g_variant_unref (secrets_dict);
+ }
+ }
+ if (priv->system_secrets) {
+ secrets_dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
+ if (secrets_dict) {
+ (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL);
+ g_variant_unref (secrets_dict);
+ }
+ }
+}
+
+static void
update_complete (NMSettingsConnection *self,
UpdateInfo *info,
GError *error)
@@ -1264,11 +1315,19 @@ update_auth_cb (NMSettingsConnection *self,
return;
}
- /* Cache the new secrets from the agent, as stuff like inotify-triggered
- * changes to connection's backing config files will blow them away if
- * they're in the main connection.
- */
- update_agent_secrets_cache (self, info->new_settings);
+ if (!any_secrets_present (info->new_settings)) {
+ /* If the new connection has no secrets, we do not want to remove all
+ * secrets, rather we keep all the existing ones. Do that by merging
+ * them in to the new connection.
+ */
+ cached_secrets_to_connection (self, info->new_settings);
+ } else {
+ /* Cache the new secrets from the agent, as stuff like inotify-triggered
+ * changes to connection's backing config files will blow them away if
+ * they're in the main connection.
+ */
+ update_agent_secrets_cache (self, info->new_settings);
+ }
if (info->save_to_disk) {
nm_settings_connection_replace_and_commit (self,
@@ -1521,11 +1580,11 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
}
static void
-dbus_secrets_auth_cb (NMSettingsConnection *self,
- DBusGMethodInvocation *context,
- NMAuthSubject *subject,
- GError *error,
- gpointer user_data)
+dbus_get_secrets_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ NMAuthSubject *subject,
+ GError *error,
+ gpointer user_data)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
char *setting_name = user_data;
@@ -1569,7 +1628,7 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
context,
subject,
get_modify_permission_basic (self),
- dbus_secrets_auth_cb,
+ dbus_get_secrets_auth_cb,
g_strdup (setting_name));
g_object_unref (subject);
} else {
@@ -1578,6 +1637,67 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
}
}
+static void
+clear_secrets_cb (NMSettingsConnection *self,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
+
+static void
+dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ NMAuthSubject *subject,
+ GError *error,
+ gpointer user_data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else {
+ /* Clear secrets in connection and caches */
+ nm_connection_clear_secrets (NM_CONNECTION (self));
+ if (priv->system_secrets)
+ nm_connection_clear_secrets (priv->system_secrets);
+ if (priv->agent_secrets)
+ nm_connection_clear_secrets (priv->agent_secrets);
+
+ /* Tell agents to remove secrets for this connection */
+ nm_agent_manager_delete_secrets (priv->agent_mgr, NM_CONNECTION (self));
+
+ nm_settings_connection_commit_changes (self, clear_secrets_cb, context);
+ }
+}
+
+static void
+impl_settings_connection_clear_secrets (NMSettingsConnection *self,
+ DBusGMethodInvocation *context)
+{
+ NMAuthSubject *subject;
+ GError *error = NULL;
+
+ subject = _new_auth_subject (context, &error);
+ if (subject) {
+ auth_start (self,
+ context,
+ subject,
+ get_modify_permission_basic (self),
+ dbus_clear_secrets_auth_cb,
+ NULL);
+ g_object_unref (subject);
+ } else {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
/**************************************************************/
void