merge: secret handling enhancements (bgo #728920)

https://bugzilla.gnome.org/show_bug.cgi?id=728920
This commit is contained in:
Jiří Klimeš 2014-09-26 13:55:48 +02:00
commit df230fc2c6
2 changed files with 141 additions and 13 deletions

View file

@ -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

View file

@ -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);
@ -1208,6 +1211,54 @@ typedef struct {
gboolean save_to_disk;
} 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,
@ -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