summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/wifi/nm-device-wifi.c20
-rw-r--r--src/supplicant/nm-supplicant-interface.c62
2 files changed, 55 insertions, 27 deletions
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index e145a5c5f5..b9e71d94f1 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -1533,7 +1533,9 @@ _scan_request_ssids_build_hidden (NMDeviceWifi *self,
gs_free NMSettingsConnection **connections = NULL;
gs_unref_ptrarray GPtrArray *ssids = NULL;
gs_unref_hashtable GHashTable *unique_ssids = NULL;
- guint i, len;
+ guint connections_len;
+ guint n_hidden;
+ guint i;
NM_SET_OUT (out_has_hidden_profiles, FALSE);
@@ -1558,7 +1560,7 @@ _scan_request_ssids_build_hidden (NMDeviceWifi *self,
}
connections = nm_settings_get_connections_clone (nm_device_get_settings ((NMDevice *) self),
- &len,
+ &connections_len,
hidden_filter_func,
NULL,
NULL,
@@ -1579,28 +1581,36 @@ _scan_request_ssids_build_hidden (NMDeviceWifi *self,
}
g_qsort_with_data (connections,
- len,
+ connections_len,
sizeof (NMSettingsConnection *),
nm_settings_connection_cmp_timestamp_p_with_data,
NULL);
- for (i = 0; connections[i]; i++) {
+ n_hidden = 0;
+ for (i = 0; i < connections_len; i++) {
NMSettingWireless *s_wifi;
GBytes *ssid;
if (ssids->len >= max_scan_ssids)
break;
+ if (n_hidden > 4) {
+ /* we allow at most 4 hidden profiles to be actively scanned. The
+ * reason is speed and to not disclose too many SSIDs. */
+ break;
+ }
+
s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (connections[i]));
ssid = nm_setting_wireless_get_ssid (s_wifi);
if (!g_hash_table_add (unique_ssids, ssid))
continue;
- NM_SET_OUT (out_has_hidden_profiles, TRUE);
g_ptr_array_add (ssids, g_bytes_ref (ssid));
+ n_hidden++;
}
+ NM_SET_OUT (out_has_hidden_profiles, n_hidden > 0);
return g_steal_pointer (&ssids);
}
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index 700563624a..1c7b9a4213 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -154,6 +154,9 @@ typedef struct _NMSupplicantInterfacePrivate {
bool is_ready_main:1;
bool is_ready_p2p_device:1;
+ bool prop_scan_active:1;
+ bool prop_scan_ssid:1;
+
} NMSupplicantInterfacePrivate;
struct _NMSupplicantInterfaceClass {
@@ -1167,10 +1170,11 @@ static void
parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- gboolean have_active = FALSE;
- gboolean have_ssid = FALSE;
+ const gboolean old_prop_scan_active = priv->prop_scan_active;
+ const gboolean old_prop_scan_ssid = priv->prop_scan_ssid;
+ const guint32 old_max_scan_ssids = priv->max_scan_ssids;
gboolean have_ft = FALSE;
- gint32 max_scan_ssids = -1;
+ gint32 max_scan_ssids;
const char **array;
nm_assert (capabilities && g_variant_is_of_type (capabilities, G_VARIANT_TYPE_VARDICT));
@@ -1195,28 +1199,37 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities)
}
if (g_variant_lookup (capabilities, "Scan", "^a&s", &array)) {
- if (g_strv_contains (array, "active"))
- have_active = TRUE;
- if (g_strv_contains (array, "ssid"))
- have_ssid = TRUE;
+ const char **a;
+
+ priv->prop_scan_active = FALSE;
+ priv->prop_scan_ssid = FALSE;
+ for (a = array; *a; a++) {
+ if (nm_streq (*a, "active"))
+ priv->prop_scan_active = TRUE;
+ else if (nm_streq (*a, "ssid"))
+ priv->prop_scan_ssid = TRUE;
+ }
g_free (array);
}
if (g_variant_lookup (capabilities, "MaxScanSSID", "i", &max_scan_ssids)) {
- /* We need active scan and SSID probe capabilities to care about MaxScanSSIDs */
- if ( max_scan_ssids > 0
- && have_active
- && have_ssid) {
- /* wpa_supplicant's NM_WPAS_MAX_SCAN_SSIDS value is 16, but for speed
- * and to ensure we don't disclose too many SSIDs from the hidden
- * list, we'll limit to 5.
- */
- max_scan_ssids = CLAMP (max_scan_ssids, 0, 5);
- if (max_scan_ssids != priv->max_scan_ssids) {
- priv->max_scan_ssids = max_scan_ssids;
- _LOGD ("supports %d scan SSIDs", priv->max_scan_ssids);
- }
- }
+ const gint32 WPAS_MAX_SCAN_SSIDS = 16;
+
+ /* Even if supplicant claims that 20 SSIDs are supported, the Scan request
+ * still only accepts WPAS_MAX_SCAN_SSIDS SSIDs. Otherwise the D-Bus
+ * request will be rejected with "fi.w1.wpa_supplicant1.InvalidArgs"
+ * Body: ('Did not receive correct message arguments.', 'Too many ssids specified. Specify at most four')
+ * */
+ priv->max_scan_ssids = CLAMP (max_scan_ssids, 0, WPAS_MAX_SCAN_SSIDS);
+ }
+
+ if ( old_max_scan_ssids != priv->max_scan_ssids
+ || old_prop_scan_active != priv->prop_scan_active
+ || old_prop_scan_ssid != priv->prop_scan_ssid) {
+ _LOGD ("supports %u scan SSIDs (scan: %cactive %cssid)",
+ (guint32) priv->max_scan_ssids,
+ priv->prop_scan_active ? '+' : '-',
+ priv->prop_scan_ssid ? '+' : '-');
}
}
@@ -2514,9 +2527,14 @@ nm_supplicant_interface_get_ifname (NMSupplicantInterface *self)
guint
nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self)
{
+ NMSupplicantInterfacePrivate *priv;
+
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), 0);
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->max_scan_ssids;
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ return priv->prop_scan_active && priv->prop_scan_ssid
+ ? priv->max_scan_ssids
+ : 0u;
}
/*****************************************************************************/