summaryrefslogtreecommitdiff
path: root/libnm-util/nm-setting-vpn.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2011-06-07 18:22:48 -0500
committerDan Williams <dcbw@redhat.com>2011-06-07 18:22:48 -0500
commit864db9f9e80ab547d7dde10fc7a139b22c85c75f (patch)
tree8a730b71c662139edaa3a5c8d2db5cfe88c8254d /libnm-util/nm-setting-vpn.c
parenta2acfdd46b9fabbc8391ebe1b9b700e20242a9bf (diff)
downloadNetworkManager-864db9f9e80ab547d7dde10fc7a139b22c85c75f.tar.gz
libnm-util: add new compare flags for ignoring various types of secrets
It turns out we need a way to ignore transient (agent-owned or unsaved) secrets during connection comparison. For example, if the user is connecting to a network where the password is not saved, other changes could trigger a writeout of that connection to disk when connecting, which would the connection back in due to inotify, and the re-read connection would then no longer be recognized as the same as the in-memory connection due to the transient secret which obviously wasn't read in from disk. Adding these compare flags allows the code to not bother writing the connection out to disk when the only difference between the on-disk and in-memory connections are secrets that shouldn't get written to disk anyway.
Diffstat (limited to 'libnm-util/nm-setting-vpn.c')
-rw-r--r--libnm-util/nm-setting-vpn.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index 23f0738313..6b8be1239b 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -451,6 +451,68 @@ need_secrets (NMSetting *setting)
return g_ptr_array_sized_new (1);
}
+static gboolean
+compare_one_secret (NMSettingVPN *a,
+ NMSettingVPN *b,
+ NMSettingCompareFlags flags)
+{
+ GHashTable *a_secrets, *b_secrets;
+ GHashTableIter iter;
+ const char *key, *val;
+
+ a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets;
+ b_secrets = NM_SETTING_VPN_GET_PRIVATE (b)->secrets;
+
+ g_hash_table_iter_init (&iter, a_secrets);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
+ NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+ NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL);
+ nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL);
+
+ /* If the secret flags aren't the same, the settings aren't the same */
+ if (a_secret_flags != b_secret_flags)
+ return FALSE;
+
+ if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
+ && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
+ continue;
+
+ if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
+ && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
+ continue;
+
+ /* Now compare the values themselves */
+ if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+compare_property (NMSetting *setting,
+ NMSetting *other,
+ const GParamSpec *prop_spec,
+ NMSettingCompareFlags flags)
+{
+ gboolean same;
+
+ /* We only need to treat the 'secrets' property specially */
+ if (g_strcmp0 (prop_spec->name, NM_SETTING_VPN_SECRETS) != 0)
+ return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (setting, other, prop_spec, flags);
+
+ /* Compare A to B to ensure everything in A is found in B */
+ same = compare_one_secret (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags);
+ if (same) {
+ /* And then B to A to ensure everything in B is also found in A */
+ same = compare_one_secret (NM_SETTING_VPN (other), NM_SETTING_VPN (setting), flags);
+ }
+
+ return same;
+}
+
static void
destroy_one_secret (gpointer data)
{
@@ -572,6 +634,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
parent_class->get_secret_flags = get_secret_flags;
parent_class->set_secret_flags = set_secret_flags;
parent_class->need_secrets = need_secrets;
+ parent_class->compare_property = compare_property;
/* Properties */
/**