merge: branch 'ih/secret_hint_tags'

vpn: handle hint tags in the daemon

Closes #1536

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1958
This commit is contained in:
Íñigo Huguet 2024-06-18 14:01:02 +00:00
commit 730752bfc5
2 changed files with 58 additions and 9 deletions

View file

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

View file

@ -431,7 +431,7 @@ add_vpn_secrets(RequestData *request, GPtrArray *secrets, char **msg)
const NmcVpnPasswordName *p;
const char *vpn_msg = NULL;
char **iter;
char *secret_name;
char *ui_name;
bool is_challenge = FALSE;
bool force_echo;
@ -442,19 +442,19 @@ add_vpn_secrets(RequestData *request, GPtrArray *secrets, char **msg)
vpn_msg = &(*iter)[NM_STRLEN(NM_SECRET_TAG_VPN_MSG)];
} else {
if (NM_STR_HAS_PREFIX(*iter, NM_SECRET_TAG_DYNAMIC_CHALLENGE)) {
secret_name = &(*iter)[NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE)];
ui_name = &(*iter)[NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE)];
is_challenge = TRUE;
force_echo = FALSE;
} else if (NM_STR_HAS_PREFIX(*iter, NM_SECRET_TAG_DYNAMIC_CHALLENGE_ECHO)) {
secret_name = &(*iter)[NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE_ECHO)];
ui_name = &(*iter)[NM_STRLEN(NM_SECRET_TAG_DYNAMIC_CHALLENGE_ECHO)];
is_challenge = TRUE;
force_echo = TRUE;
} else {
secret_name = *iter;
force_echo = FALSE;
ui_name = *iter;
force_echo = FALSE;
}
add_vpn_secret_helper(secrets, s_vpn, secret_name, secret_name, force_echo);
add_vpn_secret_helper(secrets, s_vpn, *iter, ui_name, force_echo);
}
}
}