diff --git a/meson.build b/meson.build
index 2fb9c13..0d0c2dc 100644
--- a/meson.build
+++ b/meson.build
@@ -40,8 +40,8 @@ config.set('HAVE_X11_EXTENSIONS_XKB_H', cc.has_header('X11/extensions/XKB.h'))
# Network Manager stuff
if get_option('networkmanager')
- libnm = dependency('libnm', version: '>=1.2.0')
- libnma = dependency('libnma',version: '>=1.2.0')
+ libnm = dependency('libnm', version: '>=1.24')
+ libnma = dependency('libnma',version: '>=1.8.36')
else
libnm = dependency('', required: false)
libnma= dependency('', required: false)
diff --git a/panels/network/connection-editor/ce-page-details.c b/panels/network/connection-editor/ce-page-details.c
index e9f173b..c55e5c4 100644
--- a/panels/network/connection-editor/ce-page-details.c
+++ b/panels/network/connection-editor/ce-page-details.c
@@ -49,13 +49,21 @@ get_ap_security_string (NMAccessPoint *ap)
/* TRANSLATORS: this WEP WiFi security */
g_string_append_printf (str, "%s, ", _("WEP"));
}
- if (wpa_flags != NM_802_11_AP_SEC_NONE) {
- /* TRANSLATORS: this WPA WiFi security */
- g_string_append_printf (str, "%s, ", _("WPA"));
- }
- if (rsn_flags != NM_802_11_AP_SEC_NONE) {
- /* TRANSLATORS: this WPA WiFi security */
- g_string_append_printf (str, "%s, ", _("WPA2"));
+ if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE) {
+ /* TRANSLATORS: Enhanced Open (OWE) WiFi security */
+ g_string_append_printf (str, "%s, ", _("Enhanced Open"));
+ } else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE) {
+ /* TRANSLATORS: WPA3 (SAE) WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA3"));
+ } else {
+ if (wpa_flags != NM_802_11_AP_SEC_NONE) {
+ /* TRANSLATORS: this WPA WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA"));
+ }
+ if (rsn_flags != NM_802_11_AP_SEC_NONE) {
+ /* TRANSLATORS: this WPA WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA2"));
+ }
}
if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
diff --git a/panels/network/connection-editor/ce-page-security.c b/panels/network/connection-editor/ce-page-security.c
index 0f799e2..874eca6 100644
--- a/panels/network/connection-editor/ce-page-security.c
+++ b/panels/network/connection-editor/ce-page-security.c
@@ -60,6 +60,10 @@ get_default_type_for_security (NMSettingWirelessSecurity *sec)
key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec);
auth_alg = nm_setting_wireless_security_get_auth_alg (sec);
+ g_debug ("ce-page-security: saved profile key-mgmt='%s' auth-alg='%s'",
+ key_mgmt ? key_mgmt : "(null)",
+ auth_alg ? auth_alg : "(null)");
+
/* No IEEE 802.1x */
if (!strcmp (key_mgmt, "none"))
return NMU_SEC_STATIC_WEP;
@@ -89,6 +93,12 @@ get_default_type_for_security (NMSettingWirelessSecurity *sec)
return NMU_SEC_WPA_ENTERPRISE;
}
+ if (!strcmp (key_mgmt, "sae"))
+ return NMU_SEC_SAE;
+
+ if (!strcmp (key_mgmt, "owe"))
+ return NMU_SEC_OWE;
+
return NMU_SEC_INVALID;
}
@@ -109,14 +119,19 @@ security_combo_get_active (CEPageSecurity *page)
static void
wsec_size_group_clear (GtkSizeGroup *group)
{
- GSList *children;
+ GSList *to_remove;
GSList *iter;
g_return_if_fail (group != NULL);
- children = gtk_size_group_get_widgets (group);
- for (iter = children; iter; iter = g_slist_next (iter))
+ /* gtk_size_group_get_widgets() returns the live internal list, and
+ * gtk_size_group_remove_widget() mutates (frees nodes from) that same
+ * list. Iterating the original directly is a use-after-free, so copy
+ * the node list first and walk the copy. */
+ to_remove = g_slist_copy (gtk_size_group_get_widgets (group));
+ for (iter = to_remove; iter; iter = g_slist_next (iter))
gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data));
+ g_slist_free (to_remove);
}
static void
@@ -339,6 +354,32 @@ finish_setup (CEPageSecurity *page)
}
}
+ if (nm_utils_security_valid (NMU_SEC_SAE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ WirelessSecuritySAE *ws_sae;
+
+ ws_sae = ws_sae_new (connection, FALSE);
+ if (ws_sae) {
+ add_security_item (page, WIRELESS_SECURITY (ws_sae), sec_model,
+ &iter, _("WPA3 Personal"), FALSE);
+ if ((active < 0) && (default_type == NMU_SEC_SAE))
+ active = item;
+ item++;
+ }
+ }
+
+ if (nm_utils_security_valid (NMU_SEC_OWE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ WirelessSecurityOWE *ws_owe;
+
+ ws_owe = ws_owe_new (connection);
+ if (ws_owe) {
+ add_security_item (page, WIRELESS_SECURITY (ws_owe), sec_model,
+ &iter, _("Enhanced Open"), FALSE);
+ if ((active < 0) && (default_type == NMU_SEC_OWE))
+ active = item;
+ item++;
+ }
+ }
+
gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model));
gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
@@ -465,7 +506,9 @@ ce_page_security_new (NMConnection *connection,
if (default_type == NMU_SEC_STATIC_WEP ||
default_type == NMU_SEC_LEAP ||
default_type == NMU_SEC_WPA_PSK ||
- default_type == NMU_SEC_WPA2_PSK) {
+ default_type == NMU_SEC_WPA2_PSK ||
+ default_type == NMU_SEC_SAE ||
+ default_type == NMU_SEC_OWE) {
CE_PAGE (page)->security_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
}
diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c
index 5ce66d0..894d8c9 100644
--- a/panels/network/net-device-wifi.c
+++ b/panels/network/net-device-wifi.c
@@ -44,7 +44,10 @@ typedef enum {
NM_AP_SEC_NONE,
NM_AP_SEC_WEP,
NM_AP_SEC_WPA,
- NM_AP_SEC_WPA2
+ NM_AP_SEC_WPA2,
+ NM_AP_SEC_SAE,
+ NM_AP_SEC_OWE,
+ NM_AP_SEC_OWE_TM
} NMAccessPointSecurity;
static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi);
@@ -113,7 +116,13 @@ get_access_point_security (NMAccessPoint *ap)
wpa_flags = nm_access_point_get_wpa_flags (ap);
rsn_flags = nm_access_point_get_rsn_flags (ap);
- if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
+ if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)
+ type = NM_AP_SEC_SAE;
+ else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)
+ type = NM_AP_SEC_OWE_TM;
+ else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE)
+ type = NM_AP_SEC_OWE;
+ else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
wpa_flags == NM_802_11_AP_SEC_NONE &&
rsn_flags == NM_802_11_AP_SEC_NONE)
type = NM_AP_SEC_NONE;
@@ -214,13 +223,21 @@ get_ap_security_string (NMAccessPoint *ap)
/* TRANSLATORS: this WEP WiFi security */
g_string_append_printf (str, "%s, ", _("WEP"));
}
- if (wpa_flags != NM_802_11_AP_SEC_NONE) {
- /* TRANSLATORS: this WPA WiFi security */
- g_string_append_printf (str, "%s, ", _("WPA"));
- }
- if (rsn_flags != NM_802_11_AP_SEC_NONE) {
- /* TRANSLATORS: this WPA WiFi security */
- g_string_append_printf (str, "%s, ", _("WPA2"));
+ if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE) {
+ /* TRANSLATORS: Enhanced Open (OWE) WiFi security */
+ g_string_append_printf (str, "%s, ", _("Enhanced Open"));
+ } else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE) {
+ /* TRANSLATORS: WPA3 (SAE) WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA3"));
+ } else {
+ if (wpa_flags != NM_802_11_AP_SEC_NONE) {
+ /* TRANSLATORS: this WPA WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA"));
+ }
+ if (rsn_flags != NM_802_11_AP_SEC_NONE) {
+ /* TRANSLATORS: this WPA WiFi security */
+ g_string_append_printf (str, "%s, ", _("WPA2"));
+ }
}
if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
@@ -668,6 +685,17 @@ connection_add_activate_cb (GObject *source_object,
g_error_free (error);
return;
}
+
+ /* Log what NM actually saved, so we can tell whether key-mgmt forcing
+ * survived NM's auto-completion. */
+ {
+ NMRemoteConnection *rc = nm_active_connection_get_connection (conn);
+ NMSettingWirelessSecurity *s_wsec;
+
+ s_wsec = rc ? nm_connection_get_setting_wireless_security (NM_CONNECTION (rc)) : NULL;
+ g_debug ("connection_add_activate_cb: NM-saved key-mgmt='%s'",
+ s_wsec ? nm_setting_wireless_security_get_key_mgmt (s_wsec) : "(no wsec)");
+ }
}
static void
@@ -781,6 +809,8 @@ wireless_try_to_connect (NetDeviceWifi *device_wifi,
GPermission *permission;
gboolean allowed_to_share = FALSE;
NMConnection *partial = NULL;
+ NMAccessPoint *ap;
+ const char *forced_key_mgmt = NULL;
permission = polkit_permission_new_sync ("org.freedesktop.NetworkManager.settings.modify.system",
NULL, NULL, NULL);
@@ -789,15 +819,58 @@ wireless_try_to_connect (NetDeviceWifi *device_wifi,
g_object_unref (permission);
}
+ /* Pick the right key-mgmt up front for SAE-only or OWE APs.
+ * NM's auto-completion defaults to wpa-psk and never upgrades
+ * to sae, so without this an SAE-only AP gets saved as a
+ * wpa-psk profile (which then often connects via SAE anyway,
+ * masking the misconfiguration). */
+ ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), ap_object_path);
+ if (ap != NULL) {
+ NM80211ApSecurityFlags rsn_flags = nm_access_point_get_rsn_flags (ap);
+ NM80211ApSecurityFlags wpa_flags = nm_access_point_get_wpa_flags (ap);
+
+ g_debug ("wireless_try_to_connect: AP rsn=0x%x wpa=0x%x "
+ "(SAE=%d OWE=%d)",
+ rsn_flags, wpa_flags,
+ !!(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE),
+ !!(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE));
+
+ /* Prefer SAE/OWE whenever the AP advertises it. Many
+ * routers in "WPA3" mode still advertise PSK alongside
+ * SAE for legacy-client compatibility (WPA2/WPA3
+ * transition mode); without this NM defaults the new
+ * profile to wpa-psk and the user can never get a
+ * WPA3-saved profile without manually switching. */
+ if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)
+ forced_key_mgmt = "sae";
+ else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE)
+ forced_key_mgmt = "owe";
+ } else {
+ g_debug ("wireless_try_to_connect: could not resolve AP from path %s",
+ ap_object_path);
+ }
+
+ if (!allowed_to_share || forced_key_mgmt != NULL) {
+ partial = nm_simple_connection_new ();
+ }
+
if (!allowed_to_share) {
NMSettingConnection *s_con;
s_con = (NMSettingConnection *)nm_setting_connection_new ();
nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL);
- partial = nm_simple_connection_new ();
nm_connection_add_setting (partial, NM_SETTING (s_con));
}
+ if (forced_key_mgmt != NULL) {
+ NMSettingWirelessSecurity *s_wsec;
+
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, forced_key_mgmt, NULL);
+ nm_connection_add_setting (partial, NM_SETTING (s_wsec));
+ g_debug ("forcing new connection key-mgmt=%s for %s", forced_key_mgmt, ssid_target);
+ }
+
g_debug ("no existing connection found for %s, creating and activating one", ssid_target);
nm_client_add_and_activate_connection_async (client,
partial,
@@ -806,7 +879,7 @@ wireless_try_to_connect (NetDeviceWifi *device_wifi,
NULL,
connection_add_activate_cb,
device_wifi);
- if (!allowed_to_share)
+ if (partial != NULL)
g_object_unref (partial);
} else {
CcNetworkPanel *panel;
@@ -1779,7 +1852,9 @@ make_row (GtkSizeGroup *rows,
if (in_range) {
if (security != NM_AP_SEC_UNKNOWN &&
- security != NM_AP_SEC_NONE) {
+ security != NM_AP_SEC_NONE &&
+ security != NM_AP_SEC_OWE &&
+ security != NM_AP_SEC_OWE_TM) {
widget = gtk_image_new_from_icon_name ("xsi-network-wireless-encrypted-symbolic", GTK_ICON_SIZE_MENU);
} else {
widget = gtk_label_new ("");
diff --git a/panels/network/wireless-security/meson.build b/panels/network/wireless-security/meson.build
index 4a87df7..a47f073 100644
--- a/panels/network/wireless-security/meson.build
+++ b/panels/network/wireless-security/meson.build
@@ -16,6 +16,8 @@ libwireless_security_sources = [
'ws-wep-key.c',
'ws-wpa-eap.c',
'ws-wpa-psk.c',
+ 'ws-sae.c',
+ 'ws-owe.c',
gnome.compile_resources('wireless-security-resources',
'wireless-security.gresource.xml',
c_name: 'wireless_security',
diff --git a/panels/network/wireless-security/wireless-security.gresource.xml b/panels/network/wireless-security/wireless-security.gresource.xml
index 976ba27..fe4db0f 100644
--- a/panels/network/wireless-security/wireless-security.gresource.xml
+++ b/panels/network/wireless-security/wireless-security.gresource.xml
@@ -12,5 +12,7 @@
ws-wep-key.ui
ws-wpa-eap.ui
ws-wpa-psk.ui
+ ws-sae.ui
+ ws-owe.ui
diff --git a/panels/network/wireless-security/wireless-security.h b/panels/network/wireless-security/wireless-security.h
index 8c5e04a..626639b 100644
--- a/panels/network/wireless-security/wireless-security.h
+++ b/panels/network/wireless-security/wireless-security.h
@@ -103,6 +103,8 @@ GType wireless_security_get_type (void);
#include "ws-leap.h"
#include "ws-wpa-eap.h"
#include "ws-dynamic-wep.h"
+#include "ws-sae.h"
+#include "ws-owe.h"
WirelessSecurity *wireless_security_init (gsize obj_size,
WSValidateFunc validate,
diff --git a/panels/network/wireless-security/ws-owe.c b/panels/network/wireless-security/ws-owe.c
new file mode 100644
index 0000000..20e969c
--- /dev/null
+++ b/panels/network/wireless-security/ws-owe.c
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2007 - 2021 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "wireless-security.h"
+
+struct _WirelessSecurityOWE {
+ WirelessSecurity parent;
+};
+
+static gboolean
+validate (WirelessSecurity *parent, GError **error)
+{
+ return TRUE;
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+ NMSetting *s_wireless_sec;
+
+ /* Blow away the old security setting by adding a clear one */
+ s_wireless_sec = nm_setting_wireless_security_new ();
+ g_object_set (s_wireless_sec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "owe",
+ NULL);
+
+ nm_connection_add_setting (connection, s_wireless_sec);
+}
+
+WirelessSecurityOWE *
+ws_owe_new (NMConnection *connection)
+{
+ WirelessSecurity *parent;
+
+ parent = wireless_security_init (sizeof (WirelessSecurityOWE),
+ validate,
+ add_to_size_group,
+ fill_connection,
+ NULL,
+ NULL,
+ "/org/cinnamon/control-center/network/ws-owe.ui",
+ "owe_box",
+ NULL);
+ if (!parent)
+ return NULL;
+
+ parent->adhoc_compatible = FALSE;
+ parent->hotspot_compatible = TRUE;
+
+ return (WirelessSecurityOWE *) parent;
+}
diff --git a/panels/network/wireless-security/ws-owe.h b/panels/network/wireless-security/ws-owe.h
new file mode 100644
index 0000000..3770116
--- /dev/null
+++ b/panels/network/wireless-security/ws-owe.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2007 - 2021 Red Hat, Inc.
+ */
+
+#ifndef WS_OWE_H
+#define WS_OWE_H
+
+typedef struct _WirelessSecurityOWE WirelessSecurityOWE;
+
+WirelessSecurityOWE * ws_owe_new (NMConnection *connection);
+
+#endif /* WS_OWE_H */
diff --git a/panels/network/wireless-security/ws-owe.ui b/panels/network/wireless-security/ws-owe.ui
new file mode 100644
index 0000000..354fd57
--- /dev/null
+++ b/panels/network/wireless-security/ws-owe.ui
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/panels/network/wireless-security/ws-sae.c b/panels/network/wireless-security/ws-sae.c
new file mode 100644
index 0000000..aff7e41
--- /dev/null
+++ b/panels/network/wireless-security/ws-sae.c
@@ -0,0 +1,193 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2007 - 2021 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include
+#include
+
+#include "wireless-security.h"
+#include "helpers.h"
+#include "nma-ui-utils.h"
+#include "utils.h"
+
+struct _WirelessSecuritySAE {
+ WirelessSecurity parent;
+
+ gboolean editing_connection;
+ const char *password_flags_name;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
+{
+ GtkWidget *widget;
+ gboolean visible;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "sae_entry"));
+ g_assert (widget);
+
+ visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (WirelessSecurity *parent, GError **error)
+{
+ NMSettingSecretFlags secret_flags;
+ GtkWidget *entry;
+ const char *key;
+
+ entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
+ g_assert (entry);
+
+ secret_flags = nma_utils_menu_to_secret_flags (entry);
+ key = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if ( secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED
+ || secret_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) {
+ /* All good. */
+ } else if (key == NULL || key[0] == '\0') {
+ widget_set_error (entry);
+ g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing password"));
+ return FALSE;
+ }
+ widget_unset_error (entry);
+
+ return TRUE;
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_label"));
+ gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+ WirelessSecuritySAE *sae = (WirelessSecuritySAE *) parent;
+ GtkWidget *widget, *passwd_entry;
+ const char *key;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wireless_sec;
+ NMSettingSecretFlags secret_flags;
+ const char *mode;
+ gboolean is_adhoc = FALSE;
+
+ s_wireless = nm_connection_get_setting_wireless (connection);
+ g_assert (s_wireless);
+
+ mode = nm_setting_wireless_get_mode (s_wireless);
+ if (mode && !strcmp (mode, "adhoc"))
+ is_adhoc = TRUE;
+
+ /* Blow away the old security setting by adding a clear one */
+ s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
+ passwd_entry = widget;
+ key = gtk_entry_get_text (GTK_ENTRY (widget));
+ g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL);
+
+ /* Save PSK_FLAGS to the connection */
+ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry);
+ nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), NM_SETTING_WIRELESS_SECURITY_PSK,
+ secret_flags, NULL);
+
+ /* Update secret flags and popup when editing the connection */
+ if (sae->editing_connection)
+ nma_utils_update_password_storage (passwd_entry, secret_flags,
+ NM_SETTING (s_wireless_sec), sae->password_flags_name);
+
+ wireless_security_clear_ciphers (connection);
+ g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
+ if (is_adhoc) {
+ nm_setting_wireless_security_add_proto (s_wireless_sec, "rsn");
+ nm_setting_wireless_security_add_pairwise (s_wireless_sec, "ccmp");
+ nm_setting_wireless_security_add_group (s_wireless_sec, "ccmp");
+ }
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+ helper_fill_secret_entry (connection,
+ parent->builder,
+ "sae_entry",
+ NM_TYPE_SETTING_WIRELESS_SECURITY,
+ (HelperSecretFunc) nm_setting_wireless_security_get_psk);
+}
+
+WirelessSecuritySAE *
+ws_sae_new (NMConnection *connection, gboolean secrets_only)
+{
+ WirelessSecurity *parent;
+ WirelessSecuritySAE *sec;
+ NMSetting *setting = NULL;
+ GtkWidget *widget;
+
+ parent = wireless_security_init (sizeof (WirelessSecuritySAE),
+ validate,
+ add_to_size_group,
+ fill_connection,
+ update_secrets,
+ NULL,
+ "/org/cinnamon/control-center/network/ws-sae.ui",
+ "sae_notebook",
+ "sae_entry");
+ if (!parent)
+ return NULL;
+
+ parent->adhoc_compatible = TRUE;
+ parent->hotspot_compatible = TRUE;
+ sec = (WirelessSecuritySAE *) parent;
+ sec->editing_connection = secrets_only ? FALSE : TRUE;
+ sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_PSK;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
+ g_assert (widget);
+ g_signal_connect (G_OBJECT (widget), "changed",
+ (GCallback) wireless_security_changed_cb,
+ sec);
+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 28);
+
+ /* Create password-storage popup menu for password entry under entry's secondary icon */
+ if (connection)
+ setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection);
+ nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name,
+ FALSE, secrets_only);
+
+ /* Fill secrets, if any */
+ if (connection)
+ update_secrets (WIRELESS_SECURITY (sec), connection);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_sae"));
+ g_assert (widget);
+ g_signal_connect (G_OBJECT (widget), "toggled",
+ (GCallback) show_toggled_cb,
+ sec);
+
+ return sec;
+}
diff --git a/panels/network/wireless-security/ws-sae.h b/panels/network/wireless-security/ws-sae.h
new file mode 100644
index 0000000..9afa525
--- /dev/null
+++ b/panels/network/wireless-security/ws-sae.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2007 - 2021 Red Hat, Inc.
+ */
+
+#ifndef WS_SAE_H
+#define WS_SAE_H
+
+typedef struct _WirelessSecuritySAE WirelessSecuritySAE;
+
+WirelessSecuritySAE * ws_sae_new (NMConnection *connection, gboolean secrets_only);
+
+#endif /* WS_SAE_H */
diff --git a/panels/network/wireless-security/ws-sae.ui b/panels/network/wireless-security/ws-sae.ui
new file mode 100644
index 0000000..bfd910c
--- /dev/null
+++ b/panels/network/wireless-security/ws-sae.ui
@@ -0,0 +1,75 @@
+
+
+
+
+