[network-manager-applet/lr/sae: 1/3] wireless-security: add SAE support



commit 875d5fa82adb73ae84c781b9327af5f15a456c1e
Author: Lubomir Rintel <lkundrak v3 sk>
Date:   Fri Oct 4 10:31:01 2019 +0200

    wireless-security: add SAE support
    
    This is used by WPA3 Personal and secured Meshes (which we don't support
    in the applet).

 Makefile.am                               |   3 +
 po/POTFILES.in                            |   2 +
 src/wireless-security/meson.build         |   2 +
 src/wireless-security/wireless-security.c |   1 -
 src/wireless-security/wireless-security.h |   1 +
 src/wireless-security/ws-sae.c            | 203 ++++++++++++++++++++++++++++++
 src/wireless-security/ws-sae.h            |  16 +++
 src/wireless-security/ws-sae.ui           |  98 +++++++++++++++
 src/wireless-security/ws.gresource.xml    |   1 +
 9 files changed, 326 insertions(+), 1 deletion(-)
---
diff --git a/Makefile.am b/Makefile.am
index bce4be42..b863a683 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -275,6 +275,8 @@ wireless_security_c_gen = \
 wireless_security_c_real = \
        src/wireless-security/wireless-security.h \
        src/wireless-security/wireless-security.c \
+       src/wireless-security/ws-sae.h \
+       src/wireless-security/ws-sae.c \
        src/wireless-security/ws-wep-key.h \
        src/wireless-security/ws-wep-key.c \
        src/wireless-security/ws-wpa-psk.h \
@@ -392,6 +394,7 @@ EXTRA_DIST += \
        src/wireless-security/eap-method-ttls.ui \
        src/wireless-security/ws-dynamic-wep.ui \
        src/wireless-security/ws-leap.ui \
+       src/wireless-security/ws-sae.ui \
        src/wireless-security/ws-wep-key.ui \
        src/wireless-security/ws-wpa-eap.ui \
        src/wireless-security/ws-wpa-psk.ui \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 31cfdef8..c08b9128 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -125,6 +125,8 @@ src/wireless-security/wireless-security.c
 src/wireless-security/ws-dynamic-wep.ui
 src/wireless-security/ws-leap.c
 src/wireless-security/ws-leap.ui
+src/wireless-security/ws-sae.c
+src/wireless-security/ws-sae.ui
 src/wireless-security/ws-wep-key.c
 src/wireless-security/ws-wep-key.ui
 src/wireless-security/ws-wpa-eap.ui
diff --git a/src/wireless-security/meson.build b/src/wireless-security/meson.build
index 3a7cfc51..2348fcb9 100644
--- a/src/wireless-security/meson.build
+++ b/src/wireless-security/meson.build
@@ -12,6 +12,7 @@ sources = [version_header] + files(
   'wireless-security.c',
   'ws-dynamic-wep.c',
   'ws-leap.c',
+  'ws-sae.c',
   'ws-wep-key.c',
   'ws-wpa-eap.c',
   'ws-wpa-psk.c'
@@ -26,6 +27,7 @@ resource_data = files(
   'eap-method-ttls.ui',
   'ws-dynamic-wep.ui',
   'ws-leap.ui',
+  'ws-sae.ui',
   'ws-wep-key.ui',
   'ws-wpa-eap.ui',
   'ws-wpa-psk.ui'
diff --git a/src/wireless-security/wireless-security.c b/src/wireless-security/wireless-security.c
index c02c885b..5fc110f1 100644
--- a/src/wireless-security/wireless-security.c
+++ b/src/wireless-security/wireless-security.c
@@ -592,4 +592,3 @@ ws_802_1x_update_secrets (WirelessSecurity *sec,
                } while (gtk_tree_model_iter_next (model, &iter));
        }
 }
-
diff --git a/src/wireless-security/wireless-security.h b/src/wireless-security/wireless-security.h
index 6c1c4a36..49289812 100644
--- a/src/wireless-security/wireless-security.h
+++ b/src/wireless-security/wireless-security.h
@@ -80,6 +80,7 @@ void wireless_security_unref (WirelessSecurity *sec);
 
 /* Below for internal use only */
 
+#include "ws-sae.h"
 #include "ws-wep-key.h"
 #include "ws-wpa-psk.h"
 #include "ws-leap.h"
diff --git a/src/wireless-security/ws-sae.c b/src/wireless-security/ws-sae.c
new file mode 100644
index 00000000..4bebf138
--- /dev/null
+++ b/src/wireless-security/ws-sae.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2007 - 2019 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+#include "nma-private.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#include "wireless-security.h"
+#include "helpers.h"
+#include "nma-ui-utils.h"
+#include "utils.h"
+
+#define WPA_PMK_LEN 32
+
+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, "psk_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)
+{
+       GtkWidget *entry;
+       NMSettingSecretFlags secret_flags;
+       const char *key;
+
+       entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "psk_entry"));
+       g_assert (entry);
+
+       secret_flags = nma_utils_menu_to_secret_flags (entry);
+       key = gtk_editable_get_text (GTK_EDITABLE (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_type_label"));
+       gtk_size_group_add_widget (group, 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, "psk_entry"));
+       passwd_entry = widget;
+       key = gtk_editable_get_text (GTK_EDITABLE (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);
+       if (is_adhoc) {
+               /* Ad-Hoc settings as specified by the supplicant */
+               g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
+               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");
+       } else {
+               g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
+
+               /* Just leave ciphers and protocol empty, the supplicant will
+                * figure that out magically based on the AP IEs and card capabilities.
+                */
+       }
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+       helper_fill_secret_entry (connection,
+                                 parent->builder,
+                                 "psk_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/freedesktop/network-manager-applet/ws-sae.ui",
+                                        "sae_notebook",
+                                        "psk_entry");
+       if (!parent)
+               return NULL;
+
+       parent->adhoc_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, "psk_entry"));
+       g_assert (widget);
+       g_signal_connect (G_OBJECT (widget), "changed",
+                         (GCallback) wireless_security_changed_cb,
+                         sec);
+       gtk_editable_set_width_chars (GTK_EDITABLE (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);
+
+       /* Hide WPA/RSN for now since this can be autodetected by NM and the
+        * supplicant when connecting to the AP.
+        */
+
+       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_type_combo"));
+       g_assert (widget);
+       gtk_widget_hide (widget);
+
+       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_type_label"));
+       g_assert (widget);
+       gtk_widget_hide (widget);
+
+       return sec;
+}
+
diff --git a/src/wireless-security/ws-sae.h b/src/wireless-security/ws-sae.h
new file mode 100644
index 00000000..e864d90d
--- /dev/null
+++ b/src/wireless-security/ws-sae.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2007 - 2019 Red Hat, Inc.
+ */
+
+#ifndef WS_SAE_H
+#define WS_SAE_H
+
+/* For compatibility with NetworkManager-1.20 and earlier. */
+#define NMU_SEC_SAE 9
+
+typedef struct _WirelessSecuritySAE WirelessSecuritySAE;
+
+WirelessSecuritySAE * ws_sae_new (NMConnection *connection, gboolean secrets_only);
+
+#endif /* WS_SAE_H */
diff --git a/src/wireless-security/ws-sae.ui b/src/wireless-security/ws-sae.ui
new file mode 100644
index 00000000..8f0d0413
--- /dev/null
+++ b/src/wireless-security/ws-sae.ui
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="nm-applet">
+  <requires lib="gtk+" version="3.10"/>
+  <object class="GtkNotebook" id="sae_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkGrid" id="sae_table">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="row_spacing">6</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="sae_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">psk_entry</property>
+            <property name="xalign">1</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="psk_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="max_length">64</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="sae_type_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">_Type</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">sae_type_combo</property>
+            <property name="xalign">1</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_sae">
+            <property name="label" translatable="yes">Sho_w password</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="hexpand">True</property>
+            <property name="use_underline">True</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="sae_type_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="GtkLabel2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/src/wireless-security/ws.gresource.xml b/src/wireless-security/ws.gresource.xml
index 7aa6c0f9..5af6115d 100644
--- a/src/wireless-security/ws.gresource.xml
+++ b/src/wireless-security/ws.gresource.xml
@@ -3,6 +3,7 @@
        <gresource prefix="/org/freedesktop/network-manager-applet">
                <file preprocess="xml-stripblanks">ws-dynamic-wep.ui</file>
                <file preprocess="xml-stripblanks">ws-leap.ui</file>
+               <file preprocess="xml-stripblanks">ws-sae.ui</file>
                <file preprocess="xml-stripblanks">ws-wep-key.ui</file>
                <file preprocess="xml-stripblanks">ws-wpa-eap.ui</file>
                <file preprocess="xml-stripblanks">ws-wpa-psk.ui</file>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]