diff --git a/src/libnm-core-impl/nm-setting-vpn.c b/src/libnm-core-impl/nm-setting-vpn.c index b867d0186..65a14866c 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,