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