From 493841c19ca1a006f8e040612918dd0942693566 Mon Sep 17 00:00:00 2001
From: Jonathan Kang <jonathankang@gnome.org>
Date: Wed, 19 Mar 2025 10:09:42 +0800
Subject: [PATCH] gnome-control-center-bring-back-firewall-zone.patch

---
 .../connection-editor/ce-page-ethernet.c      |  27 ++++
 .../connection-editor/ce-page-security.c      |  15 +++
 .../network/connection-editor/ce-page-vpn.c   |   9 ++
 .../connection-editor/ethernet-page.ui        |  26 ++++
 .../connection-editor/firewall-helpers.c      | 125 ++++++++++++++++++
 .../connection-editor/firewall-helpers.h      |  33 +++++
 panels/network/connection-editor/meson.build  |   1 +
 .../connection-editor/security-page.ui        |  27 ++++
 panels/network/connection-editor/vpn-page.ui  |  24 ++++
 9 files changed, 287 insertions(+)
 create mode 100644 panels/network/connection-editor/firewall-helpers.c
 create mode 100644 panels/network/connection-editor/firewall-helpers.h

diff --git a/panels/network/connection-editor/ce-page-ethernet.c b/panels/network/connection-editor/ce-page-ethernet.c
index e276b0d59..5c1114330 100644
--- a/panels/network/connection-editor/ce-page-ethernet.c
+++ b/panels/network/connection-editor/ce-page-ethernet.c
@@ -27,6 +27,7 @@
 
 #include "ce-page.h"
 #include "ce-page-ethernet.h"
+#include "firewall-helpers.h"
 #include "ui-helpers.h"
 
 struct _CEPageEthernet
@@ -38,8 +39,11 @@ struct _CEPageEthernet
         GtkSpinButton   *mtu_spin;
         GtkWidget       *mtu_label;
         GtkEntry        *name_entry;
+        GtkLabel        *firewall_heading;
+        GtkComboBoxText *firewall_combo;
 
         NMClient *client;
+        NMConnection *connection;
         NMSettingConnection *setting_connection;
         NMSettingWired *setting_wired;
 };
@@ -78,6 +82,7 @@ static void
 connect_ethernet_page (CEPageEthernet *self)
 {
         NMSettingWired *setting = self->setting_wired;
+        NMSettingConnection *sc;
         char **mac_list;
         const char *s_mac_str;
         const gchar *name;
@@ -107,6 +112,10 @@ connect_ethernet_page (CEPageEthernet *self)
 
         g_signal_connect_object (self->name_entry, "changed", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
         g_signal_connect_object (self->mtu_spin, "value-changed", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
+
+        sc = nm_connection_get_setting_connection (self->connection);
+        firewall_ui_setup (sc, GTK_WIDGET (self->firewall_combo), GTK_WIDGET (self->firewall_heading), NULL);
+        g_signal_connect_swapped (self->firewall_combo, "changed", G_CALLBACK (ce_page_changed), self);
 }
 
 static void
@@ -134,6 +143,8 @@ ui_to_setting (CEPageEthernet *self)
         g_object_set (self->setting_connection,
                       NM_SETTING_CONNECTION_ID, gtk_editable_get_text (GTK_EDITABLE (self->name_entry)),
                       NULL);
+
+        firewall_ui_to_setting (self->setting_connection, GTK_WIDGET (self->firewall_combo));
 }
 
 static const gchar *
@@ -177,6 +188,16 @@ ce_page_ethernet_validate (CEPage        *page,
                nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error);
 }
 
+static void
+ce_page_ethernet_dispose (GObject *object)
+{
+        CEPageEthernet *self = CE_PAGE_ETHERNET (object);
+
+        g_clear_object (&self->connection);
+
+        G_OBJECT_CLASS (ce_page_ethernet_parent_class)->dispose (object);
+}
+
 static void
 ce_page_ethernet_init (CEPageEthernet *self)
 {
@@ -186,8 +207,11 @@ ce_page_ethernet_init (CEPageEthernet *self)
 static void
 ce_page_ethernet_class_init (CEPageEthernetClass *klass)
 {
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+        object_class->dispose = ce_page_ethernet_dispose;
+
         gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/network/ethernet-page.ui");
 
         gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, cloned_mac_combo);
@@ -195,6 +219,8 @@ ce_page_ethernet_class_init (CEPageEthernetClass *klass)
         gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, mtu_spin);
         gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, mtu_label);
         gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, name_entry);
+        gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, firewall_heading);
+        gtk_widget_class_bind_template_child (widget_class, CEPageEthernet, firewall_combo);
 }
 
 static void
@@ -213,6 +239,7 @@ ce_page_ethernet_new (NMConnection     *connection,
         self = g_object_new (CE_TYPE_PAGE_ETHERNET, NULL);
 
         self->client = client;
+        self->connection = g_object_ref (connection);
         self->setting_connection = nm_connection_get_setting_connection (connection);
         self->setting_wired = nm_connection_get_setting_wired (connection);
 
diff --git a/panels/network/connection-editor/ce-page-security.c b/panels/network/connection-editor/ce-page-security.c
index 273ba8bc9..246be0315 100644
--- a/panels/network/connection-editor/ce-page-security.c
+++ b/panels/network/connection-editor/ce-page-security.c
@@ -27,6 +27,7 @@
 
 #include "ce-page.h"
 #include "ce-page-security.h"
+#include "firewall-helpers.h"
 #include "nma-ws.h"
 
 struct _CEPageSecurity
@@ -36,6 +37,8 @@ struct _CEPageSecurity
         GtkBox      *box;
         GtkComboBox *security_combo;
         GtkLabel    *security_label;
+        GtkComboBox *firewall_combo;
+        GtkWidget   *firewall_heading;
 
         NMConnection *connection;
         const gchar  *security_setting;
@@ -164,6 +167,7 @@ security_combo_changed (CEPageSecurity *self)
                         gtk_box_remove (self->box, GTK_WIDGET (sec));
 
                 gtk_size_group_add_widget (self->group, GTK_WIDGET (self->security_label));
+                gtk_size_group_add_widget (self->group, self->firewall_heading);
                 nma_ws_add_to_size_group (sec, self->group);
 
                 gtk_box_append (self->box, g_object_ref (GTK_WIDGET (sec)));
@@ -221,6 +225,7 @@ finish_setup (CEPageSecurity *self)
 {
         NMSettingWireless *sw;
         NMSettingWirelessSecurity *sws;
+        NMSettingConnection *sc;
         gboolean is_adhoc = FALSE;
         g_autoptr(GtkListStore) sec_model = NULL;
         GtkTreeIter iter;
@@ -387,6 +392,10 @@ finish_setup (CEPageSecurity *self)
 
         gtk_combo_box_set_active (self->security_combo, active < 0 ? 0 : (guint32) active);
 
+        sc = nm_connection_get_setting_connection (self->connection);
+        firewall_ui_setup (sc, GTK_WIDGET (self->firewall_combo), self->firewall_heading, NULL);
+        g_signal_connect_swapped (self->firewall_combo, "changed", G_CALLBACK (ce_page_changed), self);
+
         security_combo_changed (self);
         g_signal_connect_object (self->security_combo, "changed",
                                  G_CALLBACK (security_combo_changed), self, G_CONNECT_SWAPPED);
@@ -422,6 +431,7 @@ ce_page_security_validate (CEPage        *page,
 {
         CEPageSecurity *self = CE_PAGE_SECURITY (page);
         NMSettingWireless *sw;
+        NMSettingConnection *sc;
         NMAWs *sec;
         gboolean valid = FALSE;
         const char *mode;
@@ -478,6 +488,9 @@ ce_page_security_validate (CEPage        *page,
 
         }
 
+        sc = nm_connection_get_setting_connection (connection);
+        firewall_ui_to_setting (sc, GTK_WIDGET (CE_PAGE_SECURITY (self)->firewall_combo));
+
         return valid;
 }
 
@@ -500,6 +513,8 @@ ce_page_security_class_init (CEPageSecurityClass *klass)
         gtk_widget_class_bind_template_child (widget_class, CEPageSecurity, box);
         gtk_widget_class_bind_template_child (widget_class, CEPageSecurity, security_label);
         gtk_widget_class_bind_template_child (widget_class, CEPageSecurity, security_combo);
+        gtk_widget_class_bind_template_child (widget_class, CEPageSecurity, firewall_heading);
+        gtk_widget_class_bind_template_child (widget_class, CEPageSecurity, firewall_combo);
 }
 
 static void
diff --git a/panels/network/connection-editor/ce-page-vpn.c b/panels/network/connection-editor/ce-page-vpn.c
index 48892b1b4..453d5b897 100644
--- a/panels/network/connection-editor/ce-page-vpn.c
+++ b/panels/network/connection-editor/ce-page-vpn.c
@@ -27,6 +27,7 @@
 
 #include "ce-page.h"
 #include "ce-page-vpn.h"
+#include "firewall-helpers.h"
 #include "vpn-helpers.h"
 
 struct _CEPageVpn
@@ -36,6 +37,8 @@ struct _CEPageVpn
         GtkBox     *box;
         GtkLabel   *failure_label;
         GtkEntry   *name_entry;
+        GtkLabel   *firewall_heading;
+        GtkComboBoxText *firewall_combo;
 
         NMConnection *connection;
         NMSettingConnection *setting_connection;
@@ -124,6 +127,9 @@ connect_vpn_page (CEPageVpn *self)
         name = nm_setting_connection_get_id (self->setting_connection);
         gtk_editable_set_text (GTK_EDITABLE (self->name_entry), name);
         g_signal_connect_object (self->name_entry, "changed", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
+
+        firewall_ui_setup (self->setting_connection, GTK_WIDGET (self->firewall_combo), GTK_WIDGET (self->firewall_heading), NULL);
+        g_signal_connect_swapped (self->firewall_combo, "changed", G_CALLBACK (ce_page_changed), self);
 }
 
 static void
@@ -159,6 +165,7 @@ ce_page_vpn_validate (CEPage        *page,
         g_object_set (self->setting_connection,
                       NM_SETTING_CONNECTION_ID, gtk_editable_get_text (GTK_EDITABLE (self->name_entry)),
                       NULL);
+        firewall_ui_to_setting (self->setting_connection, GTK_WIDGET (self->firewall_combo));
 
         if (!nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error))
                 return FALSE;
@@ -188,6 +195,8 @@ ce_page_vpn_class_init (CEPageVpnClass *class)
         gtk_widget_class_bind_template_child (widget_class, CEPageVpn, box);
         gtk_widget_class_bind_template_child (widget_class, CEPageVpn, failure_label);
         gtk_widget_class_bind_template_child (widget_class, CEPageVpn, name_entry);
+        gtk_widget_class_bind_template_child (widget_class, CEPageVpn, firewall_heading);
+        gtk_widget_class_bind_template_child (widget_class, CEPageVpn, firewall_combo);
 }
 
 static void
diff --git a/panels/network/connection-editor/ethernet-page.ui b/panels/network/connection-editor/ethernet-page.ui
index 89cdf8f3d..d6c6ad085 100644
--- a/panels/network/connection-editor/ethernet-page.ui
+++ b/panels/network/connection-editor/ethernet-page.ui
@@ -127,5 +127,31 @@
         </child>
       </object>
     </child>
+    <child>
+      <object class="GtkLabel" id="firewall_heading">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Firewall _Zone</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">firewall_combo</property>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">4</property>
+        </layout>
+      </object>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="firewall_combo">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="entry_text_column">0</property>
+        <property name="id_column">1</property>
+        <layout>
+          <property name="column">1</property>
+          <property name="row">4</property>
+        </layout>
+      </object>
+    </child>
   </template>
 </interface>
diff --git a/panels/network/connection-editor/firewall-helpers.c b/panels/network/connection-editor/firewall-helpers.c
new file mode 100644
index 000000000..2e2c29f5a
--- /dev/null
+++ b/panels/network/connection-editor/firewall-helpers.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * 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.
+ *
+ * (C) Copyright 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+
+#include "firewall-helpers.h"
+
+typedef struct {
+        gchar *zone;
+        GtkWidget *combo;
+        GtkWidget *label;
+} GetZonesReplyData;
+
+static void
+get_zones_reply (GObject      *source,
+                 GAsyncResult *res,
+                 gpointer      user_data)
+{
+        GDBusConnection *bus = G_DBUS_CONNECTION (source);
+        GetZonesReplyData *d = user_data;
+        GVariant *ret;
+        GError *error = NULL;
+        const gchar **zones;
+        gint idx;
+        gint i;
+
+        ret = g_dbus_connection_call_finish (bus, res, &error);
+
+        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo),
+                                        C_("Firewall zone", "Default"));
+        gtk_widget_set_tooltip_text (d->combo, _("The zone defines the trust level of the connection"));
+
+        idx = 0;
+        if (error) {
+                gtk_widget_hide (d->combo);
+                gtk_widget_hide (d->label);
+                g_error_free (error);
+        }
+        else {
+                gtk_widget_show (d->combo);
+                gtk_widget_show (d->label);
+                g_variant_get (ret, "(^a&s)", &zones);
+
+                for (i = 0; zones[i]; i++) {
+                        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo),
+                                                        zones[i]);
+                        if (g_strcmp0 (d->zone, zones[i]) == 0)
+                                idx = i + 1;
+                }
+                if (d->zone && idx == 0) {
+                        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo),
+                                                        d->zone);
+                        idx = i + 1;
+                }
+                g_variant_unref (ret);
+        }
+        gtk_combo_box_set_active (GTK_COMBO_BOX (d->combo), idx);
+
+        g_free (d->zone);
+        g_free (d);
+}
+
+void
+firewall_ui_setup (NMSettingConnection *setting,
+                   GtkWidget           *combo,
+                   GtkWidget           *label,
+                   GCancellable        *cancellable)
+{
+        GDBusConnection *bus;
+        GetZonesReplyData *d;
+
+        bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+
+        d = g_new0 (GetZonesReplyData, 1);
+        d->zone = g_strdup (nm_setting_connection_get_zone (setting));
+        d->combo = combo;
+        d->label = label;
+
+        g_dbus_connection_call (bus,
+                                "org.fedoraproject.FirewallD1",
+                                "/org/fedoraproject/FirewallD1",
+                                "org.fedoraproject.FirewallD1.zone",
+                                "getZones",
+                                NULL,
+                                NULL,
+                                0,
+                                G_MAXINT,
+                                cancellable,
+                                get_zones_reply, d);
+        g_object_unref (bus);
+}
+
+void
+firewall_ui_to_setting (NMSettingConnection *setting, GtkWidget *combo)
+{
+        gchar *zone;
+
+        zone = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
+        if (g_strcmp0 (zone, C_("Firewall zone", "Default")) == 0) {
+                g_free (zone);
+                zone = NULL;
+        }
+
+        g_object_set (setting, NM_SETTING_CONNECTION_ZONE, zone, NULL);
+        g_free (zone);
+}
diff --git a/panels/network/connection-editor/firewall-helpers.h b/panels/network/connection-editor/firewall-helpers.h
new file mode 100644
index 000000000..213c515e8
--- /dev/null
+++ b/panels/network/connection-editor/firewall-helpers.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ * (C) Copyright 2013 Red Hat, Inc.
+ */
+
+#ifndef _FIREWALL_HELPERS_H_
+#define _FIREWALL_HELPERS_H_
+
+#include <NetworkManager.h>
+#include <gtk/gtk.h>
+
+void firewall_ui_setup      (NMSettingConnection *setting,
+                             GtkWidget           *combo,
+                             GtkWidget           *label,
+                             GCancellable        *cancellable);
+void firewall_ui_to_setting (NMSettingConnection *setting,
+                             GtkWidget           *combo);
+
+
+#endif  /* _FIREWALL_HELPERS_H_ */
diff --git a/panels/network/connection-editor/meson.build b/panels/network/connection-editor/meson.build
index a9e14f594..73f2e8e59 100644
--- a/panels/network/connection-editor/meson.build
+++ b/panels/network/connection-editor/meson.build
@@ -14,6 +14,7 @@ sources = files(
   'ce-page-wireguard.c',
   'ce-page-wifi.c',
   'ce-page.c',
+  'firewall-helpers.c',
   'net-connection-editor.c',
   'vpn-helpers.c'
 )
diff --git a/panels/network/connection-editor/security-page.ui b/panels/network/connection-editor/security-page.ui
index affba837b..23c73ef12 100644
--- a/panels/network/connection-editor/security-page.ui
+++ b/panels/network/connection-editor/security-page.ui
@@ -51,5 +51,32 @@
         </child>
       </object>
     </child>
+    <child>
+      <object class="GtkLabel" id="firewall_heading">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Firewall _Zone</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">firewall_combo</property>
+         <layout>
+          <property name="column">0</property>
+          <property name="row">2</property>
+        </layout>
+      </object>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="firewall_combo">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="entry_text_column">0</property>
+        <property name="id_column">1</property>
+         <layout>
+          <property name="column">1</property>
+          <property name="row">2</property>
+        </layout>
+      </object>
+    </child>
   </template>
 </interface>
diff --git a/panels/network/connection-editor/vpn-page.ui b/panels/network/connection-editor/vpn-page.ui
index d087e5e29..614e26582 100644
--- a/panels/network/connection-editor/vpn-page.ui
+++ b/panels/network/connection-editor/vpn-page.ui
@@ -34,6 +34,30 @@
                 </child>
               </object>
             </child>
+            <child>
+              <object class="GtkBox" id="box1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="firewall_heading">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Firewall _Zone</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">firewall_combo</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="firewall_combo">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="entry_text_column">0</property>
+                    <property name="id_column">1</property>
+                  </object>
+                </child>
+              </object>
+            </child>
             <child>
               <object class="GtkLabel" id="failure_label">
                 <property name="xalign">0</property>
-- 
2.48.1

