212 lines
7.6 KiB
Python
212 lines
7.6 KiB
Python
# statusPage.py - show selinux status
|
|
## Copyright (C) 2006-2009 Red Hat, Inc.
|
|
|
|
## This program is free software; you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation; either version 2 of the License, or
|
|
## (at your option) any later version.
|
|
|
|
## This program is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with this program; if not, write to the Free Software
|
|
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
## Author: Dan Walsh
|
|
import os
|
|
import sys
|
|
from gi.repository import Gtk
|
|
import selinux
|
|
|
|
INSTALLPATH = '/usr/share/system-config-selinux'
|
|
sys.path.append(INSTALLPATH)
|
|
|
|
ENFORCING = 1
|
|
PERMISSIVE = 0
|
|
DISABLED = -1
|
|
modearray = ("disabled", "permissive", "enforcing")
|
|
|
|
SELINUXDIR = "/etc/selinux/"
|
|
RELABELFILE = "/.autorelabel"
|
|
|
|
##
|
|
## I18N
|
|
##
|
|
PROGNAME = "selinux-gui"
|
|
try:
|
|
import gettext
|
|
kwargs = {}
|
|
if sys.version_info < (3,):
|
|
kwargs['unicode'] = True
|
|
t = gettext.translation(PROGNAME,
|
|
localedir="/usr/share/locale",
|
|
**kwargs,
|
|
fallback=True)
|
|
_ = t.gettext
|
|
except:
|
|
try:
|
|
import builtins
|
|
builtins.__dict__['_'] = str
|
|
except ImportError:
|
|
import __builtin__
|
|
__builtin__.__dict__['_'] = unicode
|
|
|
|
|
|
class statusPage:
|
|
|
|
def __init__(self, xml):
|
|
self.xml = xml
|
|
self.needRelabel = False
|
|
|
|
self.type = selinux.selinux_getpolicytype()
|
|
# Bring in widgets from glade file.
|
|
self.selinuxTypeOptionMenu = xml.get_object("selinuxTypeOptionMenu")
|
|
self.typeLabel = xml.get_object("typeLabel")
|
|
self.enabledOptionMenu = xml.get_object("enabledOptionMenu")
|
|
self.currentOptionMenu = xml.get_object("currentOptionMenu")
|
|
self.relabel_checkbutton = xml.get_object("relabelCheckbutton")
|
|
self.relabel_checkbutton.set_active(self.is_relabel())
|
|
self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle)
|
|
if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE:
|
|
self.currentOptionMenu.append_text(_("Permissive"))
|
|
self.currentOptionMenu.append_text(_("Enforcing"))
|
|
self.currentOptionMenu.set_active(self.get_current_mode())
|
|
self.currentOptionMenu.connect("changed", self.set_current_mode)
|
|
self.currentOptionMenu.set_sensitive(True)
|
|
else:
|
|
self.currentOptionMenu.append_text(_("Disabled"))
|
|
self.currentOptionMenu.set_active(0)
|
|
self.currentOptionMenu.set_sensitive(False)
|
|
|
|
if self.read_selinux_config() is None:
|
|
self.selinuxsupport = False
|
|
else:
|
|
self.enabledOptionMenu.connect("changed", self.enabled_changed)
|
|
#
|
|
# This line must come after read_selinux_config
|
|
#
|
|
self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed)
|
|
|
|
self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu)
|
|
|
|
def use_menus(self):
|
|
return False
|
|
|
|
def get_description(self):
|
|
return _("Status")
|
|
|
|
def get_current_mode(self):
|
|
if selinux.is_selinux_enabled():
|
|
if selinux.security_getenforce() > 0:
|
|
return ENFORCING
|
|
else:
|
|
return PERMISSIVE
|
|
else:
|
|
return DISABLED
|
|
|
|
def set_current_mode(self, menu):
|
|
selinux.security_setenforce(menu.get_active() == 1)
|
|
|
|
def is_relabel(self):
|
|
return os.access(RELABELFILE, os.F_OK) != 0
|
|
|
|
def on_relabel_toggle(self, button):
|
|
if button.get_active():
|
|
fd = open(RELABELFILE, "w")
|
|
fd.close()
|
|
else:
|
|
if os.access(RELABELFILE, os.F_OK) != 0:
|
|
os.unlink(RELABELFILE)
|
|
|
|
def verify(self, message):
|
|
dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
|
|
Gtk.ButtonsType.YES_NO,
|
|
message)
|
|
dlg.set_position(Gtk.WindowPosition.MOUSE)
|
|
dlg.show_all()
|
|
rc = dlg.run()
|
|
dlg.destroy()
|
|
return rc
|
|
|
|
def typemenu_changed(self, menu):
|
|
type = self.get_type()
|
|
enabled = self.enabledOptionMenu.get_active()
|
|
if self.initialtype != type:
|
|
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:
|
|
menu.set_active(self.typeHistory)
|
|
return None
|
|
|
|
self.relabel_checkbutton.set_active(True)
|
|
|
|
self.write_selinux_config(modearray[enabled], type)
|
|
self.typeHistory = menu.get_active()
|
|
|
|
def enabled_changed(self, combo):
|
|
enabled = combo.get_active()
|
|
type = self.get_type()
|
|
|
|
if self.initEnabled != DISABLED and enabled == DISABLED:
|
|
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:
|
|
combo.set_active(self.enabled)
|
|
return None
|
|
|
|
if self.initEnabled == DISABLED and enabled < 2:
|
|
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:
|
|
combo.set_active(self.enabled)
|
|
return None
|
|
self.relabel_checkbutton.set_active(True)
|
|
|
|
self.write_selinux_config(modearray[enabled], type)
|
|
self.enabled = enabled
|
|
|
|
def write_selinux_config(self, enforcing, type):
|
|
path = selinux.selinux_path() + "config"
|
|
backup_path = path + ".bck"
|
|
fd = open(path)
|
|
lines = fd.readlines()
|
|
fd.close()
|
|
fd = open(backup_path, "w")
|
|
for l in lines:
|
|
if l.startswith("SELINUX="):
|
|
fd.write("SELINUX=%s\n" % enforcing)
|
|
continue
|
|
if l.startswith("SELINUXTYPE="):
|
|
fd.write("SELINUXTYPE=%s\n" % type)
|
|
continue
|
|
fd.write(l)
|
|
fd.close()
|
|
os.rename(backup_path, path)
|
|
|
|
def read_selinux_config(self):
|
|
self.initialtype = selinux.selinux_getpolicytype()[1]
|
|
try:
|
|
self.initEnabled = selinux.selinux_getenforcemode()[1]
|
|
except:
|
|
self.initEnabled = False
|
|
pass
|
|
self.enabled = self.initEnabled
|
|
self.enabledOptionMenu.set_active(self.enabled + 1)
|
|
|
|
self.types = []
|
|
|
|
n = 0
|
|
current = n
|
|
|
|
for i in os.listdir(SELINUXDIR):
|
|
if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"):
|
|
self.types.append(i)
|
|
self.selinuxTypeOptionMenu.append_text(i)
|
|
if i == self.initialtype:
|
|
current = n
|
|
n = n + 1
|
|
self.selinuxTypeOptionMenu.set_active(current)
|
|
self.typeHistory = current
|
|
|
|
return 0
|
|
|
|
def get_type(self):
|
|
return self.types[self.selinuxTypeOptionMenu.get_active()]
|