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