xref: /aosp_15_r20/external/selinux/gui/booleansPage.py (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker#
2*2d543d20SAndroid Build Coastguard Worker# booleansPage.py - GUI for Booleans page in system-config-securitylevel
3*2d543d20SAndroid Build Coastguard Worker#
4*2d543d20SAndroid Build Coastguard Worker# Dan Walsh <[email protected]>
5*2d543d20SAndroid Build Coastguard Worker#
6*2d543d20SAndroid Build Coastguard Worker# Copyright 2006, 2007 Red Hat, Inc.
7*2d543d20SAndroid Build Coastguard Worker#
8*2d543d20SAndroid Build Coastguard Worker# This program is free software; you can redistribute it and/or modify
9*2d543d20SAndroid Build Coastguard Worker# it under the terms of the GNU General Public License as published by
10*2d543d20SAndroid Build Coastguard Worker# the Free Software Foundation; either version 2 of the License, or
11*2d543d20SAndroid Build Coastguard Worker# (at your option) any later version.
12*2d543d20SAndroid Build Coastguard Worker#
13*2d543d20SAndroid Build Coastguard Worker# This program is distributed in the hope that it will be useful,
14*2d543d20SAndroid Build Coastguard Worker# but WITHOUT ANY WARRANTY; without even the implied warranty of
15*2d543d20SAndroid Build Coastguard Worker# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*2d543d20SAndroid Build Coastguard Worker# GNU General Public License for more details.
17*2d543d20SAndroid Build Coastguard Worker#
18*2d543d20SAndroid Build Coastguard Worker# You should have received a copy of the GNU General Public License
19*2d543d20SAndroid Build Coastguard Worker# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*2d543d20SAndroid Build Coastguard Worker#
21*2d543d20SAndroid Build Coastguard Workerimport sys
22*2d543d20SAndroid Build Coastguard Workerfrom gi.repository import Gdk, GObject, Gtk
23*2d543d20SAndroid Build Coastguard Workerimport seobject
24*2d543d20SAndroid Build Coastguard Workerimport semanagePage
25*2d543d20SAndroid Build Coastguard Worker
26*2d543d20SAndroid Build Coastguard WorkerINSTALLPATH = '/usr/share/system-config-selinux'
27*2d543d20SAndroid Build Coastguard Workersys.path.append(INSTALLPATH)
28*2d543d20SAndroid Build Coastguard Worker
29*2d543d20SAndroid Build Coastguard Workertry:
30*2d543d20SAndroid Build Coastguard Worker    from subprocess import getstatusoutput
31*2d543d20SAndroid Build Coastguard Workerexcept ImportError:
32*2d543d20SAndroid Build Coastguard Worker    from commands import getstatusoutput
33*2d543d20SAndroid Build Coastguard Worker
34*2d543d20SAndroid Build Coastguard WorkerENFORCING = 0
35*2d543d20SAndroid Build Coastguard WorkerPERMISSIVE = 1
36*2d543d20SAndroid Build Coastguard WorkerDISABLED = 2
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker##
39*2d543d20SAndroid Build Coastguard Worker## I18N
40*2d543d20SAndroid Build Coastguard Worker##
41*2d543d20SAndroid Build Coastguard WorkerPROGNAME = "selinux-gui"
42*2d543d20SAndroid Build Coastguard Workertry:
43*2d543d20SAndroid Build Coastguard Worker    import gettext
44*2d543d20SAndroid Build Coastguard Worker    kwargs = {}
45*2d543d20SAndroid Build Coastguard Worker    if sys.version_info < (3,):
46*2d543d20SAndroid Build Coastguard Worker        kwargs['unicode'] = True
47*2d543d20SAndroid Build Coastguard Worker    t = gettext.translation(PROGNAME,
48*2d543d20SAndroid Build Coastguard Worker                    localedir="/usr/share/locale",
49*2d543d20SAndroid Build Coastguard Worker                    **kwargs,
50*2d543d20SAndroid Build Coastguard Worker                    fallback=True)
51*2d543d20SAndroid Build Coastguard Worker    _ = t.gettext
52*2d543d20SAndroid Build Coastguard Workerexcept:
53*2d543d20SAndroid Build Coastguard Worker    try:
54*2d543d20SAndroid Build Coastguard Worker        import builtins
55*2d543d20SAndroid Build Coastguard Worker        builtins.__dict__['_'] = str
56*2d543d20SAndroid Build Coastguard Worker    except ImportError:
57*2d543d20SAndroid Build Coastguard Worker        import __builtin__
58*2d543d20SAndroid Build Coastguard Worker        __builtin__.__dict__['_'] = unicode
59*2d543d20SAndroid Build Coastguard Worker
60*2d543d20SAndroid Build Coastguard Worker
61*2d543d20SAndroid Build Coastguard Workerclass Modifier:
62*2d543d20SAndroid Build Coastguard Worker
63*2d543d20SAndroid Build Coastguard Worker    def __init__(self, name, on, save):
64*2d543d20SAndroid Build Coastguard Worker        self.on = on
65*2d543d20SAndroid Build Coastguard Worker        self.name = name
66*2d543d20SAndroid Build Coastguard Worker        self.save = save
67*2d543d20SAndroid Build Coastguard Worker
68*2d543d20SAndroid Build Coastguard Worker    def set(self, value):
69*2d543d20SAndroid Build Coastguard Worker        self.on = value
70*2d543d20SAndroid Build Coastguard Worker        self.save = True
71*2d543d20SAndroid Build Coastguard Worker
72*2d543d20SAndroid Build Coastguard Worker    def isOn(self):
73*2d543d20SAndroid Build Coastguard Worker        return self.on
74*2d543d20SAndroid Build Coastguard Worker
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Workerclass Boolean(Modifier):
77*2d543d20SAndroid Build Coastguard Worker
78*2d543d20SAndroid Build Coastguard Worker    def __init__(self, name, val, save=False):
79*2d543d20SAndroid Build Coastguard Worker        Modifier.__init__(self, name, val, save)
80*2d543d20SAndroid Build Coastguard Worker
81*2d543d20SAndroid Build Coastguard WorkerACTIVE = 0
82*2d543d20SAndroid Build Coastguard WorkerMODULE = 1
83*2d543d20SAndroid Build Coastguard WorkerDESC = 2
84*2d543d20SAndroid Build Coastguard WorkerBOOLEAN = 3
85*2d543d20SAndroid Build Coastguard Worker
86*2d543d20SAndroid Build Coastguard Worker
87*2d543d20SAndroid Build Coastguard Workerclass booleansPage:
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker    def __init__(self, xml, doDebug=None):
90*2d543d20SAndroid Build Coastguard Worker        self.xml = xml
91*2d543d20SAndroid Build Coastguard Worker        self.window = self.xml.get_object("mainWindow").get_root_window()
92*2d543d20SAndroid Build Coastguard Worker        self.local = False
93*2d543d20SAndroid Build Coastguard Worker        self.types = []
94*2d543d20SAndroid Build Coastguard Worker        self.selinuxsupport = True
95*2d543d20SAndroid Build Coastguard Worker        self.typechanged = False
96*2d543d20SAndroid Build Coastguard Worker        self.doDebug = doDebug
97*2d543d20SAndroid Build Coastguard Worker        self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)
98*2d543d20SAndroid Build Coastguard Worker        self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)
99*2d543d20SAndroid Build Coastguard Worker
100*2d543d20SAndroid Build Coastguard Worker        # Bring in widgets from glade file.
101*2d543d20SAndroid Build Coastguard Worker        self.booleansFilter = xml.get_object("booleansFilter")
102*2d543d20SAndroid Build Coastguard Worker        self.booleansFilter.connect("focus_out_event", self.filter_changed)
103*2d543d20SAndroid Build Coastguard Worker        self.booleansFilter.connect("activate", self.filter_changed)
104*2d543d20SAndroid Build Coastguard Worker        self.booleansFilter.connect("changed", self.filter_changed)
105*2d543d20SAndroid Build Coastguard Worker
106*2d543d20SAndroid Build Coastguard Worker        self.booleansView = xml.get_object("booleansView")
107*2d543d20SAndroid Build Coastguard Worker
108*2d543d20SAndroid Build Coastguard Worker        self.revertButton = xml.get_object("booleanRevertButton")
109*2d543d20SAndroid Build Coastguard Worker        self.revertButton.set_sensitive(self.local)
110*2d543d20SAndroid Build Coastguard Worker        self.revertButton.connect("clicked", self.on_revert_clicked)
111*2d543d20SAndroid Build Coastguard Worker        listStore = Gtk.ListStore(GObject.TYPE_STRING)
112*2d543d20SAndroid Build Coastguard Worker        cell = Gtk.CellRendererText()
113*2d543d20SAndroid Build Coastguard Worker
114*2d543d20SAndroid Build Coastguard Worker        self.store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
115*2d543d20SAndroid Build Coastguard Worker        self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING)
116*2d543d20SAndroid Build Coastguard Worker        self.booleansView.set_model(self.store)
117*2d543d20SAndroid Build Coastguard Worker
118*2d543d20SAndroid Build Coastguard Worker        checkbox = Gtk.CellRendererToggle()
119*2d543d20SAndroid Build Coastguard Worker        checkbox.connect("toggled", self.boolean_toggled)
120*2d543d20SAndroid Build Coastguard Worker        col = Gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
121*2d543d20SAndroid Build Coastguard Worker        col.set_clickable(True)
122*2d543d20SAndroid Build Coastguard Worker        col.set_sort_column_id(ACTIVE)
123*2d543d20SAndroid Build Coastguard Worker        self.booleansView.append_column(col)
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker        col = Gtk.TreeViewColumn("Module", Gtk.CellRendererText(), text=MODULE)
126*2d543d20SAndroid Build Coastguard Worker        col.set_sort_column_id(MODULE)
127*2d543d20SAndroid Build Coastguard Worker        col.set_resizable(True)
128*2d543d20SAndroid Build Coastguard Worker        self.booleansView.append_column(col)
129*2d543d20SAndroid Build Coastguard Worker
130*2d543d20SAndroid Build Coastguard Worker        col = Gtk.TreeViewColumn("Description", Gtk.CellRendererText(), text=DESC)
131*2d543d20SAndroid Build Coastguard Worker        col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
132*2d543d20SAndroid Build Coastguard Worker        col.set_fixed_width(400)
133*2d543d20SAndroid Build Coastguard Worker        col.set_sort_column_id(DESC)
134*2d543d20SAndroid Build Coastguard Worker        col.set_resizable(True)
135*2d543d20SAndroid Build Coastguard Worker        self.booleansView.append_column(col)
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker        col = Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=BOOLEAN)
138*2d543d20SAndroid Build Coastguard Worker        col.set_sort_column_id(BOOLEAN)
139*2d543d20SAndroid Build Coastguard Worker        col.set_resizable(True)
140*2d543d20SAndroid Build Coastguard Worker        self.booleansView.set_search_equal_func(self.__search)
141*2d543d20SAndroid Build Coastguard Worker        self.booleansView.append_column(col)
142*2d543d20SAndroid Build Coastguard Worker        self.filter = ""
143*2d543d20SAndroid Build Coastguard Worker        self.load(self.filter)
144*2d543d20SAndroid Build Coastguard Worker
145*2d543d20SAndroid Build Coastguard Worker    def error(self, message):
146*2d543d20SAndroid Build Coastguard Worker        dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
147*2d543d20SAndroid Build Coastguard Worker                                Gtk.ButtonsType.CLOSE,
148*2d543d20SAndroid Build Coastguard Worker                                message)
149*2d543d20SAndroid Build Coastguard Worker        dlg.set_position(Gtk.WindowPosition.MOUSE)
150*2d543d20SAndroid Build Coastguard Worker        dlg.show_all()
151*2d543d20SAndroid Build Coastguard Worker        dlg.run()
152*2d543d20SAndroid Build Coastguard Worker        dlg.destroy()
153*2d543d20SAndroid Build Coastguard Worker
154*2d543d20SAndroid Build Coastguard Worker    def __search(self, model, col, key, i):
155*2d543d20SAndroid Build Coastguard Worker        sort_col = self.store.get_sort_column_id()[0]
156*2d543d20SAndroid Build Coastguard Worker        if sort_col > 0:
157*2d543d20SAndroid Build Coastguard Worker            val = model.get_value(i, sort_col)
158*2d543d20SAndroid Build Coastguard Worker            if val.lower().startswith(key.lower()):
159*2d543d20SAndroid Build Coastguard Worker                return False
160*2d543d20SAndroid Build Coastguard Worker        return True
161*2d543d20SAndroid Build Coastguard Worker
162*2d543d20SAndroid Build Coastguard Worker    def wait(self):
163*2d543d20SAndroid Build Coastguard Worker        self.window.set_cursor(self.busy_cursor)
164*2d543d20SAndroid Build Coastguard Worker        semanagePage.idle_func()
165*2d543d20SAndroid Build Coastguard Worker
166*2d543d20SAndroid Build Coastguard Worker    def ready(self):
167*2d543d20SAndroid Build Coastguard Worker        self.window.set_cursor(self.ready_cursor)
168*2d543d20SAndroid Build Coastguard Worker        semanagePage.idle_func()
169*2d543d20SAndroid Build Coastguard Worker
170*2d543d20SAndroid Build Coastguard Worker    def deleteDialog(self):
171*2d543d20SAndroid Build Coastguard Worker        store, iter = self.booleansView.get_selection().get_selected()
172*2d543d20SAndroid Build Coastguard Worker        if iter is None:
173*2d543d20SAndroid Build Coastguard Worker            return
174*2d543d20SAndroid Build Coastguard Worker        boolean = store.get_value(iter, BOOLEAN)
175*2d543d20SAndroid Build Coastguard Worker        # change cursor
176*2d543d20SAndroid Build Coastguard Worker        if boolean is None:
177*2d543d20SAndroid Build Coastguard Worker            return
178*2d543d20SAndroid Build Coastguard Worker        try:
179*2d543d20SAndroid Build Coastguard Worker            self.wait()
180*2d543d20SAndroid Build Coastguard Worker            (rc, out) = getstatusoutput("semanage boolean -d %s" % boolean)
181*2d543d20SAndroid Build Coastguard Worker
182*2d543d20SAndroid Build Coastguard Worker            self.ready()
183*2d543d20SAndroid Build Coastguard Worker            if rc != 0:
184*2d543d20SAndroid Build Coastguard Worker                return self.error(out)
185*2d543d20SAndroid Build Coastguard Worker            self.load(self.filter)
186*2d543d20SAndroid Build Coastguard Worker        except ValueError as e:
187*2d543d20SAndroid Build Coastguard Worker            self.error(e.args[0])
188*2d543d20SAndroid Build Coastguard Worker
189*2d543d20SAndroid Build Coastguard Worker    def filter_changed(self, *arg):
190*2d543d20SAndroid Build Coastguard Worker        filter = arg[0].get_text()
191*2d543d20SAndroid Build Coastguard Worker        if filter != self.filter:
192*2d543d20SAndroid Build Coastguard Worker            self.load(filter)
193*2d543d20SAndroid Build Coastguard Worker            self.filter = filter
194*2d543d20SAndroid Build Coastguard Worker
195*2d543d20SAndroid Build Coastguard Worker    def use_menus(self):
196*2d543d20SAndroid Build Coastguard Worker        return False
197*2d543d20SAndroid Build Coastguard Worker
198*2d543d20SAndroid Build Coastguard Worker    def get_description(self):
199*2d543d20SAndroid Build Coastguard Worker        return _("Boolean")
200*2d543d20SAndroid Build Coastguard Worker
201*2d543d20SAndroid Build Coastguard Worker    def match(self, key, filter=""):
202*2d543d20SAndroid Build Coastguard Worker        try:
203*2d543d20SAndroid Build Coastguard Worker            f = filter.lower()
204*2d543d20SAndroid Build Coastguard Worker            cat = self.booleans.get_category(key).lower()
205*2d543d20SAndroid Build Coastguard Worker            val = self.booleans.get_desc(key).lower()
206*2d543d20SAndroid Build Coastguard Worker            k = key.lower()
207*2d543d20SAndroid Build Coastguard Worker            return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
208*2d543d20SAndroid Build Coastguard Worker        except:
209*2d543d20SAndroid Build Coastguard Worker            return False
210*2d543d20SAndroid Build Coastguard Worker
211*2d543d20SAndroid Build Coastguard Worker    def load(self, filter=None):
212*2d543d20SAndroid Build Coastguard Worker        self.store.clear()
213*2d543d20SAndroid Build Coastguard Worker        self.booleans = seobject.booleanRecords()
214*2d543d20SAndroid Build Coastguard Worker        booleansList = self.booleans.get_all(self.local)
215*2d543d20SAndroid Build Coastguard Worker        for name in booleansList:
216*2d543d20SAndroid Build Coastguard Worker            rec = booleansList[name]
217*2d543d20SAndroid Build Coastguard Worker            if self.match(name, filter):
218*2d543d20SAndroid Build Coastguard Worker                iter = self.store.append()
219*2d543d20SAndroid Build Coastguard Worker                self.store.set_value(iter, ACTIVE, rec[2] == 1)
220*2d543d20SAndroid Build Coastguard Worker                self.store.set_value(iter, MODULE, self.booleans.get_category(name))
221*2d543d20SAndroid Build Coastguard Worker                self.store.set_value(iter, DESC, self.booleans.get_desc(name))
222*2d543d20SAndroid Build Coastguard Worker                self.store.set_value(iter, BOOLEAN, name)
223*2d543d20SAndroid Build Coastguard Worker
224*2d543d20SAndroid Build Coastguard Worker    def boolean_toggled(self, widget, row):
225*2d543d20SAndroid Build Coastguard Worker        iter = self.store.get_iter(row)
226*2d543d20SAndroid Build Coastguard Worker        val = self.store.get_value(iter, ACTIVE)
227*2d543d20SAndroid Build Coastguard Worker        key = self.store.get_value(iter, BOOLEAN)
228*2d543d20SAndroid Build Coastguard Worker        self.store.set_value(iter, ACTIVE, not val)
229*2d543d20SAndroid Build Coastguard Worker        self.wait()
230*2d543d20SAndroid Build Coastguard Worker        setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
231*2d543d20SAndroid Build Coastguard Worker        rc, out = getstatusoutput(setsebool)
232*2d543d20SAndroid Build Coastguard Worker        if rc != 0:
233*2d543d20SAndroid Build Coastguard Worker            self.error(out)
234*2d543d20SAndroid Build Coastguard Worker        self.load(self.filter)
235*2d543d20SAndroid Build Coastguard Worker        self.ready()
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker    def on_revert_clicked(self, button):
238*2d543d20SAndroid Build Coastguard Worker        self.wait()
239*2d543d20SAndroid Build Coastguard Worker        setsebool = "semanage boolean --deleteall"
240*2d543d20SAndroid Build Coastguard Worker        getstatusoutput(setsebool)
241*2d543d20SAndroid Build Coastguard Worker        self.load(self.filter)
242*2d543d20SAndroid Build Coastguard Worker        self.ready()
243*2d543d20SAndroid Build Coastguard Worker
244*2d543d20SAndroid Build Coastguard Worker    def on_local_clicked(self, button):
245*2d543d20SAndroid Build Coastguard Worker        self.local = not self.local
246*2d543d20SAndroid Build Coastguard Worker        self.revertButton.set_sensitive(self.local)
247*2d543d20SAndroid Build Coastguard Worker
248*2d543d20SAndroid Build Coastguard Worker        if self.local:
249*2d543d20SAndroid Build Coastguard Worker            button.set_label(_("all"))
250*2d543d20SAndroid Build Coastguard Worker        else:
251*2d543d20SAndroid Build Coastguard Worker            button.set_label(_("Customized"))
252*2d543d20SAndroid Build Coastguard Worker
253*2d543d20SAndroid Build Coastguard Worker        self.load(self.filter)
254*2d543d20SAndroid Build Coastguard Worker        return True
255