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