selinux/gui/polgengui.py
Nicolas Iooss 0f3beeb00e gui: port to Python 3 by migrating to PyGI
PyGTK has been deprecated in favor of PyGI+GTK and thus has never been
ported to python3. Using pygi-convert.sh from
https://git.gnome.org/browse/pygobject/tree/pygi-convert.sh helps
migrating most of the API but gnome-python.

The glade file has been converted to GtkBuilder using

  gtk-builder-convert system-config-selinux.glade system-config-selinux.ui

and some fixes in order to provide an application window (object
GnomeApp disappeared, GtkVBox is deprecated, etc.). The associated
Python code also needed some modifications in order to migrate to
GtkBuilder.

The result has been tested on Arch Linux with Python 3.6. There are some
bugs in the GUI itself, for which patches will be sent afterwards.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-09-25 12:54:12 -04:00

780 lines
33 KiB
Python

#!/usr/bin/python -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.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.glade", os.F_OK):
xml.add_from_file("polgen.glade")
else:
xml.add_from_file("/usr/share/system-config-selinux/polgen.glade")
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_widget("notebook")
self.label_dict = {}
self.tooltip_dict = {}
label = xml.get_widget("select_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_user_roles_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_dir_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_domain_admin_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_in_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_out_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_common_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_manages_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("select_booleans_label")
self.label_dict[label] = label.get_text()
label = xml.get_widget("existing_user_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("transition_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_tcp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_tcp_reserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_tcp_unreserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_tcp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_udp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_udp_reserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_udp_unreserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("in_udp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("out_tcp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("out_udp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("out_tcp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("out_udp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("boolean_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
label = xml.get_widget("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 = ""
xml.signal_connect("on_delete_clicked", self.delete)
xml.signal_connect("on_delete_boolean_clicked", self.delete_boolean)
xml.signal_connect("on_exec_select_clicked", self.exec_select)
xml.signal_connect("on_init_script_select_clicked", self.init_script_select)
xml.signal_connect("on_add_clicked", self.add)
xml.signal_connect("on_add_boolean_clicked", self.add_boolean)
xml.signal_connect("on_add_dir_clicked", self.add_dir)
xml.signal_connect("on_about_clicked", self.on_about_clicked)
xml.get_widget("cancel_button").connect("clicked", self.quit)
self.forward_button = xml.get_widget("forward_button")
self.forward_button.connect("clicked", self.forward)
self.back_button = xml.get_widget("back_button")
self.back_button.connect("clicked", self.back)
self.boolean_dialog = xml.get_widget("boolean_dialog")
self.boolean_name_entry = xml.get_widget("boolean_name_entry")
self.boolean_description_entry = xml.get_widget("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_widget("in_tcp_all_checkbutton")
self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
self.in_tcp_unreserved_checkbutton = xml.get_widget("in_tcp_unreserved_checkbutton")
self.in_tcp_entry = self.xml.get_widget("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_widget("out_tcp_all_checkbutton")
self.out_tcp_reserved_checkbutton = xml.get_widget("out_tcp_reserved_checkbutton")
self.out_tcp_unreserved_checkbutton = xml.get_widget("out_tcp_unreserved_checkbutton")
self.out_tcp_entry = self.xml.get_widget("out_tcp_entry")
self.network_buttons[self.out_tcp_all_checkbutton] = [self.out_tcp_entry]
self.in_udp_all_checkbutton = xml.get_widget("in_udp_all_checkbutton")
self.in_udp_reserved_checkbutton = xml.get_widget("in_udp_reserved_checkbutton")
self.in_udp_unreserved_checkbutton = xml.get_widget("in_udp_unreserved_checkbutton")
self.in_udp_entry = self.xml.get_widget("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_widget("out_udp_all_checkbutton")
self.out_udp_entry = self.xml.get_widget("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_widget("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_widget("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_widget("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_widget("in_tcp_reserved_checkbutton")
self.transition_treeview = self.xml.get_widget("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_widget("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_widget("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_widget("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_widget("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_widget("main_window")
self.druid = self.xml.get_widget("druid")
self.type = 0
self.name_entry = self.xml.get_widget("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_widget("exec_entry")
self.exec_button = self.xml.get_widget("exec_button")
self.init_script_entry = self.xml.get_widget("init_script_entry")
self.init_script_button = self.xml.get_widget("init_script_button")
self.output_entry = self.xml.get_widget("output_entry")
self.output_entry.set_text(os.getcwd())
self.xml.get_widget("output_button").connect("clicked", self.output_button_clicked)
self.xwindows_user_radiobutton = self.xml.get_widget("xwindows_user_radiobutton")
self.terminal_user_radiobutton = self.xml.get_widget("terminal_user_radiobutton")
self.root_user_radiobutton = self.xml.get_widget("root_user_radiobutton")
self.login_user_radiobutton = self.xml.get_widget("login_user_radiobutton")
self.admin_user_radiobutton = self.xml.get_widget("admin_user_radiobutton")
self.existing_user_radiobutton = self.xml.get_widget("existing_user_radiobutton")
self.user_radiobutton = self.xml.get_widget("user_radiobutton")
self.init_radiobutton = self.xml.get_widget("init_radiobutton")
self.inetd_radiobutton = self.xml.get_widget("inetd_radiobutton")
self.dbus_radiobutton = self.xml.get_widget("dbus_radiobutton")
self.cgi_radiobutton = self.xml.get_widget("cgi_radiobutton")
self.sandbox_radiobutton = self.xml.get_widget("sandbox_radiobutton")
self.tmp_checkbutton = self.xml.get_widget("tmp_checkbutton")
self.uid_checkbutton = self.xml.get_widget("uid_checkbutton")
self.pam_checkbutton = self.xml.get_widget("pam_checkbutton")
self.dbus_checkbutton = self.xml.get_widget("dbus_checkbutton")
self.audit_checkbutton = self.xml.get_widget("audit_checkbutton")
self.terminal_checkbutton = self.xml.get_widget("terminal_checkbutton")
self.mail_checkbutton = self.xml.get_widget("mail_checkbutton")
self.syslog_checkbutton = self.xml.get_widget("syslog_checkbutton")
self.view = self.xml.get_widget("write_treeview")
self.file_dialog = self.xml.get_widget("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.emit_stop_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:
generate.verify_ports(self.in_tcp_entry.get_text())
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:
generate.verify_ports(self.out_tcp_entry.get_text())
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 = 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()