about summary refs log tree commit diff
path: root/src/supplicant
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2019-03-12 15:13:33 +0100
committerSebastien Bacher <seb128@ubuntu.com>2019-03-12 15:13:33 +0100
commitdd428301eb6f02542015121d7b08d9997f137e50 (patch)
tree5530189f63510287d65268fc36025bdbc9414c00 /src/supplicant
parentbbae86d3d2997a853ca0365e8eb7a3ca7489ee09 (diff)
New upstream version 1.15.91
Diffstat (limited to 'src/supplicant')
-rw-r--r--src/supplicant/nm-supplicant-config.c75
-rw-r--r--src/supplicant/nm-supplicant-interface.c43
-rw-r--r--src/supplicant/nm-supplicant-manager.c70
-rw-r--r--src/supplicant/nm-supplicant-manager.h3
-rw-r--r--src/supplicant/nm-supplicant-settings-verify.c20
-rw-r--r--src/supplicant/tests/meson.build1
-rw-r--r--src/supplicant/tests/test-supplicant-config.c72
7 files changed, 209 insertions, 75 deletions
diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c
index 4acb634e..7708224b 100644
--- a/src/supplicant/nm-supplicant-config.c
+++ b/src/supplicant/nm-supplicant-config.c
@@ -23,7 +23,6 @@
 
 #include "nm-supplicant-config.h"
 
-#include <string.h>
 #include <stdlib.h>
 
 #include "nm-core-internal.h"
@@ -404,11 +403,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self,
 
 		value = nm_setting_macsec_get_mka_cak (setting);
 		if (   !value
-		    || !_nm_utils_hexstr2bin_buf (value,
-		                                  FALSE,
-		                                  FALSE,
-		                                  NULL,
-		                                  buffer_cak)) {
+		    || !nm_utils_hexstr2bin_buf (value,
+		                                 FALSE,
+		                                 FALSE,
+		                                 NULL,
+		                                 buffer_cak)) {
 			g_set_error_literal (error,
 			                     NM_SUPPLICANT_ERROR,
 			                     NM_SUPPLICANT_ERROR_CONFIG,
@@ -425,11 +424,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self,
 
 		value = nm_setting_macsec_get_mka_ckn (setting);
 		if (   !value
-		    || !_nm_utils_hexstr2bin_buf (value,
-		                                  FALSE,
-		                                  FALSE,
-		                                  NULL,
-		                                  buffer_ckn)) {
+		    || !nm_utils_hexstr2bin_buf (value,
+		                                 FALSE,
+		                                 FALSE,
+		                                 NULL,
+		                                 buffer_ckn)) {
 			g_set_error_literal (error,
 			                     NM_SUPPLICANT_ERROR,
 			                     NM_SUPPLICANT_ERROR_CONFIG,
@@ -705,14 +704,14 @@ add_wep_key (NMSupplicantConfig *self,
 		if ((key_len == 10) || (key_len == 26)) {
 			guint8 buffer[26/2];
 
-			if (!_nm_utils_hexstr2bin_full (key,
-			                                FALSE,
-			                                FALSE,
-			                                NULL,
-			                                key_len / 2,
-			                                buffer,
-			                                sizeof (buffer),
-			                                NULL)) {
+			if (!nm_utils_hexstr2bin_full (key,
+			                               FALSE,
+			                               FALSE,
+			                               NULL,
+			                               key_len / 2,
+			                               buffer,
+			                               sizeof (buffer),
+			                               NULL)) {
 				g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
 				             "cannot add wep-key %s to suplicant config because key is not hex",
 				             name);
@@ -807,15 +806,30 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
 	if (psk) {
 		size_t psk_len = strlen (psk);
 
-		if (psk_len == 64) {
+
+		if (psk_len >= 8 && psk_len <= 63) {
+			/* Use TYPE_STRING here so that it gets pushed to the
+			 * supplicant as a string, and therefore gets quoted,
+			 * and therefore the supplicant will interpret it as a
+			 * passphrase and not a hex key.
+			 */
+			if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error))
+				return FALSE;
+		} else if (nm_streq (key_mgmt, "sae")) {
+			/* If the SAE password doesn't comply with WPA-PSK limitation,
+			 * we need to call it "sae_password" instead of "psk".
+			 */
+			if (!nm_supplicant_config_add_option_with_type (self, "sae_password", psk, -1, TYPE_STRING, "<hidden>", error))
+				return FALSE;
+		} else if (psk_len == 64) {
 			guint8 buffer[32];
 
 			/* Hex PSK */
-			if (!_nm_utils_hexstr2bin_buf (psk,
-			                               FALSE,
-			                               FALSE,
-			                               NULL,
-			                               buffer)) {
+			if (!nm_utils_hexstr2bin_buf (psk,
+			                              FALSE,
+			                              FALSE,
+			                              NULL,
+			                              buffer)) {
 				g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
 				             "Cannot add psk to supplicant config due to invalid hex");
 				return FALSE;
@@ -827,14 +841,6 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
 			                                      "<hidden>",
 			                                      error))
 				return FALSE;
-		} else if (psk_len >= 8 && psk_len <= 63) {
-			/* Use TYPE_STRING here so that it gets pushed to the
-			 * supplicant as a string, and therefore gets quoted,
-			 * and therefore the supplicant will interpret it as a
-			 * passphrase and not a hex key.
-			 */
-			if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error))
-				return FALSE;
 		} else {
 			g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
 			             "Cannot add psk to supplicant config due to invalid PSK length %u (not between 8 and 63 characters)",
@@ -861,7 +867,8 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
 	/* Only WPA-specific things when using WPA */
 	if (   !strcmp (key_mgmt, "wpa-none")
 	    || !strcmp (key_mgmt, "wpa-psk")
-	    || !strcmp (key_mgmt, "wpa-eap")) {
+	    || !strcmp (key_mgmt, "wpa-eap")
+	    || !strcmp (key_mgmt, "sae")) {
 		if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, NULL, error))
 			return FALSE;
 		if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, NULL, error))
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index c30adc58..f46689eb 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -25,7 +25,6 @@
 #include "nm-supplicant-manager.h"
 
 #include <stdio.h>
-#include <string.h>
 
 #include "NetworkManagerUtils.h"
 #include "nm-supplicant-config.h"
@@ -729,9 +728,8 @@ iface_set_pmf_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 
 	self = NM_SUPPLICANT_INTERFACE (user_data);
 
-	/* This can fail if the supplicant doesn't support PMF */
 	if (error)
-		_LOGD ("failed to set Pmf=1: %s", error->message);
+		_LOGW ("failed to set Pmf=1: %s", error->message);
 
 	iface_check_ready (self);
 }
@@ -1452,7 +1450,7 @@ p2p_props_changed_cb (GDBusProxy *proxy,
 			/* We already have the proxy, nothing to do. */
 		} else if (path && g_strcmp0 (path, "/") != 0) {
 			if (priv->group_proxy != NULL) {
-				_LOGW ("P2P: Unexpected udpate of the group object path");
+				_LOGW ("P2P: Unexpected update of the group object path");
 				priv->group_proxy_acquired = FALSE;
 				_notify (self, PROP_P2P_GROUP_JOINED);
 				_notify (self, PROP_P2P_GROUP_PATH);
@@ -1548,7 +1546,7 @@ p2p_group_started (GDBusProxy *proxy,
 		}
 	}
 
-	/* Signal existance of the (new) interface. */
+	/* Signal existence of the (new) interface. */
 	g_signal_emit (self, signals[GROUP_STARTED], 0, iface);
 	g_object_unref (iface);
 }
@@ -1639,21 +1637,9 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_
 	                   NULL,
 	                   NULL);
 
-	/* Initialize global PMF setting to 'optional' */
-	priv->ready_count++;
-	g_dbus_proxy_call (priv->iface_proxy,
-	                   DBUS_INTERFACE_PROPERTIES ".Set",
-	                   g_variant_new ("(ssv)",
-	                                  WPAS_DBUS_IFACE_INTERFACE,
-	                                  "Pmf",
-	                                  g_variant_new_string ("1")),
-	                   G_DBUS_CALL_FLAGS_NONE,
-	                   -1,
-	                   priv->init_cancellable,
-	                   (GAsyncReadyCallback) iface_set_pmf_cb,
-	                   self);
-
-	/* Check whether NetworkReply and AP mode are supported */
+	/* Check whether NetworkReply and AP mode are supported.
+	 * ready_count was initialized to 1 in interface_add_done().
+	 */
 	g_dbus_proxy_call (priv->iface_proxy,
 	                   "NetworkReply",
 	                   g_variant_new ("(oss)",
@@ -1666,6 +1652,22 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_
 	                   (GAsyncReadyCallback) iface_check_netreply_cb,
 	                   self);
 
+	if (priv->pmf_support == NM_SUPPLICANT_FEATURE_YES) {
+		/* Initialize global PMF setting to 'optional' */
+		priv->ready_count++;
+		g_dbus_proxy_call (priv->iface_proxy,
+		                   DBUS_INTERFACE_PROPERTIES ".Set",
+		                   g_variant_new ("(ssv)",
+		                                  WPAS_DBUS_IFACE_INTERFACE,
+		                                  "Pmf",
+		                                  g_variant_new_string ("1")),
+		                   G_DBUS_CALL_FLAGS_NONE,
+		                   -1,
+		                   priv->init_cancellable,
+		                   (GAsyncReadyCallback) iface_set_pmf_cb,
+		                   self);
+	}
+
 	if (priv->ap_support == NM_SUPPLICANT_FEATURE_UNKNOWN) {
 		/* If the global supplicant capabilities property is not present, we can
 		 * fall back to checking whether the ProbeRequest method is supported.  If
@@ -2482,7 +2484,6 @@ nm_supplicant_interface_p2p_start_find (NMSupplicantInterface *self,
 
 	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
 
-	/* Find parameters */
 	g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
 	g_variant_builder_add (&builder, "{sv}", "Timeout", g_variant_new_int32 (timeout));
 
diff --git a/src/supplicant/nm-supplicant-manager.c b/src/supplicant/nm-supplicant-manager.c
index 64a057f3..104aeee7 100644
--- a/src/supplicant/nm-supplicant-manager.c
+++ b/src/supplicant/nm-supplicant-manager.c
@@ -23,8 +23,6 @@
 
 #include "nm-supplicant-manager.h"
 
-#include <string.h>
-
 #include "nm-supplicant-interface.h"
 #include "nm-supplicant-types.h"
 #include "nm-core-internal.h"
@@ -71,7 +69,7 @@ NM_CACHED_QUARK_FCN ("nm-supplicant-error-quark", nm_supplicant_error_quark)
 
 /*****************************************************************************/
 
-static inline gboolean
+static gboolean
 die_count_exceeded (guint32 count)
 {
 	return count > 2;
@@ -125,6 +123,72 @@ _sup_iface_last_ref (gpointer data,
 	g_object_remove_toggle_ref ((GObject *) sup_iface, _sup_iface_last_ref, self);
 }
 
+static void
+on_supplicant_wfd_ies_set (GObject *source_object,
+                           GAsyncResult *res,
+                           gpointer user_data)
+{
+	gs_unref_variant GVariant *result = NULL;
+	gs_free_error GError *error = NULL;
+
+	result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error);
+
+	if (!result)
+		_LOGW ("failed to set WFD IEs on wpa_supplicant: %s", error->message);
+}
+
+/**
+ * nm_supplicant_manager_set_wfd_ies:
+ * @self: the #NMSupplicantManager
+ * @wfd_ies: a #GBytes with the WFD IEs or %NULL
+ *
+ * This function sets the global WFD IEs on wpa_supplicant. Note that
+ * it would make more sense if this was per-device, but wpa_supplicant
+ * simply does not work that way.
+ * */
+void
+nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self,
+                                   GBytes *wfd_ies)
+{
+	NMSupplicantManagerPrivate *priv;
+	GVariantBuilder params;
+	GVariant *val;
+
+	g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
+
+	priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+
+	_LOGD ("setting WFD IEs for P2P operation");
+
+	if (wfd_ies)
+		val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+		                                 g_bytes_get_data (wfd_ies, NULL),
+		                                 g_bytes_get_size (wfd_ies),
+		                                 sizeof (guint8));
+	else
+		val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+		                                 NULL, 0, sizeof (guint8));
+
+	g_variant_builder_init (&params, G_VARIANT_TYPE ("(ssv)"));
+
+	g_variant_builder_add (&params, "s", g_dbus_proxy_get_interface_name (priv->proxy));
+	g_variant_builder_add (&params, "s", "WFDIEs");
+	g_variant_builder_add_value (&params, g_variant_new_variant (val));
+
+	g_dbus_connection_call (g_dbus_proxy_get_connection (priv->proxy),
+	                        g_dbus_proxy_get_name (priv->proxy),
+	                        g_dbus_proxy_get_object_path (priv->proxy),
+	                        "org.freedesktop.DBus.Properties",
+	                        "Set",
+	                        g_variant_builder_end (&params),
+	                        G_VARIANT_TYPE_UNIT,
+	                        G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                        1000,
+	                        NULL,
+	                        on_supplicant_wfd_ies_set,
+	                        NULL);
+}
+
 /**
  * nm_supplicant_manager_create_interface:
  * @self: the #NMSupplicantManager
diff --git a/src/supplicant/nm-supplicant-manager.h b/src/supplicant/nm-supplicant-manager.h
index 7225a36b..058745fb 100644
--- a/src/supplicant/nm-supplicant-manager.h
+++ b/src/supplicant/nm-supplicant-manager.h
@@ -38,6 +38,9 @@ GType nm_supplicant_manager_get_type (void);
 
 NMSupplicantManager *nm_supplicant_manager_get (void);
 
+void nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self,
+                                        GBytes *wfd_ies);
+
 NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr,
                                                                const char *ifname,
                                                                NMSupplicantDriver driver);
diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c
index 1e25675d..f10bbb04 100644
--- a/src/supplicant/nm-supplicant-settings-verify.c
+++ b/src/supplicant/nm-supplicant-settings-verify.c
@@ -24,8 +24,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <errno.h>
 
 struct Opt {
 	const char *     key;
@@ -72,7 +70,7 @@ const char * proto_allowed[] =    { "WPA", "RSN", NULL };
 const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256",
                                     "WPA-EAP", "WPA-EAP-SHA256",
                                     "FILS-SHA256", "FILS-SHA384",
-                                    "IEEE8021X", "WPA-NONE",
+                                    "IEEE8021X", "WPA-NONE", "SAE",
                                     "NONE", NULL };
 const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL };
 const char * eap_allowed[] =      { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM",
@@ -159,23 +157,13 @@ validate_type_int (const struct Opt * opt,
                    const char * value,
                    const guint32 len)
 {
-	long int intval;
+	gint64 v;
 
 	g_return_val_if_fail (opt != NULL, FALSE);
 	g_return_val_if_fail (value != NULL, FALSE);
 
-	errno = 0;
-	intval = strtol (value, NULL, 10);
-	if (errno != 0)
-		return FALSE;
-
-	/* strtol returns a long, but we are dealing with ints */
-	if (intval > INT_MAX || intval < INT_MIN)
-		return FALSE;
-	if (intval > opt->int_high || intval < opt->int_low)
-		return FALSE;
-
-	return TRUE;
+	v = _nm_utils_ascii_str_to_int64 (value, 10, opt->int_low, opt->int_high, G_MININT64);
+	return v != G_MININT64 || errno == 0;
 }
 
 static gboolean
diff --git a/src/supplicant/tests/meson.build b/src/supplicant/tests/meson.build
index 7cc9d6af..fbccb313 100644
--- a/src/supplicant/tests/meson.build
+++ b/src/supplicant/tests/meson.build
@@ -10,4 +10,5 @@ test(
   'supplicant/' + test_unit,
   test_script,
   args: test_args + [exe.full_path()],
+  timeout: default_test_timeout,
 )
diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c
index d7ec1fe2..2c7a71a3 100644
--- a/src/supplicant/tests/test-supplicant-config.c
+++ b/src/supplicant/tests/test-supplicant-config.c
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <string.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
@@ -389,6 +388,76 @@ test_wifi_wpa_psk (const char *detail,
 }
 
 static void
+test_wifi_sae_psk (const char *psk)
+{
+	gs_unref_object NMConnection *connection = NULL;
+	gs_unref_variant GVariant *config_dict = NULL;
+	NMSettingWirelessSecurity *s_wsec;
+	gboolean success;
+	GError *error = NULL;
+	const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
+	gs_unref_bytes GBytes *ssid = g_bytes_new (ssid_data, sizeof (ssid_data));
+	const char *bssid_str = "11:22:33:44:55:66";
+	int short_psk = strlen (psk) < 8;
+
+	connection = new_basic_connection ("Test Wifi SAE", ssid, bssid_str);
+
+	/* Wifi Security setting */
+	s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+	g_object_set (s_wsec,
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae",
+	              NM_SETTING_WIRELESS_SECURITY_PSK, psk,
+	              NULL);
+	nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+	nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
+	nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+	nm_setting_wireless_security_add_group (s_wsec, "tkip");
+	nm_setting_wireless_security_add_group (s_wsec, "ccmp");
+
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	NMTST_EXPECT_NM_INFO ("Config: added 'ssid' value 'Test SSID'*");
+	NMTST_EXPECT_NM_INFO ("Config: added 'scan_ssid' value '1'*");
+	NMTST_EXPECT_NM_INFO ("Config: added 'bssid' value '11:22:33:44:55:66'*");
+	NMTST_EXPECT_NM_INFO ("Config: added 'freq_list' value *");
+	NMTST_EXPECT_NM_INFO ("Config: added 'key_mgmt' value 'SAE'");
+	if (short_psk)
+		NMTST_EXPECT_NM_INFO ("Config: added 'sae_password' value *");
+	else
+		NMTST_EXPECT_NM_INFO ("Config: added 'psk' value *");
+	NMTST_EXPECT_NM_INFO ("Config: added 'proto' value 'RSN'");
+	NMTST_EXPECT_NM_INFO ("Config: added 'pairwise' value 'TKIP CCMP'");
+	NMTST_EXPECT_NM_INFO ("Config: added 'group' value 'TKIP CCMP'");
+	NMTST_EXPECT_NM_INFO ("Config: added 'ieee80211w' value '0'");
+	config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE);
+
+	g_test_assert_expected_messages ();
+	g_assert (config_dict);
+
+	validate_opt ("wifi-sae", config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1));
+	validate_opt ("wifi-sae", config_dict, "ssid", TYPE_BYTES, ssid);
+	validate_opt ("wifi-sae", config_dict, "bssid", TYPE_KEYWORD, bssid_str);
+	validate_opt ("wifi-sae", config_dict, "key_mgmt", TYPE_KEYWORD, "SAE");
+	validate_opt ("wifi-sae", config_dict, "proto", TYPE_KEYWORD, "RSN");
+	validate_opt ("wifi-sae", config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP");
+	validate_opt ("wifi-sae", config_dict, "group", TYPE_KEYWORD, "TKIP CCMP");
+	if (short_psk)
+		validate_opt ("wifi-sae", config_dict, "sae_password", TYPE_KEYWORD, psk);
+	else
+		validate_opt ("wifi-sae", config_dict, "psk", TYPE_KEYWORD, psk);
+}
+
+static void
+test_wifi_sae (void)
+{
+	test_wifi_sae_psk ("Moo");
+	test_wifi_sae_psk ("Hello World!");
+}
+
+static void
 test_wifi_wpa_psk_types (void)
 {
 	const char *key1 = "d4721e911461d3cdef9793858e977fcda091779243abb7316c2f11605a160893";
@@ -580,6 +649,7 @@ int main (int argc, char **argv)
 	g_test_add_func ("/supplicant-config/wifi-eap/locked-bssid", test_wifi_eap_locked_bssid);
 	g_test_add_func ("/supplicant-config/wifi-eap/unlocked-bssid", test_wifi_eap_unlocked_bssid);
 	g_test_add_func ("/supplicant-config/wifi-eap/fils-disabled", test_wifi_eap_fils_disabled);
+	g_test_add_func ("/supplicant-config/wifi-sae", test_wifi_sae);
 
 	return g_test_run ();
 }