2012-04-13 17:04:45 +02:00
# 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
2017-09-20 08:56:54 +02:00
from gi . repository import Gtk
2016-08-04 20:34:02 +02:00
import selinux
2012-04-13 17:04:45 +02:00
INSTALLPATH = ' /usr/share/system-config-selinux '
sys . path . append ( INSTALLPATH )
ENFORCING = 1
PERMISSIVE = 0
DISABLED = - 1
2015-07-24 10:07:13 +02:00
modearray = ( " disabled " , " permissive " , " enforcing " )
2012-04-13 17:04:45 +02:00
SELINUXDIR = " /etc/selinux/ "
RELABELFILE = " /.autorelabel "
##
## I18N
##
2022-04-01 11:57:24 +02:00
PROGNAME = " selinux-gui "
2012-04-13 17:04:45 +02:00
try :
2016-08-04 20:34:02 +02:00
import gettext
kwargs = { }
if sys . version_info < ( 3 , ) :
kwargs [ ' unicode ' ] = True
2022-05-06 16:06:23 +02:00
t = gettext . translation ( PROGNAME ,
2016-08-04 20:34:02 +02:00
localedir = " /usr/share/locale " ,
2022-06-24 16:24:25 +02:00
* * kwargs ,
fallback = True )
2022-05-06 16:06:23 +02:00
_ = t . gettext
2016-08-04 20:34:02 +02:00
except :
try :
import builtins
builtins . __dict__ [ ' _ ' ] = str
except ImportError :
import __builtin__
__builtin__ . __dict__ [ ' _ ' ] = unicode
2012-04-13 17:04:45 +02:00
2015-07-24 10:07:13 +02:00
2012-04-13 17:04:45 +02:00
class statusPage :
2015-07-24 10:07:13 +02:00
2012-04-13 17:04:45 +02:00
def __init__ ( self , xml ) :
self . xml = xml
self . needRelabel = False
self . type = selinux . selinux_getpolicytype ( )
# Bring in widgets from glade file.
2017-09-20 08:56:54 +02:00
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 " )
2012-04-13 17:04:45 +02:00
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 :
2015-07-24 10:07:13 +02:00
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 )
2012-04-13 17:04:45 +02:00
else :
2015-07-24 10:07:13 +02:00
self . currentOptionMenu . append_text ( _ ( " Disabled " ) )
self . currentOptionMenu . set_active ( 0 )
self . currentOptionMenu . set_sensitive ( False )
2012-04-13 17:04:45 +02:00
2017-09-20 08:56:54 +02:00
if self . read_selinux_config ( ) is None :
2012-04-13 17:04:45 +02:00
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
2015-07-24 10:07:13 +02:00
def set_current_mode ( self , menu ) :
2012-04-13 17:04:45 +02:00
selinux . security_setenforce ( menu . get_active ( ) == 1 )
def is_relabel ( self ) :
return os . access ( RELABELFILE , os . F_OK ) != 0
2015-07-24 10:07:13 +02:00
def on_relabel_toggle ( self , button ) :
2012-04-13 17:04:45 +02:00
if button . get_active ( ) :
2015-07-24 10:07:13 +02:00
fd = open ( RELABELFILE , " w " )
2012-04-13 17:04:45 +02:00
fd . close ( )
else :
if os . access ( RELABELFILE , os . F_OK ) != 0 :
os . unlink ( RELABELFILE )
def verify ( self , message ) :
2017-09-20 08:56:54 +02:00
dlg = Gtk . MessageDialog ( None , 0 , Gtk . MessageType . INFO ,
Gtk . ButtonsType . YES_NO ,
2012-04-13 17:04:45 +02:00
message )
2017-09-20 08:56:54 +02:00
dlg . set_position ( Gtk . WindowPosition . MOUSE )
2012-04-13 17:04:45 +02:00
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 :
2017-09-20 08:56:54 +02:00
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 :
2012-04-13 17:04:45 +02:00
menu . set_active ( self . typeHistory )
return None
self . relabel_checkbutton . set_active ( True )
2015-07-24 10:07:13 +02:00
self . write_selinux_config ( modearray [ enabled ] , type )
2012-04-13 17:04:45 +02:00
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 :
2017-09-20 08:56:54 +02:00
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 :
2012-04-13 17:04:45 +02:00
combo . set_active ( self . enabled )
return None
if self . initEnabled == DISABLED and enabled < 2 :
2017-09-20 08:56:54 +02:00
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 :
2012-04-13 17:04:45 +02:00
combo . set_active ( self . enabled )
return None
self . relabel_checkbutton . set_active ( True )
2015-07-24 10:07:13 +02:00
self . write_selinux_config ( modearray [ enabled ] , type )
2012-04-13 17:04:45 +02:00
self . enabled = enabled
def write_selinux_config ( self , enforcing , type ) :
2015-07-24 10:07:13 +02:00
path = selinux . selinux_path ( ) + " config "
2012-12-06 20:40:23 +01:00
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 )
2012-04-13 17:04:45 +02:00
def read_selinux_config ( self ) :
self . initialtype = selinux . selinux_getpolicytype ( ) [ 1 ]
2013-01-21 21:04:56 +01:00
try :
self . initEnabled = selinux . selinux_getenforcemode ( ) [ 1 ]
except :
self . initEnabled = False
pass
2012-04-13 17:04:45 +02:00
self . enabled = self . initEnabled
2015-07-24 10:07:13 +02:00
self . enabledOptionMenu . set_active ( self . enabled + 1 )
2012-04-13 17:04:45 +02:00
self . types = [ ]
n = 0
current = n
for i in os . listdir ( SELINUXDIR ) :
2015-07-24 10:07:13 +02:00
if os . path . isdir ( SELINUXDIR + i ) and os . path . isdir ( SELINUXDIR + i + " /policy " ) :
2012-04-13 17:04:45 +02:00
self . types . append ( i )
self . selinuxTypeOptionMenu . append_text ( i )
if i == self . initialtype :
current = n
2015-07-24 10:07:13 +02:00
n = n + 1
2012-04-13 17:04:45 +02:00
self . selinuxTypeOptionMenu . set_active ( current )
self . typeHistory = current
return 0
def get_type ( self ) :
return self . types [ self . selinuxTypeOptionMenu . get_active ( ) ]