blob: 7849bea26a063b8eb4a79fa87a1f71c2ac60d4e3 [file] [log] [blame]
Dan Walsh514af852012-04-13 11:04:45 -04001#
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#
Dan Walsh514af852012-04-13 11:04:45 -040021import sys
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020022from gi.repository import Gdk, GObject, Gtk
Dan Walsh514af852012-04-13 11:04:45 -040023import seobject
24import semanagePage
25
Jason Zaman789d0eb2015-07-24 16:07:13 +080026INSTALLPATH = '/usr/share/system-config-selinux'
Dan Walsh514af852012-04-13 11:04:45 -040027sys.path.append(INSTALLPATH)
28
Jason Zaman05d1cea2016-08-05 02:34:04 +080029try:
30 from subprocess import getstatusoutput
31except ImportError:
32 from commands import getstatusoutput
33
Jason Zaman789d0eb2015-07-24 16:07:13 +080034ENFORCING = 0
35PERMISSIVE = 1
36DISABLED = 2
Dan Walsh514af852012-04-13 11:04:45 -040037
38##
39## I18N
40##
Jason Zaman789d0eb2015-07-24 16:07:13 +080041PROGNAME = "policycoreutils"
Dan Walsh514af852012-04-13 11:04:45 -040042try:
Jason Zamanaf595442016-08-05 02:34:02 +080043 import gettext
44 kwargs = {}
45 if sys.version_info < (3,):
46 kwargs['unicode'] = True
Dan Walsh514af852012-04-13 11:04:45 -040047 gettext.install(PROGNAME,
48 localedir="/usr/share/locale",
Jason Zamanaf595442016-08-05 02:34:02 +080049 codeset='utf-8',
50 **kwargs)
51except:
52 try:
53 import builtins
54 builtins.__dict__['_'] = str
55 except ImportError:
56 import __builtin__
57 __builtin__.__dict__['_'] = unicode
Dan Walsh514af852012-04-13 11:04:45 -040058
Dan Walsh514af852012-04-13 11:04:45 -040059
Jason Zaman789d0eb2015-07-24 16:07:13 +080060class Modifier:
61
62 def __init__(self, name, on, save):
63 self.on = on
64 self.name = name
65 self.save = save
66
67 def set(self, value):
68 self.on = value
69 self.save = True
Dan Walsh514af852012-04-13 11:04:45 -040070
71 def isOn(self):
72 return self.on
73
Jason Zaman789d0eb2015-07-24 16:07:13 +080074
Dan Walsh514af852012-04-13 11:04:45 -040075class Boolean(Modifier):
Jason Zaman789d0eb2015-07-24 16:07:13 +080076
77 def __init__(self, name, val, save=False):
78 Modifier.__init__(self, name, val, save)
Dan Walsh514af852012-04-13 11:04:45 -040079
80ACTIVE = 0
81MODULE = 1
82DESC = 2
83BOOLEAN = 3
84
Jason Zaman789d0eb2015-07-24 16:07:13 +080085
Dan Walsh514af852012-04-13 11:04:45 -040086class booleansPage:
Jason Zaman789d0eb2015-07-24 16:07:13 +080087
Dan Walsh514af852012-04-13 11:04:45 -040088 def __init__(self, xml, doDebug=None):
89 self.xml = xml
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020090 self.window = self.xml.get_object("mainWindow").get_root_window()
Dan Walsh514af852012-04-13 11:04:45 -040091 self.local = False
Jason Zaman789d0eb2015-07-24 16:07:13 +080092 self.types = []
Dan Walsh514af852012-04-13 11:04:45 -040093 self.selinuxsupport = True
94 self.typechanged = False
95 self.doDebug = doDebug
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020096 self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)
97 self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)
Dan Walsh514af852012-04-13 11:04:45 -040098
99 # Bring in widgets from glade file.
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200100 self.booleansFilter = xml.get_object("booleansFilter")
Dan Walsh514af852012-04-13 11:04:45 -0400101 self.booleansFilter.connect("focus_out_event", self.filter_changed)
102 self.booleansFilter.connect("activate", self.filter_changed)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200103 self.booleansFilter.connect("changed", self.filter_changed)
Dan Walsh514af852012-04-13 11:04:45 -0400104
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200105 self.booleansView = xml.get_object("booleansView")
Dan Walsh514af852012-04-13 11:04:45 -0400106
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200107 self.revertButton = xml.get_object("booleanRevertButton")
Dan Walsh514af852012-04-13 11:04:45 -0400108 self.revertButton.set_sensitive(self.local)
109 self.revertButton.connect("clicked", self.on_revert_clicked)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200110 listStore = Gtk.ListStore(GObject.TYPE_STRING)
111 cell = Gtk.CellRendererText()
Dan Walsh514af852012-04-13 11:04:45 -0400112
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200113 self.store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
114 self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING)
Dan Walsh514af852012-04-13 11:04:45 -0400115 self.booleansView.set_model(self.store)
116
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200117 checkbox = Gtk.CellRendererToggle()
Dan Walsh514af852012-04-13 11:04:45 -0400118 checkbox.connect("toggled", self.boolean_toggled)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200119 col = Gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
Dan Walsh514af852012-04-13 11:04:45 -0400120 col.set_clickable(True)
121 col.set_sort_column_id(ACTIVE)
122 self.booleansView.append_column(col)
123
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200124 col = Gtk.TreeViewColumn("Module", Gtk.CellRendererText(), text=MODULE)
Dan Walsh514af852012-04-13 11:04:45 -0400125 col.set_sort_column_id(MODULE)
126 col.set_resizable(True)
127 self.booleansView.append_column(col)
128
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200129 col = Gtk.TreeViewColumn("Description", Gtk.CellRendererText(), text=DESC)
130 col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
Dan Walsh514af852012-04-13 11:04:45 -0400131 col.set_fixed_width(400)
132 col.set_sort_column_id(DESC)
133 col.set_resizable(True)
134 self.booleansView.append_column(col)
135
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200136 col = Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=BOOLEAN)
Dan Walsh514af852012-04-13 11:04:45 -0400137 col.set_sort_column_id(BOOLEAN)
138 col.set_resizable(True)
139 self.booleansView.set_search_equal_func(self.__search)
140 self.booleansView.append_column(col)
Jason Zaman789d0eb2015-07-24 16:07:13 +0800141 self.filter = ""
Dan Walsh514af852012-04-13 11:04:45 -0400142 self.load(self.filter)
143
Dan Walsh39d6b462012-05-24 05:51:41 -0400144 def error(self, message):
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200145 dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
146 Gtk.ButtonsType.CLOSE,
Dan Walsh39d6b462012-05-24 05:51:41 -0400147 message)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200148 dlg.set_position(Gtk.WindowPosition.MOUSE)
Dan Walsh39d6b462012-05-24 05:51:41 -0400149 dlg.show_all()
150 dlg.run()
151 dlg.destroy()
152
Dan Walsh514af852012-04-13 11:04:45 -0400153 def __search(self, model, col, key, i):
154 sort_col = self.store.get_sort_column_id()[0]
155 if sort_col > 0:
156 val = model.get_value(i, sort_col)
157 if val.lower().startswith(key.lower()):
158 return False
159 return True
160
161 def wait(self):
162 self.window.set_cursor(self.busy_cursor)
163 semanagePage.idle_func()
164
165 def ready(self):
166 self.window.set_cursor(self.ready_cursor)
167 semanagePage.idle_func()
168
169 def deleteDialog(self):
170 store, iter = self.booleansView.get_selection().get_selected()
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200171 if iter is None:
Dan Walsh514af852012-04-13 11:04:45 -0400172 return
173 boolean = store.get_value(iter, BOOLEAN)
174 # change cursor
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200175 if boolean is None:
Dan Walsh514af852012-04-13 11:04:45 -0400176 return
177 try:
178 self.wait()
Jason Zaman05d1cea2016-08-05 02:34:04 +0800179 (rc, out) = getstatusoutput("semanage boolean -d %s" % boolean)
Dan Walsh514af852012-04-13 11:04:45 -0400180
181 self.ready()
182 if rc != 0:
183 return self.error(out)
184 self.load(self.filter)
Jason Zaman4d340e42016-08-05 02:34:03 +0800185 except ValueError as e:
Dan Walsh514af852012-04-13 11:04:45 -0400186 self.error(e.args[0])
187
188 def filter_changed(self, *arg):
Jason Zaman789d0eb2015-07-24 16:07:13 +0800189 filter = arg[0].get_text()
Dan Walsh514af852012-04-13 11:04:45 -0400190 if filter != self.filter:
191 self.load(filter)
Jason Zaman789d0eb2015-07-24 16:07:13 +0800192 self.filter = filter
Dan Walsh514af852012-04-13 11:04:45 -0400193
194 def use_menus(self):
195 return False
196
197 def get_description(self):
198 return _("Boolean")
199
Jason Zaman789d0eb2015-07-24 16:07:13 +0800200 def match(self, key, filter=""):
Dan Walsh514af852012-04-13 11:04:45 -0400201 try:
Jason Zaman789d0eb2015-07-24 16:07:13 +0800202 f = filter.lower()
203 cat = self.booleans.get_category(key).lower()
204 val = self.booleans.get_desc(key).lower()
205 k = key.lower()
Dan Walsh514af852012-04-13 11:04:45 -0400206 return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
207 except:
208 return False
209
Dan Walsh514af852012-04-13 11:04:45 -0400210 def load(self, filter=None):
211 self.store.clear()
212 self.booleans = seobject.booleanRecords()
213 booleansList = self.booleans.get_all(self.local)
214 for name in booleansList:
215 rec = booleansList[name]
216 if self.match(name, filter):
Jason Zaman789d0eb2015-07-24 16:07:13 +0800217 iter = self.store.append()
Dan Walsh514af852012-04-13 11:04:45 -0400218 self.store.set_value(iter, ACTIVE, rec[2] == 1)
219 self.store.set_value(iter, MODULE, self.booleans.get_category(name))
220 self.store.set_value(iter, DESC, self.booleans.get_desc(name))
221 self.store.set_value(iter, BOOLEAN, name)
222
223 def boolean_toggled(self, widget, row):
224 iter = self.store.get_iter(row)
225 val = self.store.get_value(iter, ACTIVE)
226 key = self.store.get_value(iter, BOOLEAN)
Jason Zaman789d0eb2015-07-24 16:07:13 +0800227 self.store.set_value(iter, ACTIVE, not val)
Dan Walsh514af852012-04-13 11:04:45 -0400228 self.wait()
Jason Zaman789d0eb2015-07-24 16:07:13 +0800229 setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
Jason Zaman05d1cea2016-08-05 02:34:04 +0800230 rc, out = getstatusoutput(setsebool)
Dan Walsh39d6b462012-05-24 05:51:41 -0400231 if rc != 0:
232 self.error(out)
Dan Walsh514af852012-04-13 11:04:45 -0400233 self.load(self.filter)
234 self.ready()
235
236 def on_revert_clicked(self, button):
237 self.wait()
Jason Zaman789d0eb2015-07-24 16:07:13 +0800238 setsebool = "semanage boolean --deleteall"
Jason Zaman05d1cea2016-08-05 02:34:04 +0800239 getstatusoutput(setsebool)
Dan Walsh514af852012-04-13 11:04:45 -0400240 self.load(self.filter)
241 self.ready()
242
Dan Walsh514af852012-04-13 11:04:45 -0400243 def on_local_clicked(self, button):
244 self.local = not self.local
245 self.revertButton.set_sensitive(self.local)
246
247 if self.local:
248 button.set_label(_("all"))
249 else:
250 button.set_label(_("Customized"))
251
252 self.load(self.filter)
253 return True