mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-10 05:50:21 +01:00
libnm-util: fix VPN update_one_secret()
The old function took a string value, which wasn't really correct as the property type is a GHashTable of string:string. For whatever reason this is how nm-applet passed VPN secrets back to NM in the return from the GetSecrets() D-Bus call. This was probably easier or something but it was a special case that's magic and quite unclear. Since we use nm_connection_update_secrets() more these days, and we depend on the GValue types we pass into it matching the property types of the setting property the secret is for, we need to fix that up for VPN connections. But keep the old code for backwards compatibility. In the future secret agents should pass back VPN secrets in the same form as the VPN setting specifies them for the "secrets" property: a GHashTable of string:string. But the old mechanism of just dumping the key/value pairs into the returned VPN hash as string:string will still work.
This commit is contained in:
parent
b94fb03197
commit
d7a86ffd04
2 changed files with 131 additions and 14 deletions
|
|
@ -264,34 +264,91 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
|
||||
update_secret_string (NMSetting *setting,
|
||||
const char *key,
|
||||
const char *value,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
|
||||
char *str;
|
||||
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
if (!G_VALUE_HOLDS_STRING (value)) {
|
||||
g_set_error (error, NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"%s", key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
str = g_value_dup_string (value);
|
||||
if (!str || !strlen (str)) {
|
||||
if (!value || !strlen (value)) {
|
||||
g_set_error (error, NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"Secret %s was empty", key);
|
||||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_hash_table_insert (priv->secrets, g_strdup (key), str);
|
||||
g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_secret_hash (NMSetting *setting,
|
||||
GHashTable *secrets,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
|
||||
GHashTableIter iter;
|
||||
const char *name, *value;
|
||||
|
||||
g_return_val_if_fail (secrets != NULL, FALSE);
|
||||
|
||||
/* Make sure the items are valid */
|
||||
g_hash_table_iter_init (&iter, secrets);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) {
|
||||
if (!name || !strlen (name)) {
|
||||
g_set_error_literal (error, NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"Secret name was empty");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!value || !strlen (value)) {
|
||||
g_set_error (error, NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"Secret %s value was empty", name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now add the items to the settings' secrets list */
|
||||
g_hash_table_iter_init (&iter, secrets);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value))
|
||||
g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
if (G_VALUE_HOLDS_STRING (value)) {
|
||||
/* Passing the string properties individually isn't correct, and won't
|
||||
* produce the correct result, but for some reason that's how it used
|
||||
* to be done. So even though it's not correct, keep the code around
|
||||
* for compatibility's sake.
|
||||
*/
|
||||
success = update_secret_string (setting, key, g_value_get_string (value), error);
|
||||
} else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) {
|
||||
if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) {
|
||||
g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET,
|
||||
"Property %s not a secret property", key);
|
||||
} else
|
||||
success = update_secret_hash (setting, g_value_get_boxed (value), error);
|
||||
} else
|
||||
g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_secret_flags (NMSetting *setting,
|
||||
const char *secret_name,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2011 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -131,6 +131,65 @@ test_setting_vpn_items (void)
|
|||
g_object_unref (s_vpn);
|
||||
}
|
||||
|
||||
static void
|
||||
test_setting_vpn_update_secrets (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingVPN *s_vpn;
|
||||
GHashTable *settings, *vpn, *secrets;
|
||||
GValue val = { 0 };
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
const char *tmp;
|
||||
const char *key1 = "foobar";
|
||||
const char *key2 = "blahblah";
|
||||
const char *val1 = "value1";
|
||||
const char *val2 = "value2";
|
||||
|
||||
connection = nm_connection_new ();
|
||||
ASSERT (connection != NULL,
|
||||
"vpn-update-secrets",
|
||||
"error creating connection");
|
||||
|
||||
s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
|
||||
ASSERT (s_vpn != NULL,
|
||||
"vpn-update-secrets",
|
||||
"error creating vpn setting");
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_vpn));
|
||||
|
||||
settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy);
|
||||
vpn = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset);
|
||||
g_hash_table_insert (settings, NM_SETTING_VPN_SETTING_NAME, vpn);
|
||||
|
||||
secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
|
||||
g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
|
||||
g_value_take_boxed (&val, secrets);
|
||||
g_hash_table_insert (vpn, NM_SETTING_VPN_SECRETS, &val);
|
||||
|
||||
/* Add some secrets */
|
||||
g_hash_table_insert (secrets, (char *) key1, (char *) val1);
|
||||
g_hash_table_insert (secrets, (char *) key2, (char *) val2);
|
||||
|
||||
success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error);
|
||||
ASSERT (success == TRUE,
|
||||
"vpn-update-secrets", "failed to update VPN secrets: %s", error->message);
|
||||
|
||||
/* Read the secrets back out */
|
||||
tmp = nm_setting_vpn_get_secret (s_vpn, key1);
|
||||
ASSERT (tmp != NULL,
|
||||
"vpn-update-secrets", "unexpected failure getting key #1");
|
||||
ASSERT (strcmp (tmp, val1) == 0,
|
||||
"vpn-update-secrets", "unexpected key #1 value");
|
||||
|
||||
tmp = nm_setting_vpn_get_secret (s_vpn, key2);
|
||||
ASSERT (tmp != NULL,
|
||||
"vpn-update-secrets", "unexpected failure getting key #2");
|
||||
ASSERT (strcmp (tmp, val2) == 0,
|
||||
"vpn-update-secrets", "unexpected key #2 value");
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
|
|
@ -617,6 +676,7 @@ int main (int argc, char **argv)
|
|||
|
||||
/* The tests */
|
||||
test_setting_vpn_items ();
|
||||
test_setting_vpn_update_secrets ();
|
||||
test_setting_ip6_config_old_address_array ();
|
||||
test_setting_gsm_apn_spaces ();
|
||||
test_setting_gsm_apn_bad_chars ();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue