summary refs log tree commit diff
path: root/src/libnm-core-impl/nm-setting-vpn.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2024-06-24 12:22:41 +0200
committerMichael Biebl <biebl@debian.org>2024-06-24 12:22:41 +0200
commit8e2fde558a5af5c3b03a5112dbd8f9085c5a8369 (patch)
tree4da74f7af9031f00703228c00dc36c755b95f3ae /src/libnm-core-impl/nm-setting-vpn.c
parentbaef747c9365b6044db3c2dfbb859652bdde1d76 (diff)
New upstream version 1.48.2 upstream/1.48.2
Diffstat (limited to 'src/libnm-core-impl/nm-setting-vpn.c')
-rw-r--r--src/libnm-core-impl/nm-setting-vpn.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/libnm-core-impl/nm-setting-vpn.c b/src/libnm-core-impl/nm-setting-vpn.c
index b867d018..65a14866 100644
--- a/src/libnm-core-impl/nm-setting-vpn.c
+++ b/src/libnm-core-impl/nm-setting-vpn.c
@@ -577,14 +577,48 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
     return TRUE;
 }
 
+static gboolean
+_parse_secret_hint_tag(const char           *secret_name,
+                       const char          **out_secret_name,
+                       NMSettingSecretFlags *out_implied_flags)
+{
+    NMSettingSecretFlags implied_flags = NM_SETTING_SECRET_FLAG_NONE;
+    gboolean             ret           = FALSE;
+
+    nm_assert(secret_name);
+
+    if (g_str_has_prefix(secret_name, NM_SECRET_TAG_DYNAMIC_CHALLENGE)) {
+        secret_name += NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE);
+        implied_flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
+        ret = TRUE;
+    } else if (g_str_has_prefix(secret_name, NM_SECRET_TAG_DYNAMIC_CHALLENGE_ECHO)) {
+        secret_name += NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE_ECHO);
+        implied_flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
+        ret = TRUE;
+    }
+
+    NM_SET_OUT(out_secret_name, secret_name);
+    NM_SET_OUT(out_implied_flags, implied_flags);
+    return ret;
+}
+
 static NMSettingUpdateSecretResult
 update_secret_string(NMSetting *setting, const char *key, const char *value, GError **error)
 {
     NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting);
+    NMSettingSecretFlags hint_implied_flags, flags;
 
     g_return_val_if_fail(key && key[0], NM_SETTING_UPDATE_SECRET_ERROR);
     g_return_val_if_fail(value, NM_SETTING_UPDATE_SECRET_ERROR);
 
+    /* If the name is prefixed with a hint tag, process it before saving:
+     * remove the prefix and apply the flags that it implies */
+    _parse_secret_hint_tag(key, &key, &hint_implied_flags);
+    if (hint_implied_flags) {
+        nm_setting_get_secret_flags(setting, key, &flags, NULL);
+        nm_setting_set_secret_flags(setting, key, flags | hint_implied_flags, NULL);
+    }
+
     if (nm_streq0(nm_g_hash_table_lookup(priv->secrets, key), value))
         return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
 
@@ -599,6 +633,7 @@ update_secret_dict(NMSetting *setting, GVariant *secrets, GError **error)
     GVariantIter                iter;
     const char                 *name, *value;
     NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
+    NMSettingSecretFlags        hint_implied_flags, flags;
 
     g_return_val_if_fail(secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
 
@@ -618,6 +653,14 @@ update_secret_dict(NMSetting *setting, GVariant *secrets, GError **error)
     /* Now add the items to the settings' secrets list */
     g_variant_iter_init(&iter, secrets);
     while (g_variant_iter_next(&iter, "{&s&s}", &name, &value)) {
+        /* If the name is prefixed with a hint tag, process it before saving:
+         * remove the prefix and apply the flags that it implies */
+        _parse_secret_hint_tag(name, &name, &hint_implied_flags);
+        if (hint_implied_flags) {
+            nm_setting_get_secret_flags(setting, name, &flags, NULL);
+            nm_setting_set_secret_flags(setting, name, flags | hint_implied_flags, NULL);
+        }
+
         if (nm_streq0(nm_g_hash_table_lookup(priv->secrets, name), value))
             continue;
 
@@ -727,6 +770,7 @@ get_secret_flags(NMSetting            *setting,
                  GError              **error)
 {
     NMSettingVpnPrivate *priv           = NM_SETTING_VPN_GET_PRIVATE(setting);
+    NMSettingSecretFlags implied_flags  = NM_SETTING_SECRET_FLAG_NONE;
     gs_free char        *flags_key_free = NULL;
     const char          *flags_key;
     const char          *flags_val;
@@ -734,6 +778,10 @@ get_secret_flags(NMSetting            *setting,
 
     nm_assert(secret_name);
 
+    /* Secrets received via D-Bus from VPN plugins might be prefixed by a hint tag. If
+     * that's the case, process it first: remove the tag and get the flags that it implies */
+    _parse_secret_hint_tag(secret_name, &secret_name, &implied_flags);
+
     if (!secret_name[0]) {
         g_set_error(error,
                     NM_CONNECTION_ERROR,
@@ -746,7 +794,7 @@ get_secret_flags(NMSetting            *setting,
 
     if (!priv->data
         || !g_hash_table_lookup_extended(priv->data, flags_key, NULL, (gpointer *) &flags_val)) {
-        NM_SET_OUT(out_flags, NM_SETTING_SECRET_FLAG_NONE);
+        NM_SET_OUT(out_flags, implied_flags);
 
         /* having no secret flag for the secret is fine, as long as there
          * is the secret itself... */
@@ -772,7 +820,7 @@ get_secret_flags(NMSetting            *setting,
         return TRUE;
     }
 
-    NM_SET_OUT(out_flags, (NMSettingSecretFlags) i64);
+    NM_SET_OUT(out_flags, (NMSettingSecretFlags) i64 | implied_flags);
     return TRUE;
 }
 
@@ -783,7 +831,8 @@ set_secret_flags(NMSetting           *setting,
                  GError             **error)
 {
     nm_assert(secret_name);
-
+    nm_assert(!_parse_secret_hint_tag(secret_name, NULL, NULL)); /* Accept hint tags only via D-Bus,
+                                                                    saved by update_one_secret */
     if (!secret_name[0]) {
         g_set_error(error,
                     NM_CONNECTION_ERROR,