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 19 import string 20 import gtk 21 import gtk.glade 22 import os 23 import gobject 24 import sys 25 import tempfile 26 27 INSTALLPATH = '/usr/share/system-config-selinux' 28 sys.path.append(INSTALLPATH) 29 30 import commands 31 ENFORCING = 1 32 PERMISSIVE = 0 33 DISABLED = -1 34 modearray = ("disabled", "permissive", "enforcing") 35 36 SELINUXDIR = "/etc/selinux/" 37 RELABELFILE = "/.autorelabel" 38 39 ## 40 ## I18N 41 ## 42 PROGNAME = "policycoreutils" 43 import gettext 44 gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 45 gettext.textdomain(PROGNAME) 46 import selinux 47 try: 48 gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=1) 49 except IOError: 50 import __builtin__ 51 __builtin__.__dict__['_'] = unicode 52 53 54 class statusPage: 55 56 def __init__(self, xml): 57 self.xml = xml 58 self.needRelabel = False 59 60 self.type = selinux.selinux_getpolicytype() 61 # Bring in widgets from glade file. 62 self.typeHBox = xml.get_widget("typeHBox") 63 self.selinuxTypeOptionMenu = xml.get_widget("selinuxTypeOptionMenu") 64 self.typeLabel = xml.get_widget("typeLabel") 65 self.enabledOptionMenu = xml.get_widget("enabledOptionMenu") 66 self.currentOptionMenu = xml.get_widget("currentOptionMenu") 67 self.relabel_checkbutton = xml.get_widget("relabelCheckbutton") 68 self.relabel_checkbutton.set_active(self.is_relabel()) 69 self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle) 70 if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE: 71 self.currentOptionMenu.append_text(_("Permissive")) 72 self.currentOptionMenu.append_text(_("Enforcing")) 73 self.currentOptionMenu.set_active(self.get_current_mode()) 74 self.currentOptionMenu.connect("changed", self.set_current_mode) 75 self.currentOptionMenu.set_sensitive(True) 76 else: 77 self.currentOptionMenu.append_text(_("Disabled")) 78 self.currentOptionMenu.set_active(0) 79 self.currentOptionMenu.set_sensitive(False) 80 81 if self.read_selinux_config() == None: 82 self.selinuxsupport = False 83 else: 84 self.enabledOptionMenu.connect("changed", self.enabled_changed) 85 # 86 # This line must come after read_selinux_config 87 # 88 self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed) 89 90 self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu) 91 92 def use_menus(self): 93 return False 94 95 def get_description(self): 96 return _("Status") 97 98 def get_current_mode(self): 99 if selinux.is_selinux_enabled(): 100 if selinux.security_getenforce() > 0: 101 return ENFORCING 102 else: 103 return PERMISSIVE 104 else: 105 return DISABLED 106 107 def set_current_mode(self, menu): 108 selinux.security_setenforce(menu.get_active() == 1) 109 110 def is_relabel(self): 111 return os.access(RELABELFILE, os.F_OK) != 0 112 113 def on_relabel_toggle(self, button): 114 if button.get_active(): 115 fd = open(RELABELFILE, "w") 116 fd.close() 117 else: 118 if os.access(RELABELFILE, os.F_OK) != 0: 119 os.unlink(RELABELFILE) 120 121 def verify(self, message): 122 dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, 123 gtk.BUTTONS_YES_NO, 124 message) 125 dlg.set_position(gtk.WIN_POS_MOUSE) 126 dlg.show_all() 127 rc = dlg.run() 128 dlg.destroy() 129 return rc 130 131 def typemenu_changed(self, menu): 132 type = self.get_type() 133 enabled = self.enabledOptionMenu.get_active() 134 if self.initialtype != type: 135 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: 136 menu.set_active(self.typeHistory) 137 return None 138 139 self.relabel_checkbutton.set_active(True) 140 141 self.write_selinux_config(modearray[enabled], type) 142 self.typeHistory = menu.get_active() 143 144 def enabled_changed(self, combo): 145 enabled = combo.get_active() 146 type = self.get_type() 147 148 if self.initEnabled != DISABLED and enabled == DISABLED: 149 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: 150 combo.set_active(self.enabled) 151 return None 152 153 if self.initEnabled == DISABLED and enabled < 2: 154 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: 155 combo.set_active(self.enabled) 156 return None 157 self.relabel_checkbutton.set_active(True) 158 159 self.write_selinux_config(modearray[enabled], type) 160 self.enabled = enabled 161 162 def write_selinux_config(self, enforcing, type): 163 path = selinux.selinux_path() + "config" 164 backup_path = path + ".bck" 165 fd = open(path) 166 lines = fd.readlines() 167 fd.close() 168 fd = open(backup_path, "w") 169 for l in lines: 170 if l.startswith("SELINUX="): 171 fd.write("SELINUX=%s\n" % enforcing) 172 continue 173 if l.startswith("SELINUXTYPE="): 174 fd.write("SELINUXTYPE=%s\n" % type) 175 continue 176 fd.write(l) 177 fd.close() 178 os.rename(backup_path, path) 179 180 def read_selinux_config(self): 181 self.initialtype = selinux.selinux_getpolicytype()[1] 182 try: 183 self.initEnabled = selinux.selinux_getenforcemode()[1] 184 except: 185 self.initEnabled = False 186 pass 187 self.enabled = self.initEnabled 188 self.enabledOptionMenu.set_active(self.enabled + 1) 189 190 self.types = [] 191 192 n = 0 193 current = n 194 195 for i in os.listdir(SELINUXDIR): 196 if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"): 197 self.types.append(i) 198 self.selinuxTypeOptionMenu.append_text(i) 199 if i == self.initialtype: 200 current = n 201 n = n + 1 202 self.selinuxTypeOptionMenu.set_active(current) 203 self.typeHistory = current 204 205 return 0 206 207 def get_type(self): 208 return self.types[self.selinuxTypeOptionMenu.get_active()] 209