core: fix dispatcher handling of empty VPN interface (bgo #649773)

We pass a VPN IP iface of "" through D-Bus (since dbus doesn't do NULL)
and the dispatcher code wasn't ignoring that as it should have been.
This commit is contained in:
Dan Williams
2011-05-10 11:33:43 -05:00
parent 5e2cda5c20
commit a08e9b928e
6 changed files with 74 additions and 19 deletions

View File

@@ -410,6 +410,12 @@ nm_dispatcher_utils_construct_envp (const char *action,
if (!strcmp (action, "hostname")) if (!strcmp (action, "hostname"))
return g_new0 (char *, 1); return g_new0 (char *, 1);
/* Canonicalize the VPN interface name; "" is used when passing it through
* D-Bus so make sure that's fixed up here.
*/
if (vpn_ip_iface && !strlen (vpn_ip_iface))
vpn_ip_iface = NULL;
con_setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_CONNECTION_SETTING_NAME); con_setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_CONNECTION_SETTING_NAME);
if (!con_setting_hash) { if (!con_setting_hash) {
g_warning ("Failed to read connection setting"); g_warning ("Failed to read connection setting");
@@ -437,6 +443,8 @@ nm_dispatcher_utils_construct_envp (const char *action,
return NULL; return NULL;
} }
iface = g_value_get_string (value); iface = g_value_get_string (value);
if (iface && !strlen (iface))
iface = NULL;
/* IP interface name */ /* IP interface name */
value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE); value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE);

View File

@@ -1,6 +1,6 @@
[main] [main]
action=down action=down
iface=wlan0 expected-iface=wlan0
uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 uuid=3fd2a33a-d81b-423f-ae99-e6baba742311
id=Random Connection id=Random Connection

View File

@@ -1,6 +1,6 @@
[main] [main]
action=up action=up
iface=wlan0 expected-iface=wlan0
uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 uuid=3fd2a33a-d81b-423f-ae99-e6baba742311
id=Random Connection id=Random Connection

View File

@@ -1,6 +1,6 @@
[main] [main]
action=vpn-down action=vpn-down
iface=tun0 expected-iface=tun0
uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e
id=Random Connection id=Random Connection

View File

@@ -1,6 +1,6 @@
[main] [main]
action=vpn-up action=vpn-up
iface=tun0 expected-iface=tun0
uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e
id=Random Connection id=Random Connection

View File

@@ -130,18 +130,21 @@ static gboolean
parse_main (GKeyFile *kf, parse_main (GKeyFile *kf,
GHashTable **out_con_hash, GHashTable **out_con_hash,
GHashTable **out_con_props, GHashTable **out_con_props,
char **out_iface, char **out_expected_iface,
char **out_action, char **out_action,
char **out_vpn_ip_iface,
GError **error) GError **error)
{ {
char *uuid, *id; char *uuid, *id;
NMConnection *connection; NMConnection *connection;
NMSettingConnection *s_con; NMSettingConnection *s_con;
*out_iface = g_key_file_get_string (kf, "main", "iface", error); *out_expected_iface = g_key_file_get_string (kf, "main", "expected-iface", error);
if (*out_iface == NULL) if (*out_expected_iface == NULL)
return FALSE; return FALSE;
*out_vpn_ip_iface = g_key_file_get_string (kf, "main", "vpn-ip-iface", NULL);
*out_action = g_key_file_get_string (kf, "main", "action", error); *out_action = g_key_file_get_string (kf, "main", "action", error);
if (*out_action == NULL) if (*out_action == NULL)
return FALSE; return FALSE;
@@ -413,7 +416,7 @@ get_dispatcher_file (const char *file,
GHashTable **out_device_ip6_props, GHashTable **out_device_ip6_props,
GHashTable **out_device_dhcp4_props, GHashTable **out_device_dhcp4_props,
GHashTable **out_device_dhcp6_props, GHashTable **out_device_dhcp6_props,
const char **out_vpn_ip_iface, char **out_vpn_ip_iface,
GHashTable **out_vpn_ip4_props, GHashTable **out_vpn_ip4_props,
GHashTable **out_vpn_ip6_props, GHashTable **out_vpn_ip6_props,
char **out_expected_iface, char **out_expected_iface,
@@ -429,7 +432,13 @@ get_dispatcher_file (const char *file,
if (!g_key_file_load_from_file (kf, file, G_KEY_FILE_NONE, error)) if (!g_key_file_load_from_file (kf, file, G_KEY_FILE_NONE, error))
return FALSE; return FALSE;
if (!parse_main (kf, out_con_hash, out_con_props, out_expected_iface, out_action, error)) if (!parse_main (kf,
out_con_hash,
out_con_props,
out_expected_iface,
out_action,
out_vpn_ip_iface,
error))
goto out; goto out;
if (!parse_device (kf, out_device_props, error)) if (!parse_device (kf, out_device_props, error))
@@ -474,7 +483,7 @@ out:
/*******************************************/ /*******************************************/
static void static void
test_generic (const char *path, const char *file) test_generic (const char *path, const char *file, const char *override_vpn_ip_iface)
{ {
GHashTable *con_hash = NULL; GHashTable *con_hash = NULL;
GHashTable *con_props = NULL; GHashTable *con_props = NULL;
@@ -483,7 +492,7 @@ test_generic (const char *path, const char *file)
GHashTable *device_ip6_props = NULL; GHashTable *device_ip6_props = NULL;
GHashTable *device_dhcp4_props = NULL; GHashTable *device_dhcp4_props = NULL;
GHashTable *device_dhcp6_props = NULL; GHashTable *device_dhcp6_props = NULL;
const char *vpn_ip_iface = NULL; char *vpn_ip_iface = NULL;
GHashTable *vpn_ip4_props = NULL; GHashTable *vpn_ip4_props = NULL;
GHashTable *vpn_ip6_props = NULL; GHashTable *vpn_ip6_props = NULL;
char *expected_iface = NULL; char *expected_iface = NULL;
@@ -525,25 +534,31 @@ test_generic (const char *path, const char *file)
device_ip6_props, device_ip6_props,
device_dhcp4_props, device_dhcp4_props,
device_dhcp6_props, device_dhcp6_props,
vpn_ip_iface, override_vpn_ip_iface ? override_vpn_ip_iface : vpn_ip_iface,
vpn_ip4_props, vpn_ip4_props,
vpn_ip6_props, vpn_ip6_props,
&out_iface); &out_iface);
/* Print out environment for now */ /* Print out environment for now */
g_message ("\n"); #ifdef DEBUG
g_message ("\n******* Generated environment:");
for (iter = denv; iter && *iter; iter++) for (iter = denv; iter && *iter; iter++)
g_message (" %s", *iter); g_message (" %s", *iter);
#endif
g_assert_cmpint (g_strv_length (denv), ==, g_hash_table_size (expected_env)); #ifdef DEBUG
{ {
GHashTableIter k; GHashTableIter k;
const char *key; const char *key;
g_message ("\n******* Expected environment:");
g_hash_table_iter_init (&k, expected_env); g_hash_table_iter_init (&k, expected_env);
while (g_hash_table_iter_next (&k, (gpointer) &key, NULL)) while (g_hash_table_iter_next (&k, (gpointer) &key, NULL))
g_message (" %s", key); g_message (" %s", key);
} }
#endif
g_assert_cmpint (g_strv_length (denv), ==, g_hash_table_size (expected_env));
/* Compare dispatcher generated env and expected env */ /* Compare dispatcher generated env and expected env */
for (iter = denv; iter && *iter; iter++) { for (iter = denv; iter && *iter; iter++) {
@@ -556,6 +571,27 @@ test_generic (const char *path, const char *file)
} }
g_assert_cmpstr (expected_iface, ==, out_iface); g_assert_cmpstr (expected_iface, ==, out_iface);
g_free (out_iface);
g_free (vpn_ip_iface);
g_free (expected_iface);
g_free (action);
g_hash_table_destroy (con_hash);
g_hash_table_destroy (con_props);
g_hash_table_destroy (device_props);
if (device_ip4_props)
g_hash_table_destroy (device_ip4_props);
if (device_ip6_props)
g_hash_table_destroy (device_ip6_props);
if (device_dhcp4_props)
g_hash_table_destroy (device_dhcp4_props);
if (device_dhcp6_props)
g_hash_table_destroy (device_dhcp6_props);
if (vpn_ip4_props)
g_hash_table_destroy (vpn_ip4_props);
if (vpn_ip6_props)
g_hash_table_destroy (vpn_ip6_props);
g_hash_table_destroy (expected_env);
} }
/*******************************************/ /*******************************************/
@@ -563,25 +599,34 @@ test_generic (const char *path, const char *file)
static void static void
test_old_up (const char *path) test_old_up (const char *path)
{ {
test_generic (path, "dispatcher-old-up"); test_generic (path, "dispatcher-old-up", NULL);
} }
static void static void
test_old_down (const char *path) test_old_down (const char *path)
{ {
test_generic (path, "dispatcher-old-down"); test_generic (path, "dispatcher-old-down", NULL);
} }
static void static void
test_old_vpn_up (const char *path) test_old_vpn_up (const char *path)
{ {
test_generic (path, "dispatcher-old-vpn-up"); test_generic (path, "dispatcher-old-vpn-up", NULL);
} }
static void static void
test_old_vpn_down (const char *path) test_old_vpn_down (const char *path)
{ {
test_generic (path, "dispatcher-old-vpn-down"); test_generic (path, "dispatcher-old-vpn-down", NULL);
}
static void
test_up_empty_vpn_iface (const char *path)
{
/* Test that an empty VPN iface variable, like is passed through D-Bus
* from NM, is ignored by the dispatcher environment construction code.
*/
test_generic (path, "dispatcher-old-up", "");
} }
/*******************************************/ /*******************************************/
@@ -610,6 +655,8 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_old_vpn_up, argv[1])); g_test_suite_add (suite, TESTCASE (test_old_vpn_up, argv[1]));
g_test_suite_add (suite, TESTCASE (test_old_vpn_down, argv[1])); g_test_suite_add (suite, TESTCASE (test_old_vpn_down, argv[1]));
g_test_suite_add (suite, TESTCASE (test_up_empty_vpn_iface, argv[1]));
return g_test_run (); return g_test_run ();
} }