These are massive changes involved in building new GUI.

Too difficult to break out into seperate patches at this point.
Since almost no other groups are using sepolicy yet, I will push together.
This commit is contained in:
Dan Walsh 2013-10-11 10:16:57 -04:00 committed by Stephen Smalley
parent 43c9e8c7e2
commit e6a1298e54
95 changed files with 10793 additions and 592 deletions

View file

@ -1 +1,3 @@
build
tmp
*.bak

View file

@ -4,10 +4,11 @@ SYSCONFDIR ?= $(DESTDIR)/etc/sysconfig
LIBDIR ?= $(PREFIX)/lib
BINDIR ?= $(PREFIX)/bin
SBINDIR ?= $(PREFIX)/sbin
DATADIR ?= $(PREFIX)/share
MANDIR ?= $(PREFIX)/share/man
LOCALEDIR ?= /usr/share/locale
PYTHON ?= /usr/bin/python
BASHCOMPLETIONDIR ?= $(DESTDIR)/etc/bash_completion.d/
BASHCOMPLETIONDIR ?= $(DESTDIR)/usr/share/bash-completion/completions
SHAREDIR ?= $(PREFIX)/share/sandbox
override CFLAGS = -I$(PREFIX)/include -DPACKAGE="policycoreutils" -Wall -Werror -Wextra -W -DSHARED -shared
@ -22,6 +23,9 @@ clean:
$(PYTHON) setup.py clean
-rm -rf build *~ \#* *pyc .#*
sepolgen:
ln -sf sepolicy sepolgen
test:
@python test_sepolicy.py -v
@ -29,7 +33,17 @@ install:
$(PYTHON) setup.py install `test -n "$(DESTDIR)" && echo --root $(DESTDIR)`
[ -d $(BINDIR) ] || mkdir -p $(BINDIR)
install -m 755 sepolicy.py $(BINDIR)/sepolicy
(cd $(BINDIR); ln -sf sepolicy sepolgen)
-mkdir -p $(MANDIR)/man8
install -m 644 *.8 $(MANDIR)/man8
-mkdir -p $(BASHCOMPLETIONDIR)
install -m 644 $(BASHCOMPLETIONS) $(BASHCOMPLETIONDIR)
install -m 644 $(BASHCOMPLETIONS) $(BASHCOMPLETIONDIR)/sepolicy
-mkdir -p $(DESTDIR)/etc/dbus-1/system.d/
install -m 644 org.selinux.conf $(DESTDIR)/etc/dbus-1/system.d/
-mkdir -p $(DESTDIR)/usr/share/dbus-1/system-services
install -m 644 org.selinux.service $(DESTDIR)/usr/share/dbus-1/system-services
-mkdir -p $(DESTDIR)/usr/share/polkit-1/actions/
install -m 644 org.selinux.policy $(DESTDIR)/usr/share/polkit-1/actions/
-mkdir -p $(DESTDIR)/usr/share/system-config-selinux
install -m 755 selinux_server.py $(DESTDIR)/usr/share/system-config-selinux
install -m 644 *.desktop $(DATADIR)/system-config-selinux

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root can own the service -->
<policy user="root">
<allow own="org.selinux"/>
</policy>
<!-- Allow anyone to invoke methods on the interfaces,
authorization is performed by PolicyKit -->
<policy at_console="true">
<allow send_destination="org.selinux"/>
</policy>
<policy context="default">
<allow send_destination="org.selinux"
send_interface="org.freedesktop.DBus.Introspectable"/>
</policy>
</busconfig>

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<vendor>Red Hat Inc.</vendor>
<vendor_url>http://www.redhat.com</vendor_url>
<action id="org.selinux.restorecon">
<description>SELinux write access</description>
<message>System policy prevents restorecon access to SELinux</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.selinux.setenforce">
<description>SELinux write access</description>
<message>System policy prevents setenforce access to SELinux</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.selinux.semanage">
<description>SELinux write access</description>
<message>System policy prevents semanage access to SELinux</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.selinux.customized">
<description>SELinux Read access</description>
<message>System policy prevents read access to SELinux</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
<action id="org.selinux.semodule_list">
<description>SELinux list modules access</description>
<message>System policy prevents read access to SELinux modules</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
<action id="org.selinux.relabel_on_boot">
<description>SELinux write access</description>
<message>System policy prevents relabel_on_boot access to SELinux</message>
<defaults>
<allow_any>yes</allow_any>
</defaults>
</action>
<action id="org.selinux.change_default_policy">
<description>SELinux write access</description>
<message>System policy prevents change_default_policy access to SELinux</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.selinux.change_policy_type">
<description>SELinux write access</description>
<message>System policy prevents change_policy_type access to SELinux</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

View file

@ -0,0 +1,4 @@
[D-BUS Service]
Name=org.selinux
Exec=/usr/share/system-config-selinux/selinux_server.py
User=root

View file

@ -0,0 +1,43 @@
import dbus
import dbus.service
from sepolicy.sedbus import SELinuxDBus
def convert_customization(buf):
cust_dict = {}
cust_dict["fcontext-equiv"] = {}
for i in buf.split("\n"):
rec = i.split()
if len(rec) == 0:
continue
if rec[1] == "-D":
continue
if rec[0] not in cust_dict:
cust_dict[rec[0]] = {}
if rec[0] == "boolean":
cust_dict["boolean"][rec[-1]] = { "active": rec[2] == "-1" }
if rec[0] == "login":
cust_dict["login"][rec[-1]] = { "seuser": rec[3], "range": rec[5] }
if rec[0] == "interface":
cust_dict["login"][rec[-1]] = { "type": rec[3] }
if rec[0] == "user":
cust_dict["user"][rec[-1]] = { "level": rec[3], "range": rec[5], "role": rec[7] }
if rec[0] == "port":
cust_dict["port"][(rec[-1], rec[-2] )] = { "type": rec[3] }
if rec[0] == "node":
cust_dict["node"][rec[-1]] = { "mask": rec[3], "protocol":rec[5], "type": rec[7] }
if rec[0] == "fcontext":
if rec[2] == "-e":
cust_dict["fcontext-equiv"][(rec[-1])] = { "equiv": rec[3] }
else:
cust_dict["fcontext"][(rec[-1],rec[3])] = { "type": rec[5] }
if rec[0] == "module":
cust_dict["module"][rec[-1]] = { "enabled": rec[2] != "-d" }
return cust_dict
if __name__ == "__main__":
try:
dbus_proxy = SELinuxDBus()
resp = dbus_proxy.customized()
print convert_customization(resp)
except dbus.DBusException, e:
print e

View file

@ -0,0 +1,131 @@
#!/usr/bin/python
import dbus
import dbus.service
import dbus.mainloop.glib
import gobject
import slip.dbus.service
from slip.dbus import polkit
import os
import selinux
from subprocess import Popen, PIPE, STDOUT
class selinux_server(slip.dbus.service.Object):
default_polkit_auth_required = "org.selinux.semanage"
def __init__ (self, *p, **k):
super(selinux_server, self).__init__(*p, **k)
#
# The semanage method runs a transaction on a series of semanage commands,
# these commnds can take the output of customized
#
@slip.dbus.polkit.require_auth("org.selinux.semanage")
@dbus.service.method("org.selinux", in_signature='s')
def semanage(self, buf):
p = Popen(["/usr/sbin/semanage", "import"],stdout=PIPE, stderr=PIPE, stdin=PIPE)
p.stdin.write(buf)
output = p.communicate()
if p.returncode and p.returncode != 0:
raise dbus.exceptions.DBusException(output[1])
#
# 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.
#
@slip.dbus.polkit.require_auth("org.selinux.customized")
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
def customized(self):
p = Popen(["/usr/sbin/semanage", "export"],stdout=PIPE, stderr=PIPE)
buf = p.stdout.read()
output = p.communicate()
if p.returncode and p.returncode != 0:
raise OSError("Failed to read SELinux configuration: %s", output)
return buf
#
# The semodule_list method will return the output of semodule -l, using the customized polkit,
# since this is a readonly behaviour
#
@slip.dbus.polkit.require_auth("org.selinux.customized")
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
def semodule_list(self):
p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE)
buf = p.stdout.read()
output = p.communicate()
if p.returncode and p.returncode != 0:
raise OSError("Failed to list SELinux modules: %s", output)
return buf
#
# The restorecon method modifies any file path to the default system label
#
@dbus.service.method("org.selinux", in_signature='s')
def restorecon(self, path):
selinux.restorecon(str(path), recursive=1)
#
# The setenforce method turns off the current enforcement of SELinux
#
@dbus.service.method("org.selinux", in_signature='i')
def setenforce(self, value):
selinux.security_setenforce(value)
#
# The setenforce method turns off the current enforcement of SELinux
#
@dbus.service.method("org.selinux", in_signature='i')
def relabel_on_boot(self, value):
if value == 1:
fd = open("/.autorelabel","w")
fd.close()
else:
os.unlink("/.autorelabel")
def write_selinux_config(self, enforcing=None, policy=None):
path = selinux.selinux_path() + "config"
backup_path = path + ".bck"
fd = open(path)
lines = fd.readlines()
fd.close()
fd = open(backup_path, "w")
for l in lines:
if enforcing and l.startswith("SELINUX="):
fd.write("SELINUX=%s\n" % enforcing)
continue
if policy and l.startswith("SELINUXTYPE="):
fd.write("SELINUXTYPE=%s\n" % policy)
continue
fd.write(l)
fd.close()
os.rename(backup_path, path)
#
# The change_default_enforcement modifies the current enforcement mode
#
@dbus.service.method("org.selinux", in_signature='s')
def change_default_mode(self, value):
values = [ "enforcing", "permissive", "disabled" ]
if value not in values:
raise ValueError("Enforcement mode must be %s" % ", ".join(values))
self.write_selinux_config(enforcing=value)
#
# The change_default_policy method modifies the policy type
#
@dbus.service.method("org.selinux", in_signature='s')
def change_default_policy(self, value):
path = selinux.selinux_path() + value
if os.path.isdir(path):
return self.write_selinux_config(policy=value)
raise ValueError("%s does not exist" % path)
if __name__ == "__main__":
mainloop = gobject.MainLoop()
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
system_bus = dbus.SystemBus()
name = dbus.service.BusName("org.selinux", system_bus)
object = selinux_server(system_bus, "/org/selinux/object")
slip.dbus.service.set_mainloop(mainloop)
mainloop.run()

View file

@ -0,0 +1 @@
.so man8/sepolicy-generate.8

View file

@ -1,6 +1,6 @@
# This file is part of systemd.
#
# Copyright 2012 Dan Walsh
# Copyright 2012-2013 Dan Walsh
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -69,6 +69,7 @@ _sepolicy () {
[BOOLEANS]='booleans'
[COMMUNICATE]='communicate'
[GENERATE]='generate'
[GUI]='gui'
[INTERFACE]='interface'
[MANPAGE]='manpage'
[NETWORK]='network'
@ -80,8 +81,9 @@ _sepolicy () {
[booleans]='-h --help -p --path -a -all -b --boolean'
[communicate]='-h --help -s --source -t --target -c --class -S --sourceaccess -T --targetaccess'
[generate]='-a --admin --admin_user --application --cgi --confined_admin --customize -d --domain --dbus --desktop_user -h --help --inetd --init -n --name --newtype -p --path --sandbox -T --test --term_user -u --user -w --writepath --x_user'
[interface]='-h --help -a --list_admin" -u --list_user -l --list'
[manpage]='-h --help -p --path -a -all -o --os -d --domain -w --web'
[gui]='-h --help'
[interface]='-h --help -a --list_admin -c --compile -i --interface -l --list -u --list_user -u --list_user -v --verbose'
[manpage]='-h --help -p --path -a -all -o --os -d --domain -w --web -r --root'
[network]='-h --help -d --domain -l --list -p --port -t --type '
[transition]='-h --help -s --source -t --target'
)
@ -130,17 +132,17 @@ _sepolicy () {
COMPREPLY=( $( compgen -d -- "$cur") )
compopt -o filenames
return 0
elif [ "$prev" = "--type" -o "$prev" = "-t" ]; then
COMPREPLY=( $(compgen -W '0 1 2 3 4 5 6 7 8 9 10 11' -- "$cur") )
return 0
elif [ "$prev" = "--domain" -o "$prev" = "-d" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_domain_types ) " -- "$cur") )
return 0
elif [ "$prev" = "--newtype" ]; then
COMPREPLY=( $(compgen -W "-n --name -t --type" -- "$cur") )
return 0
elif [ "$prev" = "--admin" -o "$prev" = "-a" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_admin_interaces ) " -- "$cur") )
return 0
elif [ "$prev" = "--user" -o "$prev" = "-u" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_users ) " -- "$cur") )
COMPREPLY=( $(compgen -W "$( __get_all_users )" -- "$cur") )
return 0
elif [[ "$cur" == "$verb" || "$cur" == "" || "$cur" == -* ]]; then
COMPREPLY=( $(compgen -W '${OPTS[$verb]}' -- "$cur") )
@ -156,6 +158,10 @@ _sepolicy () {
if [ "$prev" = "-d" -o "$prev" = "--domain" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_domains ) " -- "$cur") )
return 0
elif test "$prev" = "-r" || test "$prev" = "--root" ; then
COMPREPLY=( $( compgen -d -- "$cur") )
compopt -o filenames
return 0
elif [ "$prev" = "-o" -o "$prev" = "--os" ]; then
return 0
elif test "$prev" = "-p" || test "$prev" = "--path" ; then
@ -167,11 +173,11 @@ _sepolicy () {
return 0
elif [ "$verb" = "network" ]; then
if [ "$prev" = "-t" -o "$prev" = "--type" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_port_types ) " -- "$cur") )
COMPREPLY=( $(compgen -W "$( __get_all_port_types )" -- "$cur") )
return 0
fi
if [ "$prev" = "-d" -o "$prev" = "--domain" ]; then
COMPREPLY=( $(compgen -W "$( __get_all_domain_types ) " -- "$cur") )
COMPREPLY=( $(compgen -W "$( __get_all_domain_types )" -- "$cur") )
return 0
fi
COMPREPLY=( $(compgen -W '${OPTS[$verb]}' -- "$cur") )

View file

@ -4,16 +4,66 @@ sepolicy-generate \- Generate an initial SELinux policy module template.
.SH "SYNOPSIS"
Common options
.B sepolicy generate [\-h ] [\-p PATH]
.br
.B sepolicy generate [\-h] [\-d DOMAIN] [\-u USER] [\-w WRITE_PATH ] [\-a ADMIN_DOMAIN] [\-n NAME] [\-p PATH] [\-\-admin_user | \-\-application | \-\-cgi | \-\-confined_admin | \-\-customize | \-\-dbus | \-\-desktop_user | \-\-inetd | \-\-newtype | \-\-init | \-\-sandbox | \-\-term_user | \-\-x_user]
Confined Applications
.br
.B sepolicy generate \-\-application [\-n NAME] command [\-w WRITE_PATH ]
.br
.B sepolicy generate \-\-cgi [\-n NAME] command [\-w WRITE_PATH ]
.br
.B sepolicy generate \-\-dbus [\-n NAME] command [\-w WRITE_PATH ]
.br
.B sepolicy generate \-\-inetd [\-n NAME] command [\-w WRITE_PATH ]
.br
.B sepolicy generate \-\-init [\-n NAME] command [\-w WRITE_PATH ]
Confined Users
.br
.B sepolicy generate \-\-admin_user [\-r TRANSITION_ROLE] \-n NAME
.br
.B sepolicy generate \-\-confined_admin \-n NAME [\-a ADMIN_DOMAIN] [\-u USER] [\-n NAME] [\-w WRITE_PATH]
.br
.B sepolicy generate \-\-desktop_user \-n NAME [\-w WRITE_PATH]
.br
.B sepolicy generate \-\-term_user \-n NAME [\-w WRITE_PATH]
.br
.B sepolicy generate \-\-x_user \-n NAME [\-w WRITE_PATH]
.br
Miscellaneous Policy
.br
.B sepolicy generate \-\-customize \-d DOMAIN \-n NAME [\-a ADMIN_DOMAIN]
.br
.B sepolicy generate \-\-newtype \-t type \-n NAME
.br
.B sepolicy generate \-\-sandbox \-n NAME
.SH "DESCRIPTION"
Use sepolicy generate to generate an SELinux policy Module. sepolicy generate will generate 4 files.
Use \fBsepolicy generate\fP to generate an SELinux policy Module.
.br
\fBsepolicy generate\fP will create 5 files.
When specifying a \fBconfined application\fP you must specify a
path. \fBsepolicy generate\fP will use the rpm payload of the
application along with \fBnm -D APPLICATION\fP to help it generate
types and policy rules for your policy files.
.B Type Enforcing File NAME.te
.br
This file can be used to define all the types rules for a particular domain.
.I Note:
Policy generated by \fBsepolicy generate\fP will automatically add a permissive DOMAIN to your te file. When you are satisfied that your policy works, you need to remove the permissive line from the te file to run your domain in enforcing mode.
.B Interface File NAME.if
.br
This file defines the interfaces for the types generated in the te file, which can be used by other policy domains.
@ -25,7 +75,7 @@ file paths to the types. Tools like restorecon and RPM will use these paths to
.B RPM Spec File NAME_selinux.spec
.br
This file is an RPM SPEC file that can be used to install the SELinux policy on to machines and setup the labeling. The spec file also installs the interface file and a man page describing the policy. You can use sepolicy manpage -d NAME to generate the man page.
This file is an RPM SPEC file that can be used to install the SELinux policy on to machines and setup the labeling. The spec file also installs the interface file and a man page describing the policy. You can use \fBsepolicy manpage -d NAME\fP to generate the man page.
.B Shell File NAME.sh
.br
@ -39,13 +89,22 @@ If a generate is possible, this tool will print out all generate paths from the
.I \-h, \-\-help
Display help message
.TP
.I \-d, \-\-domain
Enter domain type(s) which you will be extending
.TP
.I \-n, \-\-name
Specify alternate name of policy. The policy will default to the executable or name specified.
Specify alternate name of policy. The policy will default to the executable or name specified
.TP
.I \-p, \-\-path
Specify the directory to store the created policy files. (Default to current working directory )
optional arguments:
.TP
.I \-r, \-\-role
Enter role(s) to which this admin user will transition.
.TP
.I \-t, \-\-type
Enter type(s) for which you will generate new definition and rule(s)
.TP
.I \-u, \-\-user
SELinux user(s) which will transition to this domain
.TP
@ -53,7 +112,7 @@ SELinux user(s) which will transition to this domain
Path(s) which the confined processes need to write
.TP
.I \-a, \-\-admin
Domain(s) that this confined admin will administrate
Domain(s) which the confined admin will administrate
.TP
.I \-\-admin_user
Generate Policy for Administrator Login User Role
@ -95,7 +154,7 @@ Generate Policy for Minimal Terminal Login User Role
Generate Policy for Minimal X Windows Login User Role
.SH "EXAMPLE"
.B > sepolicy generate /usr/sbin/rwhod
.B > sepolicy generate --init /usr/sbin/rwhod
.br
Generating Policy for /usr/sbin/rwhod named rwhod
.br

View file

@ -0,0 +1,29 @@
.TH "sepolicy-gui" "8" "20121005" "" ""
.SH "NAME"
sepolicy-gui \- Graphical User Interface for SELinux policy.
.SH "SYNOPSIS"
Common options
.B sepolicy gui [\-h ] [ \-d DOMAIN ]
.br
.SH "DESCRIPTION"
Use \fBsepolicy gui\fP to run a the graphical user interface, which
allows you to explore how SELinux confines different process domains.
.SH "OPTIONS"
.TP
.I \-h, \-\-help
Display help message
.TP
.I \-d, \-\-domain
Initialize gui to the selected domain.
.SH "AUTHOR"
This man page was written by Daniel Walsh <dwalsh@redhat.com>
.SH "SEE ALSO"
sepolicy(8), selinux(8)

View file

@ -5,7 +5,7 @@ sepolicy-interface \- Print interface information based on the installed SELinux
.SH "SYNOPSIS"
.br
.B sepolicy interface [\-h] [\-a | \-u | \-l ]
.B sepolicy interface [\-h] [\-c] [\-v] [\-a | \-u | \-l | \-i INTERFACE [INTERFACE ... ]]
.SH "DESCRIPTION"
Use sepolicy interface to print interfaces information based on SELinux Policy.
@ -15,14 +15,23 @@ Use sepolicy interface to print interfaces information based on SELinux Policy.
.I \-a, \-\-list_admin
List all domains with admin interface
.TP
.I \-c, \-\-compile
Test compile of interfaces
.TP
.I \-h, \-\-help
Display help message
.TP
.I \-i, \-\-interface
Interface(s) to be displayed
.TP
.I \-l, \-\-list
List all interfaces
.TP
.I \-u, \-\-list_user
List all domains with SELinux user role interface
.TP
.I \-v, \-\-verbose
Display extended information about the interface including parameters and desctiprion if available.
.SH "AUTHOR"
This man page was written by Daniel Walsh <dwalsh@redhat.com>

View file

@ -5,7 +5,7 @@ sepolicy-manpage \- Generate a man page based on the installed SELinux Policy
.SH "SYNOPSIS"
.br
.B sepolicy manpage [\-w] [\-h] [\-p PATH ] [\-a | \-d ]
.B sepolicy manpage [\-w] [\-h] [\-p PATH ] [\-r ROOTDIR ] [\-a | \-d ]
.SH "DESCRIPTION"
Use sepolicy manpage to generate manpages based on SELinux Policy.
@ -24,6 +24,9 @@ Display help message
.I \-p, \-\-path
Specify the directory to store the created man pages. (Default to /tmp)
.TP
.I \-r, \-\-root
Specify alternate root directory to generate man pages from. (Default to /)
.TP
.I \-w, \-\-web
Generate an additional HTML man pages for the specified domain(s).

View file

@ -5,13 +5,16 @@ sepolicy-network \- Examine the SELinux Policy and generate a network report
.SH "SYNOPSIS"
.br
.B sepolicy network [\-h] (\-l | \-p PORT [PORT ...] | \-t TYPE [TYPE ...] | \-d DOMAIN [DOMAIN ...])
.B sepolicy network [\-h] (\-l | \-a application [application ...] | \-p PORT [PORT ...] | \-t TYPE [TYPE ...] | \-d DOMAIN [DOMAIN ...])
.SH "DESCRIPTION"
Use sepolicy network to examine SELinux Policy and generate network reports.
.SH "OPTIONS"
.TP
.I \-a, \-\-application
Generate a report listing the ports to which the specified init application is allowed to connect and or bind.
.TP
.I \-d, \-\-domain
Generate a report listing the ports to which the specified domain is allowed to connect and or bind.
.TP
@ -27,6 +30,59 @@ Generate a report listing the port numbers associate with the specified SELinux
.I \-p, \-\-port
Generate a report listing the SELinux port types associate with the specified port number.
.SH "EXAMPLES"
.B sepolicy network -p 22
.br
22: tcp ssh_port_t 22
.br
22: udp reserved_port_t 1-511
.br
22: tcp reserved_port_t 1-511
.B sepolicy network -a /usr/sbin/sshd
.br
sshd_t: tcp name_connect
.br
111 (portmap_port_t)
.br
53 (dns_port_t)
.br
88, 750, 4444 (kerberos_port_t)
.br
9080 (ocsp_port_t)
.br
9180, 9701, 9443-9447 (pki_ca_port_t)
.br
32768-61000 (ephemeral_port_t)
.br
all ports < 1024 (reserved_port_type)
.br
all ports with out defined types (port_t)
.br
sshd_t: tcp name_bind
.br
22 (ssh_port_t)
.br
5900-5983, 5985-5999 (vnc_port_t)
.br
6000-6020 (xserver_port_t)
.br
32768-61000 (ephemeral_port_t)
.br
all ports > 500 and < 1024 (rpc_port_type)
.br
all ports with out defined types (port_t)
.br
sshd_t: udp name_bind
.br
32768-61000 (ephemeral_port_t)
.br
all ports > 500 and < 1024 (rpc_port_type)
.br
all ports with out defined types (port_t)
.SH "AUTHOR"
This man page was written by Daniel Walsh <dwalsh@redhat.com>

View file

@ -25,6 +25,10 @@ Query SELinux policy to see if domains can communicate with each other
.br
.br
Generate SELinux Policy module template
.B gui
.br
.br
Launch Graphical User Interface for SELinux Policy, requires policycoreutils-gui package.
.B sepolicy-generate(8)
.br
@ -68,4 +72,4 @@ Display help message
This man page was written by Daniel Walsh <dwalsh@redhat.com>
.SH "SEE ALSO"
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)

View file

@ -0,0 +1,10 @@
[Desktop Entry]
Name=SELinux Policy Management Tool
Comment=Generate SELinux policy modules
Icon=system-config-selinux
Exec=/usr/bin/sepolicy gui
Type=Application
Terminal=false
Categories=System;Security;
X-Desktop-File-Install-Version=0.2
Keywords=policy;security;selinux;avc;permission;mac;

View file

@ -22,7 +22,9 @@
#
#
import os, sys
from sepolicy import get_os_version
import selinux
import sepolicy
from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text
import argparse
import gettext
PROGNAME="policycoreutils"
@ -37,6 +39,9 @@ except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
usage = "sepolicy generate [-h] [-n NAME] [-p PATH] ["
usage_dict = {' --newtype':('-t [TYPES [TYPES ...]]',),' --customize':('-d DOMAIN','-a ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --admin_user':('[-r TRANSITION_ROLE ]',"[ -w WRITEPATHS ]",), ' --application':('COMMAND',"[ -w WRITEPATHS ]",), ' --cgi':('COMMAND',"[ -w WRITEPATHS ]",), ' --confined_admin':('-a ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --dbus':('COMMAND',"[ -w WRITEPATHS ]",), ' --desktop_user':('',"[ -w WRITEPATHS ]",),' --inetd':('COMMAND',"[ -w WRITEPATHS ]",),' --init':('COMMAND',"[ -w WRITEPATHS ]",), ' --sandbox':("[ -w WRITEPATHS ]",), ' --term_user':("[ -w WRITEPATHS ]",), ' --x_user':("[ -w WRITEPATHS ]",)}
class CheckPath(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if not os.path.exists(values):
@ -45,7 +50,7 @@ class CheckPath(argparse.Action):
class CheckType(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.network import domains
domains = sepolicy.get_all_domains()
if isinstance(values,str):
setattr(namespace, self.dest, values)
@ -58,9 +63,30 @@ class CheckType(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, newval)
class CheckBoolean(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
booleans = sepolicy.get_all_booleans()
newval = getattr(namespace, self.dest)
if not newval:
newval = []
if isinstance(values,str):
v = selinux.selinux_boolean_sub(values)
if v not in booleans:
raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans)))
newval.append(v)
setattr(namespace, self.dest, newval)
else:
for value in values:
v = selinux.selinux_boolean_sub(value)
if v not in booleans:
raise ValueError("%s must be an SELinux boolean:\nValid boolean: %s" % (v, ", ".join(booleans)))
newval.append(v)
setattr(namespace, self.dest, newval)
class CheckDomain(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.network import domains
domains = sepolicy.get_all_domains()
if isinstance(values,str):
if values not in domains:
@ -80,7 +106,6 @@ class CheckDomain(argparse.Action):
all_classes = None
class CheckClass(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
import sepolicy
global all_classes
if not all_classes:
all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
@ -114,7 +139,7 @@ class CheckPort(argparse.Action):
class CheckPortType(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.network import port_types
port_types = sepolicy.get_all_port_types()
newval = getattr(namespace, self.dest)
if not newval:
newval = []
@ -140,71 +165,150 @@ class CheckPolicyType(argparse.Action):
class CheckUser(argparse.Action):
def __call__(self, parser, namespace, value, option_string=None):
from sepolicy import get_all_users
newval = getattr(namespace, self.dest)
if not newval:
newval = []
users = get_all_users()
users = sepolicy.get_all_users()
if value not in users:
raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
newval.append(value)
setattr(namespace, self.dest, newval)
class CheckRole(argparse.Action):
def __call__(self, parser, namespace, value, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
newval = []
roles = sepolicy.get_all_roles()
if value not in roles:
raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
newval.append(value[:-2])
setattr(namespace, self.dest, newval)
class InterfaceInfo(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.interface import get_interface_dict
interface_dict = get_interface_dict()
for v in values:
if v not in interface_dict.keys():
raise ValueError(_("Interface %s does not exist.") % v)
setattr(namespace, self.dest, values)
def generate_custom_usage(usage_text,usage_dict):
sorted_keys = []
for i in usage_dict.keys():
sorted_keys.append(i)
sorted_keys.sort()
for k in sorted_keys:
usage_text += "%s %s |" % (k,(" ".join(usage_dict[k])))
usage_text = usage_text[:-1] + "]"
usage_text = _(usage_text)
return usage_text
def numcmp(val1,val2):
try:
v1 = int(val1.split(",")[0].split("-")[0])
v2 = int(val2.split(",")[0].split("-")[0])
if v1 > v2:
return 1
if v1 == v2:
return 0
if v1 < v2:
return -1
except:
return cmp(val1,val2)
def _print_net(src, protocol, perm):
from sepolicy.network import get_network_connect
portdict = get_network_connect(src, protocol, perm)
import sepolicy.network
portdict = sepolicy.network.get_network_connect(src, protocol, perm)
if len(portdict) > 0:
print "%s: %s %s" % (src, protocol, perm)
bold_start="\033[1m"
bold_end="\033[0;0m"
print "\n"+bold_start+"%s: %s %s" % (src, protocol, perm) + bold_end
port_strings=[]
boolean_text=""
for p in portdict:
for recs in portdict[p]:
print "\t" + recs
for t, recs in portdict[p]:
cond=get_conditionals(src,t,"%s_socket" % protocol, [perm])
if cond:
boolean_text=get_conditionals_format_text(cond)
port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text))
else:
port_strings.append("%s (%s)" % (", ".join(recs), t))
port_strings.sort(numcmp)
for p in port_strings:
print "\t" + p
def network(args):
from sepolicy.network import portrecsbynum, portrecs, get_network_connect
portrecs, portrecsbynum = sepolicy.gen_port_dict()
all_ports = []
if args.list_ports:
all_ports = []
for i in portrecs:
if i[0] not in all_ports:
all_ports.append(i[0])
all_ports.sort()
print "\n".join(all_ports)
if args.port:
for port in args.port:
found = False
for i in portrecsbynum:
if i[0] <= port and port <= i[1]:
if i[0] == i[1]:
range = i[0]
else:
range = "%s-%s" % (i[0], i[1])
found = True
print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
if not found:
if port < 500:
print "Undefined reserved port type"
for port in args.port:
found = False
for i in portrecsbynum:
if i[0] <= port and port <= i[1]:
if i[0] == i[1]:
range = i[0]
else:
print "Undefined port type"
if args.type:
for t in args.type:
if (t,'tcp') in portrecs.keys():
print "%s: tcp: %s" % (t, ",".join(portrecs[t,'tcp']))
if (t,'udp') in portrecs.keys():
print "%s: udp: %s" % (t, ",".join(portrecs[t,'udp']))
if args.domain:
for d in args.domain:
_print_net(d, "tcp", "name_connect")
for net in ("tcp", "udp"):
_print_net(d, net, "name_bind")
range = "%s-%s" % (i[0], i[1])
found = True
print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
if not found:
if port < 500:
print "Undefined reserved port type"
else:
print "Undefined port type"
for t in args.type:
if (t,'tcp') in portrecs.keys():
print "%s: tcp: %s" % (t, ",".join(portrecs[t,'tcp']))
if (t,'udp') in portrecs.keys():
print "%s: udp: %s" % (t, ",".join(portrecs[t,'udp']))
for a in args.applications:
d = sepolicy.get_init_transtype(a)
if d:
args.domain.append(d)
for d in args.domain:
_print_net(d, "tcp", "name_connect")
for net in ("tcp", "udp"):
_print_net(d, net, "name_bind")
def gui_run(args):
try:
import sepolicy.gui
sepolicy.gui.SELinuxGui(args.domain, args.test)
pass
except ImportError:
raise ValueError(_("You need to install policycoreutils-gui package to use the gui option"))
def gen_gui_args(parser):
gui = parser.add_parser("gui",
help=_('Graphical User Interface for SELinux Policy'))
gui.add_argument("-d", "--domain", default=None,
action=CheckDomain,
help=_("Domain name(s) of man pages to be created"))
gui.add_argument("-t", "--test", default=False, action="store_true",
help=argparse.SUPPRESS)
gui.set_defaults(func=gui_run)
def manpage(args):
from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains
path = args.path
if args.policy:
for f in ( "policy.xml", "file_context", "file_context.homedirs"):
if not os.path.exists(path + f):
raise ValueError("manpage creation with alternate policy requires the %s file exist" % (path + f))
if not args.policy and args.root != "/":
sepolicy.policy(sepolicy.get_installed_policy(args.root))
if args.source_files and args.root == "/":
raise ValueError(_("Alternative root needs to be setup"))
if args.all:
test_domains = gen_domains()
@ -212,30 +316,34 @@ def manpage(args):
test_domains = args.domain
for domain in test_domains:
m = ManPage(domain, path, args.web)
m = ManPage(domain, path, args.root,args.source_files, args.web)
print m.get_man_page_path()
if args.web:
HTMLManPages(manpage_roles, manpage_domains, path, args.os)
def gen_manpage_args(parser):
man = parser.add_parser("manpage",
help=_('Generate SELinux man pages'))
man = parser.add_parser("manpage",
help=_('Generate SELinux man pages'))
man.add_argument("-p", "--path", dest="path", default="/tmp",
help=_("path in which the generated SELinux man pages will be stored"))
man.add_argument("-o", "--os", dest="os", default=get_os_version(),
help=_("name of the OS for man pages"))
man.add_argument("-w", "--web", dest="web", default=False, action="store_true",
help=_("Generate HTML man pages structure for selected SELinux man page"))
group = man.add_mutually_exclusive_group(required=True)
group.add_argument("-a", "--all", dest="all", default=False,
action="store_true",
help=_("All domains"))
group.add_argument("-d", "--domain", nargs="+",
action=CheckDomain,
help=_("Domain name(s) of man pages to be created"))
man.set_defaults(func=manpage)
man.add_argument("-p", "--path", dest="path", default="/tmp",
help=_("path in which the generated SELinux man pages will be stored"))
man.add_argument("-o", "--os", dest="os", default=get_os_version(),
help=_("name of the OS for man pages"))
man.add_argument("-w", "--web", dest="web", default=False, action="store_true",
help=_("Generate HTML man pages structure for selected SELinux man page"))
man.add_argument("-r", "--root", dest="root", default="/",
help=_("Alternate root directory, defaults to /"))
man.add_argument("--source_files", dest="source_files", default=False, action="store_true",
help=_("With this flag, alternative root path needs to include file context files and policy.xml file"))
group = man.add_mutually_exclusive_group(required=True)
group.add_argument("-a", "--all", dest="all", default=False,
action="store_true",
help=_("All domains"))
group.add_argument("-d", "--domain", nargs="+",
action=CheckDomain,
help=_("Domain name(s) of man pages to be created"))
man.set_defaults(func=manpage)
def gen_network_args(parser):
net = parser.add_parser("network",
@ -245,15 +353,18 @@ def gen_network_args(parser):
group.add_argument("-l", "--list", dest="list_ports",
action="store_true",
help=_("list all SELinux port types"))
group.add_argument("-p", "--port", dest="port", default=None,
group.add_argument("-p", "--port", dest="port", default=[],
action=CheckPort, nargs="+", type=int,
help=_("show SELinux type related to the port"))
group.add_argument("-t", "--type", dest="type", default=None,
group.add_argument("-t", "--type", dest="type", default=[],
action=CheckPortType,nargs="+",
help=_("Show ports defined for this SELinux type"))
group.add_argument("-d", "--domain", dest="domain", default=None,
group.add_argument("-d", "--domain", dest="domain", default=[],
action=CheckDomain, nargs="+",
help=_("show ports to which this domain can bind and/or connect"))
group.add_argument("-a", "--application", dest="applications", default=[],
nargs="+",
help=_("show ports to which this application can bind and/or connect"))
net.set_defaults(func=network)
def communicate(args):
@ -283,7 +394,6 @@ def gen_communicate_args(parser):
comm.set_defaults(func=communicate)
def booleans(args):
import selinux
from sepolicy import boolean_desc
if args.all:
rc, args.booleans = selinux.security_get_boolean_names()
@ -300,6 +410,7 @@ def gen_booleans_args(parser):
action="store_true",
help=_("get all booleans descriptions"))
group.add_argument("-b", "--boolean", dest="booleans", nargs="+",
action=CheckBoolean, required=False,
help=_("boolean to get description"))
bools.set_defaults(func=booleans)
@ -319,22 +430,49 @@ def gen_transition_args(parser):
help=_("target process domain"))
trans.set_defaults(func=transition)
def print_interfaces(interfaces, args, append=""):
from sepolicy.interface import get_interface_format_text, interface_compile_test
for i in interfaces:
if args.verbose:
try:
print get_interface_format_text(i + append)
except KeyError:
print i
if args.compile:
try:
interface_compile_test(i)
except KeyError:
print i
else:
print i
def interface(args):
from sepolicy.interface import get_admin, get, get_user
from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces
if args.list_admin:
for a in get_admin():
print a
print_interfaces(get_admin(args.file), args, "_admin")
if args.list_user:
for a in get_user():
print a
print_interfaces(get_user(args.file), args, "_role")
if args.list:
for m in get():
print m
print_interfaces(get_all_interfaces(args.file), args)
if args.interfaces:
print_interfaces(args.interfaces, args)
def generate(args):
from sepolicy.generate import policy, USERS, SANDBOX, APPLICATIONS, NEWTYPE
from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE
cmd = None
if args.policytype not in USERS + [ SANDBOX, NEWTYPE]:
# numbers present POLTYPE defined in sepolicy.generate
conflict_args = {'TYPES':(NEWTYPE,), 'DOMAIN':(EUSER,), 'ADMIN_DOMAIN':(AUSER, RUSER, EUSER,)}
error_text = ""
if args.policytype is None:
generate_usage = generate_custom_usage(usage, usage_dict)
for k in usage_dict:
error_text += "%s" % (k)
print(generate_usage)
print(_("sepolicy generate: error: one of the arguments %s is required") % error_text)
sys.exit(1)
if args.policytype in APPLICATIONS:
if not args.command:
raise ValueError(_("Command required for this type of policy"))
cmd = os.path.realpath(args.command)
@ -346,8 +484,22 @@ def generate(args):
mypolicy.set_program(cmd)
if args.types:
if args.policytype not in conflict_args['TYPES']:
raise ValueError(_("-t option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
mypolicy.set_types(args.types)
if args.domain:
if args.policytype not in conflict_args['DOMAIN']:
raise ValueError(_("-d option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
if args.admin_domain:
if args.policytype not in conflict_args['ADMIN_DOMAIN']:
raise ValueError(_("-a option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
if len(args.writepaths) > 0 and args.policytype == NEWTYPE:
raise ValueError(_("-w option can not be used with the --newtype option"))
for p in args.writepaths:
if os.path.isdir(p):
mypolicy.add_dir(p)
@ -355,6 +507,7 @@ def generate(args):
mypolicy.add_file(p)
mypolicy.set_transition_users(args.user)
mypolicy.set_admin_roles(args.role)
mypolicy.set_admin_domains(args.admin_domain)
mypolicy.set_existing_domains(args.domain)
@ -366,20 +519,34 @@ def generate(args):
def gen_interface_args(parser):
itf = parser.add_parser("interface",
help=_('List SELinux Policy interfaces'))
itf.add_argument("-c", "--compile", dest="compile",
action="store_true", default=False,
help="Run compile test for selected interface")
itf.add_argument("-v", "--verbose", dest="verbose",
action="store_true", default=False,
help="Show verbose information")
itf.add_argument("-f", "--file", dest="file",
help="Interface file")
group = itf.add_mutually_exclusive_group(required=True)
group.add_argument("-a", "--list_admin", dest="list_admin",action="store_true", default=False,
help="List all domains with admin interface")
help="List all domains with admin interface - DOMAIN_admin()")
group.add_argument("-u", "--list_user", dest="list_user",action="store_true",
default=False,
help="List all domains with SELinux user role interface")
help="List all domains with SELinux user role interface - DOMAIN_role()")
group.add_argument("-l", "--list", dest="list",action="store_true",
default=False,
help="List all interfaces")
group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces",
action=InterfaceInfo,
help=_("Enter interface names, you wish to query"))
itf.set_defaults(func=interface)
def gen_generate_args(parser):
from sepolicy.generate import DAEMON, get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE
pol = parser.add_parser("generate",
generate_usage = generate_custom_usage(usage, usage_dict)
pol = parser.add_parser("generate", usage = generate_usage,
help=_('Generate SELinux Policy module template'))
pol.add_argument("-d", "--domain", dest="domain", default=[],
action=CheckDomain, nargs="*",
@ -387,9 +554,12 @@ def gen_generate_args(parser):
pol.add_argument("-u", "--user", dest="user", default=[],
action=CheckUser,
help=_("Enter SELinux user(s) which will transition to this domain"))
pol.add_argument("-r", "--role", dest="role", default=[],
action=CheckRole,
help=_("Enter SELinux role(s) to which the administror domain will transition"))
pol.add_argument("-a", "--admin", dest="admin_domain",default=[],
action=CheckAdmin,
help=_("Enter domain(s) that this confined admin will administrate"))
help=_("Enter domain(s) which this confined admin will administrate"))
pol.add_argument("-n", "--name", dest="name",
default=None,
help=_("name of policy to generate"))
@ -397,53 +567,57 @@ def gen_generate_args(parser):
help=argparse.SUPPRESS)
pol.add_argument("-t", "--type", dest="types", default=[], nargs="*",
action=CheckType,
help=argparse.SUPPRESS)
help="Enter type(s) for which you will generate new definition and rule(s)")
pol.add_argument("-p", "--path", dest="path", default=os.getcwd(),
help=_("path in which the generated policy files will be stored"))
pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default = [],
help=_("path to which the confined processes will need to write"))
pol.add_argument("command",nargs="?", default=None,
help=_("executable to confine"))
group = pol.add_mutually_exclusive_group(required=False)
group.add_argument("--newtype", dest="policytype", const=NEWTYPE,
cmdtype = pol.add_argument_group(_("Policy types which require a command"))
cmdgroup = cmdtype.add_mutually_exclusive_group(required=False)
cmdgroup.add_argument("--application", dest="policytype", const=USER,
action="store_const",
help=_("Generate Policy for %s") % poltype[NEWTYPE])
help=_("Generate '%s' policy") % poltype[USER])
cmdgroup.add_argument("--cgi", dest="policytype", const=CGI,
action="store_const",
help=_("Generate '%s' policy") % poltype[CGI])
cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS,
action="store_const",
help=_("Generate '%s' policy") % poltype[DBUS])
cmdgroup.add_argument("--inetd", dest="policytype", const=INETD,
action="store_const",
help=_("Generate '%s' policy") % poltype[INETD])
cmdgroup.add_argument("--init", dest="policytype", const=DAEMON,
action="store_const", default=DAEMON,
help=_("Generate '%s' policy") % poltype[DAEMON])
type = pol.add_argument_group("Policy types which do not require a command")
group = type.add_mutually_exclusive_group(required=False)
group.add_argument("--admin_user", dest="policytype", const=AUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[AUSER])
group.add_argument("--application", dest="policytype", const=USER,
action="store_const",
help=_("Generate Policy for %s") % poltype[USER])
group.add_argument("--cgi", dest="policytype", const=CGI,
action="store_const",
help=_("Generate Policy for %s") % poltype[CGI])
help=_("Generate '%s' policy") % poltype[AUSER])
group.add_argument("--confined_admin", dest="policytype", const=RUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[RUSER])
help=_("Generate '%s' policy") % poltype[RUSER])
group.add_argument("--customize", dest="policytype", const=EUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[EUSER])
group.add_argument("--dbus", dest="policytype", const=DBUS,
action="store_const",
help=_("Generate Policy for %s") % poltype[DBUS])
help=_("Generate '%s' policy") % poltype[EUSER])
group.add_argument("--desktop_user", dest="policytype", const=LUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[LUSER])
group.add_argument("--inetd", dest="policytype", const=INETD,
help=_("Generate '%s' policy ") % poltype[LUSER])
group.add_argument("--newtype", dest="policytype", const=NEWTYPE,
action="store_const",
help=_("Generate Policy for %s") % poltype[INETD])
group.add_argument("--init", dest="policytype", const=DAEMON,
action="store_const", default=DAEMON,
help=_("Generate Policy for %s") % poltype[DAEMON])
help=_("Generate '%s' policy") % poltype[NEWTYPE])
group.add_argument("--sandbox", dest="policytype", const=SANDBOX,
action="store_const",
help=_("Generate Policy for %s") % poltype[SANDBOX])
help=_("Generate '%s' policy") % poltype[SANDBOX])
group.add_argument("--term_user", dest="policytype", const=TUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[TUSER])
help=_("Generate '%s' policy") % poltype[TUSER])
group.add_argument("--x_user", dest="policytype", const=XUSER,
action="store_const",
help=_("Generate Policy for %s") % poltype[XUSER])
help=_("Generate '%s' policy") % poltype[XUSER])
pol.add_argument("command",nargs="?", default=None,
help=_("executable to confine"))
pol.set_defaults(func=generate)
if __name__ == '__main__':
@ -455,17 +629,25 @@ if __name__ == '__main__':
gen_booleans_args(subparsers)
gen_communicate_args(subparsers)
gen_generate_args(subparsers)
gen_gui_args(subparsers)
gen_interface_args(subparsers)
gen_manpage_args(subparsers)
gen_network_args(subparsers)
gen_transition_args(subparsers)
try:
args = parser.parse_args()
if os.path.basename(sys.argv[0]) == "sepolgen":
args = parser.parse_args([ "generate" ] + sys.argv[1:])
else:
args = parser.parse_args()
args.func(args)
sys.exit(0)
except ValueError,e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except IOError,e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except KeyboardInterrupt:
print "Out"
sys.exit(0)

View file

@ -1,12 +1,15 @@
#!/usr/bin/python
# Author: Thomas Liu <tliu@redhat.com>
# Author: Dan Walsh <dwalsh@redhat.com>
# Author: Ryan Hallisey <rhallise@redhat.com>
import _policy
import selinux, glob
PROGNAME="policycoreutils"
import gettext
import sepolgen.defaults as defaults
import sepolgen.interfaces as interfaces
import sys
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
@ -37,16 +40,385 @@ CLASS = 'class'
TRANSITION = 'transition'
ROLE_ALLOW = 'role_allow'
def __get_installed_policy():
def info(setype, name=None):
dict_list = _policy.info(setype, name)
return dict_list
def search(types, info = {}):
seinfo = info
valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]
for setype in types:
if setype not in valid_types:
raise ValueError("Type has to be in %s" % valid_types)
seinfo[setype] = True
perms = []
if PERMS in seinfo:
perms = info[PERMS]
seinfo[PERMS] = ",".join(seinfo[PERMS])
dict_list = _policy.search(seinfo)
if dict_list and len(perms) != 0:
dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list)
return dict_list
def get_conditionals(src,dest,tclass,perm):
tdict = {}
tlist = []
if dest.endswith("_t"):
allows=search([ALLOW],{SOURCE:src,TARGET:dest,CLASS:tclass,PERMS:perm})
else:
# to include attribute
allows=search([ALLOW],{SOURCE:src,CLASS:tclass,PERMS:perm})
for i in allows:
if i['target'] == dest:
allows=[]
allows.append(i)
try:
path = selinux.selinux_binary_policy_path()
for i in map(lambda y: (y), filter(lambda x: set(perm).issubset(x[PERMS]) and x['boolean'], allows)):
tdict.update({'source':i['source'],'boolean':i['boolean']})
if tdict not in tlist:
tlist.append(tdict)
tdict={}
except KeyError:
return(tlist)
return (tlist)
def get_conditionals_format_text(cond):
enabled = len(filter(lambda x: x['boolean'][0][1], cond)) > 0
return _("-- Allowed %s [ %s ]") % (enabled, " || ".join(set(map(lambda x: "%s=%d" % (x['boolean'][0][0], x['boolean'][0][1]), cond))))
def get_types_from_attribute(attribute):
return info(ATTRIBUTE,attribute)[0]["types"]
file_type_str = {}
file_type_str["a"] = _("all files")
file_type_str["f"] = _("regular file")
file_type_str["d"] = _("directory")
file_type_str["c"] = _("character device")
file_type_str["b"] = _("block device")
file_type_str["s"] = _("socket file")
file_type_str["l"] = _("symbolic link")
file_type_str["p"] = _("named pipe")
trans_file_type_str = {}
trans_file_type_str[""] = "a"
trans_file_type_str["--"] = "f"
trans_file_type_str["-d"] = "d"
trans_file_type_str["-c"] = "c"
trans_file_type_str["-b"] = "b"
trans_file_type_str["-s"] = "s"
trans_file_type_str["-l"] = "l"
trans_file_type_str["-p"] = "p"
def get_file_types(setype):
flist=[]
mpaths={}
for f in get_all_file_types():
if f.startswith(gen_short_name(setype)):
flist.append(f)
fcdict = get_fcdict()
for f in flist:
try:
mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]])
except KeyError:
mpaths[f] = []
return mpaths
def get_writable_files(setype):
all_attributes = get_all_attributes()
file_types = get_all_file_types()
all_writes = []
mpaths = {}
permlist = search([ALLOW],{'source':setype, 'permlist':['open', 'write'], 'class':'file'})
if permlist == None or len(permlist) == 0:
return mpaths
fcdict = get_fcdict()
attributes = ["proc_type", "sysctl_type"]
for i in permlist:
if i['target'] in attributes:
continue
if i['target'].endswith("_t"):
if i['target'] not in file_types:
continue
if i['target'] not in all_writes:
if i['target'] != setype:
all_writes.append(i['target'])
else:
for t in get_types_from_attribute(i['target']):
if t not in all_writes:
all_writes.append(t)
for f in all_writes:
try:
mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]])
except KeyError:
mpaths[f] = [] #{"regex":[],"paths":[]}
return mpaths
import os, re, sys
def find_file(reg):
if os.path.exists(reg):
return [ reg ]
try:
pat = re.compile(r"%s$" % reg)
except:
print "bad reg:", reg
return []
p = reg
if p.endswith("(/.*)?"):
p = p[:-6] + "/"
path = os.path.dirname(p)
try: # Bug fix: when "all files on system"
if path[-1] != "/": # is pass in it breaks without try block
path += "/"
except IndexError:
print "try failed got an IndexError"
pass
try:
pat = re.compile(r"%s$" % reg)
return filter(pat.match, map(lambda x: path + x, os.listdir(path)))
except:
return []
def find_all_files(domain, exclude_list = []):
all_entrypoints = []
executable_files = get_entrypoints(domain)
for exe in executable_files.keys():
if exe.endswith("_exec_t") and exe not in exclude_list:
for path in executable_files[exe]:
for f in find_file(path):
return f
#all_entrypoints.append(f)
return None
#return all_entrypoints
def find_entrypoint_path(exe, exclude_list = []):
fcdict = get_fcdict()
try:
if exe.endswith("_exec_t") and exe not in exclude_list:
for path in fcdict[exe]["regex"]:
for f in find_file(path):
return f
except KeyError:
pass
return None
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 }
return edict
file_equiv_modified=None
def get_file_equiv_modified(fc_path = selinux.selinux_file_context_path()):
global file_equiv_modified
if file_equiv_modified:
return file_equiv_modified
file_equiv_modified = {}
file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True)
return file_equiv_modified
file_equiv=None
def get_file_equiv(fc_path = selinux.selinux_file_context_path()):
global file_equiv
if file_equiv:
return file_equiv
file_equiv = get_file_equiv_modified(fc_path)
file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify = False)
return file_equiv
local_files=None
def get_local_file_paths(fc_path = selinux.selinux_file_context_path()):
global local_files
if local_files:
return local_files
local_files=[]
fd = open(fc_path+".local", "r")
fc = fd.readlines()
fd.close()
for i in fc:
rec = i.split()
if len(rec) == 0:
continue
try:
if len(rec) > 2:
ftype = trans_file_type_str[rec[1]]
else:
ftype = "a"
local_files.append((rec[0], ftype))
except KeyError:
pass
return local_files
fcdict=None
def get_fcdict(fc_path = selinux.selinux_file_context_path()):
global fcdict
if fcdict:
return fcdict
fd = open(fc_path, "r")
fc = fd.readlines()
fd.close()
fd = open(fc_path+".homedirs", "r")
fc += fd.readlines()
fd.close()
fcdict = {}
fd = open(fc_path+".local", "r")
fc += fd.readlines()
fd.close()
for i in fc:
rec = i.split()
try:
if len(rec) > 2:
ftype = trans_file_type_str[rec[1]]
else:
ftype = "a"
t = rec[-1].split(":")[2]
if t in fcdict:
fcdict[t]["regex"].append(rec[0])
else:
fcdict[t] = { "regex": [ rec[0] ], "ftype": ftype}
except:
pass
fcdict["logfile"] = { "regex" : [ "all log files" ]}
fcdict["user_tmp_type"] = { "regex" : [ "all user tmp files" ]}
fcdict["user_home_type"] = { "regex" : [ "all user home files" ]}
fcdict["virt_image_type"] = { "regex" : [ "all virtual image files" ]}
fcdict["noxattrfs"] = { "regex" : [ "all files on file systems which do not support extended attributes" ]}
fcdict["sandbox_tmpfs_type"] = { "regex" : [ "all sandbox content in tmpfs file systems" ]}
fcdict["user_tmpfs_type"] = { "regex" : [ "all user content in tmpfs file systems" ]}
fcdict["file_type"] = { "regex" : [ "all files on the system" ]}
fcdict["samba_share_t"] = { "regex" : [ "use this label for random content that will be shared using samba" ]}
return fcdict
def get_transitions_into(setype):
try:
return filter(lambda x: x["transtype"] == setype, search([TRANSITION],{ 'class':'process'}))
except TypeError:
pass
return None
def get_transitions(setype):
try:
return search([TRANSITION],{'source':setype, 'class':'process'})
except TypeError:
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 })
for p in permlist:
if "boolean" in p:
try:
for b in p["boolean"]:
if boolean in b:
boollist.append(p)
except:
pass
return boollist
def get_all_entrypoints():
return get_types_from_attribute("entry_type")
def get_entrypoint_types(setype):
entrypoints = []
try:
entrypoints = map(lambda x: x['target'],filter(lambda x: x['source'] == setype, search([ALLOW],{'source':setype, 'permlist':['entrypoint'], 'class':'file'})))
except TypeError:
pass
return entrypoints
def get_init_transtype(path):
entrypoint = selinux.getfilecon(path)[1].split(":")[2]
try:
entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION],{'source':"init_t", 'class':'process'}))
if len(entrypoints) == 0:
return None
return entrypoints[0]["transtype"]
except TypeError:
pass
return None
def get_init_entrypoint(transtype):
try:
entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION],{'source':"init_t", 'class':'process'}))
if len(entrypoints) == 0:
return None
return entrypoints[0]["target"]
except TypeError:
pass
return None
def get_init_entrypoint_target(entrypoint):
try:
entrypoints = map(lambda x: x['transtype'], search([TRANSITION],{'source':"init_t", 'target':entrypoint, 'class':'process'}))
return entrypoints[0]
except TypeError:
pass
return None
def get_entrypoints(setype):
fcdict = get_fcdict()
mpaths = {}
for f in get_entrypoint_types(setype):
try:
mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]])
except KeyError:
mpaths[f] = []
return mpaths
def get_installed_policy(root = "/"):
try:
path = root + selinux.selinux_binary_policy_path()
policies = glob.glob ("%s.*" % path )
policies.sort()
return policies[-1]
except:
pass
raise ValueError(_("No SELinux Policy installed"))
methods = []
def get_methods():
global methods
if len(methods) > 0:
return methods
gen_interfaces()
fn = defaults.interface_info()
try:
fd = open(fn)
# List of per_role_template interfaces
ifs = interfaces.InterfaceSet()
ifs.from_file(fd)
methods = ifs.interfaces.keys()
fd.close()
except:
sys.stderr.write("could not open interface info [%s]\n" % fn)
sys.exit(1)
methods.sort()
return methods
all_types = None
def get_all_types():
global all_types
@ -54,23 +426,31 @@ def get_all_types():
all_types = map(lambda x: x['name'], info(TYPE))
return all_types
user_types = None
def get_user_types():
global user_types
if user_types == None:
user_types = info(ATTRIBUTE,"userdomain")[0]["types"]
return user_types
role_allows = None
def get_all_role_allows():
global role_allows
if role_allows:
return role_allows
role_allows = {}
for r in search([ROLE_ALLOW]):
if r["source"] == "system_r" or r["target"] == "system_r":
continue
if r["source"] in role_allows:
role_allows[r["source"]].append(r["target"])
else:
role_allows[r["source"]] = [ r["target"] ]
global role_allows
if role_allows:
return role_allows
role_allows = {}
for r in search([ROLE_ALLOW]):
if r["source"] == "system_r" or r["target"] == "system_r":
continue
if r["source"] in role_allows:
role_allows[r["source"]].append(r["target"])
else:
role_allows[r["source"]] = [ r["target"] ]
return role_allows
return role_allows
def get_all_entrypoint_domains():
import re
all_domains = []
types=get_all_types()
types.sort()
@ -81,138 +461,366 @@ def get_all_entrypoint_domains():
all_domains.append(m[0])
return all_domains
portrecs = None
portrecsbynum = None
def gen_interfaces():
import commands
ifile = defaults.interface_info()
headers = defaults.headers()
rebuild = False
try:
if os.stat(headers).st_mtime <= os.stat(ifile).st_mtime:
return
except OSError:
pass
if os.getuid() != 0:
raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
print commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1]
def gen_port_dict():
global portrecs
global portrecsbynum
if portrecs:
return ( portrecs, portrecsbynum )
portrecsbynum = {}
portrecs = {}
for i in info(PORT):
if i['low'] == i['high']:
port = str(i['low'])
else:
port = "%s-%s" % (str(i['low']), str(i['high']))
if (i['type'], i['protocol']) in portrecs:
portrecs [(i['type'], i['protocol'])].append(port)
else:
portrecs [(i['type'], i['protocol'])] = [port]
if 'range' in i:
portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'], i['range'])
else:
portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'])
return ( portrecs, portrecsbynum )
all_domains = None
def get_all_domains():
global all_domains
if not all_domains:
all_domains = info(ATTRIBUTE,"domain")[0]["types"]
return all_domains
global all_domains
if not all_domains:
all_domains = info(ATTRIBUTE,"domain")[0]["types"]
return all_domains
roles = None
def get_all_roles():
global roles
if roles:
return roles
global roles
if roles:
return roles
roles = map(lambda x: x['name'], info(ROLE))
roles.remove("object_r")
roles.sort()
return roles
users = None
selinux_user_list = None
def get_selinux_users():
global selinux_user_list
if not selinux_user_list:
selinux_user_list = info(USER)
for x in selinux_user_list:
x['range']="".join(x['range'].split(" "))
return selinux_user_list
login_mappings = None
def get_login_mappings():
global login_mappings
if login_mappings:
return login_mappings
fd = open(selinux.selinux_usersconf_path(), "r")
buf=fd.read()
fd.close()
login_mappings = []
for b in buf.split("\n"):
b = b.strip()
if len(b) == 0 or b.startswith("#"):
continue
x = b.split(":")
login_mappings.append({ "name": x[0], "seuser": x[1], "mls":":".join(x[2:])})
return login_mappings
def get_all_users():
global users
if users:
return users
users = map(lambda x: x['name'], info(USER))
return users
users = map(lambda x: x['name'], get_selinux_users())
users.sort()
return users
file_types = None
def get_all_file_types():
global file_types
if file_types:
return file_types
file_types = info(ATTRIBUTE,"file_type")[0]["types"]
file_types.sort()
return file_types
global file_types
if file_types:
return file_types
file_types = info(ATTRIBUTE,"file_type")[0]["types"]
file_types.sort()
return file_types
port_types = None
def get_all_port_types():
global port_types
if port_types:
return port_types
port_types = info(ATTRIBUTE,"port_type")[0]["types"]
port_types.sort()
return port_types
global port_types
if port_types:
return port_types
port_types = info(ATTRIBUTE,"port_type")[0]["types"]
port_types.sort()
return port_types
bools = None
def get_all_bools():
global bools
if not bools:
bools = info(BOOLEAN)
return bools
global bools
if not bools:
bools = info(BOOLEAN)
return bools
def prettyprint(f,trim):
return " ".join(f[:-len(trim)].split("_"))
def markup(f):
return f
# Autofill for adding files *************************
DEFAULT_DIRS = {}
DEFAULT_DIRS["/etc"] = "etc_t"
DEFAULT_DIRS["/tmp"] = "tmp_t"
DEFAULT_DIRS["/usr/lib/systemd/system"] = "unit_file_t"
DEFAULT_DIRS["/lib/systemd/system"] = "unit_file_t"
DEFAULT_DIRS["/etc/systemd/system"] = "unit_file_t"
DEFAULT_DIRS["/var/cache"] = "var_cache_t"
DEFAULT_DIRS["/var/lib"] = "var_lib_t"
DEFAULT_DIRS["/var/log"] = "log_t"
DEFAULT_DIRS["/var/run"] = "var_run_t"
DEFAULT_DIRS["/run"] = "var_run_t"
DEFAULT_DIRS["/run/lock"] = "var_lock_t"
DEFAULT_DIRS["/var/run/lock"] = "var_lock_t"
DEFAULT_DIRS["/var/spool"] = "var_spool_t"
DEFAULT_DIRS["/var/www"] = "content_t"
def get_description(f, markup=markup):
txt = "Set files with the %s type, if you want to " % markup(f)
if f.endswith("_var_run_t"):
return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
if f.endswith("_pid_t"):
return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
if f.endswith("_var_lib_t"):
return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_t"):
return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_spool_t"):
return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_spool_t"):
return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_cache_t") or f.endswith("_var_cache_t"):
return txt + "store the files under the /var/cache directory."
if f.endswith("_keytab_t"):
return txt + "treat the files as kerberos keytab files."
if f.endswith("_lock_t"):
return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t")
if f.endswith("_log_t"):
return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t")
if f.endswith("_config_t"):
return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t")
if f.endswith("_conf_t"):
return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t")
if f.endswith("_exec_t"):
return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
if f.endswith("_cgi_content_t"):
return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
if f.endswith("_rw_content_t"):
return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t")
if f.endswith("_rw_t"):
return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_t")
if f.endswith("_write_t"):
return txt + "treat the files as %s read/write content." % prettyprint(f,"_write_t")
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")
if f.endswith("_cert_t"):
return txt + "treat the files as %s certificate data." % prettyprint(f,"_cert_t")
if f.endswith("_key_t"):
return txt + "treat the files as %s key data." % prettyprint(f,"_key_t")
if f.endswith("_secret_t"):
return txt + "treat the files as %s secret data." % prettyprint(f,"_key_t")
if f.endswith("_ra_t"):
return txt + "treat the files as %s read/append content." % prettyprint(f,"_ra_t")
if f.endswith("_ro_t"):
return txt + "treat the files as %s read/only content." % prettyprint(f,"_ro_t")
if f.endswith("_modules_t"):
return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t")
if f.endswith("_content_t"):
return txt + "treat the files as %s content." % prettyprint(f, "_content_t")
if f.endswith("_state_t"):
return txt + "treat the files as %s state data." % prettyprint(f, "_state_t")
if f.endswith("_files_t"):
return txt + "treat the files as %s content." % prettyprint(f, "_files_t")
if f.endswith("_file_t"):
return txt + "treat the files as %s content." % prettyprint(f, "_file_t")
if f.endswith("_data_t"):
return txt + "treat the files as %s content." % prettyprint(f, "_data_t")
if f.endswith("_file_t"):
return txt + "treat the data as %s content." % prettyprint(f, "_file_t")
if f.endswith("_tmp_t"):
return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
if f.endswith("_etc_t"):
return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
if f.endswith("_home_t"):
return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t")
if f.endswith("_tmpfs_t"):
return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
if f.endswith("_unit_file_t"):
return txt + "treat files as a systemd unit file."
if f.endswith("_htaccess_t"):
return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
return txt + "treat the files as %s data." % prettyprint(f,"_t")
all_attributes = None
def get_all_attributes():
global all_attributes
if not all_attributes:
all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
return all_attributes
global all_attributes
if not all_attributes:
all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
return all_attributes
def policy(policy_file):
global all_domains
global all_attributes
global bools
global all_types
global role_allows
global users
global roles
global file_types
global port_types
all_domains = None
all_attributes = None
bools = None
all_types = None
role_allows = None
users = None
roles = None
file_types = None
port_types = None
try:
_policy.policy(policy_file)
except:
raise ValueError(_("Failed to read %s policy file") % policy_file)
policy_file = selinux.selinux_current_policy_path()
if not policy_file:
policy_file = __get_installed_policy()
try:
policy_file = get_installed_policy()
policy(policy_file)
except ValueError, e:
if selinux.is_selinux_enabled() == 1:
raise e
def search(types, info = {} ):
valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]
for type in types:
if type not in valid_types:
raise ValueError("Type has to be in %s" % valid_types)
info[type] = True
perms = []
if PERMS in info:
perms = info[PERMS]
info[PERMS] = ",".join(info[PERMS])
dict_list = _policy.search(info)
if dict_list and len(perms) != 0:
dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list)
return dict_list
def _dict_has_perms(dict, perms):
for perm in perms:
if perm not in dict[PERMS]:
return False
return True
def info(setype, name=None):
dict_list = _policy.info(setype, name)
return dict_list
def gen_short_name(setype):
all_domains = get_all_domains()
if setype.endswith("_t"):
domainname = setype[:-2]
else:
domainname = setype
if domainname + "_t" not in all_domains:
raise ValueError("domain %s_t does not exist" % domainname)
if domainname[-1]=='d':
short_name = domainname[:-1] + "_"
else:
short_name = domainname + "_"
return (domainname, short_name)
def get_bools(setype):
bools = []
domainbools = []
domainname, short_name = gen_short_name(setype)
for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW],{'source' : setype}))):
for b in i:
if not isinstance(b,tuple):
continue
try:
enabled = selinux.security_get_boolean_active(b[0])
except OSError:
enabled = b[1]
if b[0].startswith(short_name) or b[0].startswith(domainname):
if (b[0], enabled) not in domainbools and (b[0], not enabled) not in domainbools:
domainbools.append((b[0], enabled))
else:
if (b[0], enabled) not in bools and (b[0], not enabled) not in bools:
bools.append((b[0],enabled))
return (domainbools, bools)
booleans = None
def get_all_booleans():
global booleans
if not booleans:
booleans = selinux.security_get_boolean_names()[1]
return booleans
booleans_dict = None
import gzip
def policy_xml(path="/usr/share/selinux/devel/policy.xml"):
try:
fd = gzip.open(path)
buf = fd.read()
fd.close()
except IOError:
fd = open(path)
buf = fd.read()
fd.close()
return buf
def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"):
global booleans_dict
if booleans_dict:
return booleans_dict
import xml.etree.ElementTree
import re
booleans_dict = {}
try:
tree = xml.etree.ElementTree.parse(path)
for l in tree.findall("layer"):
for m in l.findall("module"):
for b in m.findall("tunable"):
desc = b.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
for b in m.findall("bool"):
desc = b.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
for i in tree.findall("bool"):
desc = i.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
for i in tree.findall("tunable"):
desc = i.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
except IOError, e:
pass
return booleans_dict
import xml.etree.ElementTree
import re
booleans_dict = {}
try:
tree = xml.etree.ElementTree.fromstring(policy_xml(path))
for l in tree.findall("layer"):
for m in l.findall("module"):
for b in m.findall("tunable"):
desc = b.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
for b in m.findall("bool"):
desc = b.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
for i in tree.findall("bool"):
desc = i.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
for i in tree.findall("tunable"):
desc = i.find("desc").find("p").text.strip("\n")
desc = re.sub("\n", " ", desc)
booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
except IOError, e:
pass
return booleans_dict
def boolean_category(boolean):
booleans_dict = gen_bool_dict()
@ -233,18 +841,58 @@ def get_os_version():
os_version = ""
pkg_name = "selinux-policy"
try:
import commands
rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
if rc == 0:
os_version = output.split(".")[-2]
import commands
rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
if rc == 0:
os_version = output.split(".")[-2]
except:
os_version = ""
os_version = ""
if os_version[0:2] == "fc":
os_version = "Fedora"+os_version[2:]
os_version = "Fedora"+os_version[2:]
elif os_version[0:2] == "el":
os_version = "RHEL"+os_version[2:]
os_version = "RHEL"+os_version[2:]
else:
os_version = ""
os_version = ""
return os_version
def reinit():
global all_attributes
global all_domains
global all_types
global booleans
global booleans_dict
global bools
global fcdict
global file_types
global local_files
global methods
global methods
global portrecs
global portrecsbynum
global port_types
global role_allows
global roles
global login_mappings
global selinux_user_list
global user_types
all_attributes = None
all_domains = None
all_types = None
booleans = None
booleans_dict = None
bools = None
fcdict = None
file_types = None
local_files=None
methods = None
methods = None
portrecs = None
portrecsbynum = None
port_types = None
role_allows = None
roles = None
user_types = None
login_mappings = None
selinux_user_list = None

View file

@ -40,7 +40,7 @@ def expand_attribute(attribute):
def get_types(src, tclass, perm):
allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
if not allows:
raise TypeError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
raise ValueError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
tlist = []
for l in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):

View file

@ -63,20 +63,6 @@ except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
user_types = sepolicy.info(sepolicy.ATTRIBUTE,"userdomain")[0]["types"]
methods = []
fn = defaults.interface_info()
try:
fd = open(fn)
# List of per_role_template interfaces
ifs = interfaces.InterfaceSet()
ifs.from_file(fd)
methods = ifs.interfaces.keys()
fd.close()
except:
sys.stderr.write("could not open interface info [%s]\n" % fn)
sys.exit(1)
def get_rpm_nvr_from_header(hdr):
'Given an RPM header return the package NVR as a string'
name = hdr['name']
@ -164,7 +150,7 @@ def get_poltype_desc():
return msg
APPLICATIONS = [ DAEMON, DBUS, INETD, USER, CGI ]
USERS = [ XUSER, TUSER, LUSER, AUSER, EUSER, RUSER]
USERS = [ XUSER, TUSER, LUSER, AUSER, RUSER]
def verify_ports(ports):
if ports == "":
@ -206,7 +192,7 @@ class policy:
raise ValueError(_("You must enter a valid policy type"))
if not name:
raise ValueError(_("You must enter a name for your policy module for your %s.") % poltype[type])
raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
try:
self.ports = get_all_ports()
except ValueError, e:
@ -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;
self.DEFAULT_EXT["port_t"] = network;
self.DEFAULT_EXT["_port_t"] = network;
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 +579,7 @@ class policy:
def generate_network_action(self, protocol, action, port_name):
line = ""
method = "corenet_%s_%s_%s" % (protocol, action, port_name)
if method in methods:
if method in sepolicy.get_methods():
line = "%s(%s_t)\n" % (method, self.name)
else:
line = """
@ -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:
raise ValueError(_("%s policy modules require existing domains") % poltype[self.type])
raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
newte += """gen_require(`"""
@ -873,18 +865,20 @@ allow %s_t %s_t:%s_socket name_%s;
for t in self.types:
for i in self.DEFAULT_EXT:
if t.endswith(i):
print t, t[:-len(i)]
newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
break
if NEWTYPE and newte == "":
default_ext = []
for i in self.DEFAULT_EXT:
default_ext.append(i)
raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
return newte
def generate_new_rules(self):
newte = ""
for t in self.types:
for i in self.DEFAULT_EXT:
if t.endswith(i):
newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_rules)
break
return newte
return ""
def generate_daemon_types(self):
newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
@ -1014,7 +1008,7 @@ allow %s_t %s_t:%s_socket name_%s;
def generate_roles_rules(self):
newte = ""
if self.type in ( TUSER, XUSER, AUSER, LUSER, EUSER):
if self.type in ( TUSER, XUSER, AUSER, LUSER ):
roles = ""
if len(self.roles) > 0:
newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
@ -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":
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
if self.type != EUSER:
newte +="""
########################################
#
# %s local policy
#""" % self.name
#
""" % self.name
newte += self.generate_capabilities()
newte += self.generate_process()
newte += self.generate_network_types()
@ -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:
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
for i in self.DEFAULT_DIRS[d][1]:
if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
break
if self.type == EUSER:
newte_tmp = ""
for domain in self.existing_domains:
newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2]+"_t", self.DEFAULT_DIRS[d][2].te_rules)
newte += re.sub("TEMPLATETYPE_rw_t", self.name+"_rw_t", newte_tmp)
else:
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
for i in self.DEFAULT_DIRS[d][1]:
if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
if self.type == EUSER:
for domain in self.existing_domains:
newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
else:
newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
break
newte += self.generate_tmp_rules()
newte += self.generate_network_rules()
@ -1077,19 +1083,6 @@ allow %s_t %s_t:%s_socket name_%s;
def generate_fc(self):
newfc = ""
fclist = []
if self.type in USERS + [ SANDBOX ]:
return executable.fc_user
if self.type != NEWTYPE and not self.program:
raise ValueError(_("You must enter the executable path for your confined process"))
if self.program:
t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
if self.initscript != "":
t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
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 +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))
if self.type in USERS + [ SANDBOX ]:
if len(fclist) == 0:
return executable.fc_user
if self.type not in USERS + [ SANDBOX, EUSER, NEWTYPE ] and not self.program:
raise ValueError(_("You must enter the executable path for your confined process"))
if self.program:
t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
if self.initscript != "":
t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
fclist.sort()
newfc="\n".join(fclist)
return newfc
def generate_user_sh(self):
newsh = ""
if self.type not in ( TUSER, XUSER, AUSER, LUSER, EUSER):
if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
return newsh
roles = ""
@ -1117,13 +1125,10 @@ allow %s_t %s_t:%s_socket name_%s;
roles += " %s_r" % role
if roles != "":
roles += " system_r"
if self.type == EUSER:
tmp = re.sub("TEMPLATETYPE", self.name, script.eusers)
else:
tmp = re.sub("TEMPLATETYPE", self.name, script.users)
tmp = re.sub("TEMPLATETYPE", self.name, script.users)
newsh += re.sub("ROLES", roles, tmp)
if self.type == RUSER:
if self.type == RUSER or self.type == AUSER:
for u in self.transition_users:
tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans)
newsh += re.sub("USER", u, tmp)
@ -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)
newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
if self.program:
newsh += re.sub("FILENAME", self.program, script.restorecon)
if self.initscript != "":
@ -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()
newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
return newsh
@ -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)
return newspec
# Remove man pages from EUSER spec file
if self.type == EUSER:
newspec = re.sub(".*%s_selinux.8.*" % self.name,"", newspec)
# Remove user context file from non users spec file
if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
newspec = re.sub(".*%s_u.*" % self.name,"", newspec)
return newspec
def write_spec(self, out_dir):
specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
@ -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"))
out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
if self.type != NEWTYPE:
out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
return out

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View file

@ -0,0 +1,6 @@
You are viewing the booleans page for the application domain.
SELinux Policy writers have written booleans, if-than-else rules, into the policy. This allows the administrator to change the way SELinux enforces policy on an application. The administrator can tighten or loosen the SELinux policy based on his needs.
You can use the 'Filter Text Entry' to search for appropriate booleans. The Show Modified Only toggle, will show the booleans that your system has customized.

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View file

@ -0,0 +1,4 @@
You are viewing the booleans page for the application domain.
Selecting the 'More...' button will open a dialog containing the SELinux allow rules that are turned on by the selected boolean.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -0,0 +1 @@
You are viewing the booleans page for the application domain.

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View file

@ -0,0 +1,4 @@
You are viewing the booleans page for the application domain.
Toggle the button to turn on or off the boolean. This will not happen immediately. All changes on the application screen are bundled up into a single transaction. You need to select the update button to apply all of your changes to the system.

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -0,0 +1,20 @@
SELinux can either setup labeling directory using the Application/files screen, or you can setup file equivalence.
File Equivalence allows an administrator to label entire directory trees as the same way as the Equivalence directory tree.
Use Case 1:
An administrator want to store his Apache root content in a location other then /var/www like /srv/www. He could define an equivalence between /srv/www and /var/www.
libselinux reads the equivalence rules and does the substitution when ever the matchpathcon function is called. Tools like restorecon/rpm/udev and others will all follow the substitution. Using the example above when matchpathcon is handed /srv/www/cgi-bin/myscript.cgi, it substitutes /var/www for /svr/www and looks up the context of /var/www/cgi-bin/myscript.cgi.
In the command line you could execute.
# semanage fcontext -a -e /var/www /srv/www
Another common case where you might want to use file equivalence, is if you put your users home directories in a location other then /home.
If you setup an equivalence between /home and /export/home
# matchpathcon /export/home/dwalsh/.ssh
/export/home/dwalsh/.ssh unconfined_u:object_r:home_ssh_t:s0

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View file

@ -0,0 +1,8 @@
This screen shows application types that are defined for process running with the '%(APP)s' type.
The description should give you a decent description for what the application is allowed to do with the type. If your application type is being denied access to a particular file, you might want to change the label of that file.
It is recommended that you use one of the types defined on this page.
Note if the label of the content that is being denied is owned by another domain, you might have to write policy or use 'audit2allow -M mypol' to allow access.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View file

@ -0,0 +1,4 @@
This screen shows application types that can transition to a process running with the '%(APP)s' type.
In SELinux these are called entrypoints. SELinux controls the executable files that can be used as an entrypoint to an confined domain. If you have an alternate executable that you would like to run in the '%(APP)s' domain, you need to change the executable file type to the entrypoint type.

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View file

@ -0,0 +1,9 @@
This screen shows files types to which a process running with the '%(APP)s' type is allowed to write.
The description should give you a decent description for what the application is allowed to do with the type. If your application type is being denied access to a particular file, you might want to change the label of that file.
It is recommended that you use one of the types defined on this page.
Note if the label of the content that is being denied is owned by another domain, you might have to write policy or use 'audit2allow -M mypol'
to allow access.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View file

@ -0,0 +1,4 @@
The Lockdown Screen allows you to tighten the SELinux Security on your machine.
These lockdown measures are recommended, but can cause SELinux issues. If you have a machine you truly want to secure, and are confident in your understanding of SELinux you should try some of these options.

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -0,0 +1,10 @@
Disable Permissive Processes
Disabling the 'permissivedomains' module allows you to remove all permissive domains shipped with the distribution.
When the distribution policy writers write a new confined domain, they initially ship the policy for that domain in permissive mode. Permissive mode means that a process running in the domain will not be confined by SELinux. The kernel will log the AVC messages, access denials, that would have happened had the process been run in enforcing mode.
Permissive domain policies are experimental and will be turned to enforcing in future Operation System Releases.
Note if you disable the permissive domains module, you may see an increase in the denials in your log files.

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -0,0 +1,14 @@
Disable ptrace capability on your system.
The deny_ptrace feature allows an administrator to toggle the ability of processes on the computer system from examining other processes on the system, including user processes. It can even block processes running as root.
Most people do not realize that any program they run can examine the memory of any other process run by them. Meaning the computer game you are running on your desktop can watch everything going on in Firefox or a programs like pwsafe or kinit or other program that attempts to hide passwords..
SELinux defines this access as ptrace and sys_ptrace. These accesses allow one process to read the memory of another process. ptrace allows developers and administrators to debug how a process is running using tools like strace, ptrace and gdb. You can even use gdb (GNU Debugger to manipulate another process running memory and environment.
The problem is this is allowed by default.
My wife does not debug programs, why is she allowed to debug them? As a matter of fact most of the time, I am not debugging applications, so it would be more secure if we could disable it by default.
Note: Disabling ptrace can break some bug trappers that attempt to collect crash data.

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,9 @@
Disable Unconfined System Processes
By default any system process that is started at boot that do not have SELinux Policy defined for them, run as initrc_t or init_t. These domains are unconfined by SELinux. Other similar processes which do not have SELinux Policy written for them run also unconfined. By disabling the unconfined module moves you closer to what used to be called strict policy, and locks down your machine tighter.
Disabling the unconfined module will leave certain unconfined domains running on your system, specifically the unconfined_t user. If you do not
want unconfined_t users on your system you would need to remove them from the 'Login Mapping' and Users Screens.
Note if you disable the unconfined module, you may see an increase in the denials, and if you have processes running as initrc_t, you may need to write policy for them.

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -0,0 +1,21 @@
By Default on a SELinux Targeted Policy system, all users login using the unconfined_t user.
But SELinux has a very powerful concept called confined users. You can setup individual users on your system to login with different SELinux user types. This Login Mapping Screen allows you to map a Linux login user to an SELinux User.
Default SELinux Users:
* Terminal user/ssh - guest_u
- No Network, No setuid, no exec in homedir
* Browser user/kiosk - xguest_u
- Web access ports only. No setuid, no exec in homedir
* Full Desktop user - User_u
- Full Network, No SETUID.
* Confined Admin/Desktop User - Staff_u
- Full Network, sudo to admin only, no root password. Usually a confined admin
* Unconfined user - unconfined_u (Default)
- SELinux does not block access.

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View file

@ -0,0 +1,8 @@
The Login Mapping Screen has a special Login user called __default__. This record is used to setup the default login user for any login account that is not specified separately.
If this is a desktop system you might want to specify the user_u or xguest_u user. If this is a terminal server the guest_u user might be a good match.
Then you would need to add the admin users or a Linux group with a different label. Perhaps as unconfined_u or staff_u.
You could use %%wheel to indicate the wheel group.

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -0,0 +1,6 @@
This screen shows the network ports that processes running with the '%(APP)s' type is allowed to bind to.
SELinux controls the network ports that a application is allowed to bind to based on SELinux Port types.
This screen allows you to modify the port number/port type definitions, which the '(APP)s' is currently allowed to bind.

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,6 @@
This screen shows the network ports to which processes running with the '%(APP)s' type is allowed to connect.
SELinux controls the network ports that a applications are allowed to connect, based on SELinux Port types.
This screen allows you to modify the port number/port type definitions, which the '%(APP)s' is currently allowed to connect.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,6 @@
You must 'Select' the initial screen to view for SELinux Configuration.
This application allows you to browse SELinux confinement per application. You can enter the name of the application to see how SELinux confines it, or you could enter the SELinux name for the running process.
Alternatively you can select to manage SELinux on the system, lockdown the system via SELinux. You can also manage confined users and confined user mappings. Finally you could setup File System Labeling equivalence.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View file

@ -0,0 +1 @@
This screen allows you to view modify the way SELinux is running on your system.

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View file

@ -0,0 +1,13 @@
SELinux Systems can boot in three different modes.
* Enforcing mode (Default)
- SELinux security policy is enforced.
* Permissive
- SELinux prints warnings instead of enforcing.
* Disabled
- No SELinux policy is loaded, SELinux does not run.
You can use this screen to change the enforcing mode.
Note if you disable SELinux, you will need to to reboot, to turn it off. Also the next time you turn SELinux on, a full system relabel will be performed.

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View file

@ -0,0 +1,6 @@
You can switch SELinux between Enforcing mode and Permissive mode.
When a machine is in permissive mode, SELinux will continue to log SELinux AVC messages, that would have been denied if the machine was in enforcing mode.
Changing the current mode of the system will not survive a reboot. You would need to change the system mode for this.

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,6 @@
SELinux allows you to export/import the current configuration of the machine.
If you have several machines configured the same way you may want to modify the SELinux configuration on one machine and then export the configuration to a file. Then you could copy that file to another machine and import it on that machine.
Note, If you import a configuration to a machine, the local configuration will get removed.

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View file

@ -0,0 +1,5 @@
If you have more then one policy type installed, the advanced screen will become visible. You can select the advanced tab and modify the policy type that SELinux is running with.
Policy types are installed as sub-directories of /etc/selinux.
Changing the policy type of the machine will require a system relabeled in permissive mode. The gui will insure that proper labels get assigned on the next reboot.

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,10 @@
SELinux is a labeling system. Sometimes the labels on disk can get messed up. One way to fix this is to trigger a full relabel on the next boot.
You can toggle this behavior using this screen.
Note: Sometimes a simple restorecon is all you need to fix the labels on a file or directory.
If you add a new disk which does not have labels you could simply execute
# restorecon -R -v PATHTODISK

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -0,0 +1,15 @@
This screen shows the 'file types' of the specified 'class' that will be created by processes running with '%(APP)s' type in the '%(APP)s' directory.
SELinux allows policy writers to define file transition rules. These rules define the label of a newly create file system object.
By default an newly created file system object will get the label of the directory the object is being created in.
Creating an file in a directory with the file type of etc_t will get the label etc_t. In certain situations SELinux aware applications
can override this behavior, for example the passwd command creates /etc/shadow with a type of shadow_t.
A third option is for policy writers to write a transition rule. For example a process labeled NetworkManager creating content in a directory labeled etc_t will create it with the label net_conf_t.
File Transition Rules can be written to create all objects of a particular class, or specific to a particular file name.
You need to build a policy module if you want to add additional File Transition Rules.

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View file

@ -0,0 +1,10 @@
This screen shows when a process running with the '%(APP)s' type executes 'Commands File Paths' that they will transition to the specified types.
Under SELinux, when a process running with a 'type' attempts to execute an executable, one of three things can happen.
1. The process can be prevented from running the executable.
2. The executable executes with the same label as parent.
3. The executable 'transitions' to a new 'type' based on policy.
This screen shows the executables that transition to another domain when '%(APP)s' executes them, and the 'SELinux Application Type' of the newly created process.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View file

@ -0,0 +1,8 @@
Transitions can be controlled by SELinux Booleans.
SELinux Booleans are If-then-else rules in policy, that allow the administrator to modify the access control on a process type.
Transition rules are either always allowed or can be turned on and off based on the boolean settings. If the 'Boolean Enabled' column has an arrow on it, this indicates the transition is controlled by a boolean.
Go to the next screen to see the effect of clicking on the arrow.

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View file

@ -0,0 +1 @@
After selecting the arrow under Boolean Enabled column, the line will expand to show a link which you can click. This will take you to the booleans page and allow you to enable the boolean which will enable or disable the transition.

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1,4 @@
This screen shows you the boolean page with the boolean selected.
Enable or disable the boolean to turn on or off the transition.

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -0,0 +1,10 @@
This screen shows the SELinux process 'types' which will transition to the '%(APP)s' type when executing the 'Commands File Paths'.
Under SELinux, when a process running with a 'type' attempts to execute an executable, one of three things can happen.
1. The process can be prevented from running the executable.
2. The executable executes with the same label as parent.
3. The executable 'transitions' to a new 'type' based on policy.
This screen shows the executables that transition to another domain when '%(APP)s' executes them, and the 'SELinux Application Type' of the newly created process.

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -0,0 +1,20 @@
By Default on a SELinux Targeted Policy system, all users login using the unconfined_t user.
SELinux has a very powerful concept called confined users. You can setup individual users on your system to login with different SELinux user types. This SELinux User Screen allows you to create/modify SELinux Users and map them to SELinux Roles and MLS/MCS Ranges
Default SELinux Users:
* Terminal user/ssh - guest_u
- No Network, No setuid, no exec in homedir
* Browser user/kiosk - xguest_u
- Web access ports only. No setuid, no exec in homedir
* Full Desktop user - User_u
- Full Network, No SETUID.
* Confined Admin/Desktop User - Staff_u
- Full Network, sudo to admin only, no root password. Usually a confined admin
* Unconfined user - unconfined_u (Default)
- SELinux does not block access.

View file

@ -21,15 +21,12 @@
# 02111-1307 USA
#
#
import re
import sepolgen.interfaces as interfaces
import sepolgen.defaults as defaults
import re, sys
import sepolicy
ADMIN_TRANSITION_INTERFACE = "_admin$"
USER_TRANSITION_INTERFACE = "_role$"
from sepolicy.generate import get_all_types
__all__ = [ 'get', 'get_admin', 'get_user' ]
__all__ = [ 'get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user' ,'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test' ]
##
## I18N
@ -48,34 +45,173 @@ except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
def get():
""" Get all Methods """
fn = defaults.interface_info()
try:
fd = open(fn)
ifs = interfaces.InterfaceSet()
ifs.from_file(fd)
methods = ifs.interfaces.keys()
fd.close()
except:
raise ValueError(_("could not open interface info [%s]\n") % fn)
def get_interfaces_from_xml(path):
""" Get all interfaces from given xml file"""
interfaces_list = []
idict = get_interface_dict(path)
for k in idict.keys():
interfaces_list.append(k)
return interfaces_list
return methods
def get_admin():
""" Get all domains with an admin interface"""
def get_all_interfaces(path=""):
from sepolicy import get_methods
all_interfaces = []
if not path:
all_interfaces = get_methods()
else:
xml_path = get_xml_file(path)
all_interfaces = get_interfaces_from_xml(xml_path)
return all_interfaces
def get_admin(path=""):
""" Get all domains with an admin interface from installed policy."""
""" If xml_path is specified, func returns an admin interface from specified xml file"""
admin_list = []
for i in get():
if i.endswith("_admin"):
admin_list.append(i.split("_admin")[0])
if path:
try:
xml_path = get_xml_file(path)
idict = get_interface_dict(xml_path)
for k in idict.keys():
if k.endswith("_admin"):
admin_list.append(k)
except IOError, e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
else:
for i in sepolicy.get_methods():
if i.endswith("_admin"):
admin_list.append(i.split("_admin")[0])
return admin_list
def get_user():
def get_user(path=""):
""" Get all domains with SELinux user role interface"""
""" If xml_path is specified, func returns an user role interface from specified xml file"""
trans_list = []
for i in get():
m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i)
if len(m) > 0:
if "%s_exec_t" % m[0] in get_all_types():
trans_list.append(m[0])
if path:
try:
xml_path = get_xml_file(path)
idict = get_interface_dict(xml_path)
for k in idict.keys():
if k.endswith("_role"):
if (("%s_exec_t" % k[:-5]) in sepolicy.get_all_types()):
trans_list.append(k)
except IOError, e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
else:
for i in sepolicy.get_methods():
m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i)
if len(m) > 0:
if "%s_exec_t" % m[0] in sepolicy.get_all_types():
trans_list.append(m[0])
return trans_list
interface_dict = None
def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
global interface_dict
import os
import xml.etree.ElementTree
if interface_dict:
return interface_dict
interface_dict = {}
param_list = []
xml_path = """<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<policy>
<layer name="admin">
"""
xml_path += path
xml_path +="""
</layer>
</policy>
"""
try:
if os.path.isfile(path):
tree = xml.etree.ElementTree.parse(path)
else:
tree = xml.etree.ElementTree.fromstring(xml_path)
for l in tree.findall("layer"):
for m in l.findall("module"):
for i in m.getiterator('interface'):
for e in i.findall("param"):
param_list.append(e.get('name'))
interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"interface"]
param_list = []
for i in m.getiterator('template'):
for e in i.findall("param"):
param_list.append(e.get('name'))
interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"template"]
param_list = []
except IOError, e:
pass
return interface_dict
def get_interface_format_text(interface,path = "/usr/share/selinux/devel/policy.xml"):
idict = get_interface_dict(path)
interface_text = "%s(%s) %s" % (interface, ", ".join(idict[interface][0]), " ".join(idict[interface][1].split("\n")))
return interface_text
def get_interface_compile_format_text(interfaces_dict, interface):
from templates import test_module
param_tmp = []
for i in interfaces_dict[interface][0]:
param_tmp.append(test_module.dict_values[i])
interface_text = "%s(%s)\n" % (interface, ", ".join(param_tmp))
return interface_text
def generate_compile_te(interface, idict, name="compiletest"):
from templates import test_module
te = ""
te += re.sub("TEMPLATETYPE", name, test_module.te_test_module )
te += get_interface_compile_format_text(idict,interface)
return te
def get_xml_file(if_file):
""" Returns xml format of interfaces for given .if policy file"""
import os, commands
basedir = os.path.dirname(if_file)+"/"
filename = os.path.basename(if_file).split(".")[0]
rc, output=commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir+filename)
if rc != 0:
sys.stderr.write("\n Could not proceed selected interface file.\n")
sys.stderr.write("\n%s" % output)
sys.exit(1)
else:
return output
def interface_compile_test(interface, path = "/usr/share/selinux/devel/policy.xml"):
exclude_interfaces = ["userdom","kernel","corenet","files", "dev"]
exclude_interface_type = ["template"]
import commands, os
policy_files = {'pp':"compiletest.pp", 'te':"compiletest.te", 'fc':"compiletest.fc", 'if':"compiletest.if"}
idict = get_interface_dict(path)
if not (interface.split("_")[0] in exclude_interfaces or idict[interface][2] in exclude_interface_type):
print(_("Compiling %s interface" % interface))
try:
fd = open(policy_files['te'], "w")
fd.write(generate_compile_te(interface, idict))
fd.close()
rc, output=commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'] )
if rc != 0:
sys.stderr.write(output)
sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
except EnvironmentError, e:
sys.stderr.write(_("\nCompile test for %s has not run. %s\n") % (interface, e))
for v in policy_files.values():
if os.path.exists(v):
os.remove(v)
else:
sys.stderr.write(_("\nCompiling of %s interface is not supported." % interface))

View file

@ -28,12 +28,12 @@ import string
import argparse
import selinux
import sepolicy
from sepolicy import network, gen_bool_dict, get_all_file_types, get_all_domains, get_all_roles, get_all_users, get_all_port_types, get_all_bools, get_all_attributes, get_all_role_allows
from sepolicy import *
import commands
import sys, os, re, time
equiv_dict={ "smbd" : [ "samba" ], "httpd" : [ "apache" ], "virtd" : [ "virt", "libvirt" ], "named" : [ "bind" ], "fsdaemon" : [ "smartmon" ], "mdadm" : [ "raid" ] }
equiv_dict={ "smbd" : [ "samba" ], "httpd" : [ "apache" ], "virtd" : [ "virt", "libvirt", "svirt", "svirt_tcg", "svirt_lxc_t", "svirt_lxc_net_t" ], "named" : [ "bind" ], "fsdaemon" : [ "smartmon" ], "mdadm" : [ "raid" ] }
equiv_dirs=[ "/var" ]
modules_dict = None
@ -45,7 +45,7 @@ def gen_modules_dict(path = "/usr/share/selinux/devel/policy.xml"):
import xml.etree.ElementTree
modules_dict = {}
try:
tree = xml.etree.ElementTree.parse(path)
tree = xml.etree.ElementTree.fromstring(policy_xml(path))
for l in tree.findall("layer"):
for m in l.findall("module"):
name = m.get("name")
@ -100,8 +100,8 @@ def gen_domains():
for d in get_all_domains():
found = False
domain = d[:-2]
if domain + "_exec_t" not in get_entrypoints():
continue
# if domain + "_exec_t" not in get_entrypoints():
# continue
if domain in domains:
continue
domains.append(domain)
@ -114,39 +114,6 @@ def gen_domains():
domains.sort()
return domains
fcdict=None
def _gen_fcdict(fc_path = selinux.selinux_file_context_path()):
global fcdict
if fcdict:
return fcdict
fd = open(fc_path, "r")
fc = fd.readlines()
fd.close()
fd = open(fc_path+".homedirs", "r")
fc += fd.readlines()
fd.close()
fcdict = {}
for i in fc:
rec = i.split()
try:
t = rec[-1].split(":")[2]
if t in fcdict:
fcdict[t].append(rec[0])
else:
fcdict[t] = [ rec[0] ]
except:
pass
fcdict["logfile"] = [ "all log files" ]
fcdict["user_tmp_type"] = [ "all user tmp files" ]
fcdict["user_home_type"] = [ "all user home files" ]
fcdict["virt_image_type"] = [ "all virtual image files" ]
fcdict["noxattrfs"] = [ "all files on file systems which do not support extended attributes" ]
fcdict["sandbox_tmpfs_type"] = [ "all sandbox content in tmpfs file systems" ]
fcdict["user_tmpfs_type"] = [ "all user content in tmpfs file systems" ]
fcdict["file_type"] = [ "all files on the system" ]
fcdict["samba_share_t"] = [ "use this label for random content that will be shared using samba" ]
return fcdict
types = None
def _gen_types():
global types
@ -184,14 +151,12 @@ def get_alphabet_manpages(manpage_list):
return alphabet_manpages
def convert_manpage_to_html(html_manpage,manpage):
fd = open(html_manpage,'w')
rc, output = commands.getstatusoutput("man2html -r %s" % manpage)
rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
if rc == 0:
print html_manpage, " has been created"
fd = open(html_manpage,'w')
fd.write(output)
else:
fd.write("Man page does not exist")
fd.close()
fd.close()
class HTMLManPages:
"""
@ -416,56 +381,51 @@ class ManPage:
"""
Generate a Manpage on an SELinux domain in the specified path
"""
all_attributes = get_all_attributes()
all_domains = get_all_domains()
all_bools = get_all_bools()
all_port_types = get_all_port_types()
all_roles = get_all_roles()
all_users = get_all_users_info()[0]
all_users_range = get_all_users_info()[1]
all_file_types = get_all_file_types()
types = _gen_types()
modules_dict = None
domains = gen_domains()
role_allows = get_all_role_allows()
enabled_str = ["Disabled", "Enabled"]
def __init__(self, domainname, path = "/tmp", html = False):
def __init__(self, domainname, path = "/tmp", root="/", source_files = False ,html = False):
self.html = html
self.portrecs = network.portrecs
self.source_files = source_files
self.root = root
self.portrecs = gen_port_dict()[0]
self.domains = gen_domains()
self.all_domains = get_all_domains()
self.all_attributes = get_all_attributes()
self.all_bools = get_all_bools()
self.all_port_types = get_all_port_types()
self.all_roles = get_all_roles()
self.all_users = get_all_users_info()[0]
self.all_users_range = get_all_users_info()[1]
self.all_file_types = get_all_file_types()
self.role_allows = get_all_role_allows()
self.types = _gen_types()
fcpath = path + "/file_contexts"
if os.path.exists(fcpath):
self.fcpath = fcpath
if self.source_files:
self.fcpath = self.root + "file_contexts"
else:
self.fcpath = selinux.selinux_file_context_path()
self.fcdict = _gen_fcdict(self.fcpath)
self.fcpath = self.root + selinux.selinux_file_context_path()
self.fcdict = get_fcdict(self.fcpath)
if not os.path.exists(path):
os.makedirs(path)
self.path = path
xmlpath = path + "/policy.xml"
if os.path.exists(xmlpath):
self.xmlpath = xmlpath
if self.source_files:
self.xmlpath = self.root + "policy.xml"
else:
self.xmlpath = "/usr/share/selinux/devel/policy.xml"
self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml"
self.booleans_dict = gen_bool_dict(self.xmlpath)
if domainname.endswith("_t"):
self.domainname = domainname[:-2]
else:
self.domainname = domainname
if self.domainname + "_t" not in self.all_domains:
raise ValueError("domain %s_t does not exist" % self.domainname)
self.short_name = self.domainname
self.domainname, self.short_name = gen_short_name(domainname)
self.type = self.domainname + "_t"
self._gen_bools()
self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname)
self.fd = open(self.man_page_path, 'w')
if domainname + "_r" in self.all_roles:
if self.domainname + "_r" in self.all_roles:
self.__gen_user_man_page()
if self.html:
manpage_roles.append(self.man_page_path)
@ -483,16 +443,16 @@ class ManPage:
def _gen_bools(self):
self.bools=[]
self.domainbools=[]
for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, sepolicy.search([sepolicy.ALLOW],{'source' : self.type }))):
for b in i:
if not isinstance(b,tuple):
continue
if b[0].startswith(self.short_name):
if b not in self.domainbools and (b[0], not b[1]) not in self.domainbools:
self.domainbools.append(b)
else:
if b not in self.bools and (b[0], not b[1]) not in self.bools:
self.bools.append(b)
types = [self.type]
if self.domainname in equiv_dict:
for t in equiv_dict[self.domainname]:
if t + "_t" in self.all_domains:
types.append(t+"_t")
for t in types:
domainbools, bools = get_bools(t)
self.bools += bools
self.domainbools += domainbools
self.bools.sort()
self.domainbools.sort()
@ -538,9 +498,6 @@ class ManPage:
print path
def __gen_man_page(self):
if self.domainname[-1]=='d':
self.short_name = self.domainname[:-1]
self.anon_list = []
self.attributes = {}
@ -563,22 +520,11 @@ class ManPage:
def _get_ptypes(self):
for f in self.all_domains:
if f.startswith(self.short_name):
self.ptypes.append(f)
def __whoami(self):
import pwd
fd = open("/proc/self/loginuid", "r")
uid = int(fd.read())
fd.close()
pw = pwd.getpwuid(uid)
if len(pw.pw_gecos) > 0:
return pw.pw_gecos
else:
return pw.pw_name
if f.startswith(self.short_name) or f.startswith(self.domainname):
self.ptypes.append(f)
def _header(self):
self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy documentation for %(domainname)s"'
self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"'
% {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")})
self.fd.write(r"""
.SH "NAME"
@ -596,95 +542,6 @@ For example:
""" % {'domainname':self.domainname})
def _explain(self, f):
if f.endswith("_var_run_t"):
return "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
if f.endswith("_pid_t"):
return "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
if f.endswith("_var_lib_t"):
return "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_t"):
return "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_spool_t"):
return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_spool_t"):
return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_cache_t") or f.endswith("_var_cache_t"):
return "store the files under the /var/cache directory."
if f.endswith("_keytab_t"):
return "treat the files as kerberos keytab files."
if f.endswith("_lock_t"):
return "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t")
if f.endswith("_log_t"):
return "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t")
if f.endswith("_config_t"):
return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t")
if f.endswith("_conf_t"):
return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t")
if f.endswith("_exec_t"):
return "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
if f.endswith("_cgi_content_t"):
return "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
if f.endswith("_rw_content_t"):
return "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t")
if f.endswith("_rw_t"):
return "treat the files as %s read/write content." % prettyprint(f,"_rw_t")
if f.endswith("_write_t"):
return "treat the files as %s read/write content." % prettyprint(f,"_write_t")
if f.endswith("_db_t"):
return "treat the files as %s database content." % prettyprint(f,"_db_t")
if f.endswith("_ra_content_t"):
return "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t")
if f.endswith("_cert_t"):
return "treat the files as %s certificate data." % prettyprint(f,"_cert_t")
if f.endswith("_key_t"):
return "treat the files as %s key data." % prettyprint(f,"_key_t")
if f.endswith("_secret_t"):
return "treat the files as %s secret data." % prettyprint(f,"_key_t")
if f.endswith("_ra_t"):
return "treat the files as %s read/append content." % prettyprint(f,"_ra_t")
if f.endswith("_ro_t"):
return "treat the files as %s read/only content." % prettyprint(f,"_ro_t")
if f.endswith("_modules_t"):
return "treat the files as %s modules." % prettyprint(f, "_modules_t")
if f.endswith("_content_t"):
return "treat the files as %s content." % prettyprint(f, "_content_t")
if f.endswith("_state_t"):
return "treat the files as %s state data." % prettyprint(f, "_state_t")
if f.endswith("_files_t"):
return "treat the files as %s content." % prettyprint(f, "_files_t")
if f.endswith("_file_t"):
return "treat the files as %s content." % prettyprint(f, "_file_t")
if f.endswith("_data_t"):
return "treat the files as %s content." % prettyprint(f, "_data_t")
if f.endswith("_file_t"):
return "treat the data as %s content." % prettyprint(f, "_file_t")
if f.endswith("_tmp_t"):
return "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
if f.endswith("_etc_t"):
return "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
if f.endswith("_home_t"):
return "store %s files in the users home directory." % prettyprint(f, "_home_t")
if f.endswith("_tmpfs_t"):
return "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
if f.endswith("_unit_file_t"):
return "treat files as a systemd unit file."
if f.endswith("_htaccess_t"):
return "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
return "treat the files as %s data." % prettyprint(f,"_t")
def _format_boolean_desc(self, b):
desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
if desc[-1] == ".":
@ -774,7 +631,7 @@ can be used to make the process type %(domainname)s_t permissive. SELinux does n
def _port_types(self):
self.ports = []
for f in self.all_port_types:
if f.startswith(self.short_name):
if f.startswith(self.short_name) or f.startswith(self.domainname):
self.ports.append(f)
if len(self.ports) == 0:
@ -821,7 +678,7 @@ Default Defined Ports:""")
if f.startswith(self.domainname):
flist.append(f)
if f in self.fcdict:
mpaths = mpaths + self.fcdict[f]
mpaths = mpaths + self.fcdict[f]["regex"]
if len(mpaths) == 0:
return
mpaths.sort()
@ -896,19 +753,19 @@ Note: SELinux often uses regular expressions to specify labels that match multip
.B %s
.EE
- Set files with the %s type, if you want to %s
""" % (f, f, self._explain(f)))
- %s
""" % ( f, sepolicy.get_description(f)))
if f in self.fcdict:
plural = ""
if len(self.fcdict[f]) > 1:
if len(self.fcdict[f]["regex"]) > 1:
plural = "s"
self.fd.write("""
.br
.TP 5
Path%s:
%s""" % (plural, self.fcdict[f][0]))
for x in self.fcdict[f][1:]:
%s""" % (plural, self.fcdict[f]["regex"][0]))
for x in self.fcdict[f]["regex"][1:]:
self.fd.write(", %s" % x)
self.fd.write("""
@ -923,13 +780,12 @@ to apply the labels.
def _see_also(self):
ret = ""
prefix = self.short_name.split("_")[0]
for d in self.domains:
if d == self.domainname:
continue
if d.startswith(prefix):
if d.startswith(self.short_name):
ret += ", %s_selinux(8)" % d
if self.domainname.startswith(d):
if d.startswith(self.domainname + "_"):
ret += ", %s_selinux(8)" % d
self.fd.write(ret)
@ -947,13 +803,14 @@ semanage fcontext -a -t public_content_t "/var/%(domainname)s(/.*)?"
.B restorecon -F -R -v /var/%(domainname)s
.pp
.TP
Allow %(domainname)s servers to read and write /var/tmp/incoming by adding the public_content_rw_t type to the directory and by restoring the file type. This also requires the allow_%(domainname)sd_anon_write boolean to be set.
Allow %(domainname)s servers to read and write /var/%(domainname)s/incoming by adding the public_content_rw_t type to the directory and by restoring the file type. You also need to turn on the %(domainname)s_anon_write boolean.
.PP
.B
semanage fcontext -a -t public_content_rw_t "/var/%(domainname)s/incoming(/.*)?"
.br
.B restorecon -F -R -v /var/%(domainname)s/incoming
.br
.B setsebool -P %(domainname)s_anon_write 1
""" % {'domainname':self.domainname})
for b in self.anon_list:
desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
@ -998,12 +855,11 @@ is a GUI tool available to customize SELinux policy settings.
.SH AUTHOR
This manual page was auto-generated using
.B "sepolicy manpage"
by %s.
.B "sepolicy manpage".
.SH "SEE ALSO"
selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)
""" % (self.__whoami(), self.domainname))
""" % (self.domainname))
if self.booltext != "":
self.fd.write(", setsebool(8)")
@ -1046,7 +902,7 @@ All executeables with the default executable label, usually stored in /usr/bin a
paths=[]
for entrypoint in entrypoints:
if entrypoint in self.fcdict:
paths += self.fcdict[entrypoint]
paths += self.fcdict[entrypoint]["regex"]
self.fd.write("""
%s""" % ", ".join(paths))
@ -1086,7 +942,7 @@ The SELinux process type %s_t can manage files labeled with the following file t
""" % f)
if f in self.fcdict:
for path in self.fcdict[f]:
for path in self.fcdict[f]["regex"]:
self.fd.write("""\t%s
.br
""" % path)
@ -1230,6 +1086,7 @@ The SELinux user %s_u is not able to terminal login.
""" % self.domainname)
def _network(self):
from sepolicy import network
self.fd.write("""
.SH NETWORK
""")
@ -1241,10 +1098,10 @@ The SELinux user %s_u is not able to terminal login.
The SELinux user %s_u is able to listen on the following %s ports.
""" % (self.domainname, net))
for p in portdict:
for recs in portdict[p]:
for t, ports in portdict[p]:
self.fd.write("""
.B %s
""" % recs)
""" % ",".join(ports))
portdict = network.get_network_connect(self.type, "tcp", "name_connect")
if len(portdict) > 0:
self.fd.write("""
@ -1252,10 +1109,10 @@ The SELinux user %s_u is able to listen on the following %s ports.
The SELinux user %s_u is able to connect to the following tcp ports.
""" % (self.domainname))
for p in portdict:
for recs in portdict[p]:
for t, ports in portdict[p]:
self.fd.write("""
.B %s
""" % recs)
""" % ",".join(ports))
def _home_exec(self):
permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,'target':'user_home_type', 'class':'file', 'permlist':['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']})

View file

@ -20,52 +20,26 @@
# 02111-1307 USA
#
#
import sys
import sepolicy
search=sepolicy.search
info=sepolicy.info
def _gen_port_dict():
portrecsbynum = {}
portrecs = {}
for i in info(sepolicy.PORT):
if i['low'] == i['high']:
port = str(i['low'])
else:
port = "%s-%s" % (str(i['low']), str(i['high']))
if (i['type'], i['protocol']) in portrecs:
portrecs [(i['type'], i['protocol'])].append(port)
else:
portrecs [(i['type'], i['protocol'])] = [port]
portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'], i['range'])
return ( portrecs, portrecsbynum )
portrecs, portrecsbynum = _gen_port_dict()
port_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"]
domains = sepolicy.info(sepolicy.ATTRIBUTE,"domain")[0]["types"]
def get_types(src, tclass, perm):
allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
nlist=[]
if allows:
for i in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]) and x['enabled'], allows)):
for i in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):
if i not in nlist:
nlist.append(i)
return nlist
def get_network_connect(src, protocol, perm):
portrecs, portrecsbynum = sepolicy.gen_port_dict()
d={}
tlist = get_types(src, "%s_socket" % protocol, [perm])
if len(tlist) > 0:
if "port_type" in tlist:
d[(src,protocol,perm)] = ["all ports"]
return d
d[(src,protocol,perm)] = []
for i in tlist:
if i == "ephemeral_port_type":
if "unreserved_port_type" in tlist:
@ -77,16 +51,18 @@ def get_network_connect(src, protocol, perm):
if "port_t" in tlist:
continue
if i == "port_t":
d[(src,protocol,perm)].append("all ports with out defined types")
d[(src,protocol,perm)].append((i, ["all ports with out defined types"]))
if i == "port_type":
d[(src,protocol,perm)].append((i, ["all ports"]))
elif i == "unreserved_port_type":
d[(src,protocol,perm)].append("%s: all ports > 1024" % i)
d[(src,protocol,perm)].append((i, ["all ports > 1024"]))
elif i == "reserved_port_type":
d[(src,protocol,perm)].append("%s: all ports < 1024" % i)
d[(src,protocol,perm)].append((i, ["all ports < 1024"]))
elif i == "rpc_port_type":
d[(src,protocol,perm)].append("%s: all ports > 500 and < 1024" % i)
d[(src,protocol,perm)].append((i, ["all ports > 500 and < 1024"]))
else:
try:
d[(src,protocol,perm)].append("%s: %s" % (i, ",".join(portrecs[(i, protocol)])))
d[(src,protocol,perm)].append((i, portrecs[(i, protocol)]))
except KeyError:
pass
return d

View file

@ -0,0 +1,58 @@
import sys
import dbus
import dbus.service
import dbus.mainloop.glib
from slip.dbus import polkit
class SELinuxDBus (object):
def __init__ (self):
self.bus = dbus.SystemBus()
self.dbus_object = self.bus.get_object("org.selinux", "/org/selinux/object")
@polkit.enable_proxy
def semanage (self, buf):
ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def restorecon (self, path):
ret = self.dbus_object.restorecon(path, dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def setenforce (self, value):
ret = self.dbus_object.setenforce(value, dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def customized (self):
ret = self.dbus_object.customized(dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def semodule_list (self):
ret = self.dbus_object.semodule_list(dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def relabel_on_boot(self, value):
ret = self.dbus_object.relabel_on_boot(value, dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def change_default_mode(self, value):
ret = self.dbus_object.change_default_mode(value, dbus_interface = "org.selinux")
return ret
@polkit.enable_proxy
def change_default_policy(self, value):
ret = self.dbus_object.change_default_policy(value, dbus_interface = "org.selinux")
return ret
if __name__ == "__main__":
try:
dbus_proxy = SELinuxDBus()
resp = dbus_proxy.setenforce(int(sys.argv[1]))
print (resp)
except dbus.DBusException, e:
print e

File diff suppressed because it is too large Load diff

View file

@ -578,3 +578,6 @@ interface(`corenet_relabelto_TEMPLATETYPE_server_packets',`
allow $1 TEMPLATETYPE_server_packet_t:packet relabelto;
')
"""
te_rules="""
"""

View file

@ -66,14 +66,17 @@ set -x
make -f /usr/share/selinux/devel/Makefile TEMPLATEFILE.pp || exit
/usr/sbin/semodule -i TEMPLATEFILE.pp
# Generate a man page off the installed module
sepolicy manpage -p . -d DOMAINTYPE_t
"""
rpm="""\
# Generate a rpm package for the newly generated policy
pwd=$(pwd)
rpmbuild --define "_sourcedir ${pwd}" --define "_specdir ${pwd}" --define "_builddir ${pwd}" --define "_srcrpmdir ${pwd}" --define "_rpmdir ${pwd}" --define "_buildrootdir ${pwd}/.build" -ba TEMPLATETYPE_selinux.spec
rpmbuild --define "_sourcedir ${pwd}" --define "_specdir ${pwd}" --define "_builddir ${pwd}" --define "_srcrpmdir ${pwd}" --define "_rpmdir ${pwd}" --define "_buildrootdir ${pwd}/.build" -ba TEMPLATEFILE_selinux.spec
"""
manpage="""\
# Generate a man page off the installed module
sepolicy manpage -p . -d DOMAINTYPE_t
"""
restorecon="""\
@ -107,8 +110,7 @@ admin_trans="""\
"""
min_login_user_default_context="""\
if [ ! -f /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u ]; then
cat > /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u << _EOF
cat > TEMPLATETYPE_u << _EOF
TEMPLATETYPE_r:TEMPLATETYPE_t:s0 TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:crond_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:initrc_su_t TEMPLATETYPE_r:TEMPLATETYPE_t
@ -116,12 +118,13 @@ system_r:local_login_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:remote_login_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:sshd_t TEMPLATETYPE_r:TEMPLATETYPE_t
_EOF
if [ ! -f /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u ]; then
cp TEMPLATETYPE_u /etc/selinux/targeted/contexts/users/
fi
"""
x_login_user_default_context="""\
if [ ! -f /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u ]; then
cat > /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u << _EOF
cat > TEMPLATETYPE_u << _EOF
TEMPLATETYPE_r:TEMPLATETYPE_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:crond_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:initrc_su_t TEMPLATETYPE_r:TEMPLATETYPE_t
@ -130,5 +133,7 @@ system_r:remote_login_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:sshd_t TEMPLATETYPE_r:TEMPLATETYPE_t
system_r:xdm_t TEMPLATETYPE_r:TEMPLATETYPE_t
_EOF
if [ ! -f /etc/selinux/targeted/contexts/users/TEMPLATETYPE_u ]; then
cp TEMPLATETYPE_u /etc/selinux/targeted/contexts/users/
fi
"""

View file

@ -18,6 +18,7 @@ URL: http://HOSTNAME
Source0: MODULENAME.pp
Source1: MODULENAME.if
Source2: DOMAINNAME_selinux.8
Source3: DOMAINNAME_u
Requires: policycoreutils, libselinux-utils
Requires(post): selinux-policy-base >= %{selinux_policyver}, policycoreutils
@ -36,13 +37,16 @@ install -m 644 %{SOURCE0} %{buildroot}%{_datadir}/selinux/packages
install -d %{buildroot}%{_datadir}/selinux/devel/include/contrib
install -m 644 %{SOURCE1} %{buildroot}%{_datadir}/selinux/devel/include/contrib/
install -d %{buildroot}%{_mandir}/man8/
install -m 644 %{SOURCE2} %{buildroot}%{_mandir}/man8/
install -m 644 %{SOURCE2} %{buildroot}%{_mandir}/man8/DOMAINNAME_selinux.8
install -d %{buildroot}/etc/selinux/targeted/contexts/users/
install -m 644 %{SOURCE3} %{buildroot}/etc/selinux/targeted/contexts/users/DOMAINNAME_u
%post
semodule -n -i %{_datadir}/selinux/packages/MODULENAME.pp
if /usr/sbin/selinuxenabled ; then
/usr/sbin/load_policy
%relabel_files
/usr/sbin/semanage user -a -R DOMAINNAME_r DOMAINNAME_u
fi;
exit 0
@ -52,6 +56,7 @@ if [ $1 -eq 0 ]; then
if /usr/sbin/selinuxenabled ; then
/usr/sbin/load_policy
%relabel_files
/usr/sbin/semanage user -d DOMAINNAME_u
fi;
fi;
exit 0
@ -60,6 +65,7 @@ exit 0
%attr(0600,root,root) %{_datadir}/selinux/packages/MODULENAME.pp
%{_datadir}/selinux/devel/include/contrib/MODULENAME.if
%{_mandir}/man8/DOMAINNAME_selinux.8.*
/etc/selinux/targeted/contexts/users/DOMAINNAME_u
%changelog
* TODAYSDATE YOUR NAME <YOUR@EMAILADDRESS> 1.0-1

View file

@ -0,0 +1,119 @@
# Copyright (C) 2007-2012 Red Hat
# see file 'COPYING' for use and warranty information
#
# policygentool is a tool for the initial generation of SELinux policy
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
#
#['domain', 'role', 'role_prefix', 'object_class', 'name', 'private_type', 'prefix', 'entrypoint', 'target_domain', 'terminal', 'range', 'domains', 'entry_point', 'entry_file', 'domain_prefix', 'private type', 'user_prefix', 'user_role', 'user_domain', 'object', 'type', 'source_domain', 'file_type', 'file', 'class', 'peer_domain', 'objectclass(es)', 'exception_types', 'home_type', 'object_type', 'directory_type', 'boolean', 'pty_type', 'userdomain', 'tty_type', 'tmpfs_type', 'script_file', 'filetype', 'filename', 'init_script_file', 'source_role', 'userdomain_prefix']
dict_values={}
dict_values['domain'] = 'sepolicy_domain_t'
dict_values['domains'] = 'sepolicy_domain_t'
dict_values['target_domain'] = 'sepolicy_target_t'
dict_values['source_domain'] = 'sepolicy_source_t'
dict_values['peer_domain'] = 'sepolicy_peer_t'
dict_values['exception_types'] = 'sepolicy_exception_types_t'
dict_values['user_domain'] = 'sepolicy_userdomain_t'
dict_values['userdomain'] = 'sepolicy_userdomain_t'
dict_values['bool_domain'] = 'sepolicy_bool_domain_t'
dict_values['type'] = 'sepolicy_file_t'
dict_values['file_type'] = 'sepolicy_file_t'
dict_values['private type'] = 'sepolicy_private_file_t'
dict_values['private_type'] = 'sepolicy_private_file_t'
dict_values['pty_type'] = 'sepolicy_devpts_t'
dict_values['tmpfs_type'] = 'sepolicy_tmpfs_t'
dict_values['home_type'] = 'sepolicy_home_file_t'
dict_values['tty_type'] = 'sepolicy_t'
dict_values['directory_type'] = 'sepolicy_file_t'
dict_values['object_type'] = 'sepolicy_object_t'
dict_values['script_file'] = 'sepolicy_exec_t'
dict_values['entry_point'] = 'sepolicy_exec_t'
dict_values['file'] = 'sepolicy_file_t'
dict_values['entry_file'] = 'sepolicy_exec_t'
dict_values['init_script_file'] = 'sepolicy_exec_t'
dict_values['entrypoint'] = 'sepolicy_exec_t'
dict_values['role'] = 'sepolicy_r'
dict_values['role_prefix'] = 'sepolicy'
dict_values['user_role'] = 'sepolicy_r'
dict_values['source_role'] = 'sepolicy_source_r'
dict_values['prefix'] = 'sepolicy_domain'
dict_values['domain_prefix'] = 'sepolicy_domain'
dict_values['userdomain_prefix'] = 'sepolicy_userdomain'
dict_values['user_prefix'] = 'sepolicy_userdomain'
dict_values['object_class'] = 'file'
dict_values['object'] = 'file'
dict_values['class'] = 'file'
dict_values['objectclass(es)'] = 'file'
dict_values['object_name'] = 'sepolicy_object'
dict_values['name'] = '"sepolicy_name"'
dict_values['terminal'] = 'sepolicy_tty_t'
dict_values['boolean'] = 'sepolicy_bool_t'
dict_values['range'] = 's0 - mcs_systemhigh'
te_test_module="""\
policy_module(TEMPLATETYPE, 1.0.0)
type sepolicy_t;
domain_type(sepolicy_t)
type sepolicy_domain_t;
domain_type(sepolicy_domain_t)
type sepolicy_target_t;
domain_type(sepolicy_target_t)
type sepolicy_source_t;
domain_type(sepolicy_source_t)
type sepolicy_peer_t;
domain_type(sepolicy_peer_t)
type sepolicy_exception_types_t;
domain_type(sepolicy_exception_types_t)
type sepolicy_userdomain_t;
domain_type(sepolicy_userdomain_t)
type sepolicy_file_t;
files_type(sepolicy_file_t)
type sepolicy_private_file_t;
files_type(sepolicy_private_file_t)
type sepolicy_home_file_t;
files_type(sepolicy_home_file_t)
type sepolicy_tty_t;
term_tty(sepolicy_tty_t)
type sepolicy_object_t;
type sepolicy_devpts_t;
term_pty(sepolicy_devpts_t)
type sepolicy_tmpfs_t;
files_type(sepolicy_tmpfs_t)
type sepolicy_exec_t;
files_type(sepolicy_exec_t)
role sepolicy_r;
role sepolicy_source_r;
role sepolicy_target_r;
#################################
#
# Local policy
#
"""

View file

@ -48,7 +48,7 @@ interface(`TEMPLATETYPE_systemctl',`
')
systemd_exec_systemctl($1)
systemd_read_fifo_file_password_run($1)
systemd_read_fifo_file_passwd_run($1)
allow $1 TEMPLATETYPE_unit_file_t:file read_file_perms;
allow $1 TEMPLATETYPE_unit_file_t:service manage_service_perms;

View file

@ -71,11 +71,6 @@ policy_module(TEMPLATETYPE, 1.0.0)
te_root_user_types="""\
policy_module(TEMPLATETYPE, 1.0.0)
########################################
#
# Declarations
#
## <desc>
## <p>
## Allow TEMPLATETYPE to read files in the user home directory
@ -90,6 +85,11 @@ gen_tunable(TEMPLATETYPE_read_user_files, false)
## </desc>
gen_tunable(TEMPLATETYPE_manage_user_files, false)
########################################
#
# Declarations
#
userdom_base_user_template(TEMPLATETYPE)
"""
@ -151,7 +151,9 @@ tunable_policy(`TEMPLATETYPE_read_user_files',`
')
tunable_policy(`TEMPLATETYPE_manage_user_files',`
userdom_manage_user_home_content(TEMPLATETYPE_t)
userdom_manage_user_home_content_dirs(TEMPLATETYPE_t)
userdom_manage_user_home_content_files(TEMPLATETYPE_t)
userdom_manage_user_home_content_symlinks(TEMPLATETYPE_t)
userdom_manage_user_tmp_files(TEMPLATETYPE_t)
')
"""

View file

@ -20,10 +20,9 @@
# 02111-1307 USA
#
#
import sepolicy, sys
import sepolicy
search=sepolicy.search
info=sepolicy.info
_failedlist = []
__all__ = [ 'setrans', ]
def _entrypoint(src):
@ -32,11 +31,11 @@ def _entrypoint(src):
def _get_trans(src):
foundstr = ""
return search([sepolicy.TRANSITION],{sepolicy.SOURCE:src, sepolicy.CLASS:"process"})
class setrans:
def __init__(self, source, dest=None):
self.seen = []
self.sdict = {}
self.source=source
self.dest=dest
@ -58,19 +57,25 @@ class setrans:
for s in self.sdict[source]["child"]:
self._process(s)
def out(self, name, seen=[], header=""):
def out(self, name, header=""):
buf = ""
if name in seen:
if name in self.seen:
return buf
seen.append(name)
self.seen.append(name)
for t in self.sdict[name]["map"]:
buf += "%s%s @ %s --> %s\n" % (header, t["source"], t["target"], t["transtype"])
if "map" in self.sdict[name]:
for t in self.sdict[name]["map"]:
cond=sepolicy.get_conditionals(t["source"], t["transtype"],"process",["transition"])
if cond:
buf += "%s%s @ %s --> %s %s\n" % (header, t["source"], t["target"], t["transtype"], sepolicy.get_conditionals_format_text(cond))
else:
buf += "%s%s @ %s --> %s\n" % (header, t["source"], t["target"], t["transtype"])
if "child" in self.sdict[name]:
for x in self.sdict[name]["child"]:
buf+= self.out(x, seen, "%s%s ... " % (header, name))
buf+= self.out(x, "%s%s ... " % (header, name))
return buf
def output(self):
self.seen = []
print self.out(self.source)

View file

@ -9,4 +9,4 @@ policy = Extension("sepolicy._policy",
sources=[ "policy.c", "info.c", "search.c"]
)
setup(name = "sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates"])
setup(name = "sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy':['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})