72dc5c6241
setools 4.2.0 dropped support for Python 2. On systems where /usr/bin/python is Python 2, several tools are now broken because of this. Update the shebang of these tools to /usr/bin/python3. For future reference, as semanage/seobject.py, sepolicy and sepolgen import setools, every program that uses one of these modules need to be run with Python 3. The following programs do not use any of these modules so their shebangs have not been modified: dbus/selinux_server.py libsemanage/utils/semanage_migrate_store mcstrans/share/util/mlscolor-test mcstrans/share/util/mlstrans-test sandbox/start Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
784 lines
33 KiB
Python
784 lines
33 KiB
Python
#!/usr/bin/python3 -Es
|
|
#
|
|
# polgengui.py - GUI for SELinux Config tool in system-config-selinux
|
|
#
|
|
# Dan Walsh <dwalsh@redhat.com>
|
|
#
|
|
# Copyright (C) 2007-2013 Red Hat
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
#
|
|
import signal
|
|
import string
|
|
import gi
|
|
gi.require_version('Gtk', '3.0')
|
|
from gi.repository import Gtk
|
|
import os
|
|
from gi.repository import GObject
|
|
import sys
|
|
try:
|
|
import sepolicy
|
|
except ValueError as e:
|
|
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
|
|
sys.exit(1)
|
|
|
|
import sepolicy.generate
|
|
import sepolicy.interface
|
|
|
|
try:
|
|
from subprocess import getstatusoutput
|
|
except ImportError:
|
|
from commands import getstatusoutput
|
|
|
|
|
|
import re
|
|
|
|
|
|
def get_all_modules():
|
|
try:
|
|
all_modules = []
|
|
rc, output = getstatusoutput("semodule -l 2>/dev/null")
|
|
if rc == 0:
|
|
l = output.split("\n")
|
|
for i in l:
|
|
all_modules.append(i.split()[0])
|
|
except:
|
|
pass
|
|
|
|
return all_modules
|
|
|
|
|
|
##
|
|
## I18N
|
|
##
|
|
PROGNAME = "policycoreutils"
|
|
try:
|
|
import gettext
|
|
kwargs = {}
|
|
if sys.version_info < (3,):
|
|
kwargs['unicode'] = True
|
|
gettext.install(PROGNAME,
|
|
localedir="/usr/share/locale",
|
|
codeset='utf-8',
|
|
**kwargs)
|
|
except:
|
|
try:
|
|
import builtins
|
|
builtins.__dict__['_'] = str
|
|
except ImportError:
|
|
import __builtin__
|
|
__builtin__.__dict__['_'] = unicode
|
|
|
|
version = "1.0"
|
|
|
|
sys.path.append('/usr/share/system-config-selinux')
|
|
sys.path.append('.')
|
|
|
|
# From John Hunter http://www.daa.com.au/pipermail/pygtk/2003-February/004454.html
|
|
|
|
|
|
def foreach(model, path, iter, selected):
|
|
selected.append(model.get_value(iter, 0))
|
|
|
|
##
|
|
## Pull in the Glade file
|
|
##
|
|
xml = Gtk.Builder()
|
|
xml.set_translation_domain(PROGNAME)
|
|
if os.access("polgen.ui", os.F_OK):
|
|
xml.add_from_file("polgen.ui")
|
|
else:
|
|
xml.add_from_file("/usr/share/system-config-selinux/polgen.ui")
|
|
|
|
FILE = 1
|
|
DIR = 2
|
|
|
|
|
|
class childWindow:
|
|
START_PAGE = 0
|
|
SELECT_TYPE_PAGE = 0
|
|
APP_PAGE = 1
|
|
EXISTING_USER_PAGE = 2
|
|
TRANSITION_PAGE = 3
|
|
USER_TRANSITION_PAGE = 4
|
|
ADMIN_PAGE = 5
|
|
ROLE_PAGE = 6
|
|
IN_NET_PAGE = 7
|
|
OUT_NET_PAGE = 8
|
|
COMMON_APPS_PAGE = 9
|
|
FILES_PAGE = 10
|
|
BOOLEAN_PAGE = 11
|
|
SELECT_DIR_PAGE = 12
|
|
FINISH_PAGE = 12
|
|
|
|
def __init__(self):
|
|
self.xml = xml
|
|
self.notebook = xml.get_object("notebook")
|
|
self.label_dict = {}
|
|
self.tooltip_dict = {}
|
|
label = xml.get_object("select_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_user_roles_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_dir_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_domain_admin_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_in_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_out_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_common_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_manages_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("select_booleans_label")
|
|
self.label_dict[label] = label.get_text()
|
|
|
|
label = xml.get_object("existing_user_treeview")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("transition_treeview")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_tcp_all_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_tcp_reserved_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_tcp_unreserved_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_tcp_entry")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_udp_all_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_udp_reserved_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_udp_unreserved_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("in_udp_entry")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("out_tcp_entry")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("out_udp_entry")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("out_tcp_all_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("out_udp_all_checkbutton")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("boolean_treeview")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
label = xml.get_object("write_treeview")
|
|
self.tooltip_dict[label] = label.get_tooltip_text()
|
|
|
|
try:
|
|
self.all_types = sepolicy.generate.get_all_types()
|
|
self.all_modules = get_all_modules()
|
|
self.all_roles = sepolicy.generate.get_all_roles()
|
|
self.all_users = sepolicy.generate.get_all_users()
|
|
except RuntimeError as e:
|
|
self.all_types = []
|
|
self.all_modules = []
|
|
self.all_roles = []
|
|
self.all_users = []
|
|
self.error(str(e))
|
|
|
|
self.name = ""
|
|
handlers = {
|
|
"on_delete_clicked": self.delete,
|
|
"on_delete_boolean_clicked": self.delete_boolean,
|
|
"on_exec_select_clicked": self.exec_select,
|
|
"on_init_script_select_clicked": self.init_script_select,
|
|
"on_add_clicked": self.add,
|
|
"on_add_boolean_clicked": self.add_boolean,
|
|
"on_add_dir_clicked": self.add_dir,
|
|
"on_about_clicked": self.on_about_clicked
|
|
}
|
|
xml.connect_signals(handlers)
|
|
xml.get_object("cancel_button").connect("clicked", self.quit)
|
|
self.forward_button = xml.get_object("forward_button")
|
|
self.forward_button.connect("clicked", self.forward)
|
|
self.back_button = xml.get_object("back_button")
|
|
self.back_button.connect("clicked", self.back)
|
|
|
|
self.boolean_dialog = xml.get_object("boolean_dialog")
|
|
self.boolean_name_entry = xml.get_object("boolean_name_entry")
|
|
self.boolean_description_entry = xml.get_object("boolean_description_entry")
|
|
|
|
self.pages = {}
|
|
for i in sepolicy.generate.USERS:
|
|
self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
self.pages[sepolicy.generate.RUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
self.pages[sepolicy.generate.LUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
self.pages[sepolicy.generate.SANDBOX] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
self.pages[sepolicy.generate.EUSER] = [self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
|
|
for i in sepolicy.generate.APPLICATIONS:
|
|
self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
self.pages[sepolicy.generate.USER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
|
|
|
|
self.current_page = 0
|
|
self.back_button.set_sensitive(0)
|
|
|
|
self.network_buttons = {}
|
|
|
|
self.in_tcp_all_checkbutton = xml.get_object("in_tcp_all_checkbutton")
|
|
self.in_tcp_reserved_checkbutton = xml.get_object("in_tcp_reserved_checkbutton")
|
|
self.in_tcp_unreserved_checkbutton = xml.get_object("in_tcp_unreserved_checkbutton")
|
|
self.in_tcp_entry = self.xml.get_object("in_tcp_entry")
|
|
self.network_buttons[self.in_tcp_all_checkbutton] = [self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry]
|
|
|
|
self.out_tcp_all_checkbutton = xml.get_object("out_tcp_all_checkbutton")
|
|
self.out_tcp_reserved_checkbutton = xml.get_object("out_tcp_reserved_checkbutton")
|
|
self.out_tcp_unreserved_checkbutton = xml.get_object("out_tcp_unreserved_checkbutton")
|
|
self.out_tcp_entry = self.xml.get_object("out_tcp_entry")
|
|
|
|
self.network_buttons[self.out_tcp_all_checkbutton] = [self.out_tcp_entry]
|
|
|
|
self.in_udp_all_checkbutton = xml.get_object("in_udp_all_checkbutton")
|
|
self.in_udp_reserved_checkbutton = xml.get_object("in_udp_reserved_checkbutton")
|
|
self.in_udp_unreserved_checkbutton = xml.get_object("in_udp_unreserved_checkbutton")
|
|
self.in_udp_entry = self.xml.get_object("in_udp_entry")
|
|
|
|
self.network_buttons[self.in_udp_all_checkbutton] = [self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry]
|
|
|
|
self.out_udp_all_checkbutton = xml.get_object("out_udp_all_checkbutton")
|
|
self.out_udp_entry = self.xml.get_object("out_udp_entry")
|
|
self.network_buttons[self.out_udp_all_checkbutton] = [self.out_udp_entry]
|
|
|
|
for b in self.network_buttons.keys():
|
|
b.connect("clicked", self.network_all_clicked)
|
|
|
|
self.boolean_treeview = self.xml.get_object("boolean_treeview")
|
|
self.boolean_store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
|
|
self.boolean_treeview.set_model(self.boolean_store)
|
|
self.boolean_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Name"), Gtk.CellRendererText(), text=0)
|
|
self.boolean_treeview.append_column(col)
|
|
col = Gtk.TreeViewColumn(_("Description"), Gtk.CellRendererText(), text=1)
|
|
self.boolean_treeview.append_column(col)
|
|
|
|
self.role_treeview = self.xml.get_object("role_treeview")
|
|
self.role_store = Gtk.ListStore(GObject.TYPE_STRING)
|
|
self.role_treeview.set_model(self.role_store)
|
|
self.role_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
|
|
self.role_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Role"), Gtk.CellRendererText(), text=0)
|
|
self.role_treeview.append_column(col)
|
|
|
|
self.existing_user_treeview = self.xml.get_object("existing_user_treeview")
|
|
self.existing_user_store = Gtk.ListStore(GObject.TYPE_STRING)
|
|
self.existing_user_treeview.set_model(self.existing_user_store)
|
|
self.existing_user_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Existing_User"), Gtk.CellRendererText(), text=0)
|
|
self.existing_user_treeview.append_column(col)
|
|
|
|
for i in self.all_roles:
|
|
iter = self.role_store.append()
|
|
self.role_store.set_value(iter, 0, i[:-2])
|
|
|
|
self.in_tcp_reserved_checkbutton = xml.get_object("in_tcp_reserved_checkbutton")
|
|
|
|
self.transition_treeview = self.xml.get_object("transition_treeview")
|
|
self.transition_store = Gtk.ListStore(GObject.TYPE_STRING)
|
|
self.transition_treeview.set_model(self.transition_store)
|
|
self.transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
|
|
self.transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
|
|
self.transition_treeview.append_column(col)
|
|
|
|
self.user_transition_treeview = self.xml.get_object("user_transition_treeview")
|
|
self.user_transition_store = Gtk.ListStore(GObject.TYPE_STRING)
|
|
self.user_transition_treeview.set_model(self.user_transition_store)
|
|
self.user_transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
|
|
self.user_transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
|
|
self.user_transition_treeview.append_column(col)
|
|
|
|
for i in self.all_users:
|
|
iter = self.user_transition_store.append()
|
|
self.user_transition_store.set_value(iter, 0, i[:-2])
|
|
iter = self.existing_user_store.append()
|
|
self.existing_user_store.set_value(iter, 0, i[:-2])
|
|
|
|
self.admin_treeview = self.xml.get_object("admin_treeview")
|
|
self.admin_store = Gtk.ListStore(GObject.TYPE_STRING)
|
|
self.admin_treeview.set_model(self.admin_store)
|
|
self.admin_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
|
|
self.admin_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
|
col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
|
|
self.admin_treeview.append_column(col)
|
|
|
|
try:
|
|
for u in sepolicy.interface.get_user():
|
|
iter = self.transition_store.append()
|
|
self.transition_store.set_value(iter, 0, u)
|
|
|
|
for a in sepolicy.interface.get_admin():
|
|
iter = self.admin_store.append()
|
|
self.admin_store.set_value(iter, 0, a)
|
|
except ValueError as e:
|
|
self.error(e.message)
|
|
|
|
def confine_application(self):
|
|
return self.get_type() in sepolicy.generate.APPLICATIONS
|
|
|
|
def forward(self, arg):
|
|
type = self.get_type()
|
|
if self.current_page == self.START_PAGE:
|
|
self.back_button.set_sensitive(1)
|
|
|
|
if self.pages[type][self.current_page] == self.SELECT_TYPE_PAGE:
|
|
if self.on_select_type_page_next():
|
|
return
|
|
|
|
if self.pages[type][self.current_page] == self.IN_NET_PAGE:
|
|
if self.on_in_net_page_next():
|
|
return
|
|
|
|
if self.pages[type][self.current_page] == self.OUT_NET_PAGE:
|
|
if self.on_out_net_page_next():
|
|
return
|
|
|
|
if self.pages[type][self.current_page] == self.APP_PAGE:
|
|
if self.on_name_page_next():
|
|
return
|
|
|
|
if self.pages[type][self.current_page] == self.EXISTING_USER_PAGE:
|
|
if self.on_existing_user_page_next():
|
|
return
|
|
|
|
if self.pages[type][self.current_page] == self.SELECT_DIR_PAGE:
|
|
outputdir = self.output_entry.get_text()
|
|
if not os.path.isdir(outputdir):
|
|
self.error(_("%s must be a directory") % outputdir)
|
|
return False
|
|
|
|
if self.pages[type][self.current_page] == self.FINISH_PAGE:
|
|
self.generate_policy()
|
|
self.xml.get_object("cancel_button").set_label(Gtk.STOCK_CLOSE)
|
|
else:
|
|
self.current_page = self.current_page + 1
|
|
self.notebook.set_current_page(self.pages[type][self.current_page])
|
|
if self.pages[type][self.current_page] == self.FINISH_PAGE:
|
|
self.forward_button.set_label(Gtk.STOCK_APPLY)
|
|
|
|
def back(self, arg):
|
|
type = self.get_type()
|
|
if self.pages[type][self.current_page] == self.FINISH_PAGE:
|
|
self.forward_button.set_label(Gtk.STOCK_GO_FORWARD)
|
|
|
|
self.current_page = self.current_page - 1
|
|
self.notebook.set_current_page(self.pages[type][self.current_page])
|
|
if self.pages[type][self.current_page] == self.START_PAGE:
|
|
self.back_button.set_sensitive(0)
|
|
|
|
def network_all_clicked(self, button):
|
|
active = button.get_active()
|
|
for b in self.network_buttons[button]:
|
|
b.set_sensitive(not active)
|
|
|
|
def verify(self, message, title=""):
|
|
dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
|
|
Gtk.ButtonsType.YES_NO,
|
|
message)
|
|
dlg.set_title(title)
|
|
dlg.set_position(Gtk.WindowPosition.MOUSE)
|
|
dlg.show_all()
|
|
rc = dlg.run()
|
|
dlg.destroy()
|
|
return rc
|
|
|
|
def info(self, message):
|
|
dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
|
|
Gtk.ButtonsType.OK,
|
|
message)
|
|
dlg.set_position(Gtk.WindowPosition.MOUSE)
|
|
dlg.show_all()
|
|
dlg.run()
|
|
dlg.destroy()
|
|
|
|
def error(self, message):
|
|
dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
|
|
Gtk.ButtonsType.CLOSE,
|
|
message)
|
|
dlg.set_position(Gtk.WindowPosition.MOUSE)
|
|
dlg.show_all()
|
|
dlg.run()
|
|
dlg.destroy()
|
|
|
|
def get_name(self):
|
|
if self.existing_user_radiobutton.get_active():
|
|
store, iter = self.existing_user_treeview.get_selection().get_selected()
|
|
if iter == None:
|
|
raise ValueError(_("You must select a user"))
|
|
return store.get_value(iter, 0)
|
|
else:
|
|
return self.name_entry.get_text()
|
|
|
|
def get_type(self):
|
|
if self.sandbox_radiobutton.get_active():
|
|
return sepolicy.generate.SANDBOX
|
|
if self.cgi_radiobutton.get_active():
|
|
return sepolicy.generate.CGI
|
|
if self.user_radiobutton.get_active():
|
|
return sepolicy.generate.USER
|
|
if self.init_radiobutton.get_active():
|
|
return sepolicy.generate.DAEMON
|
|
if self.dbus_radiobutton.get_active():
|
|
return sepolicy.generate.DBUS
|
|
if self.inetd_radiobutton.get_active():
|
|
return sepolicy.generate.INETD
|
|
if self.login_user_radiobutton.get_active():
|
|
return sepolicy.generate.LUSER
|
|
if self.admin_user_radiobutton.get_active():
|
|
return sepolicy.generate.AUSER
|
|
if self.xwindows_user_radiobutton.get_active():
|
|
return sepolicy.generate.XUSER
|
|
if self.terminal_user_radiobutton.get_active():
|
|
return sepolicy.generate.TUSER
|
|
if self.root_user_radiobutton.get_active():
|
|
return sepolicy.generate.RUSER
|
|
if self.existing_user_radiobutton.get_active():
|
|
return sepolicy.generate.EUSER
|
|
|
|
def generate_policy(self, *args):
|
|
outputdir = self.output_entry.get_text()
|
|
try:
|
|
my_policy = sepolicy.generate.policy(self.get_name(), self.get_type())
|
|
|
|
iter = self.boolean_store.get_iter_first()
|
|
while(iter):
|
|
my_policy.add_boolean(self.boolean_store.get_value(iter, 0), self.boolean_store.get_value(iter, 1))
|
|
iter = self.boolean_store.iter_next(iter)
|
|
|
|
if self.get_type() in sepolicy.generate.APPLICATIONS:
|
|
my_policy.set_program(self.exec_entry.get_text())
|
|
my_policy.gen_symbols()
|
|
|
|
my_policy.set_use_syslog(self.syslog_checkbutton.get_active() == 1)
|
|
my_policy.set_use_tmp(self.tmp_checkbutton.get_active() == 1)
|
|
my_policy.set_use_uid(self.uid_checkbutton.get_active() == 1)
|
|
my_policy.set_use_pam(self.pam_checkbutton.get_active() == 1)
|
|
|
|
my_policy.set_use_dbus(self.dbus_checkbutton.get_active() == 1)
|
|
my_policy.set_use_audit(self.audit_checkbutton.get_active() == 1)
|
|
my_policy.set_use_terminal(self.terminal_checkbutton.get_active() == 1)
|
|
my_policy.set_use_mail(self.mail_checkbutton.get_active() == 1)
|
|
if self.get_type() is sepolicy.generate.DAEMON:
|
|
my_policy.set_init_script(self.init_script_entry.get_text())
|
|
if self.get_type() == sepolicy.generate.USER:
|
|
selected = []
|
|
self.user_transition_treeview.get_selection().selected_foreach(foreach, selected)
|
|
my_policy.set_transition_users(selected)
|
|
else:
|
|
if self.get_type() == sepolicy.generate.RUSER:
|
|
selected = []
|
|
self.admin_treeview.get_selection().selected_foreach(foreach, selected)
|
|
my_policy.set_admin_domains(selected)
|
|
selected = []
|
|
self.user_transition_treeview.get_selection().selected_foreach(foreach, selected)
|
|
my_policy.set_transition_users(selected)
|
|
else:
|
|
selected = []
|
|
self.transition_treeview.get_selection().selected_foreach(foreach, selected)
|
|
my_policy.set_transition_domains(selected)
|
|
|
|
selected = []
|
|
self.role_treeview.get_selection().selected_foreach(foreach, selected)
|
|
my_policy.set_admin_roles(selected)
|
|
|
|
my_policy.set_in_tcp(self.in_tcp_all_checkbutton.get_active(), self.in_tcp_reserved_checkbutton.get_active(), self.in_tcp_unreserved_checkbutton.get_active(), self.in_tcp_entry.get_text())
|
|
my_policy.set_in_udp(self.in_udp_all_checkbutton.get_active(), self.in_udp_reserved_checkbutton.get_active(), self.in_udp_unreserved_checkbutton.get_active(), self.in_udp_entry.get_text())
|
|
my_policy.set_out_tcp(self.out_tcp_all_checkbutton.get_active(), self.out_tcp_entry.get_text())
|
|
my_policy.set_out_udp(self.out_udp_all_checkbutton.get_active(), self.out_udp_entry.get_text())
|
|
|
|
iter = self.store.get_iter_first()
|
|
while(iter):
|
|
if self.store.get_value(iter, 1) == FILE:
|
|
my_policy.add_file(self.store.get_value(iter, 0))
|
|
else:
|
|
my_policy.add_dir(self.store.get_value(iter, 0))
|
|
iter = self.store.iter_next(iter)
|
|
|
|
self.info(my_policy.generate(outputdir))
|
|
return False
|
|
except ValueError as e:
|
|
self.error(e.message)
|
|
|
|
def delete(self, args):
|
|
store, iter = self.view.get_selection().get_selected()
|
|
if iter != None:
|
|
store.remove(iter)
|
|
self.view.get_selection().select_path((0,))
|
|
|
|
def delete_boolean(self, args):
|
|
store, iter = self.boolean_treeview.get_selection().get_selected()
|
|
if iter != None:
|
|
store.remove(iter)
|
|
self.boolean_treeview.get_selection().select_path((0,))
|
|
|
|
def add_boolean(self, type):
|
|
self.boolean_name_entry.set_text("")
|
|
self.boolean_description_entry.set_text("")
|
|
rc = self.boolean_dialog.run()
|
|
self.boolean_dialog.hide()
|
|
if rc == Gtk.ResponseType.CANCEL:
|
|
return
|
|
iter = self.boolean_store.append()
|
|
self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text())
|
|
self.boolean_store.set_value(iter, 1, self.boolean_description_entry.get_text())
|
|
|
|
def __add(self, type):
|
|
rc = self.file_dialog.run()
|
|
self.file_dialog.hide()
|
|
if rc == Gtk.ResponseType.CANCEL:
|
|
return
|
|
for i in self.file_dialog.get_filenames():
|
|
iter = self.store.append()
|
|
self.store.set_value(iter, 0, i)
|
|
self.store.set_value(iter, 1, type)
|
|
|
|
def exec_select(self, args):
|
|
self.file_dialog.set_select_multiple(0)
|
|
self.file_dialog.set_title(_("Select executable file to be confined."))
|
|
self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
|
|
self.file_dialog.set_current_folder("/usr/sbin")
|
|
rc = self.file_dialog.run()
|
|
self.file_dialog.hide()
|
|
if rc == Gtk.ResponseType.CANCEL:
|
|
return
|
|
self.exec_entry.set_text(self.file_dialog.get_filename())
|
|
|
|
def init_script_select(self, args):
|
|
self.file_dialog.set_select_multiple(0)
|
|
self.file_dialog.set_title(_("Select init script file to be confined."))
|
|
self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
|
|
self.file_dialog.set_current_folder("/etc/rc.d/init.d")
|
|
rc = self.file_dialog.run()
|
|
self.file_dialog.hide()
|
|
if rc == Gtk.ResponseType.CANCEL:
|
|
return
|
|
self.init_script_entry.set_text(self.file_dialog.get_filename())
|
|
|
|
def add(self, args):
|
|
self.file_dialog.set_title(_("Select file(s) that confined application creates or writes"))
|
|
self.file_dialog.set_current_folder("/")
|
|
self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
|
|
self.file_dialog.set_select_multiple(1)
|
|
self.__add(FILE)
|
|
|
|
def add_dir(self, args):
|
|
self.file_dialog.set_title(_("Select directory(s) that the confined application owns and writes into"))
|
|
self.file_dialog.set_current_folder("/")
|
|
self.file_dialog.set_select_multiple(1)
|
|
self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
|
|
self.__add(DIR)
|
|
|
|
def on_about_clicked(self, args):
|
|
dlg = xml.get_object("about_dialog")
|
|
dlg.run()
|
|
dlg.hide()
|
|
|
|
def quit(self, args):
|
|
Gtk.main_quit()
|
|
|
|
def setupScreen(self):
|
|
# Bring in widgets from glade file.
|
|
self.mainWindow = self.xml.get_object("main_window")
|
|
self.druid = self.xml.get_object("druid")
|
|
self.type = 0
|
|
self.name_entry = self.xml.get_object("name_entry")
|
|
self.name_entry.connect("insert_text", self.on_name_entry_changed)
|
|
self.name_entry.connect("focus_out_event", self.on_focus_out_event)
|
|
self.exec_entry = self.xml.get_object("exec_entry")
|
|
self.exec_button = self.xml.get_object("exec_button")
|
|
self.init_script_entry = self.xml.get_object("init_script_entry")
|
|
self.init_script_button = self.xml.get_object("init_script_button")
|
|
self.output_entry = self.xml.get_object("output_entry")
|
|
self.output_entry.set_text(os.getcwd())
|
|
self.xml.get_object("output_button").connect("clicked", self.output_button_clicked)
|
|
|
|
self.xwindows_user_radiobutton = self.xml.get_object("xwindows_user_radiobutton")
|
|
self.terminal_user_radiobutton = self.xml.get_object("terminal_user_radiobutton")
|
|
self.root_user_radiobutton = self.xml.get_object("root_user_radiobutton")
|
|
self.login_user_radiobutton = self.xml.get_object("login_user_radiobutton")
|
|
self.admin_user_radiobutton = self.xml.get_object("admin_user_radiobutton")
|
|
self.existing_user_radiobutton = self.xml.get_object("existing_user_radiobutton")
|
|
|
|
self.user_radiobutton = self.xml.get_object("user_radiobutton")
|
|
self.init_radiobutton = self.xml.get_object("init_radiobutton")
|
|
self.inetd_radiobutton = self.xml.get_object("inetd_radiobutton")
|
|
self.dbus_radiobutton = self.xml.get_object("dbus_radiobutton")
|
|
self.cgi_radiobutton = self.xml.get_object("cgi_radiobutton")
|
|
self.sandbox_radiobutton = self.xml.get_object("sandbox_radiobutton")
|
|
self.tmp_checkbutton = self.xml.get_object("tmp_checkbutton")
|
|
self.uid_checkbutton = self.xml.get_object("uid_checkbutton")
|
|
self.pam_checkbutton = self.xml.get_object("pam_checkbutton")
|
|
self.dbus_checkbutton = self.xml.get_object("dbus_checkbutton")
|
|
self.audit_checkbutton = self.xml.get_object("audit_checkbutton")
|
|
self.terminal_checkbutton = self.xml.get_object("terminal_checkbutton")
|
|
self.mail_checkbutton = self.xml.get_object("mail_checkbutton")
|
|
self.syslog_checkbutton = self.xml.get_object("syslog_checkbutton")
|
|
self.view = self.xml.get_object("write_treeview")
|
|
self.file_dialog = self.xml.get_object("filechooserdialog")
|
|
|
|
self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
|
|
self.view.set_model(self.store)
|
|
col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0)
|
|
col.set_resizable(True)
|
|
self.view.append_column(col)
|
|
self.view.get_selection().select_path((0,))
|
|
|
|
def output_button_clicked(self, *args):
|
|
self.file_dialog.set_title(_("Select directory to generate policy files in"))
|
|
self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
|
|
self.file_dialog.set_select_multiple(0)
|
|
rc = self.file_dialog.run()
|
|
self.file_dialog.hide()
|
|
if rc == Gtk.ResponseType.CANCEL:
|
|
return
|
|
self.output_entry.set_text(self.file_dialog.get_filename())
|
|
|
|
def on_name_entry_changed(self, entry, text, size, position):
|
|
if text.find(" ") >= 0:
|
|
entry.stop_emission_by_name("insert-text")
|
|
|
|
def on_focus_out_event(self, entry, third):
|
|
name = entry.get_text()
|
|
if self.name != name:
|
|
if name in self.all_types:
|
|
if self.verify(_("Type %s_t already defined in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO:
|
|
entry.set_text("")
|
|
return False
|
|
if name in self.all_modules:
|
|
if self.verify(_("Module %s already loaded in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO:
|
|
entry.set_text("")
|
|
return False
|
|
|
|
file = "/etc/rc.d/init.d/" + name
|
|
if os.path.isfile(file) and self.init_script_entry.get_text() == "":
|
|
self.init_script_entry.set_text(file)
|
|
|
|
file = "/usr/sbin/" + name
|
|
if os.path.isfile(file) and self.exec_entry.get_text() == "":
|
|
self.exec_entry.set_text(file)
|
|
|
|
self.name = name
|
|
return False
|
|
|
|
def on_in_net_page_next(self, *args):
|
|
try:
|
|
sepolicy.generate.verify_ports(self.in_tcp_entry.get_text())
|
|
sepolicy.generate.verify_ports(self.in_udp_entry.get_text())
|
|
except ValueError as e:
|
|
self.error(e.message)
|
|
return True
|
|
|
|
def on_out_net_page_next(self, *args):
|
|
try:
|
|
sepolicy.generate.verify_ports(self.out_tcp_entry.get_text())
|
|
sepolicy.generate.verify_ports(self.out_udp_entry.get_text())
|
|
except ValueError as e:
|
|
self.error(e.message)
|
|
return True
|
|
|
|
def on_select_type_page_next(self, *args):
|
|
self.exec_entry.set_sensitive(self.confine_application())
|
|
self.exec_button.set_sensitive(self.confine_application())
|
|
self.init_script_entry.set_sensitive(self.init_radiobutton.get_active())
|
|
self.init_script_button.set_sensitive(self.init_radiobutton.get_active())
|
|
|
|
def on_existing_user_page_next(self, *args):
|
|
store, iter = self.view.get_selection().get_selected()
|
|
if iter != None:
|
|
self.error(_("You must select a user"))
|
|
return True
|
|
|
|
def on_name_page_next(self, *args):
|
|
name = self.name_entry.get_text()
|
|
if not name.isalnum():
|
|
self.error(_("You must add a name made up of letters and numbers and containing no spaces."))
|
|
return True
|
|
|
|
for i in self.label_dict:
|
|
text = '<b>%s</b>' % (self.label_dict[i] % ("'" + name + "'"))
|
|
i.set_markup(text)
|
|
|
|
for i in self.tooltip_dict:
|
|
text = self.tooltip_dict[i] % ("'" + name + "'")
|
|
i.set_tooltip_text(text)
|
|
|
|
if self.confine_application():
|
|
exe = self.exec_entry.get_text()
|
|
if exe == "":
|
|
self.error(_("You must enter a executable"))
|
|
return True
|
|
policy = sepolicy.generate.policy(name, self.get_type())
|
|
policy.set_program(exe)
|
|
policy.gen_writeable()
|
|
policy.gen_symbols()
|
|
for f in policy.files.keys():
|
|
iter = self.store.append()
|
|
self.store.set_value(iter, 0, f)
|
|
self.store.set_value(iter, 1, FILE)
|
|
|
|
for f in policy.dirs.keys():
|
|
iter = self.store.append()
|
|
self.store.set_value(iter, 0, f)
|
|
self.store.set_value(iter, 1, DIR)
|
|
self.tmp_checkbutton.set_active(policy.use_tmp)
|
|
self.uid_checkbutton.set_active(policy.use_uid)
|
|
self.pam_checkbutton.set_active(policy.use_pam)
|
|
self.dbus_checkbutton.set_active(policy.use_dbus)
|
|
self.audit_checkbutton.set_active(policy.use_audit)
|
|
self.terminal_checkbutton.set_active(policy.use_terminal)
|
|
self.mail_checkbutton.set_active(policy.use_mail)
|
|
self.syslog_checkbutton.set_active(policy.use_syslog)
|
|
|
|
def stand_alone(self):
|
|
desktopName = _("Configue SELinux")
|
|
|
|
self.setupScreen()
|
|
self.mainWindow.connect("destroy", self.quit)
|
|
|
|
self.mainWindow.show_all()
|
|
Gtk.main()
|
|
|
|
if __name__ == "__main__":
|
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
|
|
|
app = childWindow()
|
|
app.stand_alone()
|