diff options
| author | Michael Biebl <biebl@debian.org> | 2011-10-28 23:04:16 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2011-10-28 23:04:16 +0200 |
| commit | 485d149fe80915d94ed49ea6c2c0552cf7a3e79a (patch) | |
| tree | 6a48492b46b8c1e3df1c58626c28f05a978c61f7 /src/settings/plugins | |
| parent | 263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (diff) | |
Imported Upstream version 0.9.1.95 upstream/0.9.1.95
Diffstat (limited to 'src/settings/plugins')
28 files changed, 778 insertions, 119 deletions
diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in index 148e9620..c23e3be0 100644 --- a/src/settings/plugins/Makefile.in +++ b/src/settings/plugins/Makefile.in @@ -197,8 +197,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in index f02b6431..b904563a 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -267,8 +267,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index ed0dceca..b4be4cba 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -655,8 +655,10 @@ sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) } if (!success) { - dbus_g_connection_unref (priv->bus); - priv->bus = NULL; + if (priv->bus) { + dbus_g_connection_unref (priv->bus); + priv->bus = NULL; + } } } diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index cdf5889e..910cca35 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -28,10 +28,10 @@ #include <ctype.h> #include <sys/inotify.h> #include <errno.h> -#include <net/if.h> #include <sys/ioctl.h> #include <unistd.h> #include <netinet/ether.h> +#include <linux/if.h> #ifndef __user #define __user @@ -3382,7 +3382,7 @@ connection_from_file (const char *filename, network_file = SYSCONFDIR "/sysconfig/network"; if (!iscsiadm_path) - iscsiadm_path = SBINDIR "/iscsiadm"; + iscsiadm_path = "/sbin/iscsiadm"; ifcfg_name = utils_get_ifcfg_name (filename, TRUE); if (!ifcfg_name) { diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index db084969..0aa8efc2 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -142,10 +142,11 @@ svUnescape(char *s) { */ static const char escapees[] = "\"'\\$~`"; /* must be escaped */ static const char spaces[] = " \t|&;()<>"; /* only require "" */ +static const char newlines[] = "\n\r"; /* will be removed */ char * svEscape(const char *s) { char *new; - int i, j, mangle = 0, space = 0; + int i, j, mangle = 0, space = 0, newline = 0; int newlen, slen; static int esclen, splen; @@ -156,23 +157,26 @@ svEscape(const char *s) { for (i = 0; i < slen; i++) { if (strchr(escapees, s[i])) mangle++; if (strchr(spaces, s[i])) space++; + if (strchr(newlines, s[i])) newline++; } - if (!mangle && !space) return strdup(s); + if (!mangle && !space && !newline) return strdup(s); - newlen = slen + mangle + 3; /* 3 is extra ""\0 */ + newlen = slen + mangle - newline + 3; /* 3 is extra ""\0 */ new = g_malloc0(newlen); if (!new) return NULL; j = 0; new[j++] = '"'; for (i = 0; i < slen; i++) { + if (strchr(newlines, s[i])) + continue; if (strchr(escapees, s[i])) { new[j++] = '\\'; } new[j++] = s[i]; } new[j++] = '"'; - g_assert(j == slen + mangle + 2); /* j is the index of the '\0' */ + g_assert(j == slen + mangle - newline + 2); /* j is the index of the '\0' */ return new; } @@ -332,13 +336,13 @@ svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim) } end: - if (newval) free(newval); - if (val1) free(val1); - if (val2) free(val2); + g_free(newval); + g_free(val1); + g_free(val2); return; bail: - if (keyValue) free (keyValue); + g_free (keyValue); goto end; } diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in index cd37d0a7..6c509fd0 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -228,8 +228,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in index a10cbb86..7a00bcfd 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -152,8 +152,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index d1f08aa9..e32266cb 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -10141,6 +10141,207 @@ test_write_wifi_wpa_then_open (void) } static void +test_write_wifi_wpa_then_wep_with_perms (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + GSList *perm_list = NULL; + const unsigned char ssid_data[] = "SomeSSID"; + + /* Test that writing out a WPA config then changing that to a WEP + * config works and doesn't cause infinite loop or other issues. + */ + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + perm_list = g_slist_append (perm_list, "user:superman:"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "random wifi connection 2", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_PERMISSIONS, perm_list, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + g_slist_free (perm_list); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "test_write_wifi_wpa_then_wep_with_perms", "unexpected failure adding valid user permisson"); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, "My cool PSK", + NULL); + + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + g_free (unmanaged); + unmanaged = NULL; + g_free (routefile); + routefile = NULL; + g_free (route6file); + route6file = NULL; + g_object_unref (reread); + + /* Now change the connection to WEP and recheck */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "abraka dabra"); + + /* Write it back out */ + success = writer_update_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + testfile, + keyfile, + &error); + g_assert_no_error (error); + g_assert (success); + + g_free (keyfile); + keyfile = NULL; + + /* re-read it for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + + success = nm_connection_compare (connection, reread, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS); + + ASSERT (success, + "test_write_wifi_wpa_then_wep_with_perms", "failed to compare connections"); + + unlink (keyfile); + unlink (testfile); + + g_free (testfile); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (reread); + + g_object_unref (connection); +} + +static void test_write_wifi_dynamic_wep_leap (void) { NMConnection *connection; @@ -11713,6 +11914,7 @@ int main (int argc, char **argv) test_write_wifi_wpa_eap_ttls_mschapv2 (); test_write_wifi_dynamic_wep_leap (); test_write_wifi_wpa_then_open (); + test_write_wifi_wpa_then_wep_with_perms (); test_write_wired_qeth_dhcp (); test_write_wired_ctc_dhcp (); test_write_permissions (); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 192226ac..068bcda2 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -569,6 +569,7 @@ write_wireless_security_setting (NMConnection *connection, svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE); if (!strcmp (key_mgmt, "none")) { + svSetValue (ifcfg, "KEY_MGMT", NULL, FALSE); wep = TRUE; *no_8021x = TRUE; } else if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) { @@ -1725,7 +1726,7 @@ write_connection (NMConnection *connection, g_free (ifcfg_name); while (idx++ < 500) { - ifcfg_name = g_strdup_printf ("%s/ifcfg-%s %u", ifcfg_dir, escaped, idx); + ifcfg_name = g_strdup_printf ("%s/ifcfg-%s-%u", ifcfg_dir, escaped, idx); if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS) == FALSE) break; g_free (ifcfg_name); diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in index 02e2247a..b8017e24 100644 --- a/src/settings/plugins/ifcfg-suse/Makefile.in +++ b/src/settings/plugins/ifcfg-suse/Makefile.in @@ -215,8 +215,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in index 2bc7bc32..519e07c0 100644 --- a/src/settings/plugins/ifnet/Makefile.in +++ b/src/settings/plugins/ifnet/Makefile.in @@ -263,8 +263,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index 982f94f9..b4aaa8d2 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -1742,27 +1742,27 @@ ifnet_update_connection_from_config_block (const char *conn_name, GError **error /* IPv4 setting */ make_ip4_setting (connection, conn_name, error); - if (error && *error) - PLUGIN_WARN (IFNET_PLUGIN_NAME, - "Found error: %s", (*error)->message); + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message); + goto error; + } /* IPv6 setting */ make_ip6_setting (connection, conn_name, error); - if (error && *error) - PLUGIN_WARN (IFNET_PLUGIN_NAME, - "Found error: %s", (*error)->message); + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message); + goto error; + } success = nm_connection_verify (connection, error); if (error && *error) - PLUGIN_WARN (IFNET_PLUGIN_NAME, - "Found error: %s", (*error)->message); + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, success); if (!success) goto error; return connection; error: - g_object_unref (setting); g_object_unref (connection); return NULL; } diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index 83f86ab5..b533ae3f 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -313,7 +313,7 @@ is_ip4_address (const char *in_address) gboolean result = FALSE; gchar *tmp; GRegex *regex = g_regex_new (pattern, 0, 0, NULL); - GMatchInfo *match_info; + GMatchInfo *match_info = NULL; if (!address) goto done; diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in index 17b80c36..d2cbb871 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.in +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -186,8 +186,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net index e7550002..0eef399a 100644 --- a/src/settings/plugins/ifnet/tests/net +++ b/src/settings/plugins/ifnet/tests/net @@ -35,6 +35,8 @@ config_eth6=("192.168.4.{1..101}/24") config_eth7=( "dhcp" ) auto_eth7="true" +# missing config_eth8 +auto_eth8="true" config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") routes_myxjtu2=("default via 202.117.16.1") diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index d114bbba..52d9ce2a 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -252,25 +252,25 @@ test_is_unmanaged () static void test_new_connection () { - GError **error = NULL; + GError *error = NULL; NMConnection *connection; - connection = ifnet_update_connection_from_config_block ("eth2", error); + connection = ifnet_update_connection_from_config_block ("eth2", &error); ASSERT (connection != NULL, "new connection", "new connection failed: %s", - error == NULL ? "None" : (*error)->message); + error ? error->message : "None"); g_object_unref (connection); - connection = - ifnet_update_connection_from_config_block ("qiaomuf", error); + + connection = ifnet_update_connection_from_config_block ("qiaomuf", &error); ASSERT (connection != NULL, "new connection", - "new connection failed: %s", error - && (*error) ? (*error)->message : "NONE"); + "new connection failed: %s", + error ? error->message : "NONE"); g_object_unref (connection); - connection = - ifnet_update_connection_from_config_block ("myxjtu2", error); + + connection = ifnet_update_connection_from_config_block ("myxjtu2", &error); ASSERT (connection != NULL, "new connection", - "new connection failed: %s", error - && (*error) ? (*error)->message : "NONE"); + "new connection failed: %s", + error ? error->message : "NONE"); g_object_unref (connection); } @@ -280,32 +280,32 @@ test_new_connection () static void test_update_connection () { - GError **error = NULL; + GError *error = NULL; NMConnection *connection; gboolean success; - connection = ifnet_update_connection_from_config_block ("eth0", error); + connection = ifnet_update_connection_from_config_block ("eth0", &error); ASSERT (connection != NULL, "get connection", "get connection failed: %s", - error == NULL ? "None" : (*error)->message); + error ? error->message : "None"); success = ifnet_update_parsers_by_connection (connection, "eth0", NET_GEN_NAME, SUP_GEN_NAME, NULL, - error); + &error); ASSERT (success, "update connection", "update connection failed %s", "eth0"); g_object_unref (connection); - connection = ifnet_update_connection_from_config_block ("0xab3ace", error); + connection = ifnet_update_connection_from_config_block ("0xab3ace", &error); ASSERT (connection != NULL, "get connection", "get connection failed: %s", - error == NULL ? "None" : (*error)->message); + error ? error->message : "None"); success = ifnet_update_parsers_by_connection (connection, "0xab3ace", NET_GEN_NAME, SUP_GEN_NAME, NULL, - error); + &error); ASSERT (success, "update connection", "update connection failed %s", "0xab3ace"); g_object_unref (connection); @@ -357,6 +357,17 @@ test_delete_connection () } static void +test_missing_config () +{ + GError *error = NULL; + NMConnection *connection; + + connection = ifnet_update_connection_from_config_block ("eth8", &error); + ASSERT (connection == NULL && error != NULL, "get connection", + "get connection should fail with 'Unknown config for eth8'"); +} + +static void run_all (gboolean run) { if (run) { @@ -378,6 +389,7 @@ run_all (gboolean run) test_update_connection (); test_add_connection (); test_delete_connection (); + test_missing_config (); } } diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf index a2595d42..4f5f68cf 100644 --- a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf +++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf @@ -859,6 +859,7 @@ network={ identity="user@example.com" anonymous_identity="anonymous@example.com" password="foobar" - ca_cert="blob://exampleblob" + ca_cert="test_ca_cert.pem" + phase2="auth=CHAP" priority=20 } diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in index 5f5a456b..b6896b59 100644 --- a/src/settings/plugins/ifupdown/Makefile.in +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -262,8 +262,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in index 7412e65d..3c8bf793 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.in +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -186,8 +186,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index a2a7d231..cf821e46 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -238,8 +238,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index c4136e05..4128b9f2 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -730,10 +730,27 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) g_strfreev (keys); } +static void +unescape_semicolons (char *str) +{ + int i; + gsize len = strlen (str); + + for (i = 0; i < len; i++) { + if (str[i] == '\\' && str[i+1] == ';') { + memmove(str + i, str + i + 1, len - (i + 1)); + len--; + } + str[len] = '\0'; + } +} + static GByteArray * get_uchar_array (GKeyFile *keyfile, const char *setting_name, - const char *key) + const char *key, + gboolean zero_terminate, + gboolean unescape_semicolon) { GByteArray *array = NULL; char *tmp_string; @@ -742,26 +759,28 @@ get_uchar_array (GKeyFile *keyfile, int i; /* New format: just a string - * Old format: integer list; e.g. 11;25;38 + * Old format: integer list; e.g. 11;25;38; */ tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); if (tmp_string) { - gboolean new_format = FALSE; GRegex *regex; GMatchInfo *match_info; - const char *pattern = "^[[:space:]]*[[:digit:]]{1,3}[[:space:]]*(;[[:space:]]*[[:digit:]]{1,3}[[:space:]]*)*(;[[:space:]]*)?$"; + const char *pattern = "^[[:space:]]*[[:digit:]]{1,3}[[:space:]]*;([[:space:]]*[[:digit:]]{1,3}[[:space:]]*;)*([[:space:]]*)?$"; regex = g_regex_new (pattern, 0, 0, NULL); g_regex_match (regex, tmp_string, 0, &match_info); - if (!g_match_info_matches (match_info)) - new_format = TRUE; + if (!g_match_info_matches (match_info)) { + /* Handle as a simple string (ie, new format) */ + if (unescape_semicolon) + unescape_semicolons (tmp_string); + length = strlen (tmp_string); + if (zero_terminate) + length++; + array = g_byte_array_sized_new (length); + g_byte_array_append (array, (guint8 *) tmp_string, length); + } g_match_info_free (match_info); g_regex_unref (regex); - - if (new_format) { - array = g_byte_array_sized_new (strlen (tmp_string)); - g_byte_array_append (array, (guint8 *) tmp_string, strlen (tmp_string)); - } g_free (tmp_string); } @@ -796,7 +815,7 @@ ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char const char *setting_name = nm_setting_get_name (setting); GByteArray *array; - array = get_uchar_array (keyfile, setting_name, key); + array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE); if (array) { g_object_set (setting, key, array, NULL); g_byte_array_free (array, TRUE); @@ -837,21 +856,79 @@ get_cert_path (const char *keyfile_path, GByteArray *cert_path) static const char *certext[] = { ".pem", ".cert", ".crt", ".cer", ".p12", ".der", ".key" }; static gboolean -has_cert_ext (GByteArray *array) +has_cert_ext (const char *path) { int i; for (i = 0; i < G_N_ELEMENTS (certext); i++) { - guint32 extlen = strlen (certext[i]); - - if (array->len <= extlen) - continue; - if (memcmp (&array->data[array->len - extlen], certext[i], extlen) == 0) + if (g_str_has_suffix (path, certext[i])) return TRUE; } return FALSE; } +static gboolean +handle_as_scheme (GByteArray *array, NMSetting *setting, const char *key) +{ + /* It's the PATH scheme, can just set plain data */ + if ( (array->len > strlen (SCHEME_PATH)) + && g_str_has_prefix ((const char *) array->data, SCHEME_PATH) + && (array->data[array->len - 1] == '\0')) { + g_object_set (setting, key, array, NULL); + return TRUE; + } + return FALSE; +} + +static gboolean +handle_as_path (GByteArray *array, + NMSetting *setting, + const char *key, + const char *keyfile_path) +{ + gsize validate_len = array->len; + GByteArray *val; + char *path; + gboolean exists, success = FALSE; + + if (array->len > 500 || array->len < 1) + return FALSE; + + /* If there's a trailing NULL tell g_utf8_validate() to to until the NULL */ + if (array->data[array->len - 1] == '\0') + validate_len = -1; + + if (g_utf8_validate ((const char *) array->data, validate_len, NULL) == FALSE) + return FALSE; + + /* Might be a bare path without the file:// prefix; in that case + * if it's an absolute path, use that, otherwise treat it as a + * relative path to the current directory. + */ + + path = get_cert_path (keyfile_path, array); + exists = g_file_test (path, G_FILE_TEST_EXISTS); + if ( exists + || memchr (array->data, '/', array->len) + || has_cert_ext (path)) { + /* Construct the proper value as required for the PATH scheme */ + val = g_byte_array_sized_new (strlen (SCHEME_PATH) + strlen (path) + 1); + g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (val, (const guint8 *) path, strlen (path)); + g_byte_array_append (val, (const guint8 *) "\0", 1); + g_object_set (setting, key, val, NULL); + g_byte_array_free (val, TRUE); + success = TRUE; + + /* Warn if the certificate didn't exist */ + if (exists == FALSE) + PLUGIN_WARN (KEYFILE_PLUGIN_NAME, " certificate or key %s does not exist", path); + } + g_free (path); + + return success; +} + static void cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { @@ -859,62 +936,25 @@ cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char GByteArray *array; gboolean success = FALSE; - array = get_uchar_array (keyfile, setting_name, key); - if (array) { - /* Value could be either: - * 1) the raw key/cert data as a blob - * 2) a path scheme (ie, starts with "file://") - * 3) a plain path - */ - if ( (array->len > strlen (SCHEME_PATH)) - && g_str_has_prefix ((const char *) array->data, SCHEME_PATH) - && (array->data[array->len - 1] == '\0')) { - /* It's the PATH scheme, can just set plain data */ - g_object_set (setting, key, array, NULL); - success = TRUE; - } else if ( (array->len < 500) - && g_utf8_validate ((const char *) array->data, array->len, NULL)) { - GByteArray *val; - char *path; - gboolean exists; - - /* Might be a bare path without the file:// prefix; in that case - * if it's an absolute path, use that, otherwise treat it as a - * relative path to the current directory. - */ - - path = get_cert_path (keyfile_path, array); - exists = g_file_test (path, G_FILE_TEST_EXISTS); - if ( exists - || memchr (array->data, '/', array->len) - || has_cert_ext (array)) { - /* Construct the proper value as required for the PATH scheme */ - val = g_byte_array_sized_new (strlen (SCHEME_PATH) + array->len + 1); - g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (val, (const guint8 *) path, strlen (path)); - g_byte_array_append (val, (const guint8 *) "\0", 1); - g_object_set (setting, key, val, NULL); - g_byte_array_free (val, TRUE); - success = TRUE; - - /* Warn if the certificate didn't exist */ - if (exists == FALSE) { - PLUGIN_WARN (KEYFILE_PLUGIN_NAME, " certificate or key %s does not exist", path); - } - } - g_free (path); - } + array = get_uchar_array (keyfile, setting_name, key, TRUE, FALSE); + if (array && array->len > 0) { + /* Try as a path + scheme (ie, starts with "file://") */ + success = handle_as_scheme (array, setting, key); - if (!success) { - /* Assume it's a simple blob value of the certificate or private key's data */ - g_object_set (setting, key, array, NULL); - } + /* If not, it might be a plain path */ + if (success == FALSE) + success = handle_as_path (array, setting, key, keyfile_path); - g_byte_array_free (array, TRUE); + /* If neither of those two, assume blob with certificate data */ + if (success == FALSE) + g_object_set (setting, key, array, NULL); } else { g_warning ("%s: ignoring invalid key/cert value for %s / %s", __func__, setting_name, key); } + + if (array) + g_byte_array_free (array, TRUE); } typedef struct { diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index 05ed3a61..9d4f478d 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -224,8 +224,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am index 302db866..55dda7ee 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am @@ -8,6 +8,8 @@ KEYFILES = \ ATT_Data_Connect_Plain \ Test_String_SSID \ Test_Intlist_SSID \ + Test_Intlike_SSID \ + Test_Intlike_SSID_2 \ Test_Wired_TLS_Old \ Test_Wired_TLS_New \ Test_Wired_TLS_Blob \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index 083615b0..3408cb15 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -152,8 +152,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -278,6 +286,8 @@ KEYFILES = \ ATT_Data_Connect_Plain \ Test_String_SSID \ Test_Intlist_SSID \ + Test_Intlike_SSID \ + Test_Intlike_SSID_2 \ Test_Wired_TLS_Old \ Test_Wired_TLS_New \ Test_Wired_TLS_Blob \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID b/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID new file mode 100644 index 00000000..2bacb725 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID @@ -0,0 +1,11 @@ +[connection] +id=Test +uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa +type=802-11-wireless + +[802-11-wireless] +ssid=101 + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2 b/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2 new file mode 100644 index 00000000..20240251 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2 @@ -0,0 +1,11 @@ +[connection] +id=Test SSID - escaping semicolon in string +uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa +type=802-11-wireless + +[802-11-wireless] +ssid=11\\;12\\;13\\; + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index 3bbaaaec..2859cb3e 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -1563,6 +1563,246 @@ test_write_intlist_ssid (void) g_object_unref (connection); } +#define TEST_INTLIKE_SSID_FILE TEST_KEYFILES_DIR"/Test_Intlike_SSID" + +static void +test_read_intlike_ssid (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + GError *error = NULL; + gboolean success; + const GByteArray *array; + const char *expected_ssid = "101"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_INTLIKE_SSID_FILE, &error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* SSID */ + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); + + array = nm_setting_wireless_get_ssid (s_wifi); + g_assert (array != NULL); + g_assert_cmpint (array->len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (array->data, expected_ssid, strlen (expected_ssid)), ==, 0); + + g_object_unref (connection); +} + +#define TEST_INTLIKE_SSID_2_FILE TEST_KEYFILES_DIR"/Test_Intlike_SSID_2" + +static void +test_read_intlike_ssid_2 (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + GError *error = NULL; + gboolean success; + const GByteArray *array; + const char *expected_ssid = "11;12;13;"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_INTLIKE_SSID_2_FILE, &error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* SSID */ + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); + + array = nm_setting_wireless_get_ssid (s_wifi); + g_assert (array != NULL); + g_assert_cmpint (array->len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (array->data, expected_ssid, strlen (expected_ssid)), ==, 0); + + g_object_unref (connection); +} + +static void +test_write_intlike_ssid (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingIP4Config *s_ip4; + char *uuid, *testfile = NULL; + GByteArray *ssid; + unsigned char tmpssid[] = { 49, 48, 49 }; + gboolean success; + NMConnection *reread; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + GKeyFile *keyfile; + char *tmp; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Intlike SSID Test", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wireless setting */ + s_wifi = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_byte_array_free (ssid, TRUE); + + /* IP4 setting */ + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile != NULL); + + /* Ensure the SSID was written out as a plain "101" */ + keyfile = g_key_file_new (); + success = g_key_file_load_from_file (keyfile, testfile, 0, &error); + g_assert_no_error (error); + g_assert (success); + + tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, &error); + g_assert_no_error (error); + g_assert (tmp); + g_assert_cmpstr (tmp, ==, "101"); + + g_key_file_free (keyfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +static void +test_write_intlike_ssid_2 (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingIP4Config *s_ip4; + char *uuid, *testfile = NULL; + GByteArray *ssid; + unsigned char tmpssid[] = { 49, 49, 59, 49, 50, 59, 49, 51, 59}; + gboolean success; + NMConnection *reread; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + GKeyFile *keyfile; + char *tmp; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Intlike SSID Test 2", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wireless setting */ + s_wifi = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_byte_array_free (ssid, TRUE); + + /* IP4 setting */ + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile != NULL); + + /* Ensure the SSID was written out as a plain "11;12;13;" */ + keyfile = g_key_file_new (); + success = g_key_file_load_from_file (keyfile, testfile, 0, &error); + g_assert_no_error (error); + g_assert (success); + + tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, &error); + g_assert_no_error (error); + g_assert (tmp); + g_assert_cmpstr (tmp, ==, "11\\;12\\;13\\;"); + + g_key_file_free (keyfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + #define TEST_BT_DUN_FILE TEST_KEYFILES_DIR"/ATT_Data_Connect_BT" static void @@ -2616,6 +2856,12 @@ int main (int argc, char **argv) test_read_intlist_ssid (); test_write_intlist_ssid (); + test_read_intlike_ssid (); + test_write_intlike_ssid (); + + test_read_intlike_ssid_2 (); + test_write_intlike_ssid_2 (); + test_read_bt_dun_connection (); test_write_bt_dun_connection (); diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 060093ce..db43b233 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -44,6 +44,7 @@ #include <ctype.h> #include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" #include "writer.h" #include "common.h" @@ -483,6 +484,7 @@ ssid_writer (GKeyFile *file, GByteArray *array; const char *setting_name = nm_setting_get_name (setting); gboolean new_format = TRUE; + unsigned int semicolons = 0; int i, *tmp_array; char *ssid; @@ -501,11 +503,24 @@ ssid_writer (GKeyFile *file, new_format = FALSE; break; } + if (c == ';') + semicolons++; } if (new_format) { - ssid = g_malloc0 (array->len + 1); - memcpy (ssid, array->data, array->len); + ssid = g_malloc0 (array->len + semicolons + 1); + if (semicolons == 0) + memcpy (ssid, array->data, array->len); + else { + /* Escape semicolons with backslashes to make strings + * containing ';', such as '16;17;' unambiguous */ + int j = 0; + for (i = 0; i < array->len; i++) { + if (array->data[i] == ';') + ssid[j++] = '\\'; + ssid[j++] = array->data[i]; + } + } g_key_file_set_string (file, setting_name, key, ssid); g_free (ssid); } else { @@ -876,7 +891,7 @@ write_setting_value (NMSetting *setting, } else if (type == G_TYPE_BOOLEAN) { g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); } else if (type == G_TYPE_CHAR) { - g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_char (value)); + g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value)); } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { GByteArray *array; @@ -993,15 +1008,27 @@ _internal_write_connection (NMConnection *connection, path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection)); if (g_file_test (path, G_FILE_TEST_EXISTS)) { - /* Hmm, this is odd. Give up. */ - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, - "%s.%d: could not find suitable keyfile file name (%s already used)", - __FILE__, __LINE__, path); - g_free (path); - goto out; + if (existing_path == NULL || g_strcmp0 (path, existing_path) != 0) { + /* This should not happen. But, it actually occurs when + * two connections have the same UUID, and one of the connections + * is edited to contain the same ID as the other one. + * Give up. + */ + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: could not find suitable keyfile file name (%s already used)", + __FILE__, __LINE__, path); + g_free (path); + goto out; + } } } + /* In case of updating the connection and changing the file path, + * we need to remove the old one, not to end up with two connections. + */ + if (existing_path != NULL && strcmp (path, existing_path) != 0) + unlink (existing_path); + g_file_set_contents (path, data, len, error); if (chown (path, owner_uid, owner_grp) < 0) { g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, |