Home | History | Annotate | Download | only in gui
      1 #
      2 # booleansPage.py - GUI for Booleans page in system-config-securitylevel
      3 #
      4 # Dan Walsh <dwalsh (at] redhat.com>
      5 #
      6 # Copyright 2006, 2007 Red Hat, Inc.
      7 #
      8 # This program is free software; you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation; either version 2 of the License, or
     11 # (at your option) any later version.
     12 #
     13 # This program is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 #
     18 # You should have received a copy of the GNU General Public License
     19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     20 #
     21 import sys
     22 from gi.repository import Gdk, GObject, Gtk
     23 import seobject
     24 import semanagePage
     25 
     26 INSTALLPATH = '/usr/share/system-config-selinux'
     27 sys.path.append(INSTALLPATH)
     28 
     29 try:
     30     from subprocess import getstatusoutput
     31 except ImportError:
     32     from commands import getstatusoutput
     33 
     34 ENFORCING = 0
     35 PERMISSIVE = 1
     36 DISABLED = 2
     37 
     38 ##
     39 ## I18N
     40 ##
     41 PROGNAME = "policycoreutils"
     42 try:
     43     import gettext
     44     kwargs = {}
     45     if sys.version_info < (3,):
     46         kwargs['unicode'] = True
     47     gettext.install(PROGNAME,
     48                     localedir="/usr/share/locale",
     49                     codeset='utf-8',
     50                     **kwargs)
     51 except:
     52     try:
     53         import builtins
     54         builtins.__dict__['_'] = str
     55     except ImportError:
     56         import __builtin__
     57         __builtin__.__dict__['_'] = unicode
     58 
     59 
     60 class Modifier:
     61 
     62     def __init__(self, name, on, save):
     63         self.on = on
     64         self.name = name
     65         self.save = save
     66 
     67     def set(self, value):
     68         self.on = value
     69         self.save = True
     70 
     71     def isOn(self):
     72         return self.on
     73 
     74 
     75 class Boolean(Modifier):
     76 
     77     def __init__(self, name, val, save=False):
     78         Modifier.__init__(self, name, val, save)
     79 
     80 ACTIVE = 0
     81 MODULE = 1
     82 DESC = 2
     83 BOOLEAN = 3
     84 
     85 
     86 class booleansPage:
     87 
     88     def __init__(self, xml, doDebug=None):
     89         self.xml = xml
     90         self.window = self.xml.get_object("mainWindow").get_root_window()
     91         self.local = False
     92         self.types = []
     93         self.selinuxsupport = True
     94         self.typechanged = False
     95         self.doDebug = doDebug
     96         self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)
     97         self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)
     98 
     99         # Bring in widgets from glade file.
    100         self.booleansFilter = xml.get_object("booleansFilter")
    101         self.booleansFilter.connect("focus_out_event", self.filter_changed)
    102         self.booleansFilter.connect("activate", self.filter_changed)
    103         self.booleansFilter.connect("changed", self.filter_changed)
    104 
    105         self.booleansView = xml.get_object("booleansView")
    106 
    107         self.revertButton = xml.get_object("booleanRevertButton")
    108         self.revertButton.set_sensitive(self.local)
    109         self.revertButton.connect("clicked", self.on_revert_clicked)
    110         listStore = Gtk.ListStore(GObject.TYPE_STRING)
    111         cell = Gtk.CellRendererText()
    112 
    113         self.store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
    114         self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING)
    115         self.booleansView.set_model(self.store)
    116 
    117         checkbox = Gtk.CellRendererToggle()
    118         checkbox.connect("toggled", self.boolean_toggled)
    119         col = Gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
    120         col.set_clickable(True)
    121         col.set_sort_column_id(ACTIVE)
    122         self.booleansView.append_column(col)
    123 
    124         col = Gtk.TreeViewColumn("Module", Gtk.CellRendererText(), text=MODULE)
    125         col.set_sort_column_id(MODULE)
    126         col.set_resizable(True)
    127         self.booleansView.append_column(col)
    128 
    129         col = Gtk.TreeViewColumn("Description", Gtk.CellRendererText(), text=DESC)
    130         col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
    131         col.set_fixed_width(400)
    132         col.set_sort_column_id(DESC)
    133         col.set_resizable(True)
    134         self.booleansView.append_column(col)
    135 
    136         col = Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=BOOLEAN)
    137         col.set_sort_column_id(BOOLEAN)
    138         col.set_resizable(True)
    139         self.booleansView.set_search_equal_func(self.__search)
    140         self.booleansView.append_column(col)
    141         self.filter = ""
    142         self.load(self.filter)
    143 
    144     def error(self, message):
    145         dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
    146                                 Gtk.ButtonsType.CLOSE,
    147                                 message)
    148         dlg.set_position(Gtk.WindowPosition.MOUSE)
    149         dlg.show_all()
    150         dlg.run()
    151         dlg.destroy()
    152 
    153     def __search(self, model, col, key, i):
    154         sort_col = self.store.get_sort_column_id()[0]
    155         if sort_col > 0:
    156             val = model.get_value(i, sort_col)
    157             if val.lower().startswith(key.lower()):
    158                 return False
    159         return True
    160 
    161     def wait(self):
    162         self.window.set_cursor(self.busy_cursor)
    163         semanagePage.idle_func()
    164 
    165     def ready(self):
    166         self.window.set_cursor(self.ready_cursor)
    167         semanagePage.idle_func()
    168 
    169     def deleteDialog(self):
    170         store, iter = self.booleansView.get_selection().get_selected()
    171         if iter is None:
    172             return
    173         boolean = store.get_value(iter, BOOLEAN)
    174         # change cursor
    175         if boolean is None:
    176             return
    177         try:
    178             self.wait()
    179             (rc, out) = getstatusoutput("semanage boolean -d %s" % boolean)
    180 
    181             self.ready()
    182             if rc != 0:
    183                 return self.error(out)
    184             self.load(self.filter)
    185         except ValueError as e:
    186             self.error(e.args[0])
    187 
    188     def filter_changed(self, *arg):
    189         filter = arg[0].get_text()
    190         if filter != self.filter:
    191             self.load(filter)
    192             self.filter = filter
    193 
    194     def use_menus(self):
    195         return False
    196 
    197     def get_description(self):
    198         return _("Boolean")
    199 
    200     def match(self, key, filter=""):
    201         try:
    202             f = filter.lower()
    203             cat = self.booleans.get_category(key).lower()
    204             val = self.booleans.get_desc(key).lower()
    205             k = key.lower()
    206             return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
    207         except:
    208             return False
    209 
    210     def load(self, filter=None):
    211         self.store.clear()
    212         self.booleans = seobject.booleanRecords()
    213         booleansList = self.booleans.get_all(self.local)
    214         for name in booleansList:
    215             rec = booleansList[name]
    216             if self.match(name, filter):
    217                 iter = self.store.append()
    218                 self.store.set_value(iter, ACTIVE, rec[2] == 1)
    219                 self.store.set_value(iter, MODULE, self.booleans.get_category(name))
    220                 self.store.set_value(iter, DESC, self.booleans.get_desc(name))
    221                 self.store.set_value(iter, BOOLEAN, name)
    222 
    223     def boolean_toggled(self, widget, row):
    224         iter = self.store.get_iter(row)
    225         val = self.store.get_value(iter, ACTIVE)
    226         key = self.store.get_value(iter, BOOLEAN)
    227         self.store.set_value(iter, ACTIVE, not val)
    228         self.wait()
    229         setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
    230         rc, out = getstatusoutput(setsebool)
    231         if rc != 0:
    232             self.error(out)
    233         self.load(self.filter)
    234         self.ready()
    235 
    236     def on_revert_clicked(self, button):
    237         self.wait()
    238         setsebool = "semanage boolean --deleteall"
    239         getstatusoutput(setsebool)
    240         self.load(self.filter)
    241         self.ready()
    242 
    243     def on_local_clicked(self, button):
    244         self.local = not self.local
    245         self.revertButton.set_sensitive(self.local)
    246 
    247         if self.local:
    248             button.set_label(_("all"))
    249         else:
    250             button.set_label(_("Customized"))
    251 
    252         self.load(self.filter)
    253         return True
    254