From 9f373bc68ad71717f85e65686ef1aa6736da9e0f Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Tue, 6 Aug 2013 17:29:03 -0400 Subject: [PATCH] Update sepolicy gui code, cleanups and add file transition tab - Fix semanage argparse problems --- policycoreutils-rhat.patch | 1213 +++++++++++++++++++++++------------- 1 file changed, 778 insertions(+), 435 deletions(-) diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 5dab833..7d0f127 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -509902,7 +509902,7 @@ index 0000000..e2befdb + packages=["policycoreutils"], +) diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage -index 6e33c85..9f5a805 100644 +index 6e33c85..2ccddd7 100644 --- a/policycoreutils/semanage/semanage +++ b/policycoreutils/semanage/semanage @@ -1,5 +1,7 @@ @@ -509914,7 +509914,7 @@ index 6e33c85..9f5a805 100644 # see file 'COPYING' for use and warranty information # # semanage is a tool for managing SELinux configuration files -@@ -19,564 +21,798 @@ +@@ -19,564 +21,792 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA # @@ -509951,7 +509951,7 @@ index 6e33c85..9f5a805 100644 +usage_fcontext = "semanage fcontext [-h] [-n] [-N] [-s STORE] [" +usage_fcontext_dict = {' --add':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER', '|','-e EQUAL', ')','FILE_SPEC',')' ,),' --delete':('(','-t TYPE','-f FTYPE','|','-e EQUAL',')','FILE_SPEC', ')',),' --modify':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER','|','-e EQUAL',')','FILE_SPEC )',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} + -+usage_user = "semanage fcontext [-h] [-n] [-N] [-s STORE] [" ++usage_user = "semanage user [-h] [-n] [-N] [-s STORE] [" +usage_user_dict = {' --add':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name'')'),' --delete':('selinux_name',),' --modify':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} + +usage_port = "semanage port [-h] [-n] [-N] [-s STORE] [" @@ -509964,7 +509964,7 @@ index 6e33c85..9f5a805 100644 +usage_interface_dict = {' --add':('-t TYPE','-r RANGE','interface'),' --modify':('-t TYPE','-r RANGE','interface'), ' --delete':('interface',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} + +usage_boolean = "semanage boolean [-h] [-n] [-N] [-s STORE] [" -+usage_boolean_dict = {' --modify':('(','(','(','--on','|','--off',')','(','boolean',')',')',')',')'), ' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++usage_boolean_dict = {' --modify':('(','--on','|','--off',')','boolean'), ' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} + +import sepolicy +class CheckRole(argparse.Action): @@ -509996,7 +509996,7 @@ index 6e33c85..9f5a805 100644 + +class SetExportFile(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): -+ if values is not None: ++ if values: + if values is not "-": + try: + sys.stdout = open(values, 'w') @@ -510005,19 +510005,14 @@ index 6e33c85..9f5a805 100644 + sys.exit(1) + setattr(namespace, self.dest, values) + -+fd = None +class SetImportFile(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): -+ global fd -+ if values != None: -+ if values == "-": -+ fd = sys.stdin -+ else: -+ try: -+ fd = open(values, 'r') -+ except IOError,e: -+ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) -+ sys.exit(1) ++ if values and values is not "-": ++ try: ++ sys.stdin = open(values, 'r') ++ except IOError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) + setattr(namespace, self.dest, values) + +# functions for OBJECT initialization @@ -510038,7 +510033,7 @@ index 6e33c85..9f5a805 100644 + return OBJECT + +def interface_ini(): -+ OBJECT = seobject.nodeRecords(store) ++ OBJECT = seobject.interfaceRecords(store) + return OBJECT + +def node_ini(): @@ -510240,8 +510235,9 @@ index 6e33c85..9f5a805 100644 +as shown in the mode field by ls, e.g. use -d to match only +directories or -- to match only regular files. The following +file type options can be passed: -+"" (all files),-- (regular file),-d (directory),-c (character device), ++-- (regular file),-d (directory),-c (character device), +-b (block device),-s (socket),-l (symbolic link),-p (named pipe) ++If you do not specify a file type, the file type will default to "all files". +''' + generate_usage = generate_custom_usage(usage_fcontext, usage_fcontext_dict) + fcontextParser = subparsers.add_parser('fcontext',usage=generate_usage, help=_("Manage file context mapping definitions")) @@ -510262,7 +510258,7 @@ index 6e33c85..9f5a805 100644 + label. This is used with fcontext. Requires source and target + path arguments. The context labeling for the target subtree is + made equivalent to that defined for the source.''')) -+ fcontextParser.add_argument('-f', '--ftype', default="", choices=["all files", '""',"--","-d","-c","-b","-s","-l","-p"], help=_(ftype_help)) ++ fcontextParser.add_argument('-f', '--ftype', default="", choices=["--","-d","-c","-b","-s","-l","-p"], help=_(ftype_help)) + parser_add_seuser(fcontextParser, "fcontext") + parser_add_type(fcontextParser, "fcontext") + parser_add_range(fcontextParser, "fcontext") @@ -510390,6 +510386,8 @@ index 6e33c85..9f5a805 100644 + parser_add_noheading(interfaceParser, "interface") + parser_add_noreload(interfaceParser, "interface") + parser_add_store(interfaceParser, "interface") ++ parser_add_type(interfaceParser, "interface") ++ parser_add_range(interfaceParser, "interface") + + interface_action = interfaceParser.add_mutually_exclusive_group(required=True) + parser_add_add(interface_action, "interface") @@ -510398,8 +510396,6 @@ index 6e33c85..9f5a805 100644 + parser_add_list(interface_action, "interface") + parser_add_extract(interface_action, "interface") + parser_add_deleteall(interface_action, "interface") -+ parser_add_type(interface_action, "interface") -+ parser_add_range(interface_action, "interface") + interfaceParser.add_argument('interface', nargs='?', default=None, help=_('interface_spec')) + interfaceParser.set_defaults(func=handleInterface) + @@ -510433,18 +510429,18 @@ index 6e33c85..9f5a805 100644 + moduleParser.set_defaults(func=handleModule) + +def handleNode(args): -+ node_args = {'list':[('node','type','proto','mask'),('')],'add':[('locallist'),('type','node','proto','mask')],'modify':[('locallist'),('node','mask','proto')], 'delete':[('locallist'),('node','mask','prototype')],'extract':[('locallist','node','type','proto','mask'),('')],'deleteall':[('locallist'),('')]} ++ node_args = {'list':[('node','type','proto','netmask'),('')],'add':[('locallist'),('type','node','proto','netmask')],'modify':[('locallist'),('node','netmask','proto')], 'delete':[('locallist'),('node','netmask','prototype')],'extract':[('locallist','node','type','proto','netmask'),('')],'deleteall':[('locallist'),('')]} + handle_opts(args,node_args,args.action) + + OBJECT = object_dict['node']() + OBJECT.set_reload(args.noreload) + + if args.action is "add": -+ OBJECT.add(args.node, args.mask, args.proto, args.range, args.type) ++ OBJECT.add(args.node, args.netmask, args.proto, args.range, args.type) + if args.action is "modify": -+ OBJECT.add(args.node, args.mask, args.proto, args.range, args.type) ++ OBJECT.add(args.node, args.netmask, args.proto, args.range, args.type) + if args.action is "delete": -+ OBJECT.delete(args.node, args.mask, args.proto) ++ OBJECT.delete(args.node, args.netmask, args.proto) + if args.action is "list": + OBJECT.list(args.noheading, args.locallist) + if args.action is "deleteall": @@ -510512,11 +510508,10 @@ index 6e33c85..9f5a805 100644 + parser_add_noheading(booleanParser, "boolean") + parser_add_noreload(booleanParser, "boolean") + parser_add_store(booleanParser, "boolean") -+ booleanParser.add_argument('boolean', nargs="?", default=None, help=_('boolean | boolean_file')) ++ booleanParser.add_argument('boolean', nargs="?", default=None, help=_('boolean')) + + boolean_action = booleanParser.add_mutually_exclusive_group(required=False) + #add_add(boolean_action) -+ parser_add_delete(boolean_action, "boolean") + parser_add_modify(boolean_action, "boolean") + parser_add_list(boolean_action, "boolean") + parser_add_extract(boolean_action, "boolean") @@ -510634,7 +510629,7 @@ index 6e33c85..9f5a805 100644 + trans = seobject.semanageRecords(store) + trans.start() + -+ for l in fd.readlines(): ++ for l in sys.stdin.readlines(): + try: + commandParser = createCommandParser() + args = commandParser.parse_args(mkargv(l)) @@ -510650,7 +510645,6 @@ index 6e33c85..9f5a805 100644 + + trans.set_reload(args.noreload) + trans.finish() -+ fd.close() + +def setupImportParser(subparsers): + importParser = subparsers.add_parser('import', help=_('Output local customizations')) @@ -511361,15 +511355,15 @@ index edefd9a..ed31356 100644 return 0 diff --git a/policycoreutils/semanage/semanage-boolean.8 b/policycoreutils/semanage/semanage-boolean.8 new file mode 100644 -index 0000000..807219f +index 0000000..0a59e07 --- /dev/null +++ b/policycoreutils/semanage/semanage-boolean.8 -@@ -0,0 +1,64 @@ +@@ -0,0 +1,61 @@ +.TH "semanage-boolean" "8" "20130617" "" "" +.SH "NAME" +semanage boolean\- SELinux Policy Management boolean tool +.SH "SYNOPSIS" -+.B semanage boolean [\-h] [\-n] [\-N] [\-s STORE] [ \-\-extract | \-\-deleteall | \-\-list \-C | \-\-modify ( ( ( \-\-on | \-\-off ) boolean ) ) ] ++.B semanage boolean [\-h] [\-n] [\-N] [\-s STORE] [ \-\-extract | \-\-deleteall | \-\-list \-C | \-\-modify ( \-\-on | \-\-off ) boolean ] + +.SH "DESCRIPTION" +semanage is used to configure certain elements of @@ -511392,9 +511386,6 @@ index 0000000..807219f +.I \-C, \-\-locallist +List OBJECTS local customizations +.TP -+.I \-d, \-\-delete -+Delete a record of the specified object type -+.TP +.I \-m, \-\-modify +Modify a record of the specified object type +.TP @@ -511514,10 +511505,10 @@ index 0000000..1b20c82 +This man page was written by Daniel Walsh diff --git a/policycoreutils/semanage/semanage-fcontext.8 b/policycoreutils/semanage/semanage-fcontext.8 new file mode 100644 -index 0000000..1ac1310 +index 0000000..5e40f44 --- /dev/null +++ b/policycoreutils/semanage/semanage-fcontext.8 -@@ -0,0 +1,86 @@ +@@ -0,0 +1,87 @@ +.TH "semanage-fcontext" "8" "20130617" "" "" +.SH "NAME" +semanage fcontext\- SELinux Policy Management file context tool @@ -511569,8 +511560,9 @@ index 0000000..1ac1310 +.I \-e EQUAL, \-\-equal EQUAL +Substitute target path with sourcepath when generating default label. This is used with fcontext. Requires source and target path arguments. The context labeling for the target subtree is made equivalent to that defined for the source. +.TP -+.I \-f [{"",\-\-,\-d,\-c,\-b,\-s,\-l,\-p}], \-\-ftype [{"",\-\-,\-d,\-c,\-b,\-s,\-l,\-p}] -+File Type. This is used with fcontext. Requires a file type as shown in the mode field by ls, e.g. use \-d to match only directories or \-\- to match only regular files. The following file type options can be passed: "" (all files),\-\- (regular file),\-d (directory),\-c (character device), \-b (block device),\-s (socket),\-l (symbolic link),\-p (named pipe) ++.I \-f [{\-\-,\-d,\-c,\-b,\-s,\-l,\-p}], \-\-ftype [{\-\-,\-d,\-c,\-b,\-s,\-l,\-p}] ++File Type. This is used with fcontext. Requires a file type as shown in the mode field by ls, e.g. use \-d to match only directories or \-\- to match only regular files. The following file type options can be passed: \-\- (regular file),\-d (directory),\-c (character device), \-b (block device),\-s (socket),\-l (symbolic link),\-p (named pipe). If you do not specify a file type, the file type will default to "all files". ++ +.TP +.I \-s SEUSER, \-\-seuser SEUSER +SELinux user name @@ -512384,7 +512376,7 @@ index 28a9022..90b142e 100644 +usage: semanage [-h] + diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py -index 85bc37f..b66840f 100644 +index 85bc37f..e67602a 100644 --- a/policycoreutils/semanage/seobject.py +++ b/policycoreutils/semanage/seobject.py @@ -32,11 +32,10 @@ from IPy import IP @@ -512442,7 +512434,20 @@ index 85bc37f..b66840f 100644 (rc, u) = semanage_user_create(self.sh) if rc < 0: -@@ -1274,7 +1278,8 @@ class nodeRecords(semanageRecords): +@@ -999,8 +1003,10 @@ class portRecords(semanageRecords): + raise ValueError(_("Type %s is invalid, must be a port type") % type) + + ( k, proto_d, low, high ) = self.__genkey(port, proto) +- +- (rc, exists) = semanage_port_exists(self.sh, k) ++ if semanageRecords.transaction: ++ (rc, exists) = semanage_port_exists_local(self.sh, k) ++ else: ++ (rc, exists) = semanage_port_exists(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port)) + if exists: +@@ -1274,7 +1280,8 @@ class nodeRecords(semanageRecords): (rc, exists) = semanage_node_exists(self.sh, k) if exists: @@ -512452,7 +512457,7 @@ index 85bc37f..b66840f 100644 (rc, node) = semanage_node_create(self.sh) if rc < 0: -@@ -1475,7 +1480,8 @@ class interfaceRecords(semanageRecords): +@@ -1475,7 +1482,8 @@ class interfaceRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if interface %s is defined") % interface) if exists: @@ -512462,7 +512467,7 @@ index 85bc37f..b66840f 100644 (rc, iface) = semanage_iface_create(self.sh) if rc < 0: -@@ -1643,6 +1649,7 @@ class fcontextRecords(semanageRecords): +@@ -1643,6 +1651,7 @@ class fcontextRecords(semanageRecords): try: valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] valid_types += sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"] @@ -512470,7 +512475,7 @@ index 85bc37f..b66840f 100644 except RuntimeError: valid_types = [] -@@ -1751,9 +1758,15 @@ class fcontextRecords(semanageRecords): +@@ -1751,9 +1760,15 @@ class fcontextRecords(semanageRecords): raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t)) @@ -512487,7 +512492,7 @@ index 85bc37f..b66840f 100644 if is_mls_enabled == 1: serange = untranslate(serange) -@@ -1777,7 +1790,8 @@ class fcontextRecords(semanageRecords): +@@ -1777,7 +1792,8 @@ class fcontextRecords(semanageRecords): raise ValueError(_("Could not check if file context for %s is defined") % target) if exists: @@ -512497,7 +512502,7 @@ index 85bc37f..b66840f 100644 (rc, fcontext) = semanage_fcontext_create(self.sh) if rc < 0: -@@ -1970,7 +1984,7 @@ class fcontextRecords(semanageRecords): +@@ -1970,7 +1986,7 @@ class fcontextRecords(semanageRecords): if len(self.equiv): for target in self.equiv.keys(): @@ -512506,7 +512511,7 @@ index 85bc37f..b66840f 100644 return l def list(self, heading = 1, locallist = 0 ): -@@ -2156,7 +2170,7 @@ class booleanRecords(semanageRecords): +@@ -2156,7 +2172,7 @@ class booleanRecords(semanageRecords): keys.sort() for k in keys: if ddict[k]: @@ -513163,10 +513168,10 @@ index 4eca22d..2a9e1c7 100644 init_info(m); diff --git a/policycoreutils/sepolicy/selinux_server.py b/policycoreutils/sepolicy/selinux_server.py new file mode 100644 -index 0000000..d4a2541 +index 0000000..1206664 --- /dev/null +++ b/policycoreutils/sepolicy/selinux_server.py -@@ -0,0 +1,60 @@ +@@ -0,0 +1,69 @@ +#!/usr/bin/python + +import dbus @@ -513184,7 +513189,11 @@ index 0000000..d4a2541 + def __init__ (self, *p, **k): + super(selinux_server, self).__init__(*p, **k) + -+ @dbus.service.method("org.fedoraproject.selinux", in_signature='s', out_signature='s') ++ # ++ # The semanage method runs a transaction on a series of semanage commands, ++ # these commnds can take the output of customized ++ # ++ @dbus.service.method("org.fedoraproject.selinux", in_signature='s') + def semanage(self, buf): + fd = open("/run/selinux.input", "w") + fd.write(buf) @@ -513193,8 +513202,12 @@ index 0000000..d4a2541 + output = p.communicate() + if p.returncode and p.returncode != 0: + raise OSError("Failed update SELinux configuration: %s", output) -+ return + ++ # ++ # The customized method will return all of the custommizations for policy ++ # on the server. This output can be used with the semanage method on ++ # another server to make the two systems have duplicate policy. ++ # + @dbus.service.method("org.fedoraproject.selinux", in_signature='', out_signature='s') + def customized(self): + p = Popen(["/usr/sbin/semanage", "-o", "/run/selinux.output"],stdout=PIPE, stderr=PIPE) @@ -513206,17 +513219,21 @@ index 0000000..d4a2541 + fd.close() + return buf + -+ @dbus.service.method("org.fedoraproject.selinux", in_signature='s', out_signature='i') ++ # ++ # The restorecon method modifies any file path to the default system label ++ # ++ @dbus.service.method("org.fedoraproject.selinux", in_signature='s') + def restorecon(self, path): + selinux.restorecon(str(path)) -+ return 0 + -+ @dbus.service.method("org.fedoraproject.selinux", in_signature='i', out_signature='i') ++ # ++ # The setenforce method turns off the current enforcement of SELinux ++ # ++ @dbus.service.method("org.fedoraproject.selinux", in_signature='i') + def setenforce(self, value): + selinux.security_setenforce(value) -+ return 0 + -+if __name__ == "__main__": ++if __name__ == "__main__": + mainloop = gobject.MainLoop() + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + system_bus = dbus.SystemBus() @@ -513224,9 +513241,6 @@ index 0000000..d4a2541 + object = selinux_server(system_bus, "/org/fedoraproject/selinux/object") + slip.dbus.service.set_mainloop(mainloop) + mainloop.run() -+ -+#ex = selinux('/selinux') -+#ex.restorecon('/etc') diff --git a/policycoreutils/sepolicy/sepolgen.8 b/policycoreutils/sepolicy/sepolgen.8 new file mode 100644 index 0000000..3ecf3eb @@ -513551,7 +513565,7 @@ index 0748ca9..6348287 100644 -selinux(8), sepolicy-booleans(8), sepolicy-communicate(8), sepolicy-generate(8), sepolicy-interface(8), sepolicy-network(8), sepolicy-manpage(8), sepolicy-transition(8) +selinux(8), sepolicy-booleans(8), sepolicy-communicate(8), sepolicy-generate(8),sepolicy-gui(8), sepolicy-interface(8), sepolicy-network(8), sepolicy-manpage(8), sepolicy-transition(8) diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py -index b25d3b2..086766e 100755 +index b25d3b2..0dc3b9b 100755 --- a/policycoreutils/sepolicy/sepolicy.py +++ b/policycoreutils/sepolicy/sepolicy.py @@ -22,6 +22,8 @@ @@ -513704,7 +513718,7 @@ index b25d3b2..086766e 100755 - for recs in portdict[p]: - print "\t" + recs + for t, recs in portdict[p]: -+ port_strings.append(", ".join(recs)) ++ port_strings.append("%s (%s)" % (", ".join(recs), t)) + port_strings.sort(numcmp) + for p in port_strings: + print "\t" + p @@ -514067,7 +514081,7 @@ index b25d3b2..086766e 100755 sys.exit(0) + diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py -index 5e7415c..41fe06e 100644 +index 5e7415c..5cebe57 100644 --- a/policycoreutils/sepolicy/sepolicy/__init__.py +++ b/policycoreutils/sepolicy/sepolicy/__init__.py @@ -1,12 +1,15 @@ @@ -514087,7 +514101,7 @@ index 5e7415c..41fe06e 100644 gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: -@@ -37,16 +40,288 @@ CLASS = 'class' +@@ -37,16 +40,295 @@ CLASS = 'class' TRANSITION = 'transition' ROLE_ALLOW = 'role_allow' @@ -514185,8 +514199,7 @@ index 5e7415c..41fe06e 100644 + print "try failed got an IndexError" + pass + - try: -- path = selinux.selinux_binary_policy_path() ++ try: + pat = re.compile(r"%s$" % reg) + return filter(pat.match, map(lambda x: path + x, os.listdir(path))) + except: @@ -514277,6 +514290,13 @@ index 5e7415c..41fe06e 100644 + pass + return None + ++def get_file_transitions(setype): ++ try: ++ return filter(lambda x: x['class'] != "process", search([TRANSITION],{'source':setype})) ++ except TypeError: ++ pass ++ return None ++ +def get_boolean_rules(setype, boolean): + boollist = [] + permlist = search([ALLOW],{'source':setype }) @@ -514345,7 +514365,8 @@ index 5e7415c..41fe06e 100644 + return mpaths + +def get_installed_policy(root = "/"): -+ try: + try: +- path = selinux.selinux_binary_policy_path() + path = root + selinux.selinux_binary_policy_path() policies = glob.glob ("%s.*" % path ) policies.sort() @@ -514379,7 +514400,7 @@ index 5e7415c..41fe06e 100644 all_types = None def get_all_types(): global all_types -@@ -54,23 +329,31 @@ def get_all_types(): +@@ -54,23 +336,31 @@ def get_all_types(): all_types = map(lambda x: x['name'], info(TYPE)) return all_types @@ -514424,7 +514445,7 @@ index 5e7415c..41fe06e 100644 all_domains = [] types=get_all_types() types.sort() -@@ -81,18 +364,61 @@ def get_all_entrypoint_domains(): +@@ -81,18 +371,61 @@ def get_all_entrypoint_domains(): all_domains.append(m[0]) return all_domains @@ -514493,7 +514514,7 @@ index 5e7415c..41fe06e 100644 roles = map(lambda x: x['name'], info(ROLE)) roles.remove("object_r") roles.sort() -@@ -104,115 +430,256 @@ def get_all_users(): +@@ -104,115 +437,256 @@ def get_all_users(): if users: return users users = map(lambda x: x['name'], info(USER)) @@ -514822,7 +514843,7 @@ index 5e7415c..41fe06e 100644 def boolean_category(boolean): booleans_dict = gen_bool_dict() -@@ -233,18 +700,18 @@ def get_os_version(): +@@ -233,18 +707,18 @@ def get_os_version(): os_version = "" pkg_name = "selinux-policy" try: @@ -514863,7 +514884,7 @@ index a179d95..9b9a09a 100755 tlist = [] for l in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)): diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py -index 26f8390..e27bc88 100644 +index 26f8390..ba959ae 100644 --- a/policycoreutils/sepolicy/sepolicy/generate.py +++ b/policycoreutils/sepolicy/sepolicy/generate.py @@ -63,20 +63,6 @@ except IOError: @@ -514905,7 +514926,22 @@ index 26f8390..e27bc88 100644 try: self.ports = get_all_ports() except ValueError, e: -@@ -319,7 +305,7 @@ class policy: +@@ -268,8 +254,14 @@ class policy: + self.symbols["fowner"] = "add_capability('fowner')" + self.symbols["fsetid"] = "add_capability('fsetid')" + self.symbols["setgid"] = "add_capability('setgid')" ++ self.symbols["setegid"] = "add_capability('setgid')" ++ self.symbols["setresgid"] = "add_capability('setgid')" ++ self.symbols["setregid"] = "add_capability('setgid')" + self.symbols["setresuid"] = "add_capability('setuid')" + self.symbols["setuid"] = "add_capability('setuid')" ++ self.symbols["seteuid"] = "add_capability('setuid')" ++ self.symbols["setreuid"] = "add_capability('setuid')" ++ self.symbols["setresuid"] = "add_capability('setuid')" + self.symbols["setpcap"] = "add_capability('setpcap')" + self.symbols["linux_immutable"] = "add_capability('linux_immutable')" + self.symbols["net_bind_service"] = "add_capability('net_bind_service')" +@@ -319,7 +311,7 @@ class policy: self.DEFAULT_EXT["_var_log_t"] = var_log; self.DEFAULT_EXT["_var_run_t"] = var_run; self.DEFAULT_EXT["_var_spool_t"] = var_spool; @@ -514914,7 +514950,7 @@ index 26f8390..e27bc88 100644 self.DEFAULT_KEYS=["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system" ] -@@ -587,7 +573,7 @@ class policy: +@@ -587,7 +579,7 @@ class policy: def generate_network_action(self, protocol, action, port_name): line = "" method = "corenet_%s_%s_%s" % (protocol, action, port_name) @@ -514923,7 +514959,7 @@ index 26f8390..e27bc88 100644 line = "%s(%s_t)\n" % (method, self.name) else: line = """ -@@ -843,7 +829,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -843,7 +835,7 @@ allow %s_t %s_t:%s_socket name_%s; def generate_existing_user_types(self): if len(self.existing_domains) == 0: @@ -514932,7 +514968,7 @@ index 26f8390..e27bc88 100644 newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types) newte += """gen_require(`""" -@@ -873,19 +859,21 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -873,19 +865,21 @@ allow %s_t %s_t:%s_socket name_%s; for t in self.types: for i in self.DEFAULT_EXT: if t.endswith(i): @@ -514961,7 +514997,7 @@ index 26f8390..e27bc88 100644 def generate_daemon_types(self): newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types) if self.initscript != "": -@@ -1014,7 +1002,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1014,7 +1008,7 @@ allow %s_t %s_t:%s_socket name_%s; def generate_roles_rules(self): newte = "" @@ -514970,7 +515006,7 @@ index 26f8390..e27bc88 100644 roles = "" if len(self.roles) > 0: newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules) -@@ -1030,14 +1018,15 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1030,14 +1024,15 @@ allow %s_t %s_t:%s_socket name_%s; if len(self.DEFAULT_DIRS[d][1]) > 0: # CGI scripts already have a rw_t if self.type != CGI or d != "rw": @@ -514988,7 +515024,7 @@ index 26f8390..e27bc88 100644 newte += self.generate_capabilities() newte += self.generate_process() newte += self.generate_network_types() -@@ -1048,11 +1037,22 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1048,11 +1043,22 @@ allow %s_t %s_t:%s_socket name_%s; for d in self.DEFAULT_KEYS: if len(self.DEFAULT_DIRS[d][1]) > 0: @@ -515016,7 +515052,7 @@ index 26f8390..e27bc88 100644 newte += self.generate_tmp_rules() newte += self.generate_network_rules() -@@ -1077,19 +1077,6 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1077,19 +1083,6 @@ allow %s_t %s_t:%s_socket name_%s; def generate_fc(self): newfc = "" fclist = [] @@ -515036,7 +515072,7 @@ index 26f8390..e27bc88 100644 for i in self.files.keys(): if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]): t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file) -@@ -1103,13 +1090,28 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1103,13 +1096,28 @@ allow %s_t %s_t:%s_socket name_%s; t2 = re.sub("FILENAME", i, t1) fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2)) @@ -515066,7 +515102,7 @@ index 26f8390..e27bc88 100644 return newsh roles = "" -@@ -1117,13 +1119,10 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1117,13 +1125,10 @@ allow %s_t %s_t:%s_socket name_%s; roles += " %s_r" % role if roles != "": roles += " system_r" @@ -515082,7 +515118,7 @@ index 26f8390..e27bc88 100644 for u in self.transition_users: tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans) newsh += re.sub("USER", u, tmp) -@@ -1143,6 +1142,8 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1143,6 +1148,8 @@ allow %s_t %s_t:%s_socket name_%s; newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp) else: newsh = re.sub("TEMPLATEFILE", self.file_name, temp) @@ -515091,7 +515127,7 @@ index 26f8390..e27bc88 100644 if self.program: newsh += re.sub("FILENAME", self.program, script.restorecon) if self.initscript != "": -@@ -1165,6 +1166,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1165,6 +1172,7 @@ allow %s_t %s_t:%s_socket name_%s; newsh += re.sub("TEMPLATETYPE", self.name, t1) newsh += self.generate_user_sh() @@ -515099,7 +515135,7 @@ index 26f8390..e27bc88 100644 return newsh -@@ -1198,7 +1200,13 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1198,7 +1206,13 @@ allow %s_t %s_t:%s_socket name_%s; if self.type not in APPLICATIONS: newspec = re.sub("%relabel_files", "", newspec) @@ -515114,7 +515150,7 @@ index 26f8390..e27bc88 100644 def write_spec(self, out_dir): specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name) -@@ -1349,6 +1357,7 @@ Warning %s does not exist +@@ -1349,6 +1363,7 @@ Warning %s does not exist out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file")) out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file")) out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file")) @@ -515126,10 +515162,10 @@ index 26f8390..e27bc88 100644 return out diff --git a/policycoreutils/sepolicy/sepolicy/gui.py b/policycoreutils/sepolicy/sepolicy/gui.py new file mode 100644 -index 0000000..cebdfbf +index 0000000..af4278f --- /dev/null +++ b/policycoreutils/sepolicy/sepolicy/gui.py -@@ -0,0 +1,2189 @@ +@@ -0,0 +1,2353 @@ +#!/usr/bin/python -Es +# +# Copyright (C) 2013 Red Hat @@ -515156,7 +515192,7 @@ index 0000000..cebdfbf +# +# + -+import sys ++import os, sys +import gobject +import sepolicy +import selinux @@ -515166,8 +515202,8 @@ index 0000000..cebdfbf +from sepolicy.sedbus import SELinuxDBus +import dbus +import time -+ +import gettext ++ +PROGNAME="policycoreutils" +gettext.bindtextdomain(PROGNAME, "/usr/share/locale") +gettext.textdomain(PROGNAME) @@ -515210,7 +515246,7 @@ index 0000000..cebdfbf + self.dbus = SELinuxDBus() + self.filter_txt = "" + self.builder = gtk.Builder() # BUILDER OBJ -+ #glade_file = "/home/rhallisey/Desktop/GUI_4.glade" # The gui is now placed in the obj ++ #glade_file = "/home/rhallisey/Desktop/sepolicy.glade" # The gui is now placed in the obj + glade_file = distutils.sysconfig.get_python_lib(plat_specific = True) + "/sepolicy/sepolicy.glade" + self.builder.add_from_file(glade_file) + self.outer_notebook = self.builder.get_object("outer_notebook") # The notebook obj @@ -515225,6 +515261,7 @@ index 0000000..cebdfbf + self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) + self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) + self.current_popup = None ++ self.import_export = None + + # Data store dictionaries + self.booldict = {} @@ -515272,10 +515309,13 @@ index 0000000..cebdfbf + self.app_system_button = self.builder.get_object("app_system_button") + self.system_button = self.builder.get_object("System_button") + self.systems_box = self.builder.get_object("Systems_box") ++ self.relabel_button = self.builder.get_object("Relabel_button") ++ self.relabel_button.set_active(os.path.exists('/.autorelabel')) + # System Items ************************************** + + # Browse Items ************************************** + self.browse_popup_window = self.builder.get_object("Add_path_dialog") ++ self.file_config_window = self.builder.get_object("file_configurations") + self.select_button_browse = self.builder.get_object("select_button_browse") + self.cancel_button_browse = self.builder.get_object("cancel_button_browse") + # Browse Items ************************************** @@ -515286,6 +515326,17 @@ index 0000000..cebdfbf + self.moreTypes_treeview = self.builder.get_object("moreTypes_treeview_files") + # More types window items *************************** + ++ # System policy type ******************************** ++ self.system_policy_type_liststore = self.builder.get_object("system_policy_type_liststore") ++ self.system_policy_type_combobox = self.builder.get_object("system_policy_type_combobox") ++ self.policy_list = [] ++ self.populate_system_policy() ++ self.enforcing_button_default = self.builder.get_object("Enforcing_button_default") ++ self.permissive_button_default = self.builder.get_object("Permissive_button_default") ++ self.disabled_button_default = self.builder.get_object("Disabled_button_default") ++ self.initialize_system_default_mode() ++ # System policy type ******************************** ++ + # Update menu items ********************************* + self.update_window = self.builder.get_object("update_window") + self.update_treeview = self.builder.get_object("update_treeview") @@ -515375,10 +515426,9 @@ index 0000000..cebdfbf + self.executable_files_tab = self.builder.get_object("Executable_files_tab") + self.executable_files_tab_tooltip_txt = self.executable_files_tab.get_tooltip_text() + self.executable_files_treestore = self.builder.get_object("executable_files_treestore") -+ self.files_button = self.builder.get_object("Files_button") -+ self.files_button_tooltip_txt = self.files_button.get_tooltip_text() ++ self.files_radio_button = self.builder.get_object("Files_button") ++ self.files_button_tooltip_txt = self.files_radio_button.get_tooltip_text() + self.executable_files_treemodel_sort = self.builder.get_object("executable_files_treemodelsort") -+ #self.executable_files_tree_data_set = self.builder.get_object("executable_files_liststore") + self.executable_files_treestore.set_sort_column_id(0, gtk.SORT_ASCENDING) + # executable_files items **************************** + @@ -515415,8 +515465,8 @@ index 0000000..cebdfbf + self.out_network_tab_tooltip_txt = self.out_network_tab.get_tooltip_text() + self.out_network_treemodel_sort = self.builder.get_object("out_network_treemodelsort") + -+ self.network_button = self.builder.get_object("Network_button") -+ self.network_button_tooltip_txt = self.network_button.get_tooltip_text() ++ self.network_radio_button = self.builder.get_object("Network_button") ++ self.network_button_tooltip_txt = self.network_radio_button.get_tooltip_text() + + self.in_network_treemodel_sort = self.builder.get_object("in_network_treemodelsort") + self.in_network_tab = self.builder.get_object("Inbound_tab") @@ -515436,8 +515486,8 @@ index 0000000..cebdfbf + self.booleans_more_detail_window = self.builder.get_object("booleans_popup_window") + self.booleans_more_detail_treeview = self.builder.get_object("more_detail_treeview") + self.booleans_more_detail_tree_data_set = self.builder.get_object("booleans_more_detail_liststore") -+ self.booleans_button = self.builder.get_object("Booleans_button") -+ self.booleans_button_tooltip_txt = self.booleans_button.get_tooltip_text() ++ self.booleans_radio_button = self.builder.get_object("Booleans_button") ++ self.booleans_button_tooltip_txt = self.booleans_radio_button.get_tooltip_text() + self.booleans_treemodel_sort = self.builder.get_object("boolean_treemodelsort") + # boolean items ************************************ + @@ -515449,8 +515499,8 @@ index 0000000..cebdfbf + self.transitions_into_x_tab_tooltip_txt = self.transitions_into_x_tab.get_tooltip_text() + self.transitions_into_x_tree_data_set.set_sort_column_id(1, gtk.SORT_ASCENDING) + -+ self.transitions_button = self.builder.get_object("Transitions_button") -+ self.transitions_button_tooltip_txt = self.transitions_button.get_tooltip_text() ++ self.transitions_radio_button = self.builder.get_object("Transitions_button") ++ self.transitions_button_tooltip_txt = self.transitions_radio_button.get_tooltip_text() + + self.transitions_from_x_treemodelsort = self.builder.get_object("transitions_from_x_treemodelsort") + self.transitions_from_x_treeview = self.builder.get_object("transitions_from_x_treeview") # Get the transitions tree list @@ -515459,6 +515509,14 @@ index 0000000..cebdfbf + self.transitions_from_x_tab = self.builder.get_object("Transitions_from_x_tab") + self.transitions_from_x_tab_tooltip_txt = self.transitions_from_x_tab.get_tooltip_text() + self.transitions_from_x_treestore.set_sort_column_id(2, gtk.SORT_ASCENDING) ++ ++ self.transitions_file_treemodelsort = self.builder.get_object("File_transitions_treemodel_sort") ++ self.transitions_file_treeview = self.builder.get_object("file_transitions_treeview") # Get the transitions tree list ++ self.transitions_file_liststore = self.builder.get_object("File_transitions_liststore") # Contains the tree with Enabled, Executable File Type, Transtype ++ self.transitions_file_filter_model = self.builder.get_object("File_transitions_treemodel_filter") ++ self.transitions_file_tab = self.builder.get_object("file_transitions") ++ self.transitions_file_tab_tooltip_txt = self.transitions_from_x_tab.get_tooltip_text() ++ self.transitions_file_liststore.set_sort_column_id(0, gtk.SORT_ASCENDING) + # transitions items ************************************ + + # Combobox and Entry items ************************** @@ -515488,7 +515546,6 @@ index 0000000..cebdfbf + self.current_status_permissive = self.builder.get_object("Permissive_button") + self.status_bar = self.builder.get_object("status_bar") + status = selinux.security_getenforce() -+ self.current_status_enforcing.set_active(status) + self.context_id = self.status_bar.get_context_id("SELinux status") + + if status == -1 : @@ -515520,6 +515577,8 @@ index 0000000..cebdfbf + self.transitions_from_x_filter_data_set.set_visible_func(self.filter_the_data) + self.transitions_into_x_filter_data_set = self.transitions_into_x_filter_model + self.transitions_into_x_filter_data_set.set_visible_func(self.filter_the_data) ++ self.transitions_file_filter_data_set = self.transitions_file_filter_model ++ self.transitions_file_filter_data_set.set_visible_func(self.filter_the_data) + self.advanced_search_filter_data_set = self.advanced_search_treemodel_filter + self.advanced_search_filter_data_set.set_visible_func(self.filter_the_data) + #self.network_filter_data_set.set_visible_func(self.filter_the_data) # Set only some of the data to be visible based on what returns from the filter @@ -515563,9 +515622,9 @@ index 0000000..cebdfbf + if entrypoint: + path = sepolicy.find_entrypoint_path(entrypoint) + if path: -+ self.combo_box_initialize(path, None) # Adds all files entrypoint paths that exists on disc into the combobox -+ self.advanced_search_initialize(path) -+ self.installed_list.append(path) ++ self.combo_box_initialize(path, None) # Adds all files entrypoint paths that exists on disc into the combobox ++ self.advanced_search_initialize(path) ++ self.installed_list.append(path) + + self.loading += 1 + @@ -515629,6 +515688,15 @@ index 0000000..cebdfbf + "on_Show_modified_only_toggle_booleans_toggled" : self.bools_show_modified_only, + "on_Show_modified_only_toggle_files_toggled" : self.files_show_modified_only, + "on_Show_modified_only_toggle_network_toggled" : self.network_show_modified_only, ++ "on_cancel_button_config_clicked" : self.close_config_window, ++ "on_select_button_config_clicked" : self.import_or_export, ++ "on_Import_button_clicked" : self.import_config_show, ++ "on_Export_button_clicked" : self.export_config_show, ++ "on_system_policy_type_combobox_changed" : self.change_system_policy, ++ "on_Enforcing_button_default_toggled" : self.change_default_mode, ++ "on_Permissive_button_default_toggled" : self.change_default_mode, ++ "on_Disabled_button_default_toggled" : self.change_default_mode, ++ "on_Relabel_button_toggled" : self.relabel_on_reboot, + + "on_treemodelfilter_row_changed" : self.filter_the_data, # When a row is changed in the tree model filter + "on_Booleans_button_toggled" : self.booleans_tab_change, @@ -515680,6 +515748,41 @@ index 0000000..cebdfbf + def resize_wrap(self, *args): + print args + ++ def initialize_system_default_mode(self): ++ fd = open('/etc/selinux/config', 'r') ++ for l in fd.readlines(): ++ if l.startswith('SELINUX='): ++ l = l.split('SELINUX=')[1] ++ break ++ fd.close() ++ if l.startswith('enforcing'): ++ self.enforcing_button_default.set_active(True) ++ elif l.startswith('permissive'): ++ self.permissive_button_default.set_active(True) ++ else: ++ self.disabled_button_default.set_active(True) ++ ++ ++ def read_directory(self, a, dir, files): ++ try: ++ dir = dir.split("/etc/selinux/")[1] ++ except IndexError: ++ pass ++ if not '/' in dir and dir != None: ++ self.policy_list.append(dir) ++ ++ def populate_system_policy(self): ++ os.path.walk('/etc/selinux', self.read_directory, None) ++ for items in self.policy_list: ++ iter = self.system_policy_type_liststore.append() ++ self.system_policy_type_liststore.set_value(iter, 0, items) ++ fd = open('/etc/selinux/config', 'r') ++ for l in fd.readlines(): ++ if l.startswith('SELINUXTYPE='): ++ l = l.split("SELINUXTYPE=")[1] ++ fd.close() ++ self.system_policy_type_combobox.set_active(self.map_selected_items_into_combobox(self.system_policy_type_liststore, l)) ++ + def filter_the_data(self, list, iter): + if self.filter_txt == "": # When there is no txt in the box show all items in the tree + return True @@ -515843,6 +515946,11 @@ index 0000000..cebdfbf + self.mislabeled_files_label.set_visible(False) + self.warning_files.set_visible(False) + ++ self.booleans_filter.set_text('') ++ self.files_filter.set_text('') ++ self.network_filter.set_text('') ++ self.transitions_filter.set_text('') ++ + application = self.completion_entry.get_text() + if not self.find_application(application): + return @@ -515861,6 +515969,7 @@ index 0000000..cebdfbf + self.transitions_from_x_treestore.clear() + self.application_files_treestore.clear() + self.writable_files_treestore.clear() ++ self.transitions_file_liststore.clear() + + try: + if application[0] == '/': @@ -515877,28 +515986,32 @@ index 0000000..cebdfbf + self.out_network_tab.set_tooltip_text(_("Network Ports to which the '%s' is allowed to connect." % application)) + self.in_network_tab.set_tooltip_text(_("Network Ports to which the '%s' is allowed to listen." % application)) + self.application_files_tab.set_tooltip_text(_("File Types defined for the '%s'." % application)) -+ self.booleans_button.set_tooltip_text(_("Display boolean information that can be used to modify the policy for the '%s'." % application)) -+ self.files_button.set_tooltip_text(_("Display file type information that can be used by the '%s'." % application)) -+ self.network_button.set_tooltip_text(_("Display network ports to which the '%s' can connect or listen to." % application)) -+ self.transitions_into_x_tab.set_label(_("Transitions Into '%s'" % application)) -+ self.transitions_from_x_tab.set_label(_("Transitions From '%s'" % application)) ++ self.booleans_radio_button.set_tooltip_text(_("Display boolean information that can be used to modify the policy for the '%s'." % application)) ++ self.files_radio_button.set_tooltip_text(_("Display file type information that can be used by the '%s'." % application)) ++ self.network_radio_button.set_tooltip_text(_("Display network ports to which the '%s' can connect or listen to." % application)) ++ self.transitions_into_x_tab.set_label(_("Application Transitions Into '%s'" % application)) ++ self.transitions_from_x_tab.set_label(_("Application Transitions From '%s'" % application)) ++ self.transitions_file_tab.set_label(_("File Transitions From '%s'" % application)) + self.transitions_into_x_tab.set_tooltip_text(_("Executables which will transition to the '%s', when executing a selected domains entrypoint." % application)) + self.transitions_from_x_tab.set_tooltip_text(_("Executables which will transition to a different domain, when the '%s' executes them." % application)) -+ self.transitions_button.set_tooltip_text(_("Display applications that can transition into or out of the '%s'." % application)) ++ self.transitions_file_tab.set_tooltip_text(_("Files by '%s' will transitions to a different label." % application)) ++ self.transitions_radio_button.set_tooltip_text(_("Display applications that can transition into or out of the '%s'." % application)) + else: + self.executable_files_tab.set_tooltip_text(self.executable_files_tab_tooltip_txt) + self.writable_files_tab.set_tooltip_text(self.writable_files_tab_tooltip_txt) + self.out_network_tab.set_tooltip_text(self.out_network_tab_tooltip_txt) + self.in_network_tab.set_tooltip_text(self.in_network_tab_tooltip_txt) + self.application_files_tab.set_tooltip_text(self.application_files_tab_tooltip_txt) -+ self.booleans_button.set_tooltip_text(self.booleans_button_tooltip_txt) -+ self.files_button.set_tooltip_text(self.files_button_tooltip_txt) -+ self.network_button.set_tooltip_text(self.network_button_tooltip_txt) ++ self.booleans_radio_button.set_tooltip_text(self.booleans_radio_button_tooltip_txt) ++ self.files__radio_button.set_tooltip_text(self.files_radio_button_tooltip_txt) ++ self.network_radio_button.set_tooltip_text(self.network_radio_button_tooltip_txt) + self.transitions_into_x_tab.set_label(self.transitions_into_x_tab.get_label()) + self.transitions_from_x_tab.set_label(self.transitions_from_x_tab.get_label()) ++ self.transitions_file_tab.set_label(self.transitions_file_tab.get_label()) + self.transitions_into_x_tab.set_tooltip_text(self.transitions_into_x_tab_tooltip_txt) + self.transitions_from_x_tab.set_tooltip_text(self.transitions_from_x_tab_tooltip_txt) -+ self.transitions_button.set_tooltip_text(self.transitions_button_tooltip_txt) ++ self.transitions_file_tab.set_tooltip_text(self.transitions_file_tab_tooltip_txt) ++ self.transitions_radio_button.set_tooltip_text(self.transitions_radio_button_tooltip_txt) + + try: + self.bool_initialize(application) @@ -515913,6 +516026,7 @@ index 0000000..cebdfbf + self.transitions_into_x_initialize(application) + self.transitions_from_x_initialize(application) + self.application_file_types_initialize(application) ++ self.transitions_files_initialize(application) + if self.set_application_label: + self.applications_button_selection.set_label(self.application) + self.ready_mouse() @@ -515946,9 +516060,12 @@ index 0000000..cebdfbf + pass + + def mislabeled(self, path): -+ con = selinux.matchpathcon(path,0)[1] -+ cur = selinux.getfilecon(path)[1] -+ return con != cur ++ try: ++ con = selinux.matchpathcon(path,0)[1] ++ cur = selinux.getfilecon(path)[1] ++ return con != cur ++ except OSError: ++ return False + + def set_mislabeled(self, tree, path, iter, niter): + if not self.mislabeled(path): @@ -516123,17 +516240,33 @@ index 0000000..cebdfbf + else: + niter = self.transitions_from_x_treestore.append(iter) + self.transitions_from_x_treestore.set_value(iter, 0, enabled[active[0][1]]) # active[0][1] is either T or F (enabled is all the way at the top) -+ self.transitions_from_x_treestore.set_value(niter, 0, (_("Return to the"))) ++ markup = '%s' + if active[0][1]: -+ self.transitions_from_x_treestore.set_value(niter, 2, (_("to enable this boolean."))) ++ self.transitions_from_x_treestore.set_value(niter, 2, (_("To disable this transitions, go to the " + markup % _("Boolean section.")))) + else: -+ self.transitions_from_x_treestore.set_value(niter, 2, (_("to disable this boolean."))) ++ self.transitions_from_x_treestore.set_value(niter, 2, (_("To enable this transitions, go to the " + markup % _("Boolean section.")))) ++ + self.transitions_from_x_treestore.set_value(niter, 1, active[0][0]) # active[0][0] is the Bool Name + self.transitions_from_x_treestore.set_value(niter, 5, True) + + self.transitions_from_x_treestore.set_value(iter, 2, executable) + self.transitions_from_x_treestore.set_value(iter, 3, transtype) + ++ def transitions_files_initialize(self, application): ++ for i in sepolicy.get_file_transitions(application): ++ if 'filename' in i: ++ filename = i['filename'] ++ else: ++ filename = None ++ self.transitions_files_inital_data_insert(i['target'], i['class'], i['transtype'], filename) ++ ++ def transitions_files_inital_data_insert(self, directory, tclass, dest, name): ++ iter = self.transitions_file_liststore.append() ++ self.transitions_file_liststore.set_value(iter, 0, directory) ++ self.transitions_file_liststore.set_value(iter, 1, tclass) ++ self.transitions_file_liststore.set_value(iter, 2, dest) ++ self.transitions_file_liststore.set_value(iter, 3, name) ++ + def booleans_tab_change(self, *args): + self.outer_notebook.set_current_page(0) + @@ -516411,7 +516544,7 @@ index 0000000..cebdfbf + def map_selected_items_into_combobox(self, combolist, match): + ctr = 0 + for items in combolist: -+ if match == items[0]: ++ if match.startswith(items[0]): + break + ctr += 1 + return ctr @@ -516824,6 +516957,8 @@ index 0000000..cebdfbf + self.transitions_from_x_filter_data_set.refilter() + elif self.inner_notebook_tab == 1: + self.transitions_into_x_filter_data_set.refilter() ++ elif self.inner_notebook_tab == 2: ++ self.transitions_file_filter_data_set.refilter() + + def get_advanced_filter_data(self, entry, *args): + self.filter_txt = entry.get_text() @@ -516916,10 +517051,10 @@ index 0000000..cebdfbf + self.app_system_button.set_label("Applications") + self.main_selection_window.hide() + self.outer_notebook.set_visible(False) -+ self.booleans_button.set_visible(False) -+ self.files_button.set_visible(False) -+ self.network_button.set_visible(False) -+ self.transitions_button.set_visible(False) ++ self.booleans_radio_button.set_visible(False) ++ self.files_radio_button.set_visible(False) ++ self.network_radio_button.set_visible(False) ++ self.transitions_radio_button.set_visible(False) + self.systems_box.set_visible(True) + self.system_button.set_visible(True) + #self.window.set_resizable(False) @@ -516932,10 +517067,10 @@ index 0000000..cebdfbf + self.app_system_button.set_label("System") + self.main_selection_window.hide() + self.outer_notebook.set_visible(True) -+ self.booleans_button.set_visible(True) -+ self.files_button.set_visible(True) -+ self.network_button.set_visible(True) -+ self.transitions_button.set_visible(True) ++ self.booleans_radio_button.set_visible(True) ++ self.files_radio_button.set_visible(True) ++ self.network_radio_button.set_visible(True) ++ self.transitions_radio_button.set_visible(True) + self.systems_box.set_visible(False) + self.system_button.set_visible(False) + self.window.set_resizable(True) @@ -517173,8 +517308,10 @@ index 0000000..cebdfbf + def set_enforce_text(self, value): + if value: + self.status_bar.push(self.context_id, _("System Status: Enforcing")) ++ self.current_status_enforcing.set_active(True) + else: + self.status_bar.push(self.context_id, _("System Status: Permissive")) ++ self.current_status_permissive.set_active(True) + + def set_enforce(self, button): + self.dbus.setenforce(button.get_active()) @@ -517230,6 +517367,72 @@ index 0000000..cebdfbf + def browse_for_files(self, *args): + self.add_path_dialog.show() + ++ def close_browse_popup(self, *args): ++ self.browse_popup_window.hide() ++ ++ def close_config_window(self, *args): ++ self.file_config_window.hide() ++ ++ def change_system_policy(self, *args): ++ self.dbus.change_policy_type(self.system_policy_type_combobox.get_active_text()) ++ ++ def change_default_mode(self, button): ++ if button.get_active(): ++ self.dbus.change_default_policy(button.get_label().lower()) ++ ++ def import_config_show(self, *args): ++ self.file_config_window.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) ++ self.file_config_window.set_title("Import Configuration") ++ self.file_config_window.show() ++ self.import_export = 'Import' ++ ++ def export_config_show(self, *args): ++ self.file_config_window.set_action(gtk.FILE_CHOOSER_ACTION_SAVE) ++ self.file_config_window.set_title("Export Configuration") ++ self.file_config_window.show() ++ self.import_export = 'Export' ++ ++ def import_or_export(self, button, *args): ++ self.file_config_window.show() ++ if self.import_export == 'Import': ++ self.import_config() ++ elif self.import_export == 'Export': ++ self.export_config() ++ ++ def export_config(self, *args): ++ self.file_config_window.hide() ++ filename = self.file_config_window.get_filename() ++ if filename == None: ++ return ++ if os.path.exists(filename): ++ print "Error" ++ self.wait_mouse() ++ buf = self.dbus.customized() ++ fd = open(filename, 'w') ++ fd.write(buf) ++ fd.close() ++ self.ready_mouse() ++ #self.exportwindow.set_action ++ ++ def import_config(self, *args): ++ self.file_config_window.hide() ++ filename = self.file_config_window.get_filename() ++ if filename == None: ++ return ++ self.add_path_dialog.hide() ++ fd = open(filename, "r") ++ buf = fd.read() ++ fd.close() ++ self.wait_mouse() ++ try: ++ print self.dbus.semanage(buf) ++ except OSError: ++ pass ++ self.ready_mouse() ++ ++ def relabel_on_reboot(self, widget, *args): ++ self.dbus.relabel_on_boot(widget.get_active()) ++ + def closewindow(self, window, *args): + window.hide() + self.window.set_sensitive(True) @@ -517276,9 +517479,6 @@ index 0000000..cebdfbf + self.update_window.hide() + self.window.set_sensitive(True) + -+ def close_browse_popup(self, *args): -+ self.browse_popup_window.hide() -+ + def wait_mouse(self): + self.window.window.set_cursor(self.busy_cursor) + self.idle_func() @@ -518137,10 +518337,10 @@ index 0000000..07d5a98 + print e diff --git a/policycoreutils/sepolicy/sepolicy/sepolicy.glade b/policycoreutils/sepolicy/sepolicy/sepolicy.glade new file mode 100644 -index 0000000..375c8f7 +index 0000000..9cae364 --- /dev/null +++ b/policycoreutils/sepolicy/sepolicy/sepolicy.glade -@@ -0,0 +1,3821 @@ +@@ -0,0 +1,3964 @@ + + + @@ -518209,6 +518409,32 @@ index 0000000..375c8f7 + cancel_button_browse + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ File_transitions_liststore ++ ++ ++ File_transitions_treemodel_filter ++ + + False + popup @@ -518241,12 +518467,12 @@ index 0000000..375c8f7 + True + False + -+ -+ OK ++ ++ Cancel + True + True + True -+ ++ + + + False @@ -518256,12 +518482,12 @@ index 0000000..375c8f7 + + + -+ -+ Cancel ++ ++ OK + True + True + True -+ ++ + + + False @@ -518364,7 +518590,7 @@ index 0000000..375c8f7 + + + False -+ SELinux Gui ++ SELinux Policy Manager + center-always + 650 + 420 @@ -518581,21 +518807,6 @@ index 0000000..375c8f7 + 1 + + -+ -+ -+ Show Modified Only -+ True -+ True -+ False -+ True -+ -+ -+ -+ True -+ True -+ 2 -+ -+ + + + False @@ -518604,6 +518815,21 @@ index 0000000..375c8f7 + + + ++ ++ Show Modified Only ++ True ++ True ++ False ++ True ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ + + True + True @@ -518621,7 +518847,7 @@ index 0000000..375c8f7 + + + fixed -+ 25 ++ Enabled + True + 0 + @@ -518666,6 +518892,7 @@ index 0000000..375c8f7 + + + ++ 0 + + + @@ -518694,7 +518921,7 @@ index 0000000..375c8f7 + + True + True -+ 1 ++ 2 + + + @@ -518714,152 +518941,55 @@ index 0000000..375c8f7 + True + False + -+ ++ + True + False ++ 2 ++ 3 + -+ -+ True -+ False -+ Filter -+ -+ -+ False -+ True -+ 0 -+ ++ + + -+ -+ 170 -+ True -+ True -+ -+ 25 -+ none -+ True -+ gtk-find -+ True -+ False -+ True -+ True -+ -+ -+ -+ False -+ True -+ 1 -+ -+ -+ -+ ++ + True + False + -+ ++ + True + False -+ -+ -+ False -+ gtk-dialog-warning -+ -+ -+ False -+ True -+ 0 -+ -+ -+ -+ -+ False -+ Mislabeled files exist -+ -+ -+ -+ -+ -+ False -+ False -+ 1 -+ -+ ++ Filter + + -+ True ++ False + True + 0 + + ++ ++ ++ 170 ++ True ++ True ++ ++ 25 ++ none ++ True ++ gtk-find ++ True ++ False ++ True ++ True ++ ++ ++ ++ False ++ True ++ 1 ++ ++ + -+ -+ True -+ True -+ 2 -+ + + -+ -+ Delete -+ True -+ False -+ True -+ True -+ Delete an existing item -+ -+ -+ -+ False -+ True -+ end -+ 3 -+ -+ -+ -+ -+ Modify -+ True -+ True -+ True -+ Modify an existing item -+ -+ -+ -+ False -+ True -+ end -+ 4 -+ -+ -+ -+ -+ Add -+ True -+ False -+ True -+ True -+ Add a new item -+ -+ -+ -+ False -+ True -+ end -+ 5 -+ -+ -+ -+ -+ False -+ True -+ 0 -+ -+ -+ -+ -+ True -+ False -+ + + Show Modified Only + True @@ -518869,9 +518999,10 @@ index 0000000..375c8f7 + + + -+ False -+ False -+ 0 ++ 1 ++ 2 ++ GTK_FILL ++ + + + @@ -518883,17 +519014,111 @@ index 0000000..375c8f7 + + + -+ False -+ False -+ 105 -+ 1 ++ 1 ++ 2 ++ 1 ++ 2 ++ GTK_FILL ++ ++ ++ ++ ++ ++ True ++ False ++ ++ ++ Delete ++ True ++ False ++ True ++ True ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ Modify ++ True ++ True ++ True ++ ++ ++ ++ False ++ True ++ end ++ 1 ++ ++ ++ ++ ++ Add ++ True ++ False ++ True ++ True ++ ++ ++ ++ False ++ True ++ end ++ 2 ++ ++ ++ ++ ++ 2 ++ 3 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ False ++ gtk-dialog-warning ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ False ++ Mislabeled files exist ++ ++ ++ ++ ++ ++ False ++ True ++ 1 ++ ++ ++ ++ ++ 1 ++ 2 + + + + + False -+ False -+ 1 ++ True ++ 0 + + + @@ -519239,7 +519464,7 @@ index 0000000..375c8f7 + + True + True -+ 2 ++ 1 + + + @@ -519304,21 +519529,6 @@ index 0000000..375c8f7 + 1 + + -+ -+ -+ Show Modified Only -+ True -+ True -+ False -+ True -+ -+ -+ -+ True -+ True -+ 2 -+ -+ + + + True @@ -519384,6 +519594,21 @@ index 0000000..375c8f7 + + + ++ ++ Show Modified Only ++ True ++ True ++ False ++ True ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ + + True + True @@ -519561,7 +519786,7 @@ index 0000000..375c8f7 + + True + True -+ 1 ++ 2 + + + @@ -519661,42 +519886,29 @@ index 0000000..375c8f7 + + + -+ -+ 110 -+ 110 -+ 1 -+ -+ -+ #00004e4e9999 -+ Boolean section -+ -+ -+ 5 -+ -+ -+ -+ -+ -+ -+ -+ 5 -+ -+ -+ -+ -+ + ++ True + Executable File Type + True + True + True -+ 2 ++ 1 + + + ++ 2 + 2 + + ++ ++ ++ 0 ++ ++ ++ ++ 5 ++ ++ + + + @@ -519706,7 +519918,7 @@ index 0000000..375c8f7 + True + True + True -+ 3 ++ 2 + + + @@ -519726,7 +519938,7 @@ index 0000000..375c8f7 + Executables which will transition to a different domain, when the 'selected domain' executes them. + 1 + 1 -+ Transitions From 'select domain' ++ Applicaton Transitions From 'select domain' + + + 1 @@ -519801,13 +520013,90 @@ index 0000000..375c8f7 + True + False + Executables which will transition to the 'selected domain', when executing a selected domains entrypoint. -+ Transitions Into 'select domain' ++ Application Transitions Into 'select domain' + + + 1 + False + + ++ ++ ++ True ++ True ++ automatic ++ automatic ++ ++ ++ True ++ True ++ File_transitions_treemodel_sort ++ ++ ++ Directory Type ++ 0 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ ++ ++ Class ++ 1 ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ Destination Type ++ 2 ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ ++ ++ File Name ++ 3 ++ ++ ++ ++ 3 ++ ++ ++ ++ ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ True ++ False ++ File Transitions From 'select domain' ++ ++ ++ 2 ++ False ++ ++ + + + True @@ -519890,7 +520179,8 @@ index 0000000..375c8f7 + False + True + True -+ Permissive_button_default ++ ++ + + + True @@ -519906,6 +520196,7 @@ index 0000000..375c8f7 + False + True + Enforcing_button_default ++ + + + True @@ -519921,6 +520212,7 @@ index 0000000..375c8f7 + False + True + Enforcing_button_default ++ + + + True @@ -520079,6 +520371,7 @@ index 0000000..375c8f7 + True + False + system_policy_type_liststore ++ + + + @@ -520135,6 +520428,7 @@ index 0000000..375c8f7 + True + True + True ++ + + + False @@ -520188,6 +520482,7 @@ index 0000000..375c8f7 + True + True + True ++ + + + False @@ -520222,12 +520517,12 @@ index 0000000..375c8f7 + + + -+ ++ + Relabel -+ 65 + True + True + True ++ + + + False @@ -520351,20 +520646,6 @@ index 0000000..375c8f7 + + + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Advanced_search_liststore -+ -+ -+ advanced_treemodel_filter -+ + + False + center-on-parent @@ -520506,6 +520787,12 @@ index 0000000..375c8f7 + + + ++ ++ Advanced_search_liststore ++ ++ ++ advanced_treemodel_filter ++ + + + @@ -520591,6 +520878,36 @@ index 0000000..375c8f7 + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ executable_files_treestore ++ ++ ++ executable_files_treemodelfilter ++ ++ ++ ++ ++ ++ ++ + + False + Delete Modified File Labeling @@ -520946,29 +521263,69 @@ index 0000000..375c8f7 + + + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ executable_files_treestore -+ -+ -+ executable_files_treemodelfilter ++ ++ False ++ 5 ++ GtkFileChooserDialog ++ True ++ 320 ++ 260 ++ dialog ++ ++ ++ True ++ False ++ 2 ++ ++ ++ True ++ False ++ end ++ ++ ++ Select ++ True ++ True ++ True ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ Cancel ++ True ++ True ++ True ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ select_button_config ++ cancel_button_config ++ + + + @@ -520982,12 +521339,6 @@ index 0000000..375c8f7 + + + -+ -+ -+ -+ -+ -+ + + + @@ -521102,24 +521453,6 @@ index 0000000..375c8f7 + + + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ out_network_liststore -+ -+ -+ out_network_treemodelfilter -+ + + + @@ -521138,6 +521471,24 @@ index 0000000..375c8f7 + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ out_network_liststore ++ ++ ++ out_network_treemodelfilter ++ + + False + Add a File @@ -521743,16 +522094,8 @@ index 0000000..375c8f7 + + + -+ -+ -+ Targeted -+ -+ -+ MLS -+ -+ + -+ ++ + + + @@ -521790,30 +522133,6 @@ index 0000000..375c8f7 + + transitions_into_x_treemodelfilter + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ writable_files_treestore -+ -+ -+ writable_files_treemodelfilter -+ + + False + True @@ -521961,6 +522280,30 @@ index 0000000..375c8f7 + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ writable_files_treestore ++ ++ ++ writable_files_treemodelfilter ++ + diff --git a/policycoreutils/sepolicy/sepolicy/templates/network.py b/policycoreutils/sepolicy/sepolicy/templates/network.py index 4499440..43feee4 100644