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