[network-manager-applet] editor: add macsec support



commit c481a9366320745eb8749e4e0641f8c323788e6d
Author: Beniamino Galvani <bgalvani redhat com>
Date:   Mon May 29 15:20:28 2017 +0200

    editor: add macsec support
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1456007

 Makefile.am                                  |    3 +
 po/POTFILES.in                               |    2 +
 src/connection-editor/ce-page-macsec.ui      |  304 +++++++++++++++++++++++
 src/connection-editor/ce.gresource.xml       |    1 +
 src/connection-editor/connection-helpers.c   |    2 +
 src/connection-editor/nm-connection-editor.c |    6 +
 src/connection-editor/nm-connection-editor.h |    2 +
 src/connection-editor/page-8021x-security.c  |   24 ++-
 src/connection-editor/page-macsec.c          |  339 ++++++++++++++++++++++++++
 src/connection-editor/page-macsec.h          |   62 +++++
 10 files changed, 744 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index be5cc3f..8f2579a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -634,6 +634,8 @@ connection_editor_hc_real = \
        src/connection-editor/page-ip6.c \
        src/connection-editor/page-dsl.h \
        src/connection-editor/page-dsl.c \
+       src/connection-editor/page-macsec.h \
+       src/connection-editor/page-macsec.c \
        src/connection-editor/page-mobile.h \
        src/connection-editor/page-mobile.c \
        src/connection-editor/page-bluetooth.h \
@@ -731,6 +733,7 @@ EXTRA_DIST += \
        src/connection-editor/ce-page-ip4.ui \
        src/connection-editor/ce-page-ip6.ui \
        src/connection-editor/ce-page-ip-tunnel.ui \
+       src/connection-editor/ce-page-macsec.ui \
        src/connection-editor/ce-page-mobile.ui \
        src/connection-editor/ce-page-ppp.ui \
        src/connection-editor/ce-page-proxy.ui \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1ac9a33..64b7804 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -32,6 +32,7 @@ src/connection-editor/ce-page.h
 [type: gettext/glade]src/connection-editor/ce-page-ip-tunnel.ui
 [type: gettext/glade]src/connection-editor/ce-page-ip4.ui
 [type: gettext/glade]src/connection-editor/ce-page-ip6.ui
+[type: gettext/glade]src/connection-editor/ce-page-macsec.ui
 [type: gettext/glade]src/connection-editor/ce-page-mobile.ui
 [type: gettext/glade]src/connection-editor/ce-page-ppp.ui
 [type: gettext/glade]src/connection-editor/ce-page-proxy.ui
@@ -61,6 +62,7 @@ src/connection-editor/page-infiniband.c
 src/connection-editor/page-ip-tunnel.c
 src/connection-editor/page-ip4.c
 src/connection-editor/page-ip6.c
+src/connection-editor/page-macsec.c
 src/connection-editor/page-master.c
 src/connection-editor/page-mobile.c
 src/connection-editor/page-ppp.c
diff --git a/src/connection-editor/ce-page-macsec.ui b/src/connection-editor/ce-page-macsec.ui
new file mode 100644
index 0000000..a18f443
--- /dev/null
+++ b/src/connection-editor/ce-page-macsec.ui
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.4"/>
+  <object class="GtkListStore" id="mode_store">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">PSK</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">EAP</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkAdjustment" id="sci_port_adjustment">
+    <property name="lower">1</property>
+    <property name="upper">65534</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkListStore" id="validation_store">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Disabled</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Check</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Strict</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkGrid" id="MacsecPage">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">48</property>
+    <property name="margin_right">48</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="hexpand">True</property>
+    <property name="border_width">0</property>
+    <property name="orientation">vertical</property>
+    <property name="row_spacing">8</property>
+    <property name="column_spacing">36</property>
+    <child>
+      <object class="GtkLabel" id="name_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Device name</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="macsec_name">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="tooltip_text" translatable="yes">The name of the MACsec device.</property>
+        <property name="hexpand">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="device_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="hexpand">False</property>
+        <property name="label" translatable="yes">Parent device</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="macsec_parent">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="tooltip_text" translatable="yes">The parent interface name or parent connection UUID 
from which this MACSEC interface should be created.</property>
+        <property name="has_entry">True</property>
+        <property name="active_id">0</property>
+        <child internal-child="entry">
+          <object class="GtkEntry">
+            <property name="can_focus">True</property>
+            <property name="tooltip_text" translatable="yes">The parent interface name or parent connection 
UUID from which this MACsec interface should be created</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="macsec_ckn">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="tooltip_text" translatable="yes"> The pre-shared Connectivity-association Key 
Name</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="macsec_cak">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="tooltip_text" translatable="yes">The pre-shared Connectivity Association 
Key</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBox" id="macsec_mode">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="tooltip_text" translatable="yes">Specifies how the CAK (Connectivity Association 
Key) for MKA (MACsec Key Agreement) is obtained. For the EAP mode, fill the parameters in the 802.1X security 
page</property>
+        <property name="model">mode_store</property>
+        <child>
+          <object class="GtkCellRendererText" id="renderer2"/>
+          <attributes>
+            <attribute name="text">0</attribute>
+          </attributes>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">CKN</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="hexpand">False</property>
+        <property name="label" translatable="yes">CAK</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="hexpand">False</property>
+        <property name="label" translatable="yes">Mode</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Keys</property>
+        <property name="xalign">2.2351741291171123e-10</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Parameters</property>
+        <property name="xalign">0</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">6</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Encrypt</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">7</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Validation</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">8</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">SCI port</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">9</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBox" id="macsec_validation">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="tooltip_text" translatable="yes">Specifies the validation mode for incoming 
frames</property>
+        <property name="model">validation_store</property>
+        <child>
+          <object class="GtkCellRendererText" id="renderer3"/>
+          <attributes>
+            <attribute name="text">0</attribute>
+          </attributes>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">8</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="macsec_encryption">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="tooltip_text" translatable="yes">Whether the transmitted traffic must be 
encrypted</property>
+        <property name="draw_indicator">True</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">7</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkSpinButton" id="macsec_sci_port">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="tooltip_text" translatable="yes">The port component of the SCI (Secure Channel 
Identifier)</property>
+        <property name="adjustment">sci_port_adjustment</property>
+        <property name="climb_rate">1</property>
+        <property name="numeric">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">9</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/src/connection-editor/ce.gresource.xml b/src/connection-editor/ce.gresource.xml
index b12d953..8533ed9 100644
--- a/src/connection-editor/ce.gresource.xml
+++ b/src/connection-editor/ce.gresource.xml
@@ -17,6 +17,7 @@
                <file preprocess="xml-stripblanks">ce-page-ip4.ui</file>
                <file preprocess="xml-stripblanks">ce-page-ip6.ui</file>
                <file preprocess="xml-stripblanks">ce-page-ip-tunnel.ui</file>
+               <file preprocess="xml-stripblanks">ce-page-macsec.ui</file>
                <file preprocess="xml-stripblanks">ce-page-mobile.ui</file>
                <file preprocess="xml-stripblanks">ce-page-ppp.ui</file>
                <file preprocess="xml-stripblanks">ce-page-proxy.ui</file>
diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c
index 18a8f4f..5ec4d04 100644
--- a/src/connection-editor/connection-helpers.c
+++ b/src/connection-editor/connection-helpers.c
@@ -31,6 +31,7 @@
 #include "page-dsl.h"
 #include "page-infiniband.h"
 #include "page-ip-tunnel.h"
+#include "page-macsec.h"
 #include "page-bond.h"
 #include "page-team.h"
 #include "page-bridge.h"
@@ -118,6 +119,7 @@ get_connection_type_list (void)
        add_type_data_virtual (array, _("Bridge"), bridge_connection_new, NM_TYPE_SETTING_BRIDGE);
        add_type_data_virtual (array, _("VLAN"), vlan_connection_new, NM_TYPE_SETTING_VLAN);
        add_type_data_virtual (array, _("IP tunnel"), ip_tunnel_connection_new, NM_TYPE_SETTING_IP_TUNNEL);
+       add_type_data_virtual (array, _("MACsec"), macsec_connection_new, NM_TYPE_SETTING_MACSEC);
 
        add_type_data_virtual (array, _("VPN"), vpn_connection_new, NM_TYPE_SETTING_VPN);
 
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index be211f2..7d101e2 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -61,6 +61,7 @@
 #include "page-bridge-port.h"
 #include "page-vlan.h"
 #include "page-dcb.h"
+#include "page-macsec.h"
 #include "ce-polkit-button.h"
 #include "vpn-helpers.h"
 #include "eap-method.h"
@@ -1035,6 +1036,11 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor,
        } else if (!strcmp (connection_type, NM_SETTING_VLAN_SETTING_NAME)) {
                if (!add_page (editor, ce_page_vlan_new, editor->connection, error))
                        goto out;
+       } else if (!strcmp (connection_type, NM_SETTING_MACSEC_SETTING_NAME)) {
+               if (!add_page (editor, ce_page_macsec_new, editor->connection, error))
+                       goto out;
+               if (!add_page (editor, ce_page_8021x_security_new, editor->connection, error))
+                       goto out;
        } else {
                g_warning ("Unhandled setting type '%s'", connection_type);
        }
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index f8c12a8..a072f24 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -85,6 +85,8 @@ typedef struct {
 typedef enum {
        /* Add item for inter-page changes here */
        INTER_PAGE_CHANGE_WIFI_MODE = 1,
+       INTER_PAGE_CHANGE_MACSEC_MODE = 2,
+       INTER_PAGE_CHANGE_802_1X_ENABLE = 3,
 } InterPageChangeType;
 
 GType               nm_connection_editor_get_type (void);
diff --git a/src/connection-editor/page-8021x-security.c b/src/connection-editor/page-8021x-security.c
index 9fde940..643600e 100644
--- a/src/connection-editor/page-8021x-security.c
+++ b/src/connection-editor/page-8021x-security.c
@@ -51,8 +51,12 @@ static void
 enable_toggled (GtkToggleButton *button, gpointer user_data)
 {
        CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (user_data);
+       gboolean active = gtk_toggle_button_get_active (priv->enabled);
 
-       gtk_widget_set_sensitive (priv->security_widget, gtk_toggle_button_get_active (priv->enabled));
+       gtk_widget_set_sensitive (priv->security_widget, active);
+       nm_connection_editor_inter_page_set_value (CE_PAGE (user_data)->editor,
+                                                  INTER_PAGE_CHANGE_802_1X_ENABLE,
+                                                  GINT_TO_POINTER (active));
        ce_page_changed (CE_PAGE (user_data));
 }
 
@@ -191,6 +195,23 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
        return valid;
 }
 
+static gboolean
+inter_page_change (CEPage *page)
+{
+       CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (page);
+       gpointer macsec_mode;
+
+       if (nm_connection_editor_inter_page_get_value (page->editor,
+                                                      INTER_PAGE_CHANGE_MACSEC_MODE,
+                                                      &macsec_mode)) {
+               gtk_toggle_button_set_active (priv->enabled,
+                                             GPOINTER_TO_INT (macsec_mode) == NM_SETTING_MACSEC_MODE_EAP);
+               enable_toggled (priv->enabled, page);
+       }
+
+       return TRUE;
+}
+
 static void
 ce_page_8021x_security_init (CEPage8021xSecurity *self)
 {
@@ -227,4 +248,5 @@ ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class)
        object_class->dispose = dispose;
 
        parent_class->ce_page_validate_v = ce_page_validate_v;
+       parent_class->inter_page_change = inter_page_change;
 }
diff --git a/src/connection-editor/page-macsec.c b/src/connection-editor/page-macsec.c
new file mode 100644
index 0000000..43bfc43
--- /dev/null
+++ b/src/connection-editor/page-macsec.c
@@ -0,0 +1,339 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * 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 2017 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include <string.h>
+
+#include "page-macsec.h"
+#include "nm-connection-editor.h"
+#include "nma-ui-utils.h"
+
+G_DEFINE_TYPE (CEPageMacsec, ce_page_macsec, CE_TYPE_PAGE)
+
+#define CE_PAGE_MACSEC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_MACSEC, 
CEPageMacsecPrivate))
+
+typedef struct {
+       NMSettingMacsec *setting;
+
+       GtkEntry *name;
+       GtkComboBoxText *parent;
+       GtkComboBox *mode;
+       GtkEntry *cak;
+       GtkEntry *ckn;
+       GtkToggleButton *encryption;
+       GtkComboBox *validation;
+       GtkSpinButton *sci_port;
+} CEPageMacsecPrivate;
+
+static void
+macsec_private_init (CEPageMacsec *self)
+{
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+       GtkBuilder *builder;
+
+       builder = CE_PAGE (self)->builder;
+
+       priv->name = GTK_ENTRY (gtk_builder_get_object (builder, "macsec_name"));
+       priv->parent = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "macsec_parent"));
+       priv->mode = GTK_COMBO_BOX (gtk_builder_get_object (builder, "macsec_mode"));
+       priv->cak = GTK_ENTRY (gtk_builder_get_object (builder, "macsec_cak"));
+       priv->ckn = GTK_ENTRY (gtk_builder_get_object (builder, "macsec_ckn"));
+       priv->encryption = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "macsec_encryption"));
+       priv->validation = GTK_COMBO_BOX (gtk_builder_get_object (builder, "macsec_validation"));
+       priv->sci_port = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "macsec_sci_port"));
+}
+
+static void
+mode_changed (GtkComboBox *combo, gpointer user_data)
+{
+       CEPageMacsec *self = user_data;
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+       NMSettingMacsecMode mode;
+       NMConnection *connection;
+       gboolean mode_psk;
+
+       mode = gtk_combo_box_get_active (combo);
+
+       mode_psk = mode == NM_SETTING_MACSEC_MODE_PSK;
+
+       gtk_widget_set_sensitive (GTK_WIDGET (priv->cak), mode_psk);
+       gtk_widget_set_sensitive (GTK_WIDGET (priv->ckn), mode_psk);
+
+       if (!mode_psk) {
+               gtk_entry_set_text (priv->cak, "");
+               gtk_entry_set_text (priv->ckn, "");
+
+               connection = CE_PAGE (self)->connection;
+               if (!nm_connection_get_setting_802_1x (connection))
+                       nm_connection_add_setting (connection, nm_setting_802_1x_new ());
+       }
+
+       nm_connection_editor_inter_page_set_value (CE_PAGE (self)->editor,
+                                                  INTER_PAGE_CHANGE_MACSEC_MODE,
+                                                  GUINT_TO_POINTER (mode));
+       ce_page_changed (CE_PAGE (user_data));
+}
+
+static void
+populate_ui (CEPageMacsec *self, NMConnection *connection)
+{
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+       NMSettingMacsec *setting = priv->setting;
+       NMSettingMacsecMode mode;
+       NMSettingMacsecValidation validation;
+       const char *cak = "", *ckn = "", *str;
+
+       str = nm_connection_get_interface_name (CE_PAGE (self)->connection);
+       if (str)
+               gtk_entry_set_text (priv->name, str);
+
+       str = nm_setting_macsec_get_parent (setting);
+       ce_page_setup_device_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->parent),
+                                   G_TYPE_NONE, str,
+                                   NULL, NULL);
+
+       mode = nm_setting_macsec_get_mode (setting);
+       if (mode >= NM_SETTING_MACSEC_MODE_PSK && mode <= NM_SETTING_MACSEC_MODE_EAP)
+               gtk_combo_box_set_active (priv->mode, mode);
+
+       if (mode == NM_SETTING_MACSEC_MODE_PSK) {
+               cak = nm_setting_macsec_get_mka_cak (setting);
+               ckn = nm_setting_macsec_get_mka_ckn (setting);
+       }
+
+       gtk_entry_set_text (priv->cak, cak ?: "");
+       gtk_entry_set_text (priv->ckn, ckn ?: "");
+
+       nma_utils_setup_password_storage ((GtkWidget *) priv->cak, 0,
+                                         (NMSetting *) priv->setting,
+                                         NM_SETTING_MACSEC_MKA_CAK,
+                                         FALSE, FALSE);
+
+       gtk_toggle_button_set_active (priv->encryption,
+                                     nm_setting_macsec_get_encrypt (setting));
+
+       validation = nm_setting_macsec_get_validation (setting);
+       if (   validation >= NM_SETTING_MACSEC_VALIDATION_DISABLE
+           && validation <= NM_SETTING_MACSEC_VALIDATION_STRICT)
+               gtk_combo_box_set_active (priv->validation, validation);
+
+       gtk_spin_button_set_value (priv->sci_port, nm_setting_macsec_get_port (setting));
+
+       mode_changed (priv->mode, self);
+}
+
+static void
+stuff_changed (GtkEditable *editable, gpointer user_data)
+{
+       ce_page_changed (CE_PAGE (user_data));
+}
+
+static void
+finish_setup (CEPageMacsec *self, gpointer unused, GError *error, gpointer user_data)
+{
+       CEPage *parent = CE_PAGE (self);
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+
+       if (error)
+               return;
+
+       populate_ui (self, parent->connection);
+
+       g_signal_connect (priv->name, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->parent, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->mode, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->cak, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->ckn, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->sci_port, "value-changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->validation, "changed", G_CALLBACK (stuff_changed), self);
+       g_signal_connect (priv->encryption, "toggled", G_CALLBACK (stuff_changed), self);
+
+       g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_changed), self);
+}
+
+CEPage *
+ce_page_macsec_new (NMConnectionEditor *editor,
+                    NMConnection *connection,
+                    GtkWindow *parent_window,
+                    NMClient *client,
+                    const char **out_secrets_setting_name,
+                    GError **error)
+{
+       CEPageMacsec *self;
+       CEPageMacsecPrivate *priv;
+
+       self = CE_PAGE_MACSEC (ce_page_new (CE_TYPE_PAGE_MACSEC,
+                                           editor,
+                                           connection,
+                                           parent_window,
+                                           client,
+                                           "/org/freedesktop/network-manager-applet/ce-page-macsec.ui",
+                                           "MacsecPage",
+                                          _("MACsec")));
+       if (!self) {
+               g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load MACsec user 
interface."));
+               return NULL;
+       }
+
+       macsec_private_init (self);
+       priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+
+       priv->setting = nm_connection_get_setting_macsec (connection);
+       if (!priv->setting) {
+               priv->setting = NM_SETTING_MACSEC (nm_setting_macsec_new ());
+               nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+       }
+
+       g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);
+
+       *out_secrets_setting_name = NM_SETTING_MACSEC_SETTING_NAME;
+
+       return CE_PAGE (self);
+}
+
+static void
+ui_to_setting (CEPageMacsec *self)
+{
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+       NMSettingConnection *s_con;
+       const char *parent = NULL;
+       const char *cak = NULL;
+       const char *ckn = NULL;
+       NMSettingMacsecMode mode;
+       gboolean encryption;
+       NMSettingMacsecValidation validation;
+       gint sci_port;
+       GtkWidget *entry;
+       NMSettingSecretFlags secret_flags;
+
+       s_con = nm_connection_get_setting_connection (CE_PAGE (self)->connection);
+       g_return_if_fail (s_con != NULL);
+       g_object_set (s_con,
+                     NM_SETTING_CONNECTION_INTERFACE_NAME, gtk_entry_get_text (priv->name),
+                     NULL);
+
+       entry = gtk_bin_get_child (GTK_BIN (priv->parent));
+       if (entry) {
+               ce_page_device_entry_get (GTK_ENTRY (entry), ARPHRD_ETHER, TRUE,
+                                         (char **) &parent, NULL, NULL, NULL);
+       }
+
+       mode = gtk_combo_box_get_active (priv->mode);
+
+       if (mode == NM_SETTING_MACSEC_MODE_PSK) {
+               cak = gtk_entry_get_text (priv->cak);
+               ckn = gtk_entry_get_text (priv->ckn);
+       }
+
+       encryption = gtk_toggle_button_get_active (priv->encryption);
+       validation = gtk_combo_box_get_active (priv->validation);
+       sci_port = gtk_spin_button_get_value_as_int (priv->sci_port);
+
+       g_object_set (priv->setting,
+                     NM_SETTING_MACSEC_PARENT, parent,
+                     NM_SETTING_MACSEC_MODE, mode,
+                     NM_SETTING_MACSEC_MKA_CAK, cak,
+                     NM_SETTING_MACSEC_MKA_CKN, ckn,
+                     NM_SETTING_MACSEC_ENCRYPT, encryption,
+                     NM_SETTING_MACSEC_VALIDATION, validation,
+                     NM_SETTING_MACSEC_PORT, sci_port,
+                     NULL);
+
+       /* Save CAK flags to the connection */
+       secret_flags = nma_utils_menu_to_secret_flags ((GtkWidget *) priv->cak);
+       nm_setting_set_secret_flags (NM_SETTING (priv->setting), NM_SETTING_MACSEC_MKA_CAK,
+                                    secret_flags, NULL);
+
+       /* Update secret flags and popup when editing the connection */
+       nma_utils_update_password_storage ((GtkWidget *) priv->cak, secret_flags,
+                                          NM_SETTING (priv->setting), NM_SETTING_MACSEC_MKA_CAK);
+}
+
+static gboolean
+ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
+{
+       CEPageMacsec *self = CE_PAGE_MACSEC (page);
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (self);
+
+       ui_to_setting (self);
+       return nm_setting_verify (NM_SETTING (priv->setting), connection, error);
+}
+
+static gboolean
+inter_page_change (CEPage *page)
+{
+       CEPageMacsecPrivate *priv = CE_PAGE_MACSEC_GET_PRIVATE (page);
+       gpointer enable;
+
+       if (nm_connection_editor_inter_page_get_value (page->editor,
+                                                      INTER_PAGE_CHANGE_802_1X_ENABLE,
+                                                      &enable)) {
+               gtk_combo_box_set_active (priv->mode,
+                                         GPOINTER_TO_INT (enable) ?
+                                             NM_SETTING_MACSEC_MODE_EAP :
+                                             NM_SETTING_MACSEC_MODE_PSK);
+               ce_page_changed (page);
+       }
+
+       return TRUE;
+}
+
+static void
+ce_page_macsec_init (CEPageMacsec *self)
+{
+}
+
+static void
+ce_page_macsec_class_init (CEPageMacsecClass *macsec_class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (macsec_class);
+       CEPageClass *parent_class = CE_PAGE_CLASS (macsec_class);
+
+       g_type_class_add_private (object_class, sizeof (CEPageMacsecPrivate));
+
+       /* virtual methods */
+       parent_class->ce_page_validate_v = ce_page_validate_v;
+       parent_class->inter_page_change = inter_page_change;
+}
+
+void
+macsec_connection_new (FUNC_TAG_PAGE_NEW_CONNECTION_IMPL,
+                       GtkWindow *parent,
+                       const char *detail,
+                       gpointer detail_data,
+                       NMConnection *connection,
+                       NMClient *client,
+                       PageNewConnectionResultFunc result_func,
+                       gpointer user_data)
+{
+       gs_unref_object NMConnection *connection_tmp = NULL;
+
+       connection = _ensure_connection_other (connection, &connection_tmp);
+       ce_page_complete_connection (connection,
+                                    _("MACSEC connection %d"),
+                                    NM_SETTING_MACSEC_SETTING_NAME,
+                                    FALSE,
+                                    client);
+       nm_connection_add_setting (connection, nm_setting_macsec_new ());
+       nm_connection_add_setting (connection, nm_setting_wired_new ());
+
+       (*result_func) (FUNC_TAG_PAGE_NEW_CONNECTION_RESULT_CALL, connection, FALSE, NULL, user_data);
+}
diff --git a/src/connection-editor/page-macsec.h b/src/connection-editor/page-macsec.h
new file mode 100644
index 0000000..dd472c2
--- /dev/null
+++ b/src/connection-editor/page-macsec.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * 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 2017 Red Hat, Inc.
+ */
+
+#ifndef __PAGE_MACSEC_H__
+#define __PAGE_MACSEC_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "ce-page.h"
+
+#define CE_TYPE_PAGE_MACSEC            (ce_page_macsec_get_type ())
+#define CE_PAGE_MACSEC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_MACSEC, 
CEPageMacsec))
+#define CE_PAGE_MACSEC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_MACSEC, 
CEPageMacsecClass))
+#define CE_IS_PAGE_MACSEC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_MACSEC))
+#define CE_IS_PAGE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_MACSEC))
+#define CE_PAGE_MACSEC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_MACSEC, 
CEPageMacsecClass))
+
+typedef struct {
+       CEPage parent;
+} CEPageMacsec;
+
+typedef struct {
+       CEPageClass parent;
+} CEPageMacsecClass;
+
+GType ce_page_macsec_get_type (void);
+
+CEPage *ce_page_macsec_new (NMConnectionEditor *editor,
+                            NMConnection *connection,
+                            GtkWindow *parent,
+                            NMClient *client,
+                            const char **out_secrets_setting_name,
+                            GError **error);
+
+void macsec_connection_new (FUNC_TAG_PAGE_NEW_CONNECTION_IMPL,
+                            GtkWindow *parent,
+                            const char *detail,
+                            gpointer detail_data,
+                            NMConnection *connection,
+                            NMClient *client,
+                            PageNewConnectionResultFunc callback,
+                            gpointer user_data);
+
+#endif  /* __PAGE_MACSEC_H__ */


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