From dc115bf4068748ff089c8ec12d1d932feb8fae49 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Mon, 23 Sep 2019 16:02:32 +0200 Subject: [PATCH 1/2] iwd: support connecting to hidden networks Newer versions of iwd has supported connecting to hidden networks for a while now. There's a separate "connect-hidden" command in iwctl that needs to be used instead of the regular "connect" command. The equivalent on dbus is to use ConnectHiddenNetwork instead of Connect on the Station interface. NetworkManager however uses the Network interface and given we the explicit SSID usage we can connect to hidden networks with that. This change disabled the explicit check that disallows even attempting hidden networks when using iwd. This has been tested to work with a previously known hidden network. Tests connecting to a previously unknown network has failed. (cherry picked from commit cd095f49dce262a5107be3005f0ee7ae9720cacd) --- src/devices/wifi/nm-device-iwd.c | 34 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 3dccd1cb94..ada98ecdf1 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -615,13 +615,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError return FALSE; } - /* Hidden SSIDs not supported in any mode (client or AP) */ - if (nm_setting_wireless_get_hidden (s_wireless)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "hidden networks not supported by the IWD backend"); - return FALSE; - } - security = nm_wifi_connection_get_iwd_security (connection, &mapped); if (!mapped) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, @@ -630,6 +623,15 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError } mode = nm_setting_wireless_get_mode (s_wireless); + + /* Hidden SSIDs only supported in client mode */ + if ( nm_setting_wireless_get_hidden (s_wireless) + && !NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "non-infrastructure hidden networks not supported by the IWD backend"); + return FALSE; + } + if (NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { /* 8021x networks can only be used if they've been provisioned on the IWD side and * thus are Known Networks. @@ -757,6 +759,7 @@ complete_connection (NMDevice *device, NMWifiAP *ap; GBytes *ssid; GBytes *setting_ssid = NULL; + gboolean hidden = FALSE; const char *mode; s_wifi = nm_connection_get_setting_wireless (connection); @@ -789,16 +792,14 @@ complete_connection (NMDevice *device, /* Find a compatible AP in the scan list */ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); if (!ap) { - if (!nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "No compatible AP in the scan list and hidden SSIDs not supported."); - return FALSE; - } - + /* If we still don't have an AP, then the WiFI settings needs to be + * fully specified by the client. Might not be able to find an AP + * if the network isn't broadcasting the SSID for example. + */ if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) return FALSE; + + hidden = TRUE; } } else { ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); @@ -849,6 +850,9 @@ complete_connection (NMDevice *device, nm_setting_wireless_get_mac_address (s_wifi) ? NULL : nm_device_get_iface (device), TRUE); + if (hidden) + g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); + return TRUE; } From 4bb0e48b13f2d521534776b968d301f51016be61 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Mon, 11 Nov 2019 00:36:36 +0100 Subject: [PATCH 2/2] iwd: use ConnectHiddenNetwork to provision hidden network The Station.ConnectHiddenNetwork will provision a network in the iwd known-networks list. This should allow us to later use the Network.Connect interface to connect in the future. (Note: Attempts to use Station.ConnectHiddenNetwork on already provisioned networks, i.e. networks iwd knows about, will fail.) This commit squashed several fixups made by thaller. (cherry picked from commit 69aeed4bdc1de85a8e0a42f6d40bd0b9175c8c83) --- src/devices/wifi/nm-device-iwd.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index ada98ecdf1..acf041e936 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1790,11 +1790,34 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) goto out_fail; } + if ( !is_connection_known_network (connection) + && nm_setting_wireless_get_hidden (s_wireless)) { + gs_free char *ssid_str = NULL; + + /* Use Station.ConnectHiddenNetwork method instead of Network proxy. */ + ssid_str = _nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wireless)); + g_dbus_proxy_call (priv->dbus_station_proxy, + "ConnectHiddenNetwork", + g_variant_new ("(s)", ssid_str), + G_DBUS_CALL_FLAGS_NONE, G_MAXINT, + priv->cancellable, + network_connect_cb, + self); + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (!nm_wifi_ap_get_supplicant_path (ap)) { + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) network is provisioned but dbus supplicant path for AP unknown"); + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + goto out_fail; + } + network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (), nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)), NM_IWD_NETWORK_INTERFACE); if (!network_proxy) { - _LOGE (LOGD_DEVICE | LOGD_WIFI, + _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) could not get Network interface proxy for %s", nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap))); NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);