[gnome-control-center] Printers: Open firewall for required connections when searching for printers



commit 7962a25ecfa01b93087dd95c6e128381aeb8f2db
Author: Marek Kasik <mkasik redhat com>
Date:   Wed Jul 27 13:33:48 2011 +0200

    Printers: Open firewall for required connections when searching for printers
    
    This commit enables services mdns, ipp, ipp-client and samba-client on
    firewall for 5 minutes for detection of network printers (#648784).
    It enables required services permanently for printers selected by user
    for addition then. It shows a notification for the permanent enable.
    It uses firewalld, so if it is not installed or running it shows a warning
    message to the user in the place where discovered printers will be shown
    (both local and network). The warning disappears after the finish of
    printers discovery (but not from network part if no printer was found).

 configure.ac                            |    4 +-
 panels/printers/new-printer-dialog.ui   |   17 ++-
 panels/printers/pp-new-printer-dialog.c |  316 ++++++++++++++++++++++++++++++-
 shell/control-center.c                  |    3 +
 4 files changed, 334 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 98ece7f..5bb94b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,13 +76,15 @@ GDKPIXBUF_REQUIRED_VERSION=2.23.0
 POLKIT_REQUIRED_VERSION=0.97
 GSD_REQUIRED_VERSION=2.91.94
 NETWORK_MANAGER_REQUIRED_VERSION=0.8.992
+LIBNOTIFY_REQUIRED_VERSION=0.7.3
 
 COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION
  glib-2.0 >= $GLIB_REQUIRED_VERSION
  gthread-2.0
  gio-2.0
  gio-unix-2.0
- gsettings-desktop-schemas >= $DESKTOP_SCHEMAS_REQUIRED_VERSION"
+ gsettings-desktop-schemas >= $DESKTOP_SCHEMAS_REQUIRED_VERSION
+ libnotify >= $LIBNOTIFY_REQUIRED_VERSION"
 
 PKG_CHECK_MODULES(LIBGNOME_CONTROL_CENTER, $COMMON_MODULES gconf-2.0)
 PKG_CHECK_MODULES(LIBLANGUAGE, $COMMON_MODULES gnome-desktop-3.0)
diff --git a/panels/printers/new-printer-dialog.ui b/panels/printers/new-printer-dialog.ui
index 98aa948..cbb947f 100644
--- a/panels/printers/new-printer-dialog.ui
+++ b/panels/printers/new-printer-dialog.ui
@@ -81,6 +81,7 @@
                       <object class="GtkVBox" id="vbox2">
                         <property name="visible">True</property>
                         <property name="orientation">vertical</property>
+                        <property name="spacing">10</property>
                         <child>
                           <object class="GtkScrolledWindow" id="scrolledwindow1">
                             <property name="visible">True</property>
@@ -106,7 +107,8 @@
                             <child>
                               <object class="GtkLabel" id="label5">
                                 <property name="visible">True</property>
-                                <property name="label" translatable="yes">A_ddress</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">A_ddress:</property>
                                 <property name="use_underline">True</property>
                                 <property name="mnemonic_widget">address-entry</property>
                               </object>
@@ -176,7 +178,18 @@
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
+                      <object class="GtkTextView" id="warning-textview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="pixels_above_lines">6</property>
+                        <property name="editable">False</property>
+                        <property name="wrap_mode">word</property>
+                        <property name="left_margin">10</property>
+                        <property name="right_margin">10</property>
+                      </object>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
                     </child>
                     <child type="tab">
                       <object class="GtkLabel" id="label4">
diff --git a/panels/printers/pp-new-printer-dialog.c b/panels/printers/pp-new-printer-dialog.c
index 33d083e..e3fbe93 100644
--- a/panels/printers/pp-new-printer-dialog.c
+++ b/panels/printers/pp-new-printer-dialog.c
@@ -37,6 +37,7 @@
 #include "pp-utils.h"
 
 #include <dbus/dbus-glib.h>
+#include <libnotify/notify.h>
 
 #ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
@@ -48,6 +49,10 @@
 #define PACKAGE_KIT_PATH "/org/freedesktop/PackageKit"
 #define PACKAGE_KIT_IFACE "org.freedesktop.PackageKit.Modify"
 
+#define FIREWALLD_BUS "org.fedoraproject.FirewallD"
+#define FIREWALLD_PATH "/org/fedoraproject/FirewallD"
+#define FIREWALLD_IFACE "org.fedoraproject.FirewallD"
+
 #define ALLOWED_CHARACTERS "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/"
 
 static void pp_new_printer_dialog_hide (PpNewPrinterDialog *pp);
@@ -57,7 +62,6 @@ enum
 {
   NOTEBOOK_LOCAL_PAGE = 0,
   NOTEBOOK_NETWORK_PAGE,
-  NOTEBOOK_HP_JETDIRECT_PAGE,
   NOTEBOOK_N_PAGES
 };
 
@@ -80,7 +84,6 @@ enum
 {
   DEVICE_TYPE_LOCAL = 0,
   DEVICE_TYPE_NETWORK,
-  DEVICE_TYPE_HP_JETDIRECT,
   DEVICE_TYPE_N
 };
 
@@ -115,9 +118,31 @@ struct _PpNewPrinterDialog {
   gpointer             user_data;
 
   GCancellable *cancellable;
+
+  gchar    *warning;
+  gboolean  show_warning;
 };
 
 static void
+show_notification (gchar *primary_text,
+                   gchar *secondary_text,
+                   gchar *icon_name)
+{
+  if (primary_text)
+    {
+      NotifyNotification *notification;
+      notification = notify_notification_new (primary_text,
+                                              secondary_text,
+                                              icon_name);
+      notify_notification_set_app_name (notification, _("Printers"));
+      notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE));
+
+      notify_notification_show (notification, NULL);
+      g_object_unref (notification);
+    }
+}
+
+static void
 device_type_selection_changed_cb (GtkTreeSelection *selection,
                                   gpointer          user_data)
 {
@@ -144,7 +169,10 @@ device_type_selection_changed_cb (GtkTreeSelection *selection,
       widget = (GtkWidget*)
         gtk_builder_get_object (pp->builder, "device-type-notebook");
 
-      gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type);
+      if (pp->show_warning && device_type == DEVICE_TYPE_NETWORK)
+        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2);
+      else
+        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type);
 
       if (device_type == DEVICE_TYPE_LOCAL)
         treeview = (GtkWidget*)
@@ -479,6 +507,13 @@ devices_get (PpNewPrinterDialog *pp)
 
   if (proxy)
     {
+      if (pp->show_warning)
+        {
+          widget = (GtkWidget*)
+            gtk_builder_get_object (pp->builder, "device-type-notebook");
+          gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2);
+        }
+
       in_include = g_variant_builder_new (G_VARIANT_TYPE ("as"));
       in_exclude = g_variant_builder_new (G_VARIANT_TYPE ("as"));
 
@@ -599,6 +634,180 @@ line_split (gchar *line)
 }
 
 static void
+service_enable (gchar *service_name,
+                gint   service_timeout)
+{
+  GDBusProxy *proxy;
+  GVariant   *input = NULL;
+  GVariant   *output = NULL;
+  GError     *error = NULL;
+  gint        result;
+
+  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL,
+                                         FIREWALLD_BUS,
+                                         FIREWALLD_PATH,
+                                         FIREWALLD_IFACE,
+                                         NULL,
+                                         &error);
+
+  if (proxy)
+    {
+      input = g_variant_new ("(si)",
+                             service_name,
+                             service_timeout);
+
+      output = g_dbus_proxy_call_sync (proxy,
+                                       "enableService",
+                                       input,
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       60000,
+                                       NULL,
+                                       &error);
+
+      if (output && g_variant_n_children (output) == 1)
+        g_variant_get (output, "(i)", &result);
+
+      if (output)
+        g_variant_unref (output);
+      g_variant_unref (input);
+      g_object_unref (proxy);
+    }
+}
+
+static void
+service_disable (gchar *service_name)
+{
+  GDBusProxy *proxy;
+  GVariant   *input = NULL;
+  GVariant   *output = NULL;
+  GError     *error = NULL;
+  gint        result;
+
+  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL,
+                                         FIREWALLD_BUS,
+                                         FIREWALLD_PATH,
+                                         FIREWALLD_IFACE,
+                                         NULL,
+                                         &error);
+
+  if (proxy)
+    {
+      input = g_variant_new ("(s)", service_name);
+
+      output = g_dbus_proxy_call_sync (proxy,
+                                       "disableService",
+                                       input,
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       60000,
+                                       NULL,
+                                       &error);
+
+      if (output && g_variant_n_children (output) == 1)
+        g_variant_get (output, "(i)", &result);
+
+      if (output)
+        g_variant_unref (output);
+      g_variant_unref (input);
+      g_object_unref (proxy);
+    }
+}
+
+static gboolean
+service_enabled (gchar *service_name)
+{
+  GDBusProxy *proxy;
+  GVariant   *input = NULL;
+  GVariant   *output = NULL;
+  GError     *error = NULL;
+  gint        query_result = 0;
+
+  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL,
+                                         FIREWALLD_BUS,
+                                         FIREWALLD_PATH,
+                                         FIREWALLD_IFACE,
+                                         NULL,
+                                         &error);
+
+  if (proxy)
+    {
+      input = g_variant_new ("(s)",
+                             service_name);
+
+      output = g_dbus_proxy_call_sync (proxy,
+                                       "queryService",
+                                       input,
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       60000,
+                                       NULL,
+                                       &error);
+
+      if (output && g_variant_n_children (output) == 1)
+        g_variant_get (output, "(i)", &query_result);
+
+      if (output)
+        g_variant_unref (output);
+      g_variant_unref (input);
+      g_object_unref (proxy);
+    }
+
+  if (query_result > 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+static gboolean
+dbus_method_available (gchar *name,
+                       gchar *path,
+                       gchar *iface,
+                       gchar *method)
+{
+  GDBusProxy *proxy;
+  GError     *error = NULL;
+  GVariant   *output = NULL;
+  gboolean    result = FALSE;
+
+  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL,
+                                         name,
+                                         path,
+                                         iface,
+                                         NULL,
+                                         NULL);
+
+  if (proxy)
+    {
+      output = g_dbus_proxy_call_sync (proxy,
+                                       method,
+                                       NULL,
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       60000,
+                                       NULL,
+                                       &error);
+
+      if (error &&
+          error->domain == G_DBUS_ERROR &&
+          error->code == G_DBUS_ERROR_SERVICE_UNKNOWN)
+        result = FALSE;
+      else
+        result = TRUE;
+
+      if (output)
+        g_variant_unref (output);
+      g_object_unref (proxy);
+    }
+
+  return result;
+}
+
+static void
 search_address_cb (GtkToggleButton *togglebutton,
                    gpointer         user_data)
 {
@@ -825,10 +1034,14 @@ actualize_devices_list (PpNewPrinterDialog *pp)
 {
   GtkListStore *network_store;
   GtkListStore *local_store;
+  GtkTreeModel *model;
   GtkTreeView  *network_treeview;
   GtkTreeView  *local_treeview;
   GtkTreeIter   iter;
+  GtkWidget    *treeview;
+  GtkWidget    *widget;
   gint          i;
+  gint          device_type = -1;
 
   network_treeview = (GtkTreeView*)
     gtk_builder_get_object (pp->builder, "network-devices-treeview");
@@ -855,6 +1068,7 @@ actualize_devices_list (PpNewPrinterDialog *pp)
                                   DEVICE_ID_COLUMN, i,
                                   DEVICE_NAME_COLUMN, pp->devices[i].display_name,
                                   -1);
+              pp->show_warning = FALSE;
             }
           else if (g_strcmp0 (pp->devices[i].device_class, "direct") == 0)
             {
@@ -880,6 +1094,23 @@ actualize_devices_list (PpNewPrinterDialog *pp)
       gtk_tree_view_get_selection (GTK_TREE_VIEW (local_treeview)),
       &iter);
 
+  treeview = (GtkWidget*)
+    gtk_builder_get_object (pp->builder, "device-types-treeview");
+
+  if (gtk_tree_selection_get_selected (
+        gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
+    gtk_tree_model_get (model, &iter,
+                        DEVICE_TYPE_TYPE_COLUMN, &device_type,
+                        -1);
+
+  widget = (GtkWidget*)
+    gtk_builder_get_object (pp->builder, "device-type-notebook");
+
+  if (pp->show_warning && device_type == DEVICE_TYPE_NETWORK)
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2);
+  else
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type);
+
   g_object_unref (network_store);
   g_object_unref (local_store);
 }
@@ -889,6 +1120,9 @@ populate_devices_list (PpNewPrinterDialog *pp)
 {
   GtkTreeViewColumn *column;
   GtkCellRenderer   *renderer;
+  GtkTextBuffer     *text_buffer;
+  GtkTextView       *warning_textview;
+  GtkTextIter        text_iter;
   GtkWidget         *network_treeview;
   GtkWidget         *local_treeview;
 
@@ -905,6 +1139,41 @@ populate_devices_list (PpNewPrinterDialog *pp)
                     "changed", G_CALLBACK (device_selection_changed_cb), pp);
 
   actualize_devices_list (pp);
+
+  if (dbus_method_available (FIREWALLD_BUS,
+                             FIREWALLD_PATH,
+                             FIREWALLD_IFACE,
+                             "getServices"))
+    {
+      if (!service_enabled ("mdns"))
+        service_enable ("mdns", 300);
+
+      if (!service_enabled ("ipp"))
+        service_enable ("ipp", 300);
+
+      if (!service_enabled ("ipp-client"))
+        service_enable ("ipp-client", 300);
+
+      if (!service_enabled ("samba-client"))
+        service_enable ("samba-client", 300);
+    }
+  else
+    {
+      pp->warning = g_strdup (_("FirewallD is not running. \
+Network printer detection needs services mdns, ipp, ipp-client \
+and samba-client enabled on firewall."));
+
+      warning_textview = (GtkTextView*)
+        gtk_builder_get_object (pp->builder, "warning-textview");
+      text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (warning_textview));
+
+      gtk_text_buffer_set_text (text_buffer, "", 0);
+      gtk_text_buffer_get_iter_at_offset (text_buffer, &text_iter, 0);
+      gtk_text_buffer_insert (text_buffer, &text_iter, pp->warning, -1);
+
+      pp->show_warning = TRUE;
+    }
+
   devices_get (pp);
 
   renderer = gtk_cell_renderer_text_new ();
@@ -1352,6 +1621,43 @@ new_printer_add_button_cb (GtkButton *button,
                 }
               g_object_unref (proxy);
             }
+
+          if (pp->devices[device_id].device_uri &&
+              dbus_method_available (FIREWALLD_BUS,
+                                     FIREWALLD_PATH,
+                                     FIREWALLD_IFACE,
+                                     "getServices"))
+            {
+              if (g_str_has_prefix (pp->devices[device_id].device_uri, "dnssd:") ||
+                  g_str_has_prefix (pp->devices[device_id].device_uri, "mdns:"))
+                {
+                  show_notification (_("Opening firewall for mDNS connections"),
+                                     NULL,
+                                     "dialog-information-symbolic");
+                  service_disable ("mdns");
+                  service_enable ("mdns", 0);
+                }
+
+              if (g_strrstr (pp->devices[device_id].device_uri, "smb:") != NULL)
+                {
+                  show_notification (_("Opening firewall for Samba connections"),
+                                     NULL,
+                                     "dialog-information-symbolic");
+                  service_disable ("samba-client");
+                  service_enable ("samba-client", 0);
+                }
+
+              if (g_strrstr (pp->devices[device_id].device_uri, "ipp:") != NULL)
+                {
+                  show_notification (_("Opening firewall for IPP connections"),
+                                     NULL,
+                                     "dialog-information-symbolic");
+                  service_disable ("ipp");
+                  service_enable ("ipp", 0);
+                  service_disable ("ipp-client");
+                  service_enable ("ipp-client", 0);
+                }
+            }
         }
     }
 
@@ -1407,6 +1713,8 @@ pp_new_printer_dialog_new (GtkWindow            *parent,
   pp->user_data = user_data;
 
   pp->cancellable = NULL;
+  pp->warning = NULL;
+  pp->show_warning = FALSE;
 
   /* connect signals */
   g_signal_connect (pp->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
@@ -1459,6 +1767,8 @@ pp_new_printer_dialog_free (PpNewPrinterDialog *pp)
       g_object_unref (pp->cancellable);
     }
 
+  g_free (pp->warning);
+
   g_free (pp);
 }
 
diff --git a/shell/control-center.c b/shell/control-center.c
index 2ba41fd..167ebb6 100644
--- a/shell/control-center.c
+++ b/shell/control-center.c
@@ -28,6 +28,7 @@
 
 #include <gtk/gtk.h>
 #include <string.h>
+#include <libnotify/notify.h>
 
 #include "cc-shell-log.h"
 
@@ -181,6 +182,8 @@ main (int argc, char **argv)
   /* register a symbolic icon size for use in sidebar lists */
   gtk_icon_size_register ("cc-sidebar-list", 24, 24);
 
+  notify_init ("gnome-control-center");
+
   shell = gnome_control_center_new ();
 
   /* enforce single instance of this application */



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