diff --git a/policycoreutils-fedora.patch b/policycoreutils-fedora.patch index c32e96d..c8aaba7 100644 --- a/policycoreutils-fedora.patch +++ b/policycoreutils-fedora.patch @@ -1,3 +1,35 @@ +diff --git policycoreutils-2.7/load_policy/load_policy.8 policycoreutils-2.7/load_policy/load_policy.8 +index 5f5550d..0810995 100644 +--- policycoreutils-2.7/load_policy/load_policy.8 ++++ policycoreutils-2.7/load_policy/load_policy.8 +@@ -39,4 +39,4 @@ Initial policy load failed and enforcing mode requested + .SH AUTHORS + .nf + This manual page was written by Dan Walsh . +-The program was written by Stephen Smalley . ++The program was written by Stephen Smalley . +diff --git policycoreutils-2.7/newrole/hashtab.c policycoreutils-2.7/newrole/hashtab.c +index 77ed143..24c65c4 100644 +--- policycoreutils-2.7/newrole/hashtab.c ++++ policycoreutils-2.7/newrole/hashtab.c +@@ -1,5 +1,5 @@ + +-/* Author : Stephen Smalley, */ ++/* Author : Stephen Smalley, */ + + /* FLASK */ + +diff --git policycoreutils-2.7/newrole/hashtab.h policycoreutils-2.7/newrole/hashtab.h +index 9f737df..3790f0a 100644 +--- policycoreutils-2.7/newrole/hashtab.h ++++ policycoreutils-2.7/newrole/hashtab.h +@@ -1,5 +1,5 @@ + +-/* Author : Stephen Smalley, */ ++/* Author : Stephen Smalley, */ + + /* FLASK */ + diff --git policycoreutils-2.7/scripts/fixfiles policycoreutils-2.7/scripts/fixfiles index 1aa330f..7ec0396 100755 --- policycoreutils-2.7/scripts/fixfiles @@ -10,3 +42,16 @@ index 1aa330f..7ec0396 100755 FORCEFLAG="" RPMFILES="" PREFC="" +diff --git policycoreutils-2.7/setfiles/setfiles.8 policycoreutils-2.7/setfiles/setfiles.8 +index 9501845..ccaaf4d 100644 +--- policycoreutils-2.7/setfiles/setfiles.8 ++++ policycoreutils-2.7/setfiles/setfiles.8 +@@ -255,7 +255,7 @@ being updated provided there are no errors. + + .SH "AUTHOR" + This man page was written by Russell Coker . +-The program was written by Stephen Smalley ++The program was written by Stephen Smalley + + .SH "SEE ALSO" + .BR restorecon (8), diff --git a/policycoreutils.spec b/policycoreutils.spec index 1d5215f..56e1c66 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -1,7 +1,7 @@ %global libauditver 2.1.3-4 -%global libsepolver 2.7-1 -%global libsemanagever 2.7-1 -%global libselinuxver 2.7-1 +%global libsepolver 2.7-2 +%global libsemanagever 2.7-4 +%global libselinuxver 2.7-5 %global sepolgenver 2.7 %global generatorsdir %{_prefix}/lib/systemd/system-generators @@ -9,7 +9,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.7 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2 Group: System Environment/Base # https://github.com/SELinuxProject/selinux/wiki/Releases @@ -31,16 +31,17 @@ Source18: selinux-autorelabel.target Source19: selinux-autorelabel-generator.sh # download https://raw.githubusercontent.com/fedora-selinux/scripts/master/selinux/make-fedora-selinux-patch.sh # run: -# $ VERSION=2.7 ./make-fedora-selinux-patch.sh policycoreutils -# HEAD https://github.com/fedora-selinux/selinux/commit/70a12c5e7b56a81223d67ce2469292826b84efe9 +# HEAD https://github.com/fedora-selinux/selinux/commit/4247fad665261169b430895f0ab10f56eb33dd10 +# $ for i in policycoreutils selinux-python selinux-gui selinux-sandbox selinux-dbus semodule-utils restorecond; do +# ./make-fedora-selinux-patch.sh $i +# done Patch: policycoreutils-fedora.patch -# $ VERSION=2.7 ./make-fedora-selinux-patch.sh selinux-python Patch1: selinux-python-fedora.patch Patch2: selinux-gui-fedora.patch Patch3: selinux-sandbox-fedora.patch Patch4: selinux-dbus-fedora.patch -# Patch5: semodule-utils-fedora.patch -# Patch6: restorecond +Patch5: semodule-utils-fedora.patch +Patch6: restorecond-fedora.patch Obsoletes: policycoreutils < 2.0.61-2 Conflicts: filesystem < 3, selinux-policy-base < 3.13.1-138 # initscripts < 9.66 shipped fedora-autorelabel services which are renamed to selinux-relabel @@ -90,8 +91,8 @@ tar -xvf %{SOURCE14} -C selinux-python-%{version}/sepolicy/ %patch2 -p0 -b .selinux-gui %patch3 -p0 -b .selinux-sandbox %patch4 -p0 -b .selinux-dbus -# %patch5 -p0 -b .semodule-utils -# %patch6 -p0 -b .restorecond +%patch5 -p0 -b .semodule-utils +%patch6 -p0 -b .restorecond %build @@ -126,7 +127,6 @@ make -C semodule-utils-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBI make -C restorecond-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -# make -C policycoreutils-%{version} PYTHON=%{__python3} LSPP_PRIV=y DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" SEMODULE_PATH="/usr/sbin" install # Systemd rm -rf %{buildroot}/%{_sysconfdir}/rc.d/init.d/restorecond @@ -134,6 +134,7 @@ rm -rf %{buildroot}/%{_sysconfdir}/rc.d/init.d/restorecond tar -jxf %{SOURCE12} -C %{buildroot}/ rm -f %{buildroot}/usr/share/man/ru/man8/genhomedircon.8.gz rm -f %{buildroot}/usr/share/man/ru/man8/open_init_pty.8.gz +rm -f %{buildroot}/usr/share/man/ru/man8/semodule_deps.8.gz rm -f %{buildroot}/usr/share/man/man8/open_init_pty.8 rm -f %{buildroot}/usr/sbin/open_init_pty rm -f %{buildroot}/usr/sbin/run_init @@ -331,12 +332,9 @@ The policycoreutils-devel package contains the management tools use to develop p %{_mandir}/man8/sepolicy-manpage.8* %{_mandir}/man8/sepolicy-transition.8* %{_usr}/share/bash-completion/completions/sepolicy -%{_bindir}/semodule_deps %{_bindir}/semodule_expand %{_bindir}/semodule_link %{_bindir}/semodule_unpackage -%{_mandir}/man8/semodule_deps.8* -%{_mandir}/ru/man8/semodule_deps.8* %{_mandir}/man8/semodule_expand.8* %{_mandir}/ru/man8/semodule_expand.8* %{_mandir}/man8/semodule_link.8* @@ -405,6 +403,7 @@ system-config-selinux is a utility for managing the SELinux environment %{_datadir}/system-config-selinux/polgengui.py* %{_datadir}/system-config-selinux/system-config-selinux.py* %{_datadir}/system-config-selinux/*.glade +%{_datadir}/system-config-selinux/*.ui %{python_sitelib}/sepolicy/gui.py* %{python_sitelib}/sepolicy/sepolicy.glade %dir %{python_sitelib}/sepolicy/help @@ -503,6 +502,18 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Fri Oct 20 2017 Petr Lautrbach - 2.7-4 +- restorecond: check write() and daemon() results +- sepolicy: do not fail when file_contexts.local or .subs do not exist +- sepolicy: remove stray space in section "SEE ALSO" +- sepolicy: fix misspelling of _ra_content_t suffix +- gui: port to Python 3 by migrating to PyGI +- gui: remove the status bar +- gui: fix parsing of "semodule -lfull" in tab Modules +- gui: delete overridden definition of usersPage.delete() +- Enable listing file_contexts.homedirs (#1409813) +- remove semodule_deps + * Sat Aug 19 2017 Zbigniew Jędrzejewski-Szmek - 2.7-3 - Also add Provides for the old name without %%_isa diff --git a/restorecond-fedora.patch b/restorecond-fedora.patch new file mode 100644 index 0000000..5e07eac --- /dev/null +++ b/restorecond-fedora.patch @@ -0,0 +1,29 @@ +diff --git restorecond-2.7/restorecond.c restorecond-2.7/restorecond.c +index f379db1..6fbbd35 100644 +--- restorecond-2.7/restorecond.c ++++ restorecond-2.7/restorecond.c +@@ -103,7 +103,10 @@ static int write_pid_file(void) + pidfile = 0; + return 1; + } +- (void)write(pidfd, val, (unsigned int)len); ++ if (write(pidfd, val, (unsigned int)len) != len) { ++ syslog(LOG_ERR, "Unable to write to pidfile (%s)", strerror(errno)); ++ return 1; ++ } + close(pidfd); + return 0; + } +@@ -204,8 +207,10 @@ int main(int argc, char **argv) + watch_file = server_watch_file; + read_config(master_fd, watch_file); + +- if (!debug_mode) +- daemon(0, 0); ++ if (!debug_mode) { ++ if (daemon(0, 0) < 0) ++ exitApp("daemon"); ++ } + + write_pid_file(); + diff --git a/selinux-gui-fedora.patch b/selinux-gui-fedora.patch index 2ecb394..7ba7ab5 100644 --- a/selinux-gui-fedora.patch +++ b/selinux-gui-fedora.patch @@ -1,7 +1,513 @@ +diff --git selinux-gui-2.7/Makefile selinux-gui-2.7/Makefile +index 4fc2c1a..cfe4740 100644 +--- selinux-gui-2.7/Makefile ++++ selinux-gui-2.7/Makefile +@@ -11,14 +11,13 @@ domainsPage.py \ + fcontextPage.py \ + html_util.py \ + loginsPage.py \ +-mappingsPage.py \ + modulesPage.py \ + polgen.glade \ + portsPage.py \ + semanagePage.py \ + statusPage.py \ +-system-config-selinux.glade \ + system-config-selinux.png \ ++system-config-selinux.ui \ + usersPage.py + + all: $(TARGETS) system-config-selinux.py polgengui.py +diff --git selinux-gui-2.7/booleansPage.py selinux-gui-2.7/booleansPage.py +index a5d04bf..7849bea 100644 +--- selinux-gui-2.7/booleansPage.py ++++ selinux-gui-2.7/booleansPage.py +@@ -18,13 +18,8 @@ + # You should have received a copy of the GNU General Public License + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys +-import tempfile ++from gi.repository import Gdk, GObject, Gtk + import seobject + import semanagePage + +@@ -61,8 +56,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-from glob import fnmatch +- + + class Modifier: + +@@ -94,56 +87,53 @@ class booleansPage: + + def __init__(self, xml, doDebug=None): + self.xml = xml +- self.window = self.xml.get_widget("mainWindow").get_root_window() ++ self.window = self.xml.get_object("mainWindow").get_root_window() + self.local = False + self.types = [] + self.selinuxsupport = True + self.typechanged = False + self.doDebug = doDebug +- self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) +- self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) ++ self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) ++ self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) + + # Bring in widgets from glade file. +- self.typeHBox = xml.get_widget("typeHBox") +- self.booleanSW = xml.get_widget("booleanSW") +- self.booleansFilter = xml.get_widget("booleansFilter") ++ self.booleansFilter = xml.get_object("booleansFilter") + self.booleansFilter.connect("focus_out_event", self.filter_changed) + self.booleansFilter.connect("activate", self.filter_changed) ++ self.booleansFilter.connect("changed", self.filter_changed) + +- self.booleansView = xml.get_widget("booleansView") +- self.typeLabel = xml.get_widget("typeLabel") +- self.modifySeparator = xml.get_widget("modifySeparator") ++ self.booleansView = xml.get_object("booleansView") + +- self.revertButton = xml.get_widget("booleanRevertButton") ++ self.revertButton = xml.get_object("booleanRevertButton") + self.revertButton.set_sensitive(self.local) + self.revertButton.connect("clicked", self.on_revert_clicked) +- listStore = gtk.ListStore(gobject.TYPE_STRING) +- cell = gtk.CellRendererText() ++ listStore = Gtk.ListStore(GObject.TYPE_STRING) ++ cell = Gtk.CellRendererText() + +- self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) +- self.store.set_sort_column_id(1, gtk.SORT_ASCENDING) ++ self.store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) ++ self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING) + self.booleansView.set_model(self.store) + +- checkbox = gtk.CellRendererToggle() ++ checkbox = Gtk.CellRendererToggle() + checkbox.connect("toggled", self.boolean_toggled) +- col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE) ++ col = Gtk.TreeViewColumn('Active', checkbox, active=ACTIVE) + col.set_clickable(True) + col.set_sort_column_id(ACTIVE) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Module", gtk.CellRendererText(), text=MODULE) ++ col = Gtk.TreeViewColumn("Module", Gtk.CellRendererText(), text=MODULE) + col.set_sort_column_id(MODULE) + col.set_resizable(True) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC) +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col = Gtk.TreeViewColumn("Description", Gtk.CellRendererText(), text=DESC) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(400) + col.set_sort_column_id(DESC) + col.set_resizable(True) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Name", gtk.CellRendererText(), text=BOOLEAN) ++ col = Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=BOOLEAN) + col.set_sort_column_id(BOOLEAN) + col.set_resizable(True) + self.booleansView.set_search_equal_func(self.__search) +@@ -152,10 +142,10 @@ class booleansPage: + self.load(self.filter) + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -178,11 +168,11 @@ class booleansPage: + + def deleteDialog(self): + store, iter = self.booleansView.get_selection().get_selected() +- if iter == None: ++ if iter is None: + return + boolean = store.get_value(iter, BOOLEAN) + # change cursor +- if boolean == None: ++ if boolean is None: + return + try: + self.wait() +diff --git selinux-gui-2.7/domainsPage.py selinux-gui-2.7/domainsPage.py +index 66f882a..bad5140 100644 +--- selinux-gui-2.7/domainsPage.py ++++ selinux-gui-2.7/domainsPage.py +@@ -16,19 +16,14 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade + import os + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + +-import gobject + import sys +-import seobject +-import selinux ++from gi.repository import GObject, Gtk + import sepolicy + from semanagePage import * + +@@ -58,26 +53,26 @@ class domainsPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "domains", _("Process Domain")) +- self.domain_filter = xml.get_widget("domainsFilterEntry") ++ self.domain_filter = xml.get_object("domainsFilterEntry") + self.domain_filter.connect("focus_out_event", self.filter_changed) + self.domain_filter.connect("activate", self.filter_changed) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Domain Name"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text=1) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Mode"), Gtk.CellRendererText(), text=1) + col.set_sort_column_id(1) + col.set_resizable(True) + self.view.append_column(col) + self.view.get_selection().connect("changed", self.itemSelected) + +- self.permissive_button = xml.get_widget("permissiveButton") +- self.enforcing_button = xml.get_widget("enforcingButton") ++ self.permissive_button = xml.get_object("permissiveButton") ++ self.enforcing_button = xml.get_object("enforcingButton") + + self.domains = sepolicy.get_all_entrypoint_domains() + self.load() +@@ -112,7 +107,7 @@ class domainsPage(semanagePage): + + def itemSelected(self, selection): + store, iter = selection.get_selected() +- if iter == None: ++ if iter is None: + return + p = store.get_value(iter, 1) == _("Permissive") + self.permissive_button.set_sensitive(not p) +diff --git selinux-gui-2.7/fcontextPage.py selinux-gui-2.7/fcontextPage.py +index 2e26666..a6577ef 100644 +--- selinux-gui-2.7/fcontextPage.py ++++ selinux-gui-2.7/fcontextPage.py +@@ -16,10 +16,7 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import gtk +-import gtk.glade +-import os +-import gobject ++from gi.repository import GObject, Gtk + import seobject + try: + from subprocess import getstatusoutput +@@ -73,40 +70,40 @@ class fcontextPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "fcontext", _("File Labeling")) +- self.fcontextFilter = xml.get_widget("fcontextFilterEntry") ++ self.fcontextFilter = xml.get_object("fcontextFilterEntry") + self.fcontextFilter.connect("focus_out_event", self.filter_changed) + self.fcontextFilter.connect("activate", self.filter_changed) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) +- self.view = xml.get_widget("fcontextView") ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) ++ self.view = xml.get_object("fcontextView") + self.view.set_model(self.store) + self.view.set_search_equal_func(self.search) + +- col = gtk.TreeViewColumn(_("File\nSpecification"), gtk.CellRendererText(), text=SPEC_COL) +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col = Gtk.TreeViewColumn(_("File\nSpecification"), Gtk.CellRendererText(), text=SPEC_COL) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(250) + + col.set_sort_column_id(SPEC_COL) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("Selinux\nFile Type"), gtk.CellRendererText(), text=TYPE_COL) ++ col = Gtk.TreeViewColumn(_("Selinux\nFile Type"), Gtk.CellRendererText(), text=TYPE_COL) + +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(250) + col.set_sort_column_id(TYPE_COL) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("File\nType"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("File\nType"), Gtk.CellRendererText(), text=2) + col.set_sort_column_id(FTYPE_COL) + col.set_resizable(True) + self.view.append_column(col) + +- self.store.set_sort_column_id(SPEC_COL, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(SPEC_COL, Gtk.SortType.ASCENDING) + self.load() +- self.fcontextEntry = xml.get_widget("fcontextEntry") +- self.fcontextFileTypeCombo = xml.get_widget("fcontextFileTypeCombo") +- self.fcontextTypeEntry = xml.get_widget("fcontextTypeEntry") +- self.fcontextMLSEntry = xml.get_widget("fcontextMLSEntry") ++ self.fcontextEntry = xml.get_object("fcontextEntry") ++ self.fcontextFileTypeCombo = xml.get_object("fcontextFileTypeCombo") ++ self.fcontextTypeEntry = xml.get_object("fcontextTypeEntry") ++ self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry") + + def match(self, fcon_dict, k, filter): + try: +@@ -192,7 +189,7 @@ class fcontextPage(semanagePage): + mls = self.fcontextMLSEntry.get_text().strip() + list_model = self.fcontextFileTypeCombo.get_model() + it = self.fcontextFileTypeCombo.get_active_iter() +- ftype = list_model.get_value(it,0) ++ ftype = list_model.get_value(it, 0) + self.wait() + (rc, out) = getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, seobject.file_type_str_to_option[ftype], fspec)) + self.ready() +diff --git selinux-gui-2.7/loginsPage.py selinux-gui-2.7/loginsPage.py +index 1f35a57..b67eb8b 100644 +--- selinux-gui-2.7/loginsPage.py ++++ selinux-gui-2.7/loginsPage.py +@@ -16,17 +16,13 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + ++from gi.repository import GObject, Gtk + import seobject + from semanagePage import * + +@@ -57,23 +53,23 @@ class loginsPage(semanagePage): + def __init__(self, xml): + self.firstTime = False + semanagePage.__init__(self, xml, "logins", _("User Mapping")) +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Login\nName"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=1) ++ col = Gtk.TreeViewColumn(_("SELinux\nUser"), Gtk.CellRendererText(), text=1) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("MLS/\nMCS Range"), Gtk.CellRendererText(), text=2) + col.set_resizable(True) + self.view.append_column(col) + self.load() +- self.loginsNameEntry = xml.get_widget("loginsNameEntry") +- self.loginsSelinuxUserCombo = xml.get_widget("loginsSelinuxUserCombo") +- self.loginsMLSEntry = xml.get_widget("loginsMLSEntry") ++ self.loginsNameEntry = xml.get_object("loginsNameEntry") ++ self.loginsSelinuxUserCombo = xml.get_object("loginsSelinuxUserCombo") ++ self.loginsMLSEntry = xml.get_object("loginsMLSEntry") + + def load(self, filter=""): + self.filter = filter +@@ -91,12 +87,12 @@ class loginsPage(semanagePage): + self.view.get_selection().select_path((0,)) + + def __dialogSetup(self): +- if self.firstTime == True: ++ if self.firstTime: + return + self.firstTime = True +- liststore = gtk.ListStore(gobject.TYPE_STRING) ++ liststore = Gtk.ListStore(GObject.TYPE_STRING) + self.loginsSelinuxUserCombo.set_model(liststore) +- cell = gtk.CellRendererText() ++ cell = Gtk.CellRendererText() + self.loginsSelinuxUserCombo.pack_start(cell, True) + self.loginsSelinuxUserCombo.add_attribute(cell, 'text', 0) + +diff --git selinux-gui-2.7/modulesPage.py selinux-gui-2.7/modulesPage.py +index 3767896..34c5d9e 100644 +--- selinux-gui-2.7/modulesPage.py ++++ selinux-gui-2.7/modulesPage.py +@@ -16,21 +16,16 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os ++import sys ++from subprocess import Popen, PIPE + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + +-import gobject +-import sys +-import seobject ++from gi.repository import GObject, Gtk + import selinux + from semanagePage import * +-from subprocess import Popen, PIPE + + ## + ## I18N +@@ -58,27 +53,33 @@ class modulesPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "modules", _("Policy Module")) +- self.module_filter = xml.get_widget("modulesFilterEntry") ++ self.module_filter = xml.get_object("modulesFilterEntry") + self.module_filter.connect("focus_out_event", self.filter_changed) + self.module_filter.connect("activate", self.filter_changed) + self.audit_enabled = False + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, ++ GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Module Name"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text=1) +- self.enable_audit_button = xml.get_widget("enableAuditButton") ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Priority"), Gtk.CellRendererText(), text=1) ++ self.enable_audit_button = xml.get_object("enableAuditButton") + self.enable_audit_button.connect("clicked", self.enable_audit) +- self.new_button = xml.get_widget("newModuleButton") ++ self.new_button = xml.get_object("newModuleButton") + self.new_button.connect("clicked", self.new_module) + col.set_sort_column_id(1) + col.set_resizable(True) + self.view.append_column(col) ++ self.store.set_sort_column_id(2, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Kind"), Gtk.CellRendererText(), text=2) ++ col.set_sort_column_id(2) ++ col.set_resizable(True) ++ self.view.append_column(col) + self.store.set_sort_func(1, self.sort_int, "") + status, self.policy_type = selinux.selinux_getpolicytype() + +@@ -100,16 +101,17 @@ class modulesPage(semanagePage): + self.filter = filter + self.store.clear() + try: +- fd = Popen("semodule -l", shell=True, stdout=PIPE).stdout ++ fd = Popen("semodule -lfull", shell=True, stdout=PIPE).stdout + l = fd.readlines() + fd.close() + for i in l: +- module, ver, newline = i.split('\t') +- if not (self.match(module, filter) or self.match(ver, filter)): ++ priority, module, kind = i.decode('utf-8').split() ++ if not (self.match(module, filter) or self.match(priority, filter)): + continue + iter = self.store.append() + self.store.set_value(iter, 0, module.strip()) +- self.store.set_value(iter, 1, ver.strip()) ++ self.store.set_value(iter, 1, priority.strip()) ++ self.store.set_value(iter, 2, kind.strip()) + except: + pass + self.view.get_selection().select_path((0,)) +@@ -170,20 +172,20 @@ class modulesPage(semanagePage): + return + + def addDialog(self): +- dialog = gtk.FileChooserDialog(_("Load Policy Module"), ++ dialog = Gtk.FileChooserDialog(_("Load Policy Module"), + None, +- gtk.FILE_CHOOSER_ACTION_OPEN, +- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, +- gtk.STOCK_OPEN, gtk.RESPONSE_OK)) +- dialog.set_default_response(gtk.RESPONSE_OK) ++ Gtk.FileChooserAction.OPEN, ++ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, ++ Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) ++ dialog.set_default_response(Gtk.ResponseType.OK) + +- filter = gtk.FileFilter() ++ filter = Gtk.FileFilter() + filter.set_name("Policy Files") + filter.add_pattern("*.pp") + dialog.add_filter(filter) + + response = dialog.run() +- if response == gtk.RESPONSE_OK: ++ if response == Gtk.ResponseType.OK: + self.add(dialog.get_filename()) + dialog.destroy() + diff --git selinux-gui-2.7/polgengui.py selinux-gui-2.7/polgengui.py -index 7460cce..064001b 100644 +index 7460cce..bc01a62 100644 --- selinux-gui-2.7/polgengui.py +++ selinux-gui-2.7/polgengui.py +@@ -22,11 +22,11 @@ + # + import signal + import string +-import gtk +-import gtk.glade ++import gi ++gi.require_version('Gtk', '3.0') ++from gi.repository import Gtk + import os +-import gobject +-import gnome ++from gi.repository import GObject + import sys + try: + import sepolicy @@ -34,7 +34,9 @@ except ValueError as e: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) @@ -12,6 +518,284 @@ index 7460cce..064001b 100644 try: from subprocess import getstatusoutput except ImportError: +@@ -79,8 +81,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-gnome.program_init("SELinux Policy Generation Tool", "5") +- + version = "1.0" + + sys.path.append('/usr/share/system-config-selinux') +@@ -95,10 +95,12 @@ def foreach(model, path, iter, selected): + ## + ## Pull in the Glade file + ## ++xml = Gtk.Builder() ++xml.set_translation_domain(PROGNAME) + if os.access("polgen.glade", os.F_OK): +- xml = gtk.glade.XML("polgen.glade", domain=PROGNAME) ++ xml.add_from_file("polgen.glade") + else: +- xml = gtk.glade.XML("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME) ++ xml.add_from_file("/usr/share/system-config-selinux/polgen.glade") + + FILE = 1 + DIR = 2 +@@ -277,27 +279,27 @@ class childWindow: + 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_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.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=0) ++ 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) ++ 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_store = Gtk.ListStore(GObject.TYPE_STRING) + self.role_treeview.set_model(self.role_store) +- self.role_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.role_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text=0) ++ 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_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.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text=0) ++ 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: +@@ -307,19 +309,19 @@ class childWindow: + 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_store = Gtk.ListStore(GObject.TYPE_STRING) + self.transition_treeview.set_model(self.transition_store) +- self.transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ 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_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.SELECTION_MULTIPLE) +- self.user_transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ 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: +@@ -329,11 +331,11 @@ class childWindow: + 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_store = Gtk.ListStore(GObject.TYPE_STRING) + self.admin_treeview.set_model(self.admin_store) +- self.admin_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.admin_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ 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: +@@ -383,17 +385,17 @@ class childWindow: + + if self.pages[type][self.current_page] == self.FINISH_PAGE: + self.generate_policy() +- self.xml.get_widget("cancel_button").set_label(gtk.STOCK_CLOSE) ++ 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) ++ 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.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]) +@@ -406,30 +408,30 @@ class childWindow: + b.set_sensitive(not active) + + def verify(self, message, title=""): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) + dlg.set_title(title) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ 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.MESSAGE_INFO, +- gtk.BUTTONS_OK, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.OK, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -550,7 +552,7 @@ class childWindow: + self.boolean_description_entry.set_text("") + rc = self.boolean_dialog.run() + self.boolean_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + iter = self.boolean_store.append() + self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text()) +@@ -559,7 +561,7 @@ class childWindow: + def __add(self, type): + rc = self.file_dialog.run() + self.file_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + for i in self.file_dialog.get_filenames(): + iter = self.store.append() +@@ -569,29 +571,29 @@ class childWindow: + 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.FILE_CHOOSER_ACTION_OPEN) ++ 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.RESPONSE_CANCEL: ++ 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.FILE_CHOOSER_ACTION_OPEN) ++ 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.RESPONSE_CANCEL: ++ 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.FILE_CHOOSER_ACTION_OPEN) ++ self.file_dialog.set_action(Gtk.FileChooserAction.OPEN) + self.file_dialog.set_select_multiple(1) + self.__add(FILE) + +@@ -599,7 +601,7 @@ class childWindow: + 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.FILE_CHOOSER_ACTION_SELECT_FOLDER) ++ self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER) + self.__add(DIR) + + def on_about_clicked(self, args): +@@ -608,7 +610,7 @@ class childWindow: + dlg.hide() + + def quit(self, args): +- gtk.main_quit() ++ Gtk.main_quit() + + def setupScreen(self): + # Bring in widgets from glade file. +@@ -650,20 +652,20 @@ class childWindow: + 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.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT) + self.view.set_model(self.store) +- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0) ++ 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.FILE_CHOOSER_ACTION_SELECT_FOLDER) ++ 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.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + self.output_entry.set_text(self.file_dialog.get_filename()) + +@@ -675,11 +677,11 @@ class childWindow: + 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.RESPONSE_NO: ++ 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.RESPONSE_NO: ++ 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 + @@ -696,16 +698,16 @@ class childWindow: def on_in_net_page_next(self, *args): @@ -33,11 +817,34 @@ index 7460cce..064001b 100644 except ValueError as e: self.error(e.message) return True +@@ -770,7 +772,7 @@ class childWindow: + self.mainWindow.connect("destroy", self.quit) + + self.mainWindow.show_all() +- gtk.main() ++ Gtk.main() + + if __name__ == "__main__": + signal.signal(signal.SIGINT, signal.SIG_DFL) diff --git selinux-gui-2.7/portsPage.py selinux-gui-2.7/portsPage.py -index b8fdaad..f86d2d3 100644 +index b8fdaad..03179c5 100644 --- selinux-gui-2.7/portsPage.py +++ selinux-gui-2.7/portsPage.py -@@ -40,6 +40,12 @@ from semanagePage import * +@@ -16,12 +16,8 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys ++from gi.repository import GObject, Gtk + import seobject + + TYPE_COL = 0 +@@ -40,6 +36,12 @@ from semanagePage import * ## I18N ## PROGNAME = "policycoreutils" @@ -50,3 +857,2545 @@ index b8fdaad..f86d2d3 100644 try: import gettext kwargs = {} +@@ -62,18 +64,19 @@ class portsPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "ports", _("Network Port")) +- xml.signal_connect("on_group_clicked", self.on_group_clicked) ++ group_listview = xml.get_object("listViewButton") ++ group_listview.connect("clicked", self.on_group_clicked) + self.group = False +- self.ports_filter = xml.get_widget("portsFilterEntry") ++ self.ports_filter = xml.get_object("portsFilterEntry") + self.ports_filter.connect("focus_out_event", self.filter_changed) + self.ports_filter.connect("activate", self.filter_changed) +- self.ports_name_entry = xml.get_widget("portsNameEntry") +- self.ports_protocol_combo = xml.get_widget("portsProtocolCombo") +- self.ports_number_entry = xml.get_widget("portsNumberEntry") +- self.ports_mls_entry = xml.get_widget("portsMLSEntry") +- self.ports_add_button = xml.get_widget("portsAddButton") +- self.ports_properties_button = xml.get_widget("portsPropertiesButton") +- self.ports_delete_button = xml.get_widget("portsDeleteButton") ++ self.ports_name_entry = xml.get_object("portsNameEntry") ++ self.ports_protocol_combo = xml.get_object("portsProtocolCombo") ++ self.ports_number_entry = xml.get_object("portsNumberEntry") ++ self.ports_mls_entry = xml.get_object("portsMLSEntry") ++ self.ports_add_button = xml.get_object("portsAddButton") ++ self.ports_properties_button = xml.get_object("portsPropertiesButton") ++ self.ports_delete_button = xml.get_object("portsDeleteButton") + liststore = self.ports_protocol_combo.get_model() + iter = liststore.get_iter_first() + self.ports_protocol_combo.set_active_iter(iter) +@@ -90,28 +93,28 @@ class portsPage(semanagePage): + self.group_load(filter) + + def init_store(self): +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + self.view.set_search_equal_func(self.search) +- col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL) ++ col = Gtk.TreeViewColumn(_("SELinux Port\nType"), Gtk.CellRendererText(), text=TYPE_COL) + col.set_sort_column_id(TYPE_COL) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(TYPE_COL, Gtk.SortType.ASCENDING) + +- col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL) ++ col = Gtk.TreeViewColumn(_("Protocol"), Gtk.CellRendererText(), text=PROTOCOL_COL) + col.set_sort_column_id(PROTOCOL_COL) + col.set_resizable(True) + self.view.append_column(col) + +- self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL) ++ self.mls_col = Gtk.TreeViewColumn(_("MLS/MCS\nLevel"), Gtk.CellRendererText(), text=MLS_COL) + self.mls_col.set_resizable(True) + self.mls_col.set_sort_column_id(MLS_COL) + self.view.append_column(self.mls_col) + +- col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL) ++ col = Gtk.TreeViewColumn(_("Port"), Gtk.CellRendererText(), text=PORT_COL) + col.set_sort_column_id(PORT_COL) + col.set_resizable(True) + self.view.append_column(col) +@@ -139,7 +142,7 @@ class portsPage(semanagePage): + continue + iter = self.store.append() + if k[0] == k[1]: +- self.store.set_value(iter, PORT_COL, k[0]) ++ self.store.set_value(iter, PORT_COL, str(k[0])) + else: + rec = "%s-%s" % k[:2] + self.store.set_value(iter, PORT_COL, rec) +diff --git selinux-gui-2.7/semanagePage.py selinux-gui-2.7/semanagePage.py +index 27367f3..560ec07 100644 +--- selinux-gui-2.7/semanagePage.py ++++ selinux-gui-2.7/semanagePage.py +@@ -16,13 +16,8 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys +-import seobject ++from gi.repository import Gdk, Gtk + + ## + ## I18N +@@ -47,24 +42,25 @@ except: + + + def idle_func(): +- while gtk.events_pending(): +- gtk.main_iteration() ++ while Gtk.events_pending(): ++ Gtk.main_iteration() + + + class semanagePage: + + def __init__(self, xml, name, description): + self.xml = xml +- self.window = self.xml.get_widget("mainWindow").get_root_window() +- self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) +- self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) ++ self.window = self.xml.get_object("mainWindow").get_root_window() ++ self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) ++ self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) + + self.local = False +- self.view = xml.get_widget("%sView" % name) +- self.dialog = xml.get_widget("%sDialog" % name) +- self.filter_entry = xml.get_widget("%sFilterEntry" % name) ++ self.view = xml.get_object("%sView" % name) ++ self.dialog = xml.get_object("%sDialog" % name) ++ self.filter_entry = xml.get_object("%sFilterEntry" % name) + self.filter_entry.connect("focus_out_event", self.filter_changed) + self.filter_entry.connect("activate", self.filter_changed) ++ self.filter_entry.connect("changed", self.filter_changed) + + self.view.connect("row_activated", self.rowActivated) + self.view.get_selection().connect("changed", self.itemSelected) +@@ -81,7 +77,7 @@ class semanagePage: + def get_description(self): + return self.description + +- def itemSelected(self, args): ++ def itemSelected(self, selection): + return + + def filter_changed(self, *arg): +@@ -110,28 +106,28 @@ class semanagePage: + self.propertiesDialog() + + def verify(self, message, title=""): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) + dlg.set_title(title) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + rc = dlg.run() + dlg.destroy() + return rc + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() + + def deleteDialog(self): + store, it = self.view.get_selection().get_selected() +- if (it is not None) and (self.verify(_("Are you sure you want to delete %s '%s'?" % (self.description, store.get_value(it, 0))), _("Delete %s" % self.description)) == gtk.RESPONSE_YES): ++ if (it is not None) and (self.verify(_("Are you sure you want to delete %s '%s'?" % (self.description, store.get_value(it, 0))), _("Delete %s" % self.description)) == Gtk.ResponseType.YES): + self.delete() + + def use_menus(self): +@@ -140,11 +136,11 @@ class semanagePage: + def addDialog(self): + self.dialogClear() + self.dialog.set_title(_("Add %s" % self.description)) +- self.dialog.set_position(gtk.WIN_POS_MOUSE) ++ self.dialog.set_position(Gtk.WindowPosition.MOUSE) + +- while self.dialog.run() == gtk.RESPONSE_OK: ++ while self.dialog.run() == Gtk.ResponseType.OK: + try: +- if self.add() == False: ++ if not self.add(): + continue + break + except ValueError as e: +@@ -154,10 +150,10 @@ class semanagePage: + def propertiesDialog(self): + self.dialogInit() + self.dialog.set_title(_("Modify %s" % self.description)) +- self.dialog.set_position(gtk.WIN_POS_MOUSE) +- while self.dialog.run() == gtk.RESPONSE_OK: ++ self.dialog.set_position(Gtk.WindowPosition.MOUSE) ++ while self.dialog.run() == Gtk.ResponseType.OK: + try: +- if self.modify() == False: ++ if not self.modify(): + continue + break + except ValueError as e: +diff --git selinux-gui-2.7/statusPage.py selinux-gui-2.7/statusPage.py +index 23d0d0f..766854b 100644 +--- selinux-gui-2.7/statusPage.py ++++ selinux-gui-2.7/statusPage.py +@@ -16,23 +16,14 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade + import os +-import gobject + import sys +-import tempfile ++from gi.repository import Gtk + import selinux + + INSTALLPATH = '/usr/share/system-config-selinux' + sys.path.append(INSTALLPATH) + +-try: +- from subprocess import getstatusoutput +-except ImportError: +- from commands import getstatusoutput +- + ENFORCING = 1 + PERMISSIVE = 0 + DISABLED = -1 +@@ -71,12 +62,11 @@ class statusPage: + + self.type = selinux.selinux_getpolicytype() + # Bring in widgets from glade file. +- self.typeHBox = xml.get_widget("typeHBox") +- self.selinuxTypeOptionMenu = xml.get_widget("selinuxTypeOptionMenu") +- self.typeLabel = xml.get_widget("typeLabel") +- self.enabledOptionMenu = xml.get_widget("enabledOptionMenu") +- self.currentOptionMenu = xml.get_widget("currentOptionMenu") +- self.relabel_checkbutton = xml.get_widget("relabelCheckbutton") ++ self.selinuxTypeOptionMenu = xml.get_object("selinuxTypeOptionMenu") ++ self.typeLabel = xml.get_object("typeLabel") ++ self.enabledOptionMenu = xml.get_object("enabledOptionMenu") ++ self.currentOptionMenu = xml.get_object("currentOptionMenu") ++ self.relabel_checkbutton = xml.get_object("relabelCheckbutton") + self.relabel_checkbutton.set_active(self.is_relabel()) + self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle) + if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE: +@@ -90,7 +80,7 @@ class statusPage: + self.currentOptionMenu.set_active(0) + self.currentOptionMenu.set_sensitive(False) + +- if self.read_selinux_config() == None: ++ if self.read_selinux_config() is None: + self.selinuxsupport = False + else: + self.enabledOptionMenu.connect("changed", self.enabled_changed) +@@ -131,10 +121,10 @@ class statusPage: + os.unlink(RELABELFILE) + + def verify(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + rc = dlg.run() + dlg.destroy() +@@ -144,7 +134,7 @@ class statusPage: + type = self.get_type() + enabled = self.enabledOptionMenu.get_active() + if self.initialtype != type: +- if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: + menu.set_active(self.typeHistory) + return None + +@@ -158,12 +148,12 @@ class statusPage: + type = self.get_type() + + if self.initEnabled != DISABLED and enabled == DISABLED: +- if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == Gtk.ResponseType.NO: + combo.set_active(self.enabled) + return None + + if self.initEnabled == DISABLED and enabled < 2: +- if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: + combo.set_active(self.enabled) + return None + self.relabel_checkbutton.set_active(True) +diff --git selinux-gui-2.7/system-config-selinux.py selinux-gui-2.7/system-config-selinux.py +index ed41e98..ce7c74b 100644 +--- selinux-gui-2.7/system-config-selinux.py ++++ selinux-gui-2.7/system-config-selinux.py +@@ -20,20 +20,19 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # ++import os + import signal +-import string + import sys ++import gi ++gi.require_version('Gtk', '3.0') + try: +- import gtk ++ from gi.repository import Gtk + except RuntimeError as e: + print("system-config-selinux:", e) + print("This is a graphical application and requires DISPLAY to be set.") + sys.exit(1) + +-import gtk.glade +-import os +-import gobject +-import gnome ++from gi.repository import GObject + import statusPage + import booleansPage + import loginsPage +@@ -64,8 +63,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-gnome.program_init("SELinux Management Tool", "5") +- + version = "1.0" + + sys.path.append('/usr/share/system-config-selinux') +@@ -74,10 +71,12 @@ sys.path.append('/usr/share/system-config-selinux') + ## + ## Pull in the Glade file + ## +-if os.access("system-config-selinux.glade", os.F_OK): +- xml = gtk.glade.XML("system-config-selinux.glade", domain=PROGNAME) ++xml = Gtk.Builder() ++xml.set_translation_domain(PROGNAME) ++if os.access("system-config-selinux.ui", os.F_OK): ++ xml.add_from_file("system-config-selinux.ui") + else: +- xml = gtk.glade.XML("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME) ++ xml.add_from_file("/usr/share/system-config-selinux/system-config-selinux.ui") + + + class childWindow: +@@ -85,11 +84,16 @@ class childWindow: + def __init__(self): + self.tabs = [] + self.xml = xml +- xml.signal_connect("on_quit_activate", self.destroy) +- xml.signal_connect("on_delete_clicked", self.delete) +- xml.signal_connect("on_add_clicked", self.add) +- xml.signal_connect("on_properties_clicked", self.properties) +- xml.signal_connect("on_local_clicked", self.on_local_clicked) ++ xml.connect_signals({ ++ "on_quit_activate": self.destroy, ++ "on_delete_clicked": self.delete, ++ "on_add_clicked": self.add, ++ "on_properties_clicked": self.properties, ++ "on_local_clicked": self.on_local_clicked, ++ "on_policy_activate": self.policy, ++ "on_logging_activate": self.logging, ++ "on_about_activate": self.on_about_activate, ++ }) + self.add_page(statusPage.statusPage(xml)) + if selinux.is_selinux_enabled() > 0: + try: +@@ -103,20 +107,15 @@ class childWindow: + except ValueError as e: + self.error(e.message) + +- xml.signal_connect("on_quit_activate", self.destroy) +- xml.signal_connect("on_policy_activate", self.policy) +- xml.signal_connect("on_logging_activate", self.logging) +- xml.signal_connect("on_about_activate", self.on_about_activate) +- +- self.add_menu = xml.get_widget("add_menu_item") +- self.properties_menu = xml.get_widget("properties_menu_item") +- self.delete_menu = xml.get_widget("delete_menu_item") ++ self.add_menu = xml.get_object("add_menu_item") ++ self.properties_menu = xml.get_object("properties_menu_item") ++ self.delete_menu = xml.get_object("delete_menu_item") + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -143,12 +142,12 @@ class childWindow: + self.tabs[self.notebook.get_current_page()].on_local_clicked(button) + + def on_about_activate(self, args): +- dlg = xml.get_widget("aboutWindow") ++ dlg = xml.get_object("aboutWindow") + dlg.run() + dlg.hide() + + def destroy(self, args): +- gtk.main_quit() ++ Gtk.main_quit() + + def use_menus(self, use_menus): + self.add_menu.set_sensitive(use_menus) +@@ -166,13 +165,13 @@ class childWindow: + + def setupScreen(self): + # Bring in widgets from glade file. +- self.mainWindow = self.xml.get_widget("mainWindow") +- self.notebook = self.xml.get_widget("notebook") +- self.view = self.xml.get_widget("selectView") ++ self.mainWindow = self.xml.get_object("mainWindow") ++ self.notebook = self.xml.get_object("notebook") ++ self.view = self.xml.get_object("selectView") + self.view.get_selection().connect("changed", self.itemSelected) +- self.store = gtk.ListStore(gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING) + self.view.set_model(self.store) +- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0) ++ col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0) + col.set_resizable(True) + self.view.append_column(col) + +@@ -189,7 +188,7 @@ class childWindow: + self.mainWindow.connect("destroy", self.destroy) + + self.mainWindow.show_all() +- gtk.main() ++ Gtk.main() + + if __name__ == "__main__": + signal.signal(signal.SIGINT, signal.SIG_DFL) +diff --git selinux-gui-2.7/system-config-selinux.ui selinux-gui-2.7/system-config-selinux.ui +new file mode 100644 +index 0000000..7cc1cc5 +--- /dev/null ++++ selinux-gui-2.7/system-config-selinux.ui +@@ -0,0 +1,2024 @@ ++ ++ ++ ++ ++ ++ ++ system-config-selinux ++ False ++ 5 ++ normal ++ Copyright (c)2006 Red Hat, Inc. ++Copyright (c) 2006 Dan Walsh <dwalsh@redhat.com> ++ Daniel Walsh <dwalsh@redhat.com> ++ ++ translator-credits ++ system-config-selinux.png ++ ++ ++ False ++ ++ ++ False ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ gtk-add ++ ++ ++ True ++ False ++ gtk-properties ++ ++ ++ True ++ False ++ gtk-delete ++ ++ ++ False ++ Add SELinux Login Mapping ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ Login Name ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ SELinux User ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS Range ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ cancelbutton1 ++ okbutton1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ tcp ++ ++ ++ udp ++ ++ ++ ++ ++ False ++ Add SELinux Network Ports ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ Port Number ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Protocol ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Type ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ model1 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS ++Level ++ ++ ++ 0 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button1 ++ button2 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ all files ++ ++ ++ regular file ++ ++ ++ directory ++ ++ ++ character device ++ ++ ++ block device ++ ++ ++ socket file ++ ++ ++ symbolic link ++ ++ ++ named pipe ++ ++ ++ ++ ++ False ++ Add SELinux Login Mapping ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ File Specification ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ File Type ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Type ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ model2 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ MLS ++ ++ ++ 0 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button5 ++ button6 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Disabled ++ ++ ++ Permissive ++ ++ ++ Enforcing ++ ++ ++ ++ ++ False ++ SELinux Administration ++ 800 ++ 500 ++ system-config-selinux.png ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ _File ++ True ++ ++ ++ True ++ False ++ ++ ++ _Add ++ True ++ False ++ True ++ image13 ++ False ++ ++ ++ ++ ++ ++ ++ _Properties ++ True ++ False ++ True ++ image14 ++ False ++ ++ ++ ++ ++ ++ ++ _Delete ++ True ++ False ++ True ++ image15 ++ False ++ ++ ++ ++ ++ ++ gtk-quit ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ _Help ++ True ++ ++ ++ True ++ False ++ ++ ++ gtk-about ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ True ++ False ++ 5 ++ 0 ++ none ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ True ++ Select Management Object ++ False ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ <b>Select:</b> ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ ++ ++ True ++ False ++ False ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 5 ++ 5 ++ ++ ++ True ++ False ++ System Default Enforcing Mode ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ True ++ model3 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Current Enforcing Mode ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ True ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ System Default Policy Type: ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ True ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ False ++ Select if you wish to relabel then entire file system on next reboot. Relabeling can take a very long time, depending on the size of the system. If you are changing policy types or going from disabled to enforcing, a relabel is required. ++ False ++ True ++ ++ ++ True ++ False ++ True ++ 0 ++ 0 ++ ++ ++ True ++ False ++ True ++ 2 ++ ++ ++ True ++ False ++ gtk-refresh ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Relabel on next reboot. ++ True ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ 0 ++ 3 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ end ++ 0 ++ ++ ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Revert boolean setting to system default ++ gtk-revert-to-saved ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Booleans ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 10 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Boolean ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add File Context ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify File Context ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete File Context ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between all and customized file context ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ File Labeling ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add SELinux User Mapping ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify SELinux User Mapping ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete SELinux User Mapping ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ User Mapping ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 3 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add User ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify User ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete User ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ SELinux User ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 4 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add Network Port ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Edit Network Port ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete Network Port ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 32 ++ True ++ False ++ vertical ++ ++ ++ ++ ++ False ++ False ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Ports ++ Group View ++ True ++ gtk-indent ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Ports ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Network Port ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 5 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Generate new policy module ++ gtk-new ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Load policy module ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Remove loadable policy module ++ gtk-remove ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 10 ++ True ++ False ++ vertical ++ ++ ++ ++ ++ False ++ False ++ ++ ++ ++ ++ True ++ False ++ Enable/Disable additional audit rules, that are normally not reported in the log files. ++ Enable Audit ++ True ++ gtk-zoom-in ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Policy Module ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 6 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Change process mode to permissive. ++ Permissive ++ True ++ gtk-dialog-warning ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Change process mode to enforcing ++ Enforcing ++ True ++ gtk-dialog-error ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Process Domain ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 7 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ False ++ Add SELinux User ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ SELinux User ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS Range ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Roles ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button7 ++ button8 ++ ++ ++ ++ ++ ++ +diff --git selinux-gui-2.7/usersPage.py selinux-gui-2.7/usersPage.py +index 75b0547..26794ed 100644 +--- selinux-gui-2.7/usersPage.py ++++ selinux-gui-2.7/usersPage.py +@@ -16,17 +16,13 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + ++from gi.repository import GObject, Gtk + import seobject + from semanagePage import * + +@@ -57,27 +53,27 @@ class usersPage(semanagePage): + def __init__(self, xml): + semanagePage.__init__(self, xml, "users", _("SELinux User")) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) + +- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=0) ++ col = Gtk.TreeViewColumn(_("SELinux\nUser"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) + +- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=1) ++ col = Gtk.TreeViewColumn(_("MLS/\nMCS Range"), Gtk.CellRendererText(), text=1) + col.set_resizable(True) + self.view.append_column(col) + +- col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("SELinux Roles"), Gtk.CellRendererText(), text=2) + col.set_resizable(True) + self.view.append_column(col) + + self.load() +- self.selinuxUserEntry = xml.get_widget("selinuxUserEntry") +- self.mlsRangeEntry = xml.get_widget("mlsRangeEntry") +- self.selinuxRolesEntry = xml.get_widget("selinuxRolesEntry") ++ self.selinuxUserEntry = xml.get_object("selinuxUserEntry") ++ self.mlsRangeEntry = xml.get_object("mlsRangeEntry") ++ self.selinuxRolesEntry = xml.get_object("selinuxRolesEntry") + + def load(self, filter=""): + self.filter = filter +@@ -95,10 +91,6 @@ class usersPage(semanagePage): + self.store.set_value(iter, 2, dict[k][3]) + self.view.get_selection().select_path((0,)) + +- def delete(self): +- if semanagePage.delete(self) == gtk.RESPONSE_NO: +- return None +- + def dialogInit(self): + store, iter = self.view.get_selection().get_selected() + self.selinuxUserEntry.set_text(store.get_value(iter, 0)) diff --git a/selinux-python-fedora.patch b/selinux-python-fedora.patch index f34a4f1..944fedf 100644 --- a/selinux-python-fedora.patch +++ b/selinux-python-fedora.patch @@ -15,7 +15,7 @@ index 0bdb90f..0cdcfcc 100644 user identities to authorized role sets. In most cases, only the former mapping needs to be adjusted by the administrator; the latter diff --git selinux-python-2.7/semanage/seobject.py selinux-python-2.7/semanage/seobject.py -index 70fd192..af88126 100644 +index 70fd192..55127de 100644 --- selinux-python-2.7/semanage/seobject.py +++ selinux-python-2.7/semanage/seobject.py @@ -386,6 +386,8 @@ class moduleRecords(semanageRecords): @@ -52,11 +52,149 @@ index 70fd192..af88126 100644 rc = semanage_set_default_priority(self.sh, priority) if rc < 0: raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) +@@ -2566,10 +2574,15 @@ class fcontextRecords(semanageRecords): + if rc < 0: + raise ValueError(_("Could not list file contexts")) + ++ (rc, fchomedirs) = semanage_fcontext_list_homedirs(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list file contexts for home directories")) ++ + (rc, fclocal) = semanage_fcontext_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list local file contexts")) + ++ self.flist += fchomedirs + self.flist += fclocal + + ddict = {} diff --git selinux-python-2.7/sepolicy/sepolicy/__init__.py selinux-python-2.7/sepolicy/sepolicy/__init__.py -index 5cfc071..a10dbcd 100644 +index 5cfc071..24e3526 100644 --- selinux-python-2.7/sepolicy/sepolicy/__init__.py +++ selinux-python-2.7/sepolicy/sepolicy/__init__.py -@@ -1136,27 +1136,14 @@ def boolean_desc(boolean): +@@ -4,6 +4,7 @@ + # Author: Ryan Hallisey + # Author: Jason Zaman + ++import errno + import selinux + import setools + import glob +@@ -207,10 +208,17 @@ def info(setype, name=None): + elif len(ports) == 1: + q.ports = (ports[0], ports[0]) + ++ if _pol.mls: ++ return ({ ++ 'high': x.ports.high, ++ 'protocol': str(x.protocol), ++ 'range': str(x.context.range_), ++ 'type': str(x.context.type_), ++ 'low': x.ports.low, ++ } for x in q.results()) + return ({ + 'high': x.ports.high, + 'protocol': str(x.protocol), +- 'range': str(x.context.range_), + 'type': str(x.context.type_), + 'low': x.ports.low, + } for x in q.results()) +@@ -220,11 +228,16 @@ def info(setype, name=None): + if name: + q.name = name + ++ if _pol.mls: ++ return ({ ++ 'range': str(x.mls_range), ++ 'name': str(x), ++ 'roles': list(map(str, x.roles)), ++ 'level': str(x.mls_level), ++ } for x in q.results()) + return ({ +- 'range': str(x.mls_range), + 'name': str(x), + 'roles': list(map(str, x.roles)), +- 'level': str(x.mls_level), + } for x in q.results()) + + elif setype == BOOLEAN: +@@ -511,12 +524,15 @@ def find_entrypoint_path(exe, exclude_list=[]): + + + def read_file_equiv(edict, fc_path, modify): +- fd = open(fc_path, "r") +- fc = fd.readlines() +- fd.close() +- for e in fc: +- f = e.split() +- edict[f[0]] = {"equiv": f[1], "modify": modify} ++ try: ++ with open(fc_path, "r") as fd: ++ for e in fd: ++ f = e.split() ++ if f and not f[0].startswith('#'): ++ edict[f[0]] = {"equiv": f[1], "modify": modify} ++ except OSError as e: ++ if e.errno != errno.ENOENT: ++ raise + return edict + + +@@ -543,9 +559,13 @@ def get_local_file_paths(fc_path=selinux.selinux_file_context_path()): + if local_files: + return local_files + local_files = [] +- fd = open(fc_path + ".local", "r") +- fc = fd.readlines() +- fd.close() ++ try: ++ with open(fc_path + ".local", "r") as fd: ++ fc = fd.readlines() ++ except OSError as e: ++ if e.errno != errno.ENOENT: ++ raise ++ return [] + for i in fc: + rec = i.split() + if len(rec) == 0: +@@ -573,9 +593,12 @@ def get_fcdict(fc_path=selinux.selinux_file_context_path()): + fc += fd.readlines() + fd.close() + fcdict = {} +- fd = open(fc_path + ".local", "r") +- fc += fd.readlines() +- fd.close() ++ try: ++ with open(fc_path + ".local", "r") as fd: ++ fc += fd.readlines() ++ except OSError as e: ++ if e.errno != errno.ENOENT: ++ raise + + for i in fc: + rec = i.split() +@@ -856,8 +879,9 @@ def get_selinux_users(): + global selinux_user_list + if not selinux_user_list: + selinux_user_list = list(info(USER)) +- for x in selinux_user_list: +- x['range'] = "".join(x['range'].split(" ")) ++ if _pol.mls: ++ for x in selinux_user_list: ++ x['range'] = "".join(x['range'].split(" ")) + return selinux_user_list + + +@@ -955,7 +979,7 @@ def get_description(f, markup=markup): + if f.endswith("_db_t"): + return txt + "treat the files as %s database content." % prettyprint(f, "_db_t") + if f.endswith("_ra_content_t"): +- return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_conten_t") ++ return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_content_t") + if f.endswith("_cert_t"): + return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t") + if f.endswith("_key_t"): +@@ -1136,27 +1160,14 @@ def boolean_desc(boolean): def get_os_version(): @@ -90,11 +228,124 @@ index 5cfc071..a10dbcd 100644 def reinit(): +diff --git selinux-python-2.7/sepolicy/sepolicy/gui.py selinux-python-2.7/sepolicy/sepolicy/gui.py +index 007c94a..6562aa8 100644 +--- selinux-python-2.7/sepolicy/sepolicy/gui.py ++++ selinux-python-2.7/sepolicy/sepolicy/gui.py +@@ -907,8 +907,8 @@ class SELinuxGui(): + if "object_r" in roles: + roles.remove("object_r") + self.user_liststore.set_value(iter, 1, ", ".join(roles)) +- self.user_liststore.set_value(iter, 2, u["level"]) +- self.user_liststore.set_value(iter, 3, u["range"]) ++ self.user_liststore.set_value(iter, 2, u.get("level", "")) ++ self.user_liststore.set_value(iter, 3, u.get("range", "")) + self.user_liststore.set_value(iter, 4, True) + self.ready_mouse() + +@@ -1755,14 +1755,14 @@ class SELinuxGui(): + if self.login_mls_entry.get_text() == "": + for u in sepolicy.get_selinux_users(): + if seuser == u['name']: +- self.login_mls_entry.set_text(u['range']) ++ self.login_mls_entry.set_text(u.get('range', '')) + + def user_roles_combobox_change(self, combo, *args): + serole = self.combo_get_active_text(combo) + if self.user_mls_entry.get_text() == "": + for u in sepolicy.get_all_roles(): + if serole == u['name']: +- self.user_mls_entry.set_text(u['range']) ++ self.user_mls_entry.set_text(u.get('range', '')) + + def get_selected_iter(self): + iter = None +@@ -1973,7 +1973,10 @@ class SELinuxGui(): + self.cur_dict["user"][name] = {"action": "-m", "range": mls_range, "level": level, "role": roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname} + else: + iter = self.liststore.append(None) +- self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles} ++ if mls_range or level: ++ self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles} ++ else: ++ self.cur_dict["user"][name] = {"action": "-a", "role": roles} + + self.liststore.set_value(iter, 0, name) + self.liststore.set_value(iter, 1, roles) +@@ -2089,8 +2092,8 @@ class SELinuxGui(): + user_dict = self.cust_dict["user"] + for user in user_dict: + roles = user_dict[user]["role"] +- mls = user_dict[user]["range"] +- level = user_dict[user]["level"] ++ mls = user_dict[user].get("range", "") ++ level = user_dict[user].get("level", "") + iter = self.user_delete_liststore.append() + self.user_delete_liststore.set_value(iter, 1, user) + self.user_delete_liststore.set_value(iter, 2, roles) +@@ -2104,7 +2107,7 @@ class SELinuxGui(): + login_dict = self.cust_dict["login"] + for login in login_dict: + seuser = login_dict[login]["seuser"] +- mls = login_dict[login]["range"] ++ mls = login_dict[login].get("range", "") + iter = self.login_delete_liststore.append() + self.login_delete_liststore.set_value(iter, 1, seuser) + self.login_delete_liststore.set_value(iter, 2, login) +@@ -2268,7 +2271,7 @@ class SELinuxGui(): + self.update_treestore.set_value(niter, 3, False) + roles = self.cur_dict["user"][user]["role"] + self.update_treestore.set_value(niter, 1, (_("Roles: %s")) % roles) +- mls = self.cur_dict["user"][user]["range"] ++ mls = self.cur_dict["user"][user].get("range", "") + niter = self.update_treestore.append(iter) + self.update_treestore.set_value(niter, 3, False) + self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls) +@@ -2293,7 +2296,7 @@ class SELinuxGui(): + self.update_treestore.set_value(niter, 3, False) + seuser = self.cur_dict["login"][login]["seuser"] + self.update_treestore.set_value(niter, 1, (_("SELinux User: %s")) % seuser) +- mls = self.cur_dict["login"][login]["range"] ++ mls = self.cur_dict["login"][login].get("range", "") + niter = self.update_treestore.append(iter) + self.update_treestore.set_value(niter, 3, False) + self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls) +@@ -2487,14 +2490,18 @@ class SELinuxGui(): + for l in self.cur_dict[k]: + if self.cur_dict[k][l]["action"] == "-d": + update_buffer += "login -d %s\n" % l +- else: ++ elif "range" in self.cur_dict[k][l]: + update_buffer += "login %s -s %s -r %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], self.cur_dict[k][l]["range"], l) ++ else: ++ update_buffer += "login %s -s %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], l) + if k in "user": + for u in self.cur_dict[k]: + if self.cur_dict[k][u]["action"] == "-d": + update_buffer += "user -d %s\n" % u +- else: ++ elif "level" in self.cur_dict[k][u] and "range" in self.cur_dict[k][u]: + update_buffer += "user %s -L %s -r %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["level"], self.cur_dict[k][u]["range"], self.cur_dict[k][u]["role"], u) ++ else: ++ update_buffer += "user %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["role"], u) + + if k in "fcontext-equiv": + for f in self.cur_dict[k]: diff --git selinux-python-2.7/sepolicy/sepolicy/manpage.py selinux-python-2.7/sepolicy/sepolicy/manpage.py -index 4d84636..4772b50 100755 +index 4d84636..b463165 100755 --- selinux-python-2.7/sepolicy/sepolicy/manpage.py +++ selinux-python-2.7/sepolicy/sepolicy/manpage.py -@@ -125,8 +125,33 @@ def gen_domains(): +@@ -84,7 +84,8 @@ def get_all_users_info(): + + for d in allusers_info: + allusers.append(d['name']) +- users_range[d['name'].split("_")[0]] = d['range'] ++ if 'range' in d: ++ users_range[d['name'].split("_")[0]] = d['range'] + + for u in allusers: + if u not in ["system_u", "root", "unconfined_u"]: +@@ -125,8 +126,36 @@ def gen_domains(): domains.sort() return domains @@ -121,7 +372,10 @@ index 4d84636..4772b50 100755 +def _gen_mcs_constrained_types(): + global mcs_constrained_types + if mcs_constrained_types is None: -+ mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) ++ try: ++ mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) ++ except StopIteration: ++ mcs_constrained_types = [] + return mcs_constrained_types + + @@ -129,7 +383,7 @@ index 4d84636..4772b50 100755 def _gen_types(): global types -@@ -149,10 +174,6 @@ def prettyprint(f, trim): +@@ -149,10 +178,6 @@ def prettyprint(f, trim): manpage_domains = [] manpage_roles = [] @@ -140,7 +394,7 @@ index 4d84636..4772b50 100755 def get_alphabet_manpages(manpage_list): alphabet_manpages = dict.fromkeys(string.ascii_letters, []) for i in string.ascii_letters: -@@ -182,7 +203,7 @@ def convert_manpage_to_html(html_manpage, manpage): +@@ -182,7 +207,7 @@ def convert_manpage_to_html(html_manpage, manpage): class HTMLManPages: """ @@ -149,7 +403,7 @@ index 4d84636..4772b50 100755 """ def __init__(self, manpage_roles, manpage_domains, path, os_version): -@@ -190,9 +211,9 @@ class HTMLManPages: +@@ -190,9 +215,9 @@ class HTMLManPages: self.manpage_domains = get_alphabet_manpages(manpage_domains) self.os_version = os_version self.old_path = path + "/" @@ -161,7 +415,7 @@ index 4d84636..4772b50 100755 self.__gen_html_manpages() else: print("SELinux HTML man pages can not be generated for this %s" % os_version) -@@ -201,7 +222,6 @@ class HTMLManPages: +@@ -201,7 +226,6 @@ class HTMLManPages: def __gen_html_manpages(self): self._write_html_manpage() self._gen_index() @@ -169,7 +423,7 @@ index 4d84636..4772b50 100755 self._gen_css() def _write_html_manpage(self): -@@ -219,67 +239,21 @@ class HTMLManPages: +@@ -219,67 +243,21 @@ class HTMLManPages: convert_manpage_to_html((self.new_path + r.rsplit("_selinux", 1)[0] + ".html"), self.old_path + r) def _gen_index(self): @@ -241,7 +495,7 @@ index 4d84636..4772b50 100755 for letter in self.manpage_roles: if len(self.manpage_roles[letter]): fd.write(""" -@@ -423,6 +397,9 @@ class ManPage: +@@ -423,6 +401,9 @@ class ManPage: self.all_file_types = sepolicy.get_all_file_types() self.role_allows = sepolicy.get_all_role_allows() self.types = _gen_types() @@ -251,7 +505,7 @@ index 4d84636..4772b50 100755 if self.source_files: self.fcpath = self.root + "file_contexts" -@@ -735,10 +712,13 @@ Default Defined Ports:""") +@@ -735,10 +716,13 @@ Default Defined Ports:""") def _file_context(self): flist = [] @@ -265,7 +519,7 @@ index 4d84636..4772b50 100755 if f in self.fcdict: mpaths = mpaths + self.fcdict[f]["regex"] if len(mpaths) == 0: -@@ -790,19 +770,20 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d +@@ -790,19 +774,20 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d .PP """ % {'domainname': self.domainname, 'equiv': e, 'alt': e.split('/')[-1]}) @@ -289,7 +543,17 @@ index 4d84636..4772b50 100755 self.fd.write(r""" .I The following file types are defined for %(domainname)s: -@@ -974,8 +955,7 @@ All executeables with the default executable label, usually stored in /usr/bin a +@@ -921,8 +906,7 @@ This manual page was auto-generated using + .B "sepolicy manpage". + + .SH "SEE ALSO" +-selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8) +-""" % (self.domainname)) ++selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)""" % (self.domainname)) + + if self.booltext != "": + self.fd.write(", setsebool(8)") +@@ -974,8 +958,7 @@ All executeables with the default executable label, usually stored in /usr/bin a %s""" % ", ".join(paths)) def _mcs_types(self): diff --git a/semodule-utils-fedora.patch b/semodule-utils-fedora.patch new file mode 100644 index 0000000..236a2cf --- /dev/null +++ b/semodule-utils-fedora.patch @@ -0,0 +1,10 @@ +diff --git semodule-utils-2.7/Makefile semodule-utils-2.7/Makefile +index 6bf4aee..e0a6579 100644 +--- semodule-utils-2.7/Makefile ++++ semodule-utils-2.7/Makefile +@@ -1,4 +1,4 @@ +-SUBDIRS = semodule_package semodule_link semodule_expand semodule_deps ++SUBDIRS = semodule_package semodule_link semodule_expand + + all install relabel clean indent: + @for subdir in $(SUBDIRS); do \