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 string 22 import gtk 23 import gtk.glade 24 import os 25 import gobject 26 import sys 27 import tempfile 28 import seobject 29 import semanagePage 30 31 INSTALLPATH = '/usr/share/system-config-selinux' 32 sys.path.append(INSTALLPATH) 33 34 import commands 35 ENFORCING = 0 36 PERMISSIVE = 1 37 DISABLED = 2 38 39 ## 40 ## I18N 41 ## 42 PROGNAME = "policycoreutils" 43 44 import gettext 45 gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 46 gettext.textdomain(PROGNAME) 47 try: 48 gettext.install(PROGNAME, 49 localedir="/usr/share/locale", 50 unicode=False, 51 codeset='utf-8') 52 except IOError: 53 import __builtin__ 54 __builtin__.__dict__['_'] = unicode 55 56 from glob import fnmatch 57 58 59 class Modifier: 60 61 def __init__(self, name, on, save): 62 self.on = on 63 self.name = name 64 self.save = save 65 66 def set(self, value): 67 self.on = value 68 self.save = True 69 70 def isOn(self): 71 return self.on 72 73 74 class Boolean(Modifier): 75 76 def __init__(self, name, val, save=False): 77 Modifier.__init__(self, name, val, save) 78 79 ACTIVE = 0 80 MODULE = 1 81 DESC = 2 82 BOOLEAN = 3 83 84 85 class booleansPage: 86 87 def __init__(self, xml, doDebug=None): 88 self.xml = xml 89 self.window = self.xml.get_widget("mainWindow").get_root_window() 90 self.local = False 91 self.types = [] 92 self.selinuxsupport = True 93 self.typechanged = False 94 self.doDebug = doDebug 95 self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) 96 self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) 97 98 # Bring in widgets from glade file. 99 self.typeHBox = xml.get_widget("typeHBox") 100 self.booleanSW = xml.get_widget("booleanSW") 101 self.booleansFilter = xml.get_widget("booleansFilter") 102 self.booleansFilter.connect("focus_out_event", self.filter_changed) 103 self.booleansFilter.connect("activate", self.filter_changed) 104 105 self.booleansView = xml.get_widget("booleansView") 106 self.typeLabel = xml.get_widget("typeLabel") 107 self.modifySeparator = xml.get_widget("modifySeparator") 108 109 self.revertButton = xml.get_widget("booleanRevertButton") 110 self.revertButton.set_sensitive(self.local) 111 self.revertButton.connect("clicked", self.on_revert_clicked) 112 listStore = gtk.ListStore(gobject.TYPE_STRING) 113 cell = gtk.CellRendererText() 114 115 self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) 116 self.store.set_sort_column_id(1, gtk.SORT_ASCENDING) 117 self.booleansView.set_model(self.store) 118 119 checkbox = gtk.CellRendererToggle() 120 checkbox.connect("toggled", self.boolean_toggled) 121 col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE) 122 col.set_clickable(True) 123 col.set_sort_column_id(ACTIVE) 124 self.booleansView.append_column(col) 125 126 col = gtk.TreeViewColumn("Module", gtk.CellRendererText(), text=MODULE) 127 col.set_sort_column_id(MODULE) 128 col.set_resizable(True) 129 self.booleansView.append_column(col) 130 131 col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC) 132 col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 133 col.set_fixed_width(400) 134 col.set_sort_column_id(DESC) 135 col.set_resizable(True) 136 self.booleansView.append_column(col) 137 138 col = gtk.TreeViewColumn("Name", gtk.CellRendererText(), text=BOOLEAN) 139 col.set_sort_column_id(BOOLEAN) 140 col.set_resizable(True) 141 self.booleansView.set_search_equal_func(self.__search) 142 self.booleansView.append_column(col) 143 self.filter = "" 144 self.load(self.filter) 145 146 def error(self, message): 147 dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, 148 gtk.BUTTONS_CLOSE, 149 message) 150 dlg.set_position(gtk.WIN_POS_MOUSE) 151 dlg.show_all() 152 dlg.run() 153 dlg.destroy() 154 155 def __search(self, model, col, key, i): 156 sort_col = self.store.get_sort_column_id()[0] 157 if sort_col > 0: 158 val = model.get_value(i, sort_col) 159 if val.lower().startswith(key.lower()): 160 return False 161 return True 162 163 def wait(self): 164 self.window.set_cursor(self.busy_cursor) 165 semanagePage.idle_func() 166 167 def ready(self): 168 self.window.set_cursor(self.ready_cursor) 169 semanagePage.idle_func() 170 171 def deleteDialog(self): 172 store, iter = self.booleansView.get_selection().get_selected() 173 if iter == None: 174 return 175 boolean = store.get_value(iter, BOOLEAN) 176 # change cursor 177 if boolean == None: 178 return 179 try: 180 self.wait() 181 (rc, out) = commands.getstatusoutput("semanage boolean -d %s" % boolean) 182 183 self.ready() 184 if rc != 0: 185 return self.error(out) 186 self.load(self.filter) 187 except ValueError, e: 188 self.error(e.args[0]) 189 190 def filter_changed(self, *arg): 191 filter = arg[0].get_text() 192 if filter != self.filter: 193 self.load(filter) 194 self.filter = filter 195 196 def use_menus(self): 197 return False 198 199 def get_description(self): 200 return _("Boolean") 201 202 def match(self, key, filter=""): 203 try: 204 f = filter.lower() 205 cat = self.booleans.get_category(key).lower() 206 val = self.booleans.get_desc(key).lower() 207 k = key.lower() 208 return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0 209 except: 210 return False 211 212 def load(self, filter=None): 213 self.store.clear() 214 self.booleans = seobject.booleanRecords() 215 booleansList = self.booleans.get_all(self.local) 216 for name in booleansList: 217 rec = booleansList[name] 218 if self.match(name, filter): 219 iter = self.store.append() 220 self.store.set_value(iter, ACTIVE, rec[2] == 1) 221 self.store.set_value(iter, MODULE, self.booleans.get_category(name)) 222 self.store.set_value(iter, DESC, self.booleans.get_desc(name)) 223 self.store.set_value(iter, BOOLEAN, name) 224 225 def boolean_toggled(self, widget, row): 226 iter = self.store.get_iter(row) 227 val = self.store.get_value(iter, ACTIVE) 228 key = self.store.get_value(iter, BOOLEAN) 229 self.store.set_value(iter, ACTIVE, not val) 230 self.wait() 231 setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val) 232 rc, out = commands.getstatusoutput(setsebool) 233 if rc != 0: 234 self.error(out) 235 self.load(self.filter) 236 self.ready() 237 238 def on_revert_clicked(self, button): 239 self.wait() 240 setsebool = "semanage boolean --deleteall" 241 commands.getstatusoutput(setsebool) 242 self.load(self.filter) 243 self.ready() 244 245 def on_local_clicked(self, button): 246 self.local = not self.local 247 self.revertButton.set_sensitive(self.local) 248 249 if self.local: 250 button.set_label(_("all")) 251 else: 252 button.set_label(_("Customized")) 253 254 self.load(self.filter) 255 return True 256