Blame SOURCES/0005-network-complete-SAE-support.patch

a11c41
From 1289e8ea1dbeb91012c262fcb6f014ec73d4c690 Mon Sep 17 00:00:00 2001
a11c41
From: Jonathan Kang <jonathankang@gnome.org>
a11c41
Date: Wed, 9 Sep 2020 14:58:06 +0800
a11c41
Subject: [PATCH 5/8] network: complete SAE support
a11c41
a11c41
Added WirelessSecuritySAE class to fully implement SAE support.
a11c41
a11c41
Heavily modifid and based on the 3.28.2 version of the WPA PSK widget.
a11c41
a11c41
(cherry picked from commit 918838f567740172591ff1f2c32d8227c348be72)
a11c41
---
a11c41
 .../connection-editor/ce-page-security.c      |   8 +-
a11c41
 panels/network/wireless-security/meson.build  |   3 +
a11c41
 .../wireless-security.gresource.xml           |   1 +
a11c41
 .../wireless-security/wireless-security.h     |   1 +
a11c41
 panels/network/wireless-security/ws-sae.c     | 214 ++++++++++++++++++
a11c41
 panels/network/wireless-security/ws-sae.h     |  30 +++
a11c41
 panels/network/wireless-security/ws-sae.ui    | 117 ++++++++++
a11c41
 7 files changed, 370 insertions(+), 4 deletions(-)
a11c41
 create mode 100644 panels/network/wireless-security/ws-sae.c
a11c41
 create mode 100644 panels/network/wireless-security/ws-sae.h
a11c41
 create mode 100644 panels/network/wireless-security/ws-sae.ui
a11c41
a11c41
diff --git a/panels/network/connection-editor/ce-page-security.c b/panels/network/connection-editor/ce-page-security.c
a11c41
index 5104d7442..37b1e1286 100644
a11c41
--- a/panels/network/connection-editor/ce-page-security.c
a11c41
+++ b/panels/network/connection-editor/ce-page-security.c
a11c41
@@ -343,11 +343,11 @@ finish_setup (CEPageSecurity *page)
a11c41
 
a11c41
 #if NM_CHECK_VERSION(1,20,6)
a11c41
         if (nm_utils_security_valid (NMU_SEC_SAE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
a11c41
-                WirelessSecurityWPAPSK *ws_wpa_psk;
a11c41
+                WirelessSecuritySAE *ws_sae;
a11c41
 
a11c41
-                ws_wpa_psk = ws_wpa_psk_new (connection, FALSE);
a11c41
-                if (ws_wpa_psk) {
a11c41
-                        add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model,
a11c41
+                ws_sae = ws_sae_new (connection, FALSE);
a11c41
+                if (ws_sae) {
a11c41
+                        add_security_item (page, WIRELESS_SECURITY (ws_sae), sec_model,
a11c41
                                            &iter, _("WPA3 Personal"), FALSE);
a11c41
                         if ((active < 0) && ((default_type == NMU_SEC_SAE)))
a11c41
                                 active = item;
a11c41
diff --git a/panels/network/wireless-security/meson.build b/panels/network/wireless-security/meson.build
a11c41
index 47def7a63..6036f56af 100644
a11c41
--- a/panels/network/wireless-security/meson.build
a11c41
+++ b/panels/network/wireless-security/meson.build
a11c41
@@ -14,6 +14,7 @@ nm_applet_headers = [
a11c41
   'wireless-security.h',
a11c41
   'ws-leap.h',
a11c41
   'ws-dynamic-wep.h',
a11c41
+  'ws-sae.h',
a11c41
   'ws-wep-key.h',
a11c41
   'ws-wpa-eap.h',
a11c41
   'ws-wpa-psk.h'
a11c41
@@ -31,6 +32,7 @@ nm_applet_sources = [
a11c41
   'wireless-security.c',
a11c41
   'ws-leap.c',
a11c41
   'ws-dynamic-wep.c',
a11c41
+  'ws-sae.c',
a11c41
   'ws-wep-key.c',
a11c41
   'ws-wpa-eap.c',
a11c41
   'ws-wpa-psk.c'
a11c41
@@ -47,6 +49,7 @@ nm_resource_data = [
a11c41
   'eap-method-ttls.ui',
a11c41
   'ws-dynamic-wep.ui',
a11c41
   'ws-leap.ui',
a11c41
+  'ws-sae.ui',
a11c41
   'ws-wep-key.ui',
a11c41
   'ws-wpa-eap.ui',
a11c41
   'ws-wpa-psk.ui'
a11c41
diff --git a/panels/network/wireless-security/wireless-security.gresource.xml b/panels/network/wireless-security/wireless-security.gresource.xml
a11c41
index a483d06a0..fa1a965ad 100644
a11c41
--- a/panels/network/wireless-security/wireless-security.gresource.xml
a11c41
+++ b/panels/network/wireless-security/wireless-security.gresource.xml
a11c41
@@ -9,6 +9,7 @@
a11c41
     <file preprocess="xml-stripblanks">eap-method-ttls.ui</file>
a11c41
     <file preprocess="xml-stripblanks">ws-dynamic-wep.ui</file>
a11c41
     <file preprocess="xml-stripblanks">ws-leap.ui</file>
a11c41
+    <file preprocess="xml-stripblanks">ws-sae.ui</file>
a11c41
     <file preprocess="xml-stripblanks">ws-wep-key.ui</file>
a11c41
     <file preprocess="xml-stripblanks">ws-wpa-eap.ui</file>
a11c41
     <file preprocess="xml-stripblanks">ws-wpa-psk.ui</file>
a11c41
diff --git a/panels/network/wireless-security/wireless-security.h b/panels/network/wireless-security/wireless-security.h
a11c41
index 975e750f6..c5508ad1b 100644
a11c41
--- a/panels/network/wireless-security/wireless-security.h
a11c41
+++ b/panels/network/wireless-security/wireless-security.h
a11c41
@@ -102,6 +102,7 @@ GType wireless_security_get_type (void);
a11c41
 #include "ws-wep-key.h"
a11c41
 #include "ws-wpa-psk.h"
a11c41
 #include "ws-leap.h"
a11c41
+#include "ws-sae.h"
a11c41
 #include "ws-wpa-eap.h"
a11c41
 #include "ws-dynamic-wep.h"
a11c41
 
a11c41
diff --git a/panels/network/wireless-security/ws-sae.c b/panels/network/wireless-security/ws-sae.c
a11c41
new file mode 100644
a11c41
index 000000000..96138d522
a11c41
--- /dev/null
a11c41
+++ b/panels/network/wireless-security/ws-sae.c
a11c41
@@ -0,0 +1,214 @@
a11c41
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
a11c41
+/* NetworkManager Applet -- allow user control over networking
a11c41
+ *
a11c41
+ * Dan Williams <dcbw@redhat.com>
a11c41
+ *
a11c41
+ * This program is free software; you can redistribute it and/or modify
a11c41
+ * it under the terms of the GNU General Public License as published by
a11c41
+ * the Free Software Foundation; either version 2 of the License, or
a11c41
+ * (at your option) any later version.
a11c41
+ *
a11c41
+ * This program is distributed in the hope that it will be useful,
a11c41
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
a11c41
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
a11c41
+ * GNU General Public License for more details.
a11c41
+ *
a11c41
+ * You should have received a copy of the GNU General Public License along
a11c41
+ * with this program; if not, write to the Free Software Foundation, Inc.,
a11c41
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
a11c41
+ *
a11c41
+ * Copyright 2007 - 2014 Red Hat, Inc.
a11c41
+ */
a11c41
+
a11c41
+#include "nm-default.h"
a11c41
+
a11c41
+#include <ctype.h>
a11c41
+#include <string.h>
a11c41
+
a11c41
+#include "wireless-security.h"
a11c41
+#include "helpers.h"
a11c41
+#include "nma-ui-utils.h"
a11c41
+#include "utils.h"
a11c41
+
a11c41
+#define WPA_PMK_LEN 32
a11c41
+
a11c41
+struct _WirelessSecuritySAE {
a11c41
+	WirelessSecurity parent;
a11c41
+
a11c41
+	gboolean editing_connection;
a11c41
+	const char *password_flags_name;
a11c41
+};
a11c41
+
a11c41
+static void
a11c41
+show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
a11c41
+{
a11c41
+	GtkWidget *widget;
a11c41
+	gboolean visible;
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "sae_entry"));
a11c41
+	g_assert (widget);
a11c41
+
a11c41
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
a11c41
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
a11c41
+}
a11c41
+
a11c41
+static gboolean
a11c41
+validate (WirelessSecurity *parent, GError **error)
a11c41
+{
a11c41
+	GtkWidget *entry;
a11c41
+	const char *key;
a11c41
+
a11c41
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
a11c41
+	g_assert (entry);
a11c41
+
a11c41
+	key = gtk_entry_get_text (GTK_ENTRY (entry));
a11c41
+	if (key == NULL || key[0] == '\0') {
a11c41
+		widget_set_error (entry);
a11c41
+		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Wi-Fi password is missing."));
a11c41
+		return FALSE;
a11c41
+	}
a11c41
+	widget_unset_error (entry);
a11c41
+
a11c41
+	/* passphrase can be between 8 and 63 characters inclusive */
a11c41
+
a11c41
+	return TRUE;
a11c41
+}
a11c41
+
a11c41
+static void
a11c41
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
a11c41
+{
a11c41
+	GtkWidget *widget;
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_type_label"));
a11c41
+	gtk_size_group_add_widget (group, widget);
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_label"));
a11c41
+	gtk_size_group_add_widget (group, widget);
a11c41
+}
a11c41
+
a11c41
+static void
a11c41
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
a11c41
+{
a11c41
+	WirelessSecuritySAE *sae = (WirelessSecuritySAE *) parent;
a11c41
+	GtkWidget *widget, *passwd_entry;
a11c41
+	const char *key;
a11c41
+	NMSettingWireless *s_wireless;
a11c41
+	NMSettingWirelessSecurity *s_wireless_sec;
a11c41
+	NMSettingSecretFlags secret_flags;
a11c41
+	const char *mode;
a11c41
+	gboolean is_adhoc = FALSE;
a11c41
+
a11c41
+	s_wireless = nm_connection_get_setting_wireless (connection);
a11c41
+	g_assert (s_wireless);
a11c41
+
a11c41
+	mode = nm_setting_wireless_get_mode (s_wireless);
a11c41
+	if (mode && !strcmp (mode, "adhoc"))
a11c41
+		is_adhoc = TRUE;
a11c41
+
a11c41
+	/* Blow away the old security setting by adding a clear one */
a11c41
+	s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
a11c41
+	nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
a11c41
+	passwd_entry = widget;
a11c41
+	key = gtk_entry_get_text (GTK_ENTRY (widget));
a11c41
+	g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL);
a11c41
+
a11c41
+	/* Save PSK_FLAGS to the connection */
a11c41
+	secret_flags = nma_utils_menu_to_secret_flags (passwd_entry);
a11c41
+	nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), NM_SETTING_WIRELESS_SECURITY_PSK,
a11c41
+	                             secret_flags, NULL);
a11c41
+
a11c41
+	/* Update secret flags and popup when editing the connection */
a11c41
+	if (sae->editing_connection)
a11c41
+		nma_utils_update_password_storage (passwd_entry, secret_flags,
a11c41
+		                                   NM_SETTING (s_wireless_sec), sae->password_flags_name);
a11c41
+
a11c41
+	wireless_security_clear_ciphers (connection);
a11c41
+	if (is_adhoc) {
a11c41
+		/* Ad-Hoc settings as specified by the supplicant */
a11c41
+		g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
a11c41
+		nm_setting_wireless_security_add_proto (s_wireless_sec, "rsn");
a11c41
+		nm_setting_wireless_security_add_pairwise (s_wireless_sec, "ccmp");
a11c41
+		nm_setting_wireless_security_add_group (s_wireless_sec, "ccmp");
a11c41
+	} else {
a11c41
+		g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
a11c41
+
a11c41
+		/* Just leave ciphers and protocol empty, the supplicant will
a11c41
+		 * figure that out magically based on the AP IEs and card capabilities.
a11c41
+		 */
a11c41
+	}
a11c41
+}
a11c41
+
a11c41
+static void
a11c41
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
a11c41
+{
a11c41
+	helper_fill_secret_entry (connection,
a11c41
+	                          parent->builder,
a11c41
+	                          "sae_entry",
a11c41
+	                          NM_TYPE_SETTING_WIRELESS_SECURITY,
a11c41
+	                          (HelperSecretFunc) nm_setting_wireless_security_get_psk);
a11c41
+}
a11c41
+
a11c41
+WirelessSecuritySAE *
a11c41
+ws_sae_new (NMConnection *connection, gboolean secrets_only)
a11c41
+{
a11c41
+	WirelessSecurity *parent;
a11c41
+	WirelessSecuritySAE *sec;
a11c41
+	NMSetting *setting = NULL;
a11c41
+	GtkWidget *widget;
a11c41
+
a11c41
+	parent = wireless_security_init (sizeof (WirelessSecuritySAE),
a11c41
+	                                 validate,
a11c41
+	                                 add_to_size_group,
a11c41
+	                                 fill_connection,
a11c41
+	                                 update_secrets,
a11c41
+	                                 NULL,
a11c41
+	                                 "/org/gnome/ControlCenter/network/ws-sae.ui",
a11c41
+	                                 "sae_notebook",
a11c41
+	                                 "sae_entry");
a11c41
+	if (!parent)
a11c41
+		return NULL;
a11c41
+
a11c41
+	parent->adhoc_compatible = FALSE;
a11c41
+	sec = (WirelessSecuritySAE *) parent;
a11c41
+	sec->editing_connection = secrets_only ? FALSE : TRUE;
a11c41
+	sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_PSK;
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_entry"));
a11c41
+	g_assert (widget);
a11c41
+	g_signal_connect (G_OBJECT (widget), "changed",
a11c41
+	                  (GCallback) wireless_security_changed_cb,
a11c41
+	                  sec);
a11c41
+	gtk_entry_set_width_chars (GTK_ENTRY (widget), 28);
a11c41
+
a11c41
+	/* Create password-storage popup menu for password entry under entry's secondary icon */
a11c41
+	if (connection)
a11c41
+		setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection);
a11c41
+	nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name,
a11c41
+	                                  FALSE, secrets_only);
a11c41
+
a11c41
+	/* Fill secrets, if any */
a11c41
+	if (connection)
a11c41
+		update_secrets (WIRELESS_SECURITY (sec), connection);
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wpa"));
a11c41
+	g_assert (widget);
a11c41
+	g_signal_connect (G_OBJECT (widget), "toggled",
a11c41
+	                  (GCallback) show_toggled_cb,
a11c41
+	                  sec);
a11c41
+
a11c41
+	/* Hide WPA/RSN for now since this can be autodetected by NM and the
a11c41
+	 * supplicant when connecting to the AP.
a11c41
+	 */
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_type_combo"));
a11c41
+	g_assert (widget);
a11c41
+	gtk_widget_hide (widget);
a11c41
+
a11c41
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "sae_type_label"));
a11c41
+	g_assert (widget);
a11c41
+	gtk_widget_hide (widget);
a11c41
+
a11c41
+	return sec;
a11c41
+}
a11c41
diff --git a/panels/network/wireless-security/ws-sae.h b/panels/network/wireless-security/ws-sae.h
a11c41
new file mode 100644
a11c41
index 000000000..9a1262cd0
a11c41
--- /dev/null
a11c41
+++ b/panels/network/wireless-security/ws-sae.h
a11c41
@@ -0,0 +1,30 @@
a11c41
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
a11c41
+/* NetworkManager Applet -- allow user control over networking
a11c41
+ *
a11c41
+ * Dan Williams <dcbw@redhat.com>
a11c41
+ *
a11c41
+ * This program is free software; you can redistribute it and/or modify
a11c41
+ * it under the terms of the GNU General Public License as published by
a11c41
+ * the Free Software Foundation; either version 2 of the License, or
a11c41
+ * (at your option) any later version.
a11c41
+ *
a11c41
+ * This program is distributed in the hope that it will be useful,
a11c41
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
a11c41
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
a11c41
+ * GNU General Public License for more details.
a11c41
+ *
a11c41
+ * You should have received a copy of the GNU General Public License along
a11c41
+ * with this program; if not, write to the Free Software Foundation, Inc.,
a11c41
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
a11c41
+ *
a11c41
+ * Copyright 2007 - 2014 Red Hat, Inc.
a11c41
+ */
a11c41
+
a11c41
+#ifndef WS_SAE_H
a11c41
+#define WS_SAE_H
a11c41
+
a11c41
+typedef struct _WirelessSecuritySAE WirelessSecuritySAE;
a11c41
+
a11c41
+WirelessSecuritySAE * ws_sae_new (NMConnection *connection, gboolean secrets_only);
a11c41
+
a11c41
+#endif /* WS_SAE_H */
a11c41
diff --git a/panels/network/wireless-security/ws-sae.ui b/panels/network/wireless-security/ws-sae.ui
a11c41
new file mode 100644
a11c41
index 000000000..d523f16c8
a11c41
--- /dev/null
a11c41
+++ b/panels/network/wireless-security/ws-sae.ui
a11c41
@@ -0,0 +1,117 @@
a11c41
+
a11c41
+<interface>
a11c41
+  <requires lib="gtk+" version="3.4"/>
a11c41
+  <object class="GtkNotebook" id="sae_notebook">
a11c41
+    <property name="visible">True</property>
a11c41
+    <property name="can_focus">False</property>
a11c41
+    <property name="show_tabs">False</property>
a11c41
+    <property name="show_border">False</property>
a11c41
+    <child>
a11c41
+      <object class="GtkTable" id="sae_table">
a11c41
+        <property name="visible">True</property>
a11c41
+        <property name="can_focus">False</property>
a11c41
+        <property name="n_rows">3</property>
a11c41
+        <property name="n_columns">2</property>
a11c41
+        <property name="column_spacing">6</property>
a11c41
+        <property name="row_spacing">6</property>
a11c41
+        <child>
a11c41
+          <object class="GtkLabel" id="sae_label">
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">False</property>
a11c41
+            <property name="xalign">1</property>
a11c41
+            <property name="label" translatable="yes">_Password</property>
a11c41
+            <property name="use_underline">True</property>
a11c41
+            <property name="mnemonic_widget">sae_entry</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="x_options">GTK_FILL</property>
a11c41
+            <property name="y_options"/>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+        <child>
a11c41
+          <object class="GtkEntry" id="sae_entry">
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">True</property>
a11c41
+            <property name="max_length">64</property>
a11c41
+            <property name="visibility">False</property>
a11c41
+            <property name="activates_default">True</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="left_attach">1</property>
a11c41
+            <property name="right_attach">2</property>
a11c41
+            <property name="y_options"/>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+        <child>
a11c41
+          <object class="GtkLabel" id="sae_type_label">
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">False</property>
a11c41
+            <property name="xalign">1</property>
a11c41
+            <property name="label" translatable="yes">_Type</property>
a11c41
+            <property name="use_underline">True</property>
a11c41
+            <property name="mnemonic_widget">sae_type_combo</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="top_attach">2</property>
a11c41
+            <property name="bottom_attach">3</property>
a11c41
+            <property name="x_options">GTK_FILL</property>
a11c41
+            <property name="y_options"/>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+        <child>
a11c41
+          <object class="GtkLabel" id="label32">
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">False</property>
a11c41
+            <property name="xalign">0</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="top_attach">1</property>
a11c41
+            <property name="bottom_attach">2</property>
a11c41
+            <property name="x_options">GTK_FILL</property>
a11c41
+            <property name="y_options"/>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+        <child>
a11c41
+          <object class="GtkCheckButton" id="show_checkbutton_wpa">
a11c41
+            <property name="label" translatable="yes">Sho_w password</property>
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">True</property>
a11c41
+            <property name="receives_default">False</property>
a11c41
+            <property name="use_underline">True</property>
a11c41
+            <property name="draw_indicator">True</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="left_attach">1</property>
a11c41
+            <property name="right_attach">2</property>
a11c41
+            <property name="top_attach">1</property>
a11c41
+            <property name="bottom_attach">2</property>
a11c41
+            <property name="x_options">GTK_FILL</property>
a11c41
+            <property name="y_options"/>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+        <child>
a11c41
+          <object class="GtkComboBox" id="sae_type_combo">
a11c41
+            <property name="visible">True</property>
a11c41
+            <property name="can_focus">False</property>
a11c41
+          </object>
a11c41
+          <packing>
a11c41
+            <property name="left_attach">1</property>
a11c41
+            <property name="right_attach">2</property>
a11c41
+            <property name="top_attach">2</property>
a11c41
+            <property name="bottom_attach">3</property>
a11c41
+            <property name="y_options">GTK_FILL</property>
a11c41
+          </packing>
a11c41
+        </child>
a11c41
+      </object>
a11c41
+    </child>
a11c41
+    <child type="tab">
a11c41
+      <object class="GtkLabel" id="GtkLabel2">
a11c41
+        <property name="visible">True</property>
a11c41
+        <property name="can_focus">False</property>
a11c41
+      </object>
a11c41
+      <packing>
a11c41
+        <property name="tab_fill">False</property>
a11c41
+      </packing>
a11c41
+    </child>
a11c41
+  </object>
a11c41
+</interface>
a11c41
-- 
a11c41
2.34.1
a11c41