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