blob: 766854b19cbaf7d12d6c3e35c25cd35081c77251 [file] [log] [blame]
Dan Walsh514af852012-04-13 11:04:45 -04001# 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
Dan Walsh514af852012-04-13 11:04:45 -040019import os
Dan Walsh514af852012-04-13 11:04:45 -040020import sys
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020021from gi.repository import Gtk
Jason Zamanaf595442016-08-05 02:34:02 +080022import selinux
Dan Walsh514af852012-04-13 11:04:45 -040023
24INSTALLPATH = '/usr/share/system-config-selinux'
25sys.path.append(INSTALLPATH)
26
Dan Walsh514af852012-04-13 11:04:45 -040027ENFORCING = 1
28PERMISSIVE = 0
29DISABLED = -1
Jason Zaman789d0eb2015-07-24 16:07:13 +080030modearray = ("disabled", "permissive", "enforcing")
Dan Walsh514af852012-04-13 11:04:45 -040031
32SELINUXDIR = "/etc/selinux/"
33RELABELFILE = "/.autorelabel"
34
35##
36## I18N
37##
Jason Zaman789d0eb2015-07-24 16:07:13 +080038PROGNAME = "policycoreutils"
Dan Walsh514af852012-04-13 11:04:45 -040039try:
Jason Zamanaf595442016-08-05 02:34:02 +080040 import gettext
41 kwargs = {}
42 if sys.version_info < (3,):
43 kwargs['unicode'] = True
44 gettext.install(PROGNAME,
45 localedir="/usr/share/locale",
46 codeset='utf-8',
47 **kwargs)
48except:
49 try:
50 import builtins
51 builtins.__dict__['_'] = str
52 except ImportError:
53 import __builtin__
54 __builtin__.__dict__['_'] = unicode
Dan Walsh514af852012-04-13 11:04:45 -040055
Jason Zaman789d0eb2015-07-24 16:07:13 +080056
Dan Walsh514af852012-04-13 11:04:45 -040057class statusPage:
Jason Zaman789d0eb2015-07-24 16:07:13 +080058
Dan Walsh514af852012-04-13 11:04:45 -040059 def __init__(self, xml):
60 self.xml = xml
61 self.needRelabel = False
62
63 self.type = selinux.selinux_getpolicytype()
64 # Bring in widgets from glade file.
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020065 self.selinuxTypeOptionMenu = xml.get_object("selinuxTypeOptionMenu")
66 self.typeLabel = xml.get_object("typeLabel")
67 self.enabledOptionMenu = xml.get_object("enabledOptionMenu")
68 self.currentOptionMenu = xml.get_object("currentOptionMenu")
69 self.relabel_checkbutton = xml.get_object("relabelCheckbutton")
Dan Walsh514af852012-04-13 11:04:45 -040070 self.relabel_checkbutton.set_active(self.is_relabel())
71 self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle)
72 if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE:
Jason Zaman789d0eb2015-07-24 16:07:13 +080073 self.currentOptionMenu.append_text(_("Permissive"))
74 self.currentOptionMenu.append_text(_("Enforcing"))
75 self.currentOptionMenu.set_active(self.get_current_mode())
76 self.currentOptionMenu.connect("changed", self.set_current_mode)
77 self.currentOptionMenu.set_sensitive(True)
Dan Walsh514af852012-04-13 11:04:45 -040078 else:
Jason Zaman789d0eb2015-07-24 16:07:13 +080079 self.currentOptionMenu.append_text(_("Disabled"))
80 self.currentOptionMenu.set_active(0)
81 self.currentOptionMenu.set_sensitive(False)
Dan Walsh514af852012-04-13 11:04:45 -040082
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020083 if self.read_selinux_config() is None:
Dan Walsh514af852012-04-13 11:04:45 -040084 self.selinuxsupport = False
85 else:
86 self.enabledOptionMenu.connect("changed", self.enabled_changed)
87 #
88 # This line must come after read_selinux_config
89 #
90 self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed)
91
92 self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu)
93
94 def use_menus(self):
95 return False
96
97 def get_description(self):
98 return _("Status")
99
100 def get_current_mode(self):
101 if selinux.is_selinux_enabled():
102 if selinux.security_getenforce() > 0:
103 return ENFORCING
104 else:
105 return PERMISSIVE
106 else:
107 return DISABLED
108
Jason Zaman789d0eb2015-07-24 16:07:13 +0800109 def set_current_mode(self, menu):
Dan Walsh514af852012-04-13 11:04:45 -0400110 selinux.security_setenforce(menu.get_active() == 1)
111
112 def is_relabel(self):
113 return os.access(RELABELFILE, os.F_OK) != 0
114
Jason Zaman789d0eb2015-07-24 16:07:13 +0800115 def on_relabel_toggle(self, button):
Dan Walsh514af852012-04-13 11:04:45 -0400116 if button.get_active():
Jason Zaman789d0eb2015-07-24 16:07:13 +0800117 fd = open(RELABELFILE, "w")
Dan Walsh514af852012-04-13 11:04:45 -0400118 fd.close()
119 else:
120 if os.access(RELABELFILE, os.F_OK) != 0:
121 os.unlink(RELABELFILE)
122
123 def verify(self, message):
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200124 dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
125 Gtk.ButtonsType.YES_NO,
Dan Walsh514af852012-04-13 11:04:45 -0400126 message)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200127 dlg.set_position(Gtk.WindowPosition.MOUSE)
Dan Walsh514af852012-04-13 11:04:45 -0400128 dlg.show_all()
129 rc = dlg.run()
130 dlg.destroy()
131 return rc
132
133 def typemenu_changed(self, menu):
134 type = self.get_type()
135 enabled = self.enabledOptionMenu.get_active()
136 if self.initialtype != type:
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200137 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:
Dan Walsh514af852012-04-13 11:04:45 -0400138 menu.set_active(self.typeHistory)
139 return None
140
141 self.relabel_checkbutton.set_active(True)
142
Jason Zaman789d0eb2015-07-24 16:07:13 +0800143 self.write_selinux_config(modearray[enabled], type)
Dan Walsh514af852012-04-13 11:04:45 -0400144 self.typeHistory = menu.get_active()
145
146 def enabled_changed(self, combo):
147 enabled = combo.get_active()
148 type = self.get_type()
149
150 if self.initEnabled != DISABLED and enabled == DISABLED:
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200151 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:
Dan Walsh514af852012-04-13 11:04:45 -0400152 combo.set_active(self.enabled)
153 return None
154
155 if self.initEnabled == DISABLED and enabled < 2:
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200156 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:
Dan Walsh514af852012-04-13 11:04:45 -0400157 combo.set_active(self.enabled)
158 return None
159 self.relabel_checkbutton.set_active(True)
160
Jason Zaman789d0eb2015-07-24 16:07:13 +0800161 self.write_selinux_config(modearray[enabled], type)
Dan Walsh514af852012-04-13 11:04:45 -0400162 self.enabled = enabled
163
164 def write_selinux_config(self, enforcing, type):
Jason Zaman789d0eb2015-07-24 16:07:13 +0800165 path = selinux.selinux_path() + "config"
Dan Walsh017d35a2012-12-06 14:40:23 -0500166 backup_path = path + ".bck"
167 fd = open(path)
168 lines = fd.readlines()
169 fd.close()
170 fd = open(backup_path, "w")
171 for l in lines:
172 if l.startswith("SELINUX="):
173 fd.write("SELINUX=%s\n" % enforcing)
174 continue
175 if l.startswith("SELINUXTYPE="):
176 fd.write("SELINUXTYPE=%s\n" % type)
177 continue
178 fd.write(l)
179 fd.close()
180 os.rename(backup_path, path)
Dan Walsh514af852012-04-13 11:04:45 -0400181
182 def read_selinux_config(self):
183 self.initialtype = selinux.selinux_getpolicytype()[1]
Dan Walshb2de3262013-01-21 14:04:56 -0600184 try:
185 self.initEnabled = selinux.selinux_getenforcemode()[1]
186 except:
187 self.initEnabled = False
188 pass
Dan Walsh514af852012-04-13 11:04:45 -0400189 self.enabled = self.initEnabled
Jason Zaman789d0eb2015-07-24 16:07:13 +0800190 self.enabledOptionMenu.set_active(self.enabled + 1)
Dan Walsh514af852012-04-13 11:04:45 -0400191
192 self.types = []
193
194 n = 0
195 current = n
196
197 for i in os.listdir(SELINUXDIR):
Jason Zaman789d0eb2015-07-24 16:07:13 +0800198 if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"):
Dan Walsh514af852012-04-13 11:04:45 -0400199 self.types.append(i)
200 self.selinuxTypeOptionMenu.append_text(i)
201 if i == self.initialtype:
202 current = n
Jason Zaman789d0eb2015-07-24 16:07:13 +0800203 n = n + 1
Dan Walsh514af852012-04-13 11:04:45 -0400204 self.selinuxTypeOptionMenu.set_active(current)
205 self.typeHistory = current
206
207 return 0
208
209 def get_type(self):
210 return self.types[self.selinuxTypeOptionMenu.get_active()]