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