1*2d543d20SAndroid Build Coastguard Worker# statusPage.py - show selinux status 2*2d543d20SAndroid Build Coastguard Worker## Copyright (C) 2006-2009 Red Hat, Inc. 3*2d543d20SAndroid Build Coastguard Worker 4*2d543d20SAndroid Build Coastguard Worker## This program is free software; you can redistribute it and/or modify 5*2d543d20SAndroid Build Coastguard Worker## it under the terms of the GNU General Public License as published by 6*2d543d20SAndroid Build Coastguard Worker## the Free Software Foundation; either version 2 of the License, or 7*2d543d20SAndroid Build Coastguard Worker## (at your option) any later version. 8*2d543d20SAndroid Build Coastguard Worker 9*2d543d20SAndroid Build Coastguard Worker## This program is distributed in the hope that it will be useful, 10*2d543d20SAndroid Build Coastguard Worker## but WITHOUT ANY WARRANTY; without even the implied warranty of 11*2d543d20SAndroid Build Coastguard Worker## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*2d543d20SAndroid Build Coastguard Worker## GNU General Public License for more details. 13*2d543d20SAndroid Build Coastguard Worker 14*2d543d20SAndroid Build Coastguard Worker## You should have received a copy of the GNU General Public License 15*2d543d20SAndroid Build Coastguard Worker## along with this program; if not, write to the Free Software 16*2d543d20SAndroid Build Coastguard Worker## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17*2d543d20SAndroid Build Coastguard Worker 18*2d543d20SAndroid Build Coastguard Worker## Author: Dan Walsh 19*2d543d20SAndroid Build Coastguard Workerimport os 20*2d543d20SAndroid Build Coastguard Workerimport sys 21*2d543d20SAndroid Build Coastguard Workerfrom gi.repository import Gtk 22*2d543d20SAndroid Build Coastguard Workerimport selinux 23*2d543d20SAndroid Build Coastguard Worker 24*2d543d20SAndroid Build Coastguard WorkerINSTALLPATH = '/usr/share/system-config-selinux' 25*2d543d20SAndroid Build Coastguard Workersys.path.append(INSTALLPATH) 26*2d543d20SAndroid Build Coastguard Worker 27*2d543d20SAndroid Build Coastguard WorkerENFORCING = 1 28*2d543d20SAndroid Build Coastguard WorkerPERMISSIVE = 0 29*2d543d20SAndroid Build Coastguard WorkerDISABLED = -1 30*2d543d20SAndroid Build Coastguard Workermodearray = ("disabled", "permissive", "enforcing") 31*2d543d20SAndroid Build Coastguard Worker 32*2d543d20SAndroid Build Coastguard WorkerSELINUXDIR = "/etc/selinux/" 33*2d543d20SAndroid Build Coastguard WorkerRELABELFILE = "/.autorelabel" 34*2d543d20SAndroid Build Coastguard Worker 35*2d543d20SAndroid Build Coastguard Worker## 36*2d543d20SAndroid Build Coastguard Worker## I18N 37*2d543d20SAndroid Build Coastguard Worker## 38*2d543d20SAndroid Build Coastguard WorkerPROGNAME = "selinux-gui" 39*2d543d20SAndroid Build Coastguard Workertry: 40*2d543d20SAndroid Build Coastguard Worker import gettext 41*2d543d20SAndroid Build Coastguard Worker kwargs = {} 42*2d543d20SAndroid Build Coastguard Worker if sys.version_info < (3,): 43*2d543d20SAndroid Build Coastguard Worker kwargs['unicode'] = True 44*2d543d20SAndroid Build Coastguard Worker t = gettext.translation(PROGNAME, 45*2d543d20SAndroid Build Coastguard Worker localedir="/usr/share/locale", 46*2d543d20SAndroid Build Coastguard Worker **kwargs, 47*2d543d20SAndroid Build Coastguard Worker fallback=True) 48*2d543d20SAndroid Build Coastguard Worker _ = t.gettext 49*2d543d20SAndroid Build Coastguard Workerexcept: 50*2d543d20SAndroid Build Coastguard Worker try: 51*2d543d20SAndroid Build Coastguard Worker import builtins 52*2d543d20SAndroid Build Coastguard Worker builtins.__dict__['_'] = str 53*2d543d20SAndroid Build Coastguard Worker except ImportError: 54*2d543d20SAndroid Build Coastguard Worker import __builtin__ 55*2d543d20SAndroid Build Coastguard Worker __builtin__.__dict__['_'] = unicode 56*2d543d20SAndroid Build Coastguard Worker 57*2d543d20SAndroid Build Coastguard Worker 58*2d543d20SAndroid Build Coastguard Workerclass statusPage: 59*2d543d20SAndroid Build Coastguard Worker 60*2d543d20SAndroid Build Coastguard Worker def __init__(self, xml): 61*2d543d20SAndroid Build Coastguard Worker self.xml = xml 62*2d543d20SAndroid Build Coastguard Worker self.needRelabel = False 63*2d543d20SAndroid Build Coastguard Worker 64*2d543d20SAndroid Build Coastguard Worker self.type = selinux.selinux_getpolicytype() 65*2d543d20SAndroid Build Coastguard Worker # Bring in widgets from glade file. 66*2d543d20SAndroid Build Coastguard Worker self.selinuxTypeOptionMenu = xml.get_object("selinuxTypeOptionMenu") 67*2d543d20SAndroid Build Coastguard Worker self.typeLabel = xml.get_object("typeLabel") 68*2d543d20SAndroid Build Coastguard Worker self.enabledOptionMenu = xml.get_object("enabledOptionMenu") 69*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu = xml.get_object("currentOptionMenu") 70*2d543d20SAndroid Build Coastguard Worker self.relabel_checkbutton = xml.get_object("relabelCheckbutton") 71*2d543d20SAndroid Build Coastguard Worker self.relabel_checkbutton.set_active(self.is_relabel()) 72*2d543d20SAndroid Build Coastguard Worker self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle) 73*2d543d20SAndroid Build Coastguard Worker if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE: 74*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.append_text(_("Permissive")) 75*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.append_text(_("Enforcing")) 76*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.set_active(self.get_current_mode()) 77*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.connect("changed", self.set_current_mode) 78*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.set_sensitive(True) 79*2d543d20SAndroid Build Coastguard Worker else: 80*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.append_text(_("Disabled")) 81*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.set_active(0) 82*2d543d20SAndroid Build Coastguard Worker self.currentOptionMenu.set_sensitive(False) 83*2d543d20SAndroid Build Coastguard Worker 84*2d543d20SAndroid Build Coastguard Worker if self.read_selinux_config() is None: 85*2d543d20SAndroid Build Coastguard Worker self.selinuxsupport = False 86*2d543d20SAndroid Build Coastguard Worker else: 87*2d543d20SAndroid Build Coastguard Worker self.enabledOptionMenu.connect("changed", self.enabled_changed) 88*2d543d20SAndroid Build Coastguard Worker # 89*2d543d20SAndroid Build Coastguard Worker # This line must come after read_selinux_config 90*2d543d20SAndroid Build Coastguard Worker # 91*2d543d20SAndroid Build Coastguard Worker self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed) 92*2d543d20SAndroid Build Coastguard Worker 93*2d543d20SAndroid Build Coastguard Worker self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu) 94*2d543d20SAndroid Build Coastguard Worker 95*2d543d20SAndroid Build Coastguard Worker def use_menus(self): 96*2d543d20SAndroid Build Coastguard Worker return False 97*2d543d20SAndroid Build Coastguard Worker 98*2d543d20SAndroid Build Coastguard Worker def get_description(self): 99*2d543d20SAndroid Build Coastguard Worker return _("Status") 100*2d543d20SAndroid Build Coastguard Worker 101*2d543d20SAndroid Build Coastguard Worker def get_current_mode(self): 102*2d543d20SAndroid Build Coastguard Worker if selinux.is_selinux_enabled(): 103*2d543d20SAndroid Build Coastguard Worker if selinux.security_getenforce() > 0: 104*2d543d20SAndroid Build Coastguard Worker return ENFORCING 105*2d543d20SAndroid Build Coastguard Worker else: 106*2d543d20SAndroid Build Coastguard Worker return PERMISSIVE 107*2d543d20SAndroid Build Coastguard Worker else: 108*2d543d20SAndroid Build Coastguard Worker return DISABLED 109*2d543d20SAndroid Build Coastguard Worker 110*2d543d20SAndroid Build Coastguard Worker def set_current_mode(self, menu): 111*2d543d20SAndroid Build Coastguard Worker selinux.security_setenforce(menu.get_active() == 1) 112*2d543d20SAndroid Build Coastguard Worker 113*2d543d20SAndroid Build Coastguard Worker def is_relabel(self): 114*2d543d20SAndroid Build Coastguard Worker return os.access(RELABELFILE, os.F_OK) != 0 115*2d543d20SAndroid Build Coastguard Worker 116*2d543d20SAndroid Build Coastguard Worker def on_relabel_toggle(self, button): 117*2d543d20SAndroid Build Coastguard Worker if button.get_active(): 118*2d543d20SAndroid Build Coastguard Worker fd = open(RELABELFILE, "w") 119*2d543d20SAndroid Build Coastguard Worker fd.close() 120*2d543d20SAndroid Build Coastguard Worker else: 121*2d543d20SAndroid Build Coastguard Worker if os.access(RELABELFILE, os.F_OK) != 0: 122*2d543d20SAndroid Build Coastguard Worker os.unlink(RELABELFILE) 123*2d543d20SAndroid Build Coastguard Worker 124*2d543d20SAndroid Build Coastguard Worker def verify(self, message): 125*2d543d20SAndroid Build Coastguard Worker dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, 126*2d543d20SAndroid Build Coastguard Worker Gtk.ButtonsType.YES_NO, 127*2d543d20SAndroid Build Coastguard Worker message) 128*2d543d20SAndroid Build Coastguard Worker dlg.set_position(Gtk.WindowPosition.MOUSE) 129*2d543d20SAndroid Build Coastguard Worker dlg.show_all() 130*2d543d20SAndroid Build Coastguard Worker rc = dlg.run() 131*2d543d20SAndroid Build Coastguard Worker dlg.destroy() 132*2d543d20SAndroid Build Coastguard Worker return rc 133*2d543d20SAndroid Build Coastguard Worker 134*2d543d20SAndroid Build Coastguard Worker def typemenu_changed(self, menu): 135*2d543d20SAndroid Build Coastguard Worker type = self.get_type() 136*2d543d20SAndroid Build Coastguard Worker enabled = self.enabledOptionMenu.get_active() 137*2d543d20SAndroid Build Coastguard Worker if self.initialtype != type: 138*2d543d20SAndroid Build Coastguard Worker if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: 139*2d543d20SAndroid Build Coastguard Worker menu.set_active(self.typeHistory) 140*2d543d20SAndroid Build Coastguard Worker return None 141*2d543d20SAndroid Build Coastguard Worker 142*2d543d20SAndroid Build Coastguard Worker self.relabel_checkbutton.set_active(True) 143*2d543d20SAndroid Build Coastguard Worker 144*2d543d20SAndroid Build Coastguard Worker self.write_selinux_config(modearray[enabled], type) 145*2d543d20SAndroid Build Coastguard Worker self.typeHistory = menu.get_active() 146*2d543d20SAndroid Build Coastguard Worker 147*2d543d20SAndroid Build Coastguard Worker def enabled_changed(self, combo): 148*2d543d20SAndroid Build Coastguard Worker enabled = combo.get_active() 149*2d543d20SAndroid Build Coastguard Worker type = self.get_type() 150*2d543d20SAndroid Build Coastguard Worker 151*2d543d20SAndroid Build Coastguard Worker if self.initEnabled != DISABLED and enabled == DISABLED: 152*2d543d20SAndroid Build Coastguard Worker if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == Gtk.ResponseType.NO: 153*2d543d20SAndroid Build Coastguard Worker combo.set_active(self.enabled) 154*2d543d20SAndroid Build Coastguard Worker return None 155*2d543d20SAndroid Build Coastguard Worker 156*2d543d20SAndroid Build Coastguard Worker if self.initEnabled == DISABLED and enabled < 2: 157*2d543d20SAndroid Build Coastguard Worker if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: 158*2d543d20SAndroid Build Coastguard Worker combo.set_active(self.enabled) 159*2d543d20SAndroid Build Coastguard Worker return None 160*2d543d20SAndroid Build Coastguard Worker self.relabel_checkbutton.set_active(True) 161*2d543d20SAndroid Build Coastguard Worker 162*2d543d20SAndroid Build Coastguard Worker self.write_selinux_config(modearray[enabled], type) 163*2d543d20SAndroid Build Coastguard Worker self.enabled = enabled 164*2d543d20SAndroid Build Coastguard Worker 165*2d543d20SAndroid Build Coastguard Worker def write_selinux_config(self, enforcing, type): 166*2d543d20SAndroid Build Coastguard Worker path = selinux.selinux_path() + "config" 167*2d543d20SAndroid Build Coastguard Worker backup_path = path + ".bck" 168*2d543d20SAndroid Build Coastguard Worker fd = open(path) 169*2d543d20SAndroid Build Coastguard Worker lines = fd.readlines() 170*2d543d20SAndroid Build Coastguard Worker fd.close() 171*2d543d20SAndroid Build Coastguard Worker fd = open(backup_path, "w") 172*2d543d20SAndroid Build Coastguard Worker for l in lines: 173*2d543d20SAndroid Build Coastguard Worker if l.startswith("SELINUX="): 174*2d543d20SAndroid Build Coastguard Worker fd.write("SELINUX=%s\n" % enforcing) 175*2d543d20SAndroid Build Coastguard Worker continue 176*2d543d20SAndroid Build Coastguard Worker if l.startswith("SELINUXTYPE="): 177*2d543d20SAndroid Build Coastguard Worker fd.write("SELINUXTYPE=%s\n" % type) 178*2d543d20SAndroid Build Coastguard Worker continue 179*2d543d20SAndroid Build Coastguard Worker fd.write(l) 180*2d543d20SAndroid Build Coastguard Worker fd.close() 181*2d543d20SAndroid Build Coastguard Worker os.rename(backup_path, path) 182*2d543d20SAndroid Build Coastguard Worker 183*2d543d20SAndroid Build Coastguard Worker def read_selinux_config(self): 184*2d543d20SAndroid Build Coastguard Worker self.initialtype = selinux.selinux_getpolicytype()[1] 185*2d543d20SAndroid Build Coastguard Worker try: 186*2d543d20SAndroid Build Coastguard Worker self.initEnabled = selinux.selinux_getenforcemode()[1] 187*2d543d20SAndroid Build Coastguard Worker except: 188*2d543d20SAndroid Build Coastguard Worker self.initEnabled = False 189*2d543d20SAndroid Build Coastguard Worker pass 190*2d543d20SAndroid Build Coastguard Worker self.enabled = self.initEnabled 191*2d543d20SAndroid Build Coastguard Worker self.enabledOptionMenu.set_active(self.enabled + 1) 192*2d543d20SAndroid Build Coastguard Worker 193*2d543d20SAndroid Build Coastguard Worker self.types = [] 194*2d543d20SAndroid Build Coastguard Worker 195*2d543d20SAndroid Build Coastguard Worker n = 0 196*2d543d20SAndroid Build Coastguard Worker current = n 197*2d543d20SAndroid Build Coastguard Worker 198*2d543d20SAndroid Build Coastguard Worker for i in os.listdir(SELINUXDIR): 199*2d543d20SAndroid Build Coastguard Worker if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"): 200*2d543d20SAndroid Build Coastguard Worker self.types.append(i) 201*2d543d20SAndroid Build Coastguard Worker self.selinuxTypeOptionMenu.append_text(i) 202*2d543d20SAndroid Build Coastguard Worker if i == self.initialtype: 203*2d543d20SAndroid Build Coastguard Worker current = n 204*2d543d20SAndroid Build Coastguard Worker n = n + 1 205*2d543d20SAndroid Build Coastguard Worker self.selinuxTypeOptionMenu.set_active(current) 206*2d543d20SAndroid Build Coastguard Worker self.typeHistory = current 207*2d543d20SAndroid Build Coastguard Worker 208*2d543d20SAndroid Build Coastguard Worker return 0 209*2d543d20SAndroid Build Coastguard Worker 210*2d543d20SAndroid Build Coastguard Worker def get_type(self): 211*2d543d20SAndroid Build Coastguard Worker return self.types[self.selinuxTypeOptionMenu.get_active()] 212