diff -up system-config-printer-1.3.12/firewallsettings.py.FirewallD system-config-printer-1.3.12/firewallsettings.py --- system-config-printer-1.3.12/firewallsettings.py.FirewallD 2012-11-20 17:36:44.148167348 +0000 +++ system-config-printer-1.3.12/firewallsettings.py 2012-11-20 17:36:44.148167348 +0000 @@ -0,0 +1,279 @@ +#!/usr/bin/python + +## system-config-printer + +## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. +## Authors: +## Tim Waugh + +## 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. + +# config is generated from config.py.in by configure +import config + +import dbus +import json +from debug import * + +IPP_CLIENT_SERVICE = "ipp-client" +IPP_CLIENT_PORT = "631" +IPP_CLIENT_PROTOCOL = "udp" +IPP_SERVER_SERVICE = "ipp" +IPP_SERVER_PORT = "631" +IPP_SERVER_PROTOCOL = "tcp" +MDNS_SERVICE = "mdns" +MDNS_PORT = "5353" +MDNS_PROTOCOL = "udp" +SAMBA_CLIENT_SERVICE = "samba-client" + +class FirewallD: + DBUS_INTERFACE = "org.fedoraproject.FirewallD1" + DBUS_INTERFACE_ZONE = DBUS_INTERFACE+".zone" + DBUS_INTERFACE_CONFIG = DBUS_INTERFACE+".config" + DBUS_PATH = "/org/fedoraproject/FirewallD1" + DBUS_PATH_CONFIG = DBUS_PATH+"/config" + services_idx = 5 + ports_idx = 6 + def __init__ (self): + try: + bus = dbus.SystemBus () + obj = bus.get_object (self.DBUS_INTERFACE, self.DBUS_PATH) + self._fw = dbus.Interface(obj, self.DBUS_INTERFACE) + self._fw_zone = dbus.Interface(obj, self.DBUS_INTERFACE_ZONE) + self._fw_properties = dbus.Interface(obj, + dbus_interface='org.freedesktop.DBus.Properties') + obj_config = bus.get_object (self.DBUS_INTERFACE, + self.DBUS_PATH_CONFIG) + self._fw_config = dbus.Interface (obj_config, + self.DBUS_INTERFACE_CONFIG) + zone_name = self._get_active_zone () + if zone_name: + zone_path = self._fw_config.getZoneByName (zone_name) + self._zone = bus.get_object (self.DBUS_INTERFACE, zone_path) + else: + self._zone = None + debugprint ("Using /org/fedoraproject/FirewallD1") + except (ImportError, dbus.DBusException): + self._fw = None + self._fw_zone = None + self._fw_properties = None + self._fw_config = None + self._zone = None + + def running (self): + return self._fw_properties and \ + str(self._fw_properties.Get(self.DBUS_INTERFACE, "state")) \ + == "RUNNING" + + def _get_active_zone (self): + try: + zones = map (str, self._fw_zone.getActiveZones()) + # remove immutable zones + zones = [z for z in zones if not self._fw_zone.isImmutable(z)] + except dbus.DBusException: + debugprint ("FirewallD getting active zones failed") + zones = None + + if not zones: + debugprint ("FirewallD: no changeable zone") + return None + elif len (zones) == 1: + # most probable case + return zones[0] + else: + # Do we need to handle the 'more active zones' case ? + # It's quite unlikely case because that would mean that more + # network connections are up and running and they are + # in different network zones at the same time. + debugprint ("FirewallD returned more zones, taking first one") + return zones[0] + + def _get_fw_data (self, reply_handler=None, error_handler=None): + try: + repr_data = map (str, self._fw_data[self.services_idx]) + debugprint ("%s in _get_fw_data: _fw_data is %s" % + (self, repr(repr_data))) + if self._fw_data: + debugprint ("Using cached firewall data") + if reply_handler: + reply_handler (self._fw_data) + except AttributeError: + try: + self._fw_data = self._zone.getSettings () + debugprint ("Firewall data obtained") + if reply_handler: + reply_handler (self._fw_data) + except (dbus.DBusException, AttributeError, ValueError), e: + self._fw_data = None + debugprint ("Exception examining firewall") + if error_handler: + error_handler (e) + + return self._fw_data + + def read (self, reply_handler=None, error_handler=None): + if reply_handler: + self._get_fw_data (reply_handler, + error_handler) + else: + self._get_fw_data () + + def write (self): + if self._zone: + self._zone.update (self._fw_data) + self._fw.reload () + + def add_service (self, service): + if not self._get_fw_data (): + return + + #self._fw_data.addService (service) + if service not in self._fw_data[self.services_idx]: + self._fw_data[self.services_idx].append(service) + + def check_ipp_client_allowed (self): + if not self._get_fw_data (): + return True + + return (IPP_CLIENT_SERVICE in self._fw_data[self.services_idx] or + [IPP_CLIENT_PORT, IPP_CLIENT_PROTOCOL] in self._fw_data[self.ports_idx]) + + def check_ipp_server_allowed (self): + if not self._get_fw_data (): + return True + + return (IPP_SERVER_SERVICE in self._fw_data[self.services_idx] or + [IPP_SERVER_PORT, IPP_SERVER_PROTOCOL] in self._fw_data[self.ports_idx]) + + def check_samba_client_allowed (self): + if not self._get_fw_data (): + return True + + return (SAMBA_CLIENT_SERVICE in self._fw_data[self.services_idx]) + + def check_mdns_allowed (self): + if not self._get_fw_data (): + return True + + return (MDNS_SERVICE in self._fw_data[self.services_idx] or + [MDNS_PORT, MDNS_PROTOCOL] in self._fw_data[self.ports_idx]) + + + +class SystemConfigFirewall: + DBUS_INTERFACE = "org.fedoraproject.Config.Firewall" + DBUS_PATH = "/org/fedoraproject/Config/Firewall" + + def __init__(self): + try: + bus = dbus.SystemBus () + obj = bus.get_object (self.DBUS_INTERFACE, self.DBUS_PATH) + self._fw = dbus.Interface (obj, self.DBUS_INTERFACE) + debugprint ("Using system-config-firewall") + except (dbus.DBusException), e: + debugprint ("No firewall ") + self._fw = None + self._fw_data = (None, None) + + def _get_fw_data (self, reply_handler=None, error_handler=None): + try: + debugprint ("%s in _get_fw_data: _fw_data is %s" % + (self, repr(self._fw_data))) + if self._fw_data: + debugprint ("Using cached firewall data") + if reply_handler == None: + return self._fw_data + + self._client_reply_handler (self._fw_data) + except AttributeError: + try: + if reply_handler: + self._fw.read (reply_handler=reply_handler, + error_handler=error_handler) + return + + p = self._fw.read () + self._fw_data = json.loads (p.encode ('utf-8')) + except (dbus.DBusException, AttributeError, ValueError), e: + self._fw_data = (None, None) + if error_handler: + debugprint ("Exception examining firewall") + self._client_error_handler (e) + + return self._fw_data + + def read (self, reply_handler=None, error_handler=None): + if reply_handler: + self._client_reply_handler = reply_handler + self._client_error_handler = error_handler + self._get_fw_data (reply_handler=self.reply_handler, + error_handler=self.error_handler) + else: + self._get_fw_data () + + def reply_handler (self, result): + try: + self._fw_data = json.loads (result.encode ('utf-8')) + except ValueError, e: + self.error_handler (e) + return + + debugprint ("Firewall data obtained") + self._client_reply_handler (self._fw_data) + + def error_handler (self, exc): + debugprint ("Exception fetching firewall data") + self._client_error_handler (exc) + + def write (self): + try: + self._fw.write (json.dumps (self._fw_data[0])) + except: + pass + + def _check_any_allowed (self, search): + (args, filename) = self._get_fw_data () + if filename == None: return True + isect = set (search).intersection (set (args)) + return len (isect) != 0 + + + def add_service (self, service): + try: + (args, filename) = self._fw_data + except AttributeError: + (args, filename) = self._get_fw_data () + if filename == None: return + + args.append ("--service=" + service) + self._fw_data = (args, filename) + + def check_ipp_client_allowed (self): + return self._check_any_allowed (set(["--port=%s:%s" % + (IPP_CLIENT_PORT, IPP_CLIENT_PROTOCOL), + "--service=" + IPP_CLIENT_SERVICE])) + + def check_ipp_server_allowed (self): + return self._check_any_allowed (set(["--port=%s:%s" % + (IPP_SERVER_PORT, IPP_SERVER_PROTOCOL), + "--service=" + IPP_SERVER_SERVICE])) + + def check_samba_client_allowed (self): + return self._check_any_allowed (set(["--service=" + SAMBA_CLIENT_SERVICE])) + + def check_mdns_allowed (self): + return self._check_any_allowed (set(["--port=%s:%s" % + (MDNS_PORT, MDNS_PROTOCOL), + "--service=" + MDNS_SERVICE])) diff -up system-config-printer-1.3.12/Makefile.in.FirewallD system-config-printer-1.3.12/Makefile.in --- system-config-printer-1.3.12/Makefile.in.FirewallD 2012-10-05 17:01:02.000000000 +0100 +++ system-config-printer-1.3.12/Makefile.in 2012-11-20 17:36:44.149167352 +0000 @@ -384,7 +384,7 @@ nobase_pkgdata_DATA = \ dnssdresolve.py \ errordialogs.py \ HIG.py \ - firewall.py \ + firewallsettings.py \ gui.py \ gtkinklevel.py \ gtkspinner.py \ diff -up system-config-printer-1.3.12/newprinter.py.FirewallD system-config-printer-1.3.12/newprinter.py --- system-config-printer-1.3.12/newprinter.py.FirewallD 2012-09-17 11:08:52.000000000 +0100 +++ system-config-printer-1.3.12/newprinter.py 2012-11-20 17:36:44.149167352 +0000 @@ -63,7 +63,7 @@ from smburi import SMBURI from errordialogs import * from PhysicalDevice import PhysicalDevice import gtkspinner -import firewall +import firewallsettings import asyncconn import ppdsloader import dnssdresolve @@ -1618,11 +1618,14 @@ class NewPrinterGUI(GtkGUI): try: if (self._host == 'localhost' or self._host[0] == '/'): - self.firewall = firewall.Firewall () + self.firewall = firewallsettings.FirewallD () + if not self.firewall.running(): + self.firewall = firewallsettings.SystemConfigFirewall () + debugprint ("Examining firewall") self.firewall.read (reply_handler=self.on_firewall_read, error_handler=lambda x: - self.start_fetching_devices()) + self.start_fetching_devices()) allowed = False else: # This is a remote server. Nothing we can do about @@ -1648,11 +1651,11 @@ class NewPrinterGUI(GtkGUI): secondary_text += ("- " + _("Allow all incoming IPP Browse packets") + "\n") - f.add_rule (f.ALLOW_IPP_CLIENT) + f.add_service (firewallsettings.IPP_CLIENT_SERVICE) if not mdns_allowed: secondary_text += ("- " + _("Allow all incoming mDNS traffic") + "\n") - f.add_rule (f.ALLOW_MDNS) + f.add_service (firewallsettings.MDNS_SERVICE) if not allowed: debugprint ("Asking for permission to adjust firewall:\n%s" % @@ -1678,7 +1681,7 @@ class NewPrinterGUI(GtkGUI): def adjust_firewall_response (self, dialog, response): dialog.destroy () if response == gtk.RESPONSE_YES: - self.firewall.add_rule (self.firewall.ALLOW_IPP_SERVER) + self.firewall.add_service (firewallsettings.IPP_SERVER_SERVICE) self.firewall.write () debugprint ("Fetching devices after firewall dialog response") @@ -2070,7 +2073,9 @@ class NewPrinterGUI(GtkGUI): try: # Note: we do the browsing from *this* machine, regardless # of which CUPS server we are connected to. - f = firewall.Firewall () + f = firewallsettings.FirewallD () + if not f.running(): + f = firewallsettings.SystemConfigFirewall () allowed = f.check_samba_client_allowed () secondary_text = TEXT_adjust_firewall + "\n\n" if not allowed: @@ -2090,7 +2095,7 @@ class NewPrinterGUI(GtkGUI): dialog.destroy () if response == gtk.RESPONSE_YES: - f.add_rule (f.ALLOW_SAMBA_CLIENT) + f.add_service (firewallsettings.SAMBA_CLIENT_SERVICE) f.write () except (dbus.DBusException, Exception): nonfatalException () diff -up system-config-printer-1.3.12/printerproperties.py.FirewallD system-config-printer-1.3.12/printerproperties.py --- system-config-printer-1.3.12/printerproperties.py.FirewallD 2012-09-17 11:08:52.000000000 +0100 +++ system-config-printer-1.3.12/printerproperties.py 2012-11-20 17:37:00.853222088 +0000 @@ -2,7 +2,7 @@ ## system-config-printer -## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. +## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. ## Authors: ## Tim Waugh ## Florian Festi @@ -562,6 +562,8 @@ class PrinterPropertiesDialog(GtkGUI): self.newPrinterGUI = newprinter.NewPrinterGUI () self._connect ("newPrinterGUI", self.newPrinterGUI, "printer-modified", self.on_printer_modified) + self._connect ("newPrinterGUI", self.newPrinterGUI, + "dialog-canceled", self.on_printer_not_modified) if parent: self.dialog.set_transient_for (parent) @@ -1820,30 +1822,49 @@ class PrinterPropertiesDialog(GtkGUI): self.changed.discard(self.tvClassMembers) self.setDataButtonState() + def sensitise_new_printer_widgets (self, sensitive=True): + sensitive = (sensitive and + self.printer and + not (self.printer.discovered or + bool (self.changed))) + for button in [self.btnChangePPD, + self.btnSelectDevice]: + button.set_sensitive (sensitive) + + def desensitise_new_printer_widgets (self): + self.sensitise_new_printer_widgets (False) + # change device def on_btnSelectDevice_clicked(self, button): busy (self.dialog) - self.newPrinterGUI.init("device", device_uri=self.printer.device_uri, - name=self.printer.name, - host=self._host, - encryption=self._encryption, - parent=self.dialog) + self.desensitise_new_printer_widgets () + if not self.newPrinterGUI.init("device", device_uri=self.printer.device_uri, + name=self.printer.name, + host=self._host, + encryption=self._encryption, + parent=self.dialog): + self.sensitise_new_printer_widgets () + ready (self.dialog) # change PPD def on_btnChangePPD_clicked(self, button): busy (self.dialog) - self.newPrinterGUI.init("ppd", device_uri=self.printer.device_uri, - ppd=self.ppd, - name=self.printer.name, - host=self._host, - encryption=self._encryption, - parent=self.dialog) + self.desensitise_new_printer_widgets () + if not self.newPrinterGUI.init("ppd", device_uri=self.printer.device_uri, + ppd=self.ppd, + name=self.printer.name, + host=self._host, + encryption=self._encryption, + parent=self.dialog): + self.sensitise_new_printer_widgets () + ready (self.dialog) # NewPrinterGUI signal handlers def on_printer_modified (self, obj, name, ppd_has_changed): debugprint ("on_printer_modified called") + self.sensitise_new_printer_widgets () if self.dialog.get_property ('visible') and self.printer: try: self.printer.getAttributes () @@ -1855,6 +1876,9 @@ class PrinterPropertiesDialog(GtkGUI): except cups.IPPError: pass + def on_printer_not_modified (self, obj): + self.sensitise_new_printer_widgets () + # Monitor signal handlers def on_printer_event (self, mon, printer, eventname, event): self.on_printer_modified (None, printer, False) diff -up system-config-printer-1.3.12/serversettings.py.FirewallD system-config-printer-1.3.12/serversettings.py --- system-config-printer-1.3.12/serversettings.py.FirewallD 2012-09-17 11:08:52.000000000 +0100 +++ system-config-printer-1.3.12/serversettings.py 2012-11-20 17:36:44.150167356 +0000 @@ -34,7 +34,7 @@ import time import authconn from debug import * from errordialogs import * -import firewall +import firewallsettings from gui import GtkGUI try: @@ -526,7 +526,10 @@ class ServerSettings(GtkGUI): try: if (self._host == 'localhost' or self._host[0] == '/'): - f = firewall.Firewall () + f = firewallsettings.FirewallD () + if not f.running(): + f = firewallsettings.SystemConfigFirewall () + allowed = f.check_ipp_server_allowed () else: # This is a remote server. Nothing we can do @@ -549,7 +552,7 @@ class ServerSettings(GtkGUI): dialog.destroy () if response == gtk.RESPONSE_YES: - f.add_rule (f.ALLOW_IPP_SERVER) + f.add_service (firewallsettings.IPP_SERVER_SERVICE) f.write () except (dbus.DBusException, Exception): nonfatalException () diff -up system-config-printer-1.3.12/system-config-printer.py.FirewallD system-config-printer-1.3.12/system-config-printer.py --- system-config-printer-1.3.12/system-config-printer.py.FirewallD 2012-09-18 17:00:14.000000000 +0100 +++ system-config-printer-1.3.12/system-config-printer.py 2012-11-20 17:36:44.150167356 +0000 @@ -2,7 +2,7 @@ ## system-config-printer -## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. +## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. ## Authors: ## Tim Waugh ## Florian Festi @@ -309,9 +309,9 @@ class GUI(GtkGUI): self.btnNew.connect ('clicked', self.on_new_printer_activate) self.toolbar.add (self.btnNew) self.toolbar.add (gtk.SeparatorToolItem ()) - refreshbutton = gtk.ToolButton (gtk.STOCK_REFRESH) - refreshbutton.connect ('clicked', self.on_btnRefresh_clicked) - self.toolbar.add (refreshbutton) + self.refreshbutton = gtk.ToolButton (gtk.STOCK_REFRESH) + self.refreshbutton.connect ('clicked', self.on_btnRefresh_clicked) + self.toolbar.add (self.refreshbutton) self.toolbar.show_all () server_context_menu = gtk.Menu () @@ -370,6 +370,7 @@ class GUI(GtkGUI): self.newPrinterGUI = np = newprinter.NewPrinterGUI() np.connect ("printer-added", self.on_new_printer_added) np.connect ("printer-modified", self.on_printer_modified) + np.connect ("dialog-canceled", self.on_new_printer_not_added) # Set up "About" dialog self.AboutDialog.set_program_name(config.PACKAGE) @@ -446,6 +447,8 @@ class GUI(GtkGUI): # Printer Properties dialog self.propertiesDlg = printerproperties.PrinterPropertiesDialog () + self.propertiesDlg.connect ("dialog-closed", + self.on_properties_dialog_closed) try: self.populateList() @@ -506,11 +509,13 @@ class GUI(GtkGUI): name = unicode (model.get_value (iter, 2)) object = model.get_value (iter, 0) + self.desensitise_main_window_widgets () try: self.propertiesDlg.show (name, host=self.connect_server, encryption=self.connect_encrypt, parent=self.PrintersWindow) except cups.IPPError, (e, m): + self.sensitise_main_window_widgets () show_IPP_Error (e, m, self.PrintersWindow) if e == cups.IPP_SERVICE_UNAVAILABLE: self.cups = None @@ -518,12 +523,16 @@ class GUI(GtkGUI): self.populateList () return except RuntimeError: + self.sensitise_main_window_widgets () # Perhaps cupsGetPPD2 failed for a browsed printer. # Check that we're still connected. self.monitor.update () return + def on_properties_dialog_closed (self, obj): + self.sensitise_main_window_widgets () + def dests_iconview_selection_changed (self, iconview): self.updating_widgets = True paths = iconview.get_selected_items () @@ -1708,6 +1717,34 @@ class GUI(GtkGUI): def on_troubleshoot_quit(self, troubleshooter): del self.troubleshooter + def sensitise_main_window_widgets (self, sensitive=True): + self.dests_iconview.set_sensitive (sensitive) + self.btnNew.set_sensitive (sensitive) + self.btnAddFirstPrinter.set_sensitive (sensitive) + self.refreshbutton.set_sensitive (sensitive) + self.view_discovered_printers.set_sensitive (sensitive) + self.search_entry.set_sensitive (sensitive) + for action in ["/connect-to-server", + "/server-settings", + "/new-printer", + "/new-class", + "/rename-printer", + "/duplicate-printer", + "/delete-printer", + "/set-default-printer", + "/edit-printer", + "/create-class", + "/enable-printer", + "/share-printer", + "/filter-name", + "/filter-description", + "/filter-location", + "/filter-manufacturer"]: + self.ui_manager.get_action (action).set_sensitive (sensitive) + + def desensitise_main_window_widgets (self): + self.sensitise_main_window_widgets (False) + # About dialog def on_about_activate(self, widget): self.AboutDialog.set_transient_for (self.PrintersWindow) @@ -1728,26 +1765,44 @@ class GUI(GtkGUI): # == New Printer Dialog ============================================== # ==================================================================== + def sensitise_new_printer_widgets(self, sensitive=True): + self.btnNew.set_sensitive (sensitive) + self.btnAddFirstPrinter.set_sensitive (sensitive) + self.ui_manager.get_action ("/new-printer").set_sensitive (sensitive) + self.ui_manager.get_action ("/new-class").set_sensitive (sensitive) + + def desensitise_new_printer_widgets(self): + self.sensitise_new_printer_widgets (False) + # new printer def on_new_printer_activate(self, widget): busy (self.PrintersWindow) + self.desensitise_new_printer_widgets () if not self.newPrinterGUI.init("printer", host=self.connect_server, encryption=self.connect_encrypt, parent=self.PrintersWindow): + self.sensitise_new_printer_widgets () self.monitor.update () ready (self.PrintersWindow) # new class def on_new_class_activate(self, widget): + self.desensitise_new_printer_widgets () if not self.newPrinterGUI.init("class", host=self.connect_server, encryption=self.connect_encrypt, parent=self.PrintersWindow): + self.sensitise_new_printer_widgets () self.monitor.update () + def on_new_printer_not_added (self, obj): + self.sensitise_new_printer_widgets () + def on_new_printer_added (self, obj, name): debugprint ("New printer added: %s" % name) + + self.sensitise_new_printer_widgets () self.populateList () if not self.printers.has_key (name): diff -up system-config-printer-1.3.12/ui/NewPrinterWindow.ui.FirewallD system-config-printer-1.3.12/ui/NewPrinterWindow.ui --- system-config-printer-1.3.12/ui/NewPrinterWindow.ui.FirewallD 2012-09-17 11:08:52.000000000 +0100 +++ system-config-printer-1.3.12/ui/NewPrinterWindow.ui 2012-11-20 17:36:44.151167360 +0000 @@ -4,7 +4,7 @@ False New Printer - True + False center-on-parent 600 420 diff -up system-config-printer-1.3.12/ui/PrinterPropertiesDialog.ui.FirewallD system-config-printer-1.3.12/ui/PrinterPropertiesDialog.ui --- system-config-printer-1.3.12/ui/PrinterPropertiesDialog.ui.FirewallD 2012-08-08 13:05:21.000000000 +0100 +++ system-config-printer-1.3.12/ui/PrinterPropertiesDialog.ui 2012-11-20 17:36:44.152167364 +0000 @@ -89,7 +89,7 @@ Printer Properties - True + False center-on-parent dialog