summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2020-10-23 22:11:01 +0200
committerThomas Haller <thaller@redhat.com>2020-11-12 15:35:57 +0100
commitf03587e93c2f53ebb386f5955e21cac14f1924f1 (patch)
tree2111cfc315dd8bf8a4ba86d1ebce4597aca1390d
parent96424ca35cbc4735f3b6470dea599e6fff2aca27 (diff)
downloadNetworkManager-f03587e93c2f53ebb386f5955e21cac14f1924f1.tar.gz
iwd: Stop using _nm_utils_ssid_to_utf8()
_nm_utils_ssid_to_utf8() can be quite heavy and also has this comment: * Again, this function should be used for debugging and display purposes * _only_. In most places that we used it, we have already validated the connection's SSID to be valid UTF-8 so we can simply g_strndup() it now, even in the two places where we actually only needed it for display purposes. And we definitely don't need or want the locale-specific conversions done in _nm_utils_ssid_to_utf8 when the SSID is *not* utf8. In mirror_8021x_connection we also optimize the lookup loop to avoid validating and strdup'ing all the SSID.
-rw-r--r--src/devices/wifi/nm-device-iwd.c149
-rw-r--r--src/devices/wifi/nm-iwd-manager.c40
-rw-r--r--src/devices/wifi/nm-wifi-utils.c49
-rw-r--r--src/devices/wifi/nm-wifi-utils.h5
4 files changed, 132 insertions, 111 deletions
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 4fe8ea57bb..0e4afc9ee1 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -603,27 +603,13 @@ deactivate_async(NMDevice * device,
static gboolean
is_connection_known_network(NMConnection *connection)
{
- NMSettingWireless * s_wireless;
NMIwdNetworkSecurity security;
- gboolean security_ok;
- GBytes * ssid;
- gs_free char * ssid_utf8 = NULL;
-
- s_wireless = nm_connection_get_setting_wireless(connection);
- if (!s_wireless)
- return FALSE;
-
- ssid = nm_setting_wireless_get_ssid(s_wireless);
- if (!ssid)
- return FALSE;
+ gs_free char * ssid = NULL;
- ssid_utf8 = _nm_utils_ssid_to_utf8(ssid);
-
- security = nm_wifi_connection_get_iwd_security(connection, &security_ok);
- if (!security_ok)
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, &ssid, &security))
return FALSE;
- return nm_iwd_manager_is_known_network(nm_iwd_manager_get(), ssid_utf8, security);
+ return nm_iwd_manager_is_known_network(nm_iwd_manager_get(), ssid, security);
}
static gboolean
@@ -655,7 +641,6 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError *
const char * perm_hw_addr;
const char * mode;
NMIwdNetworkSecurity security;
- gboolean mapped;
GBytes * ssid;
const guint8 * ssid_bytes;
gsize ssid_len;
@@ -712,8 +697,8 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError *
return FALSE;
}
- security = nm_wifi_connection_get_iwd_security(connection, &mapped);
- if (!mapped) {
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)
+ || security == NM_IWD_NETWORK_SECURITY_WEP) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE,
"connection authentication type not supported by IWD backend");
@@ -799,11 +784,12 @@ check_connection_available(NMDevice * device,
const char * specific_object,
GError ** error)
{
- NMDeviceIwd * self = NM_DEVICE_IWD(device);
- NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self);
- NMSettingWireless * s_wifi;
- const char * mode;
- NMWifiAP * ap = NULL;
+ NMDeviceIwd * self = NM_DEVICE_IWD(device);
+ NMDeviceIwdPrivate * priv = NM_DEVICE_IWD_GET_PRIVATE(self);
+ NMSettingWireless * s_wifi;
+ const char * mode;
+ NMWifiAP * ap = NULL;
+ NMIwdNetworkSecurity security;
s_wifi = nm_connection_get_setting_wireless(connection);
g_return_val_if_fail(s_wifi, FALSE);
@@ -857,7 +843,8 @@ check_connection_available(NMDevice * device,
/* 8021x networks can only be used if they've been provisioned on the IWD side and
* thus are Known Networks.
*/
- if (nm_wifi_connection_get_iwd_security(connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) {
+ if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)
+ && security == NM_IWD_NETWORK_SECURITY_8021X) {
if (!is_ap_known_network(ap)) {
nm_utils_error_set_literal(
error,
@@ -870,6 +857,18 @@ check_connection_available(NMDevice * device,
return TRUE;
}
+/* To be used where the SSID has been validated before */
+static char *
+iwd_ssid_to_str(const GBytes *ssid)
+{
+ const guint8 *ssid_bytes;
+ gsize ssid_len;
+
+ ssid_bytes = g_bytes_get_data((GBytes *) ssid, &ssid_len);
+ nm_assert(ssid && g_utf8_validate((const char *) ssid_bytes, ssid_len, NULL));
+ return g_strndup((const char *) ssid_bytes, ssid_len);
+}
+
static gboolean
complete_connection(NMDevice * device,
NMConnection * connection,
@@ -964,7 +963,7 @@ complete_connection(NMDevice * device,
return FALSE;
}
- ssid_utf8 = _nm_utils_ssid_to_utf8(ssid);
+ ssid_utf8 = iwd_ssid_to_str(ssid);
nm_utils_complete_generic(
nm_device_get_platform(device),
connection,
@@ -1455,10 +1454,8 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data)
gs_unref_variant GVariant *variant = NULL;
gs_free_error GError *error = NULL;
NMConnection * connection;
- NMSettingWireless * s_wifi;
- GBytes * ssid;
- gs_free char * ssid_utf8 = NULL;
- NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED;
+ gs_free char * ssid = NULL;
+ NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED;
GVariant * value;
variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
@@ -1507,19 +1504,12 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data)
if (!connection)
goto failed;
- s_wifi = nm_connection_get_setting_wireless(connection);
- if (!s_wifi)
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, &ssid, NULL))
goto failed;
- ssid = nm_setting_wireless_get_ssid(s_wifi);
- if (!ssid)
- goto failed;
-
- ssid_utf8 = _nm_utils_ssid_to_utf8(ssid);
-
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Connected to '%s'.",
- ssid_utf8);
+ ssid);
nm_device_activate_schedule_stage3_ip_config_start(device);
if (!priv->periodic_update_id) {
@@ -1577,10 +1567,9 @@ act_start_cb(GObject *source, GAsyncResult *res, gpointer user_data)
NMDevice * device = NM_DEVICE(self);
gs_unref_variant GVariant *variant = NULL;
gs_free_error GError *error = NULL;
- NMSettingWireless * s_wireless;
- GBytes * ssid;
- gs_free char * ssid_utf8 = NULL;
+ gs_free char * ssid = NULL;
const char * mode;
+ NMSettingWireless * s_wireless;
variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
if (!variant) {
@@ -1599,21 +1588,18 @@ act_start_cb(GObject *source, GAsyncResult *res, gpointer user_data)
nm_assert(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG);
- s_wireless = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS);
- if (!s_wireless)
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(nm_device_get_applied_connection(device),
+ &ssid,
+ NULL))
goto error;
- ssid = nm_setting_wireless_get_ssid(s_wireless);
- if (!ssid)
- goto error;
-
- ssid_utf8 = _nm_utils_ssid_to_utf8(ssid);
-
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Started '%s'.",
- ssid_utf8);
+ ssid);
nm_device_activate_schedule_stage3_ip_config_start(device);
+ s_wireless =
+ (NMSettingWireless *) nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS);
mode = nm_setting_wireless_get_mode(s_wireless);
if (!priv->periodic_update_id && nm_streq0(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) {
priv->periodic_update_id = g_timeout_add_seconds(6, periodic_update_cb, self);
@@ -1633,14 +1619,13 @@ error:
static void
act_check_interface(NMDeviceIwd *self)
{
- NMDeviceIwdPrivate * priv = NM_DEVICE_IWD_GET_PRIVATE(self);
- NMDevice * device = NM_DEVICE(self);
- NMSettingWireless * s_wireless;
- NMSettingWirelessSecurity *s_wireless_sec;
- GDBusProxy * proxy = NULL;
- GBytes * ssid;
- gs_free char * ssid_utf8 = NULL;
- const char * mode;
+ NMDeviceIwdPrivate * priv = NM_DEVICE_IWD_GET_PRIVATE(self);
+ NMDevice * device = NM_DEVICE(self);
+ NMSettingWireless * s_wireless;
+ GDBusProxy * proxy = NULL;
+ gs_free char * ssid = NULL;
+ const char * mode;
+ NMIwdNetworkSecurity security;
if (!priv->act_mode_switch)
return;
@@ -1662,44 +1647,46 @@ act_check_interface(NMDeviceIwd *self)
if (!NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG))
return;
- ssid = nm_setting_wireless_get_ssid(s_wireless);
- if (!ssid)
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(nm_device_get_applied_connection(device),
+ &ssid,
+ &security))
goto failed;
- ssid_utf8 = _nm_utils_ssid_to_utf8(ssid);
-
- s_wireless_sec = (NMSettingWirelessSecurity *) nm_device_get_applied_setting(
- device,
- NM_TYPE_SETTING_WIRELESS_SECURITY);
-
- if (!s_wireless_sec) {
+ if (security == NM_IWD_NETWORK_SECURITY_NONE) {
g_dbus_proxy_call(proxy,
"StartOpen",
- g_variant_new("(s)", ssid_utf8),
+ g_variant_new("(s)", ssid),
G_DBUS_CALL_FLAGS_NONE,
G_MAXINT,
priv->cancellable,
act_start_cb,
self);
- } else {
- const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec);
+ } else if (security == NM_IWD_NETWORK_SECURITY_PSK) {
+ NMSettingWirelessSecurity *s_wireless_sec;
+ const char * psk;
+
+ s_wireless_sec = (NMSettingWirelessSecurity *) nm_device_get_applied_setting(
+ device,
+ NM_TYPE_SETTING_WIRELESS_SECURITY);
+ psk = nm_setting_wireless_security_get_psk(s_wireless_sec);
if (!psk) {
- _LOGE(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) No PSK for '%s'.", ssid_utf8);
+ _LOGE(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) No PSK for '%s'.", ssid);
goto failed;
}
g_dbus_proxy_call(proxy,
"Start",
- g_variant_new("(ss)", ssid_utf8, psk),
+ g_variant_new("(ss)", ssid, psk),
G_DBUS_CALL_FLAGS_NONE,
G_MAXINT,
priv->cancellable,
act_start_cb,
self);
- }
+ } else
+ goto failed;
- _LOGD(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Called Start('%s').", ssid_utf8);
+ _LOGD(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Called Start('%s').", ssid);
return;
failed:
@@ -1951,7 +1938,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
priv->secrets_failed = FALSE;
if (nm_wifi_ap_get_fake(ap)) {
- gs_free char *ssid_str = NULL;
+ gs_free char *ssid = NULL;
if (!nm_setting_wireless_get_hidden(s_wireless)) {
_LOGW(LOGD_DEVICE | LOGD_WIFI,
@@ -1961,11 +1948,15 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
goto out_fail;
}
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, &ssid, NULL)) {
+ NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ goto out_fail;
+ }
+
/* 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_variant_new("(s)", ssid),
G_DBUS_CALL_FLAGS_NONE,
G_MAXINT,
priv->cancellable,
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c
index 2ab023492a..15b88f8115 100644
--- a/src/devices/wifi/nm-iwd-manager.c
+++ b/src/devices/wifi/nm-iwd-manager.c
@@ -411,18 +411,22 @@ mirror_8021x_connection(NMIwdManager *self, const char *name, gboolean create_ne
NMSetting * setting;
GError * error = NULL;
gs_unref_bytes GBytes *new_ssid = NULL;
+ gsize ssid_len = strlen(name);
for (iter = nm_settings_get_connections(priv->settings, NULL); *iter; iter++) {
NMSettingsConnection *sett_conn = *iter;
NMConnection * conn = nm_settings_connection_get_connection(sett_conn);
NMIwdNetworkSecurity security;
- gs_free char * ssid_name = NULL;
NMSettingWireless * s_wifi;
NMSetting8021x * s_8021x;
gboolean external = FALSE;
guint i;
+ const guint8 * ssid_bytes;
+ gsize ssid_len2;
+
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security))
+ continue;
- security = nm_wifi_connection_get_iwd_security(conn, NULL);
if (security != NM_IWD_NETWORK_SECURITY_8021X)
continue;
@@ -430,9 +434,11 @@ mirror_8021x_connection(NMIwdManager *self, const char *name, gboolean create_ne
if (!s_wifi)
continue;
- ssid_name = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wifi));
-
- if (!nm_streq(ssid_name, name))
+ /* The SSID must be UTF-8 if it matches since name is known to be
+ * valid UTF-8, so just memcmp them.
+ */
+ ssid_bytes = g_bytes_get_data(nm_setting_wireless_get_ssid(s_wifi), &ssid_len2);
+ if (!ssid_bytes || ssid_len2 != ssid_len || memcmp(ssid_bytes, name, ssid_len))
continue;
s_8021x = nm_connection_get_setting_802_1x(conn);
@@ -468,7 +474,7 @@ mirror_8021x_connection(NMIwdManager *self, const char *name, gboolean create_ne
NULL));
nm_connection_add_setting(connection, setting);
- new_ssid = g_bytes_new(name, strlen(name));
+ new_ssid = g_bytes_new(name, ssid_len);
setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_WIRELESS,
NM_SETTING_WIRELESS_SSID,
new_ssid,
@@ -713,19 +719,27 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
NMConnection * conn = nm_settings_connection_get_connection(sett_conn);
NMSettingWireless * s_wireless;
- gboolean mapped;
KnownNetworkData * data;
KnownNetworkId id;
- gs_free char * ssid_str = NULL;
+ char ssid_buf[33];
+ const guint8 * ssid_bytes;
+ gsize ssid_len;
- id.security = nm_wifi_connection_get_iwd_security(conn, &mapped);
- if (!mapped)
+ if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &id.security))
return;
s_wireless = nm_connection_get_setting_wireless(conn);
- ssid_str = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless));
- id.name = ssid_str;
- data = g_hash_table_lookup(priv->known_networks, &id);
+ if (!s_wireless)
+ return;
+
+ ssid_bytes = g_bytes_get_data(nm_setting_wireless_get_ssid(s_wireless), &ssid_len);
+ if (!ssid_bytes || ssid_len > 32 || memchr(ssid_bytes, 0, ssid_len))
+ return;
+
+ memcpy(ssid_buf, ssid_bytes, ssid_len);
+ ssid_buf[ssid_len] = '\0';
+ id.name = ssid_buf;
+ data = g_hash_table_lookup(priv->known_networks, &id);
if (!data)
return;
diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c
index e371d19755..3fa33256ad 100644
--- a/src/devices/wifi/nm-wifi-utils.c
+++ b/src/devices/wifi/nm-wifi-utils.c
@@ -886,34 +886,49 @@ nm_wifi_utils_is_manf_default_ssid(GBytes *ssid)
return FALSE;
}
-NMIwdNetworkSecurity
-nm_wifi_connection_get_iwd_security(NMConnection *connection, gboolean *mapped)
+/* To be used for connections where the SSID has been validated before */
+gboolean
+nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection,
+ char ** ssid,
+ NMIwdNetworkSecurity *security)
{
+ NMSettingWireless * s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
const char * key_mgmt = NULL;
- if (!nm_connection_get_setting_wireless(connection))
- goto error;
+ s_wireless = nm_connection_get_setting_wireless(connection);
+ if (!s_wireless)
+ return FALSE;
+
+ if (ssid) {
+ GBytes * bytes = nm_setting_wireless_get_ssid(s_wireless);
+ gsize ssid_len;
+ const char *ssid_str = (const char *) g_bytes_get_data(bytes, &ssid_len);
- NM_SET_OUT(mapped, TRUE);
+ nm_assert(bytes && g_utf8_validate(ssid_str, ssid_len, NULL));
+ NM_SET_OUT(ssid, g_strndup(ssid_str, ssid_len));
+ }
+
+ if (!security)
+ return TRUE;
s_wireless_sec = nm_connection_get_setting_wireless_security(connection);
- if (!s_wireless_sec)
- return NM_IWD_NETWORK_SECURITY_NONE;
+ if (!s_wireless_sec) {
+ NM_SET_OUT(security, NM_IWD_NETWORK_SECURITY_NONE);
+ return TRUE;
+ }
key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wireless_sec);
nm_assert(key_mgmt);
if (NM_IN_STRSET(key_mgmt, "none", "ieee8021x"))
- return NM_IWD_NETWORK_SECURITY_WEP;
-
- if (nm_streq(key_mgmt, "wpa-psk"))
- return NM_IWD_NETWORK_SECURITY_PSK;
-
- if (nm_streq(key_mgmt, "wpa-eap"))
- return NM_IWD_NETWORK_SECURITY_8021X;
+ NM_SET_OUT(security, NM_IWD_NETWORK_SECURITY_WEP);
+ else if (nm_streq(key_mgmt, "wpa-psk"))
+ NM_SET_OUT(security, NM_IWD_NETWORK_SECURITY_PSK);
+ else if (nm_streq(key_mgmt, "wpa-eap"))
+ NM_SET_OUT(security, NM_IWD_NETWORK_SECURITY_8021X);
+ else
+ return FALSE;
-error:
- NM_SET_OUT(mapped, FALSE);
- return NM_IWD_NETWORK_SECURITY_NONE;
+ return TRUE;
}
diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h
index 678b353b1e..5c0474fb85 100644
--- a/src/devices/wifi/nm-wifi-utils.h
+++ b/src/devices/wifi/nm-wifi-utils.h
@@ -32,7 +32,8 @@ gboolean nm_wifi_utils_complete_connection(GBytes * ssid,
gboolean nm_wifi_utils_is_manf_default_ssid(GBytes *ssid);
-NMIwdNetworkSecurity nm_wifi_connection_get_iwd_security(NMConnection *connection,
- gboolean * mapped);
+gboolean nm_wifi_connection_get_iwd_ssid_and_security(NMConnection *connection,
+ char **ssid,
+ NMIwdNetworkSecurity *security);
#endif /* __NM_WIFI_UTILS_H__ */