summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-01-31 09:38:58 +0100
committerThomas Haller <thaller@redhat.com>2019-01-31 10:09:18 +0100
commit8ce4e943b91cb29d00ba65665e33c5ef1fb5dadc (patch)
tree343d7370ed339ae82c62ec02375594426471a5f0
parent6eba5eaf80651ce2092e1c93543124bda2f80fda (diff)
downloadNetworkManager-th/settings-for-each-secret.tar.gz
libnm,core: make for-each-secret implementation virtual functions of NMSettingth/settings-for-each-secret
We already need to special handle regular settings (with secrets as GObject properties) and VPN secrets. Next, we will also need to special handle WireGuard peers, which can have secrets too. Move the code to a virtual function, so that "nm-connection.c" and "nm-setting.c" does not have explicit per-setting knowledge.
-rw-r--r--libnm-core/nm-connection.c57
-rw-r--r--libnm-core/nm-core-internal.h6
-rw-r--r--libnm-core/nm-setting-vpn.c52
-rw-r--r--libnm-core/nm-setting.c21
-rw-r--r--libnm-core/nm-setting.h15
5 files changed, 98 insertions, 53 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 3d7e40692a..b576d99ea5 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -1879,7 +1879,7 @@ GVariant *
_nm_connection_for_each_secret (NMConnection *self,
GVariant *secrets,
gboolean remove_non_secrets,
- NMConnectionForEachSecretFunc callback,
+ _NMConnectionForEachSecretFunc callback,
gpointer callback_data)
{
GVariantBuilder secrets_builder;
@@ -1898,10 +1898,8 @@ _nm_connection_for_each_secret (NMConnection *self,
* The one complexity is that the VPN setting's 'secrets' property is
* *also* a dict (since the key/value pairs are arbitrary and known
* only to the VPN plugin itself). That means we have three levels of
- * dicts that we potentially have to traverse here. When we hit the
- * VPN setting's 'secrets' property, we special-case that and iterate over
- * each item in that 'secrets' dict, calling the supplied callback
- * each time.
+ * dicts that we potentially have to traverse here. The differences
+ * are handled by the virtual for_each_secret() function.
*/
g_return_val_if_fail (callback, NULL);
@@ -1921,49 +1919,14 @@ _nm_connection_for_each_secret (NMConnection *self,
g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING);
while (g_variant_iter_next (setting_iter, "{&sv}", &secret_name, &val)) {
_nm_unused gs_unref_variant GVariant *val_free = val;
- NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
- /* VPN secrets need slightly different treatment here since the
- * "secrets" property is actually a hash table of secrets.
- */
- if (NM_IS_SETTING_VPN (setting) && !g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS)) {
- GVariantBuilder vpn_secrets_builder;
- GVariantIter vpn_secrets_iter;
- const char *vpn_secret_name, *secret;
-
- if (!g_variant_is_of_type (val, G_VARIANT_TYPE ("a{ss}"))) {
- /* invalid type. Silently ignore the secrets as we cannot find out the
- * secret-flags. */
- g_variant_unref (val);
- continue;
- }
-
- /* Iterate through each secret from the VPN dict in the overall secrets dict */
- g_variant_builder_init (&vpn_secrets_builder, G_VARIANT_TYPE ("a{ss}"));
- g_variant_iter_init (&vpn_secrets_iter, val);
- while (g_variant_iter_next (&vpn_secrets_iter, "{&s&s}", &vpn_secret_name, &secret)) {
-
- /* we ignore the return value of get_secret_flags. The function may determine
- * that this is not a secret, based on having not secret-flags and no secrets.
- * But we have the secret at hand. We know it would be a valid secret, if we
- * only would add it to the VPN settings. */
- nm_setting_get_secret_flags (setting, vpn_secret_name, &secret_flags, NULL);
-
- if (callback (secret_flags, callback_data))
- g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
- }
-
- g_variant_builder_add (&setting_builder, "{sv}",
- secret_name, g_variant_builder_end (&vpn_secrets_builder));
- } else {
- if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
- if (!remove_non_secrets)
- g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
- continue;
- }
- if (callback (secret_flags, callback_data))
- g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
- }
+ NM_SETTING_GET_CLASS (setting)->for_each_secret (setting,
+ secret_name,
+ val,
+ remove_non_secrets,
+ callback,
+ callback_data,
+ &setting_builder);
}
g_variant_builder_add (&secrets_builder, "{sa{sv}}", setting_name, &setting_builder);
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 80d277d80d..228e239db8 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -732,14 +732,10 @@ GBytes *_nm_setting_802_1x_cert_value_to_bytes (NMSetting8021xCKScheme scheme,
/*****************************************************************************/
-/* Return TRUE to keep (copy to the result), FALSE to drop. */
-typedef gboolean (*NMConnectionForEachSecretFunc) (NMSettingSecretFlags flags,
- gpointer user_data);
-
GVariant *_nm_connection_for_each_secret (NMConnection *self,
GVariant *secrets,
gboolean remove_non_secrets,
- NMConnectionForEachSecretFunc callback,
+ _NMConnectionForEachSecretFunc callback,
gpointer callback_data);
typedef gboolean (*NMConnectionFindSecretFunc) (NMSettingSecretFlags flags,
diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c
index 1371140ec4..875439df76 100644
--- a/libnm-core/nm-setting-vpn.c
+++ b/libnm-core/nm-setting-vpn.c
@@ -687,6 +687,57 @@ update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError
return success;
}
+static void
+for_each_secret (NMSetting *setting,
+ const char *secret_name,
+ GVariant *val,
+ gboolean remove_non_secrets,
+ _NMConnectionForEachSecretFunc callback,
+ gpointer callback_data,
+ GVariantBuilder *setting_builder)
+{
+ GVariantBuilder vpn_secrets_builder;
+ GVariantIter vpn_secrets_iter;
+ const char *vpn_secret_name;
+ const char *secret;
+
+ if (!nm_streq (secret_name, NM_SETTING_VPN_SECRETS)) {
+ NM_SETTING_CLASS (nm_setting_vpn_parent_class)->for_each_secret (setting,
+ secret_name,
+ val,
+ remove_non_secrets,
+ callback,
+ callback_data,
+ setting_builder);
+ return;
+ }
+
+ if (!g_variant_is_of_type (val, G_VARIANT_TYPE ("a{ss}"))) {
+ /* invalid type. Silently ignore the secrets as we cannot find out the
+ * secret-flags. */
+ return;
+ }
+
+ /* Iterate through each secret from the VPN dict in the overall secrets dict */
+ g_variant_builder_init (&vpn_secrets_builder, G_VARIANT_TYPE ("a{ss}"));
+ g_variant_iter_init (&vpn_secrets_iter, val);
+ while (g_variant_iter_next (&vpn_secrets_iter, "{&s&s}", &vpn_secret_name, &secret)) {
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* we ignore the return value of get_secret_flags. The function may determine
+ * that this is not a secret, based on having not secret-flags and no secrets.
+ * But we have the secret at hand. We know it would be a valid secret, if we
+ * only add it to the VPN settings. */
+ nm_setting_get_secret_flags (setting, vpn_secret_name, &secret_flags, NULL);
+
+ if (callback (secret_flags, callback_data))
+ g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
+ }
+
+ g_variant_builder_add (setting_builder, "{sv}",
+ secret_name, g_variant_builder_end (&vpn_secrets_builder));
+}
+
static gboolean
get_secret_flags (NMSetting *setting,
const char *secret_name,
@@ -979,6 +1030,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass)
setting_class->verify = verify;
setting_class->update_one_secret = update_one_secret;
+ setting_class->for_each_secret = for_each_secret;
setting_class->get_secret_flags = get_secret_flags;
setting_class->set_secret_flags = set_secret_flags;
setting_class->need_secrets = need_secrets;
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index a62e31e80d..7b49069b91 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -2040,6 +2040,26 @@ _nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **erro
}
static void
+for_each_secret (NMSetting *setting,
+ const char *secret_name,
+ GVariant *val,
+ gboolean remove_non_secrets,
+ _NMConnectionForEachSecretFunc callback,
+ gpointer callback_data,
+ GVariantBuilder *setting_builder)
+{
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
+ if (!remove_non_secrets)
+ g_variant_builder_add (setting_builder, "{sv}", secret_name, val);
+ return;
+ }
+ if (callback (secret_flags, callback_data))
+ g_variant_builder_add (setting_builder, "{sv}", secret_name, val);
+}
+
+static void
_set_error_secret_property_not_found (GError **error,
NMSetting *setting,
const char *secret_name)
@@ -2571,6 +2591,7 @@ nm_setting_class_init (NMSettingClass *setting_class)
setting_class->set_secret_flags = set_secret_flags;
setting_class->compare_property = compare_property;
setting_class->clear_secrets = clear_secrets;
+ setting_class->for_each_secret = for_each_secret;
setting_class->duplicate_copy_properties = duplicate_copy_properties;
/**
diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h
index 0f0ac8f382..7c94ce4fc9 100644
--- a/libnm-core/nm-setting.h
+++ b/libnm-core/nm-setting.h
@@ -171,6 +171,10 @@ typedef gboolean (*NMSettingClearSecretsWithFlagsFn) (NMSetting *setting,
struct _NMMetaSettingInfo;
struct _NMSettInfoSetting;
+/*< private >*/
+typedef gboolean (*_NMConnectionForEachSecretFunc) (NMSettingSecretFlags flags,
+ gpointer user_data);
+
typedef struct {
GObjectClass parent;
@@ -226,10 +230,19 @@ typedef struct {
NMSetting *dst);
/*< private >*/
+ void (*for_each_secret) (NMSetting *setting,
+ const char *secret_name,
+ GVariant *val,
+ gboolean remove_non_secrets,
+ _NMConnectionForEachSecretFunc callback,
+ gpointer callback_data,
+ GVariantBuilder *setting_builder);
+
+ /*< private >*/
const struct _NMMetaSettingInfo *setting_info;
/*< private >*/
- gpointer padding[5];
+ gpointer padding[4];
} NMSettingClass;
/**