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