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.
2
policycoreutils/sepolicy/.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
build
|
||||
tmp
|
||||
*.bak
|
||||
|
|
|
@ -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
|
||||
|
|
23
policycoreutils/sepolicy/org.selinux.conf
Normal 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>
|
80
policycoreutils/sepolicy/org.selinux.policy
Normal 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>
|
4
policycoreutils/sepolicy/org.selinux.service
Normal file
|
@ -0,0 +1,4 @@
|
|||
[D-BUS Service]
|
||||
Name=org.selinux
|
||||
Exec=/usr/share/system-config-selinux/selinux_server.py
|
||||
User=root
|
43
policycoreutils/sepolicy/selinux_client.py
Normal 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
|
131
policycoreutils/sepolicy/selinux_server.py
Normal 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()
|
1
policycoreutils/sepolicy/sepolgen.8
Normal file
|
@ -0,0 +1 @@
|
|||
.so man8/sepolicy-generate.8
|
|
@ -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") )
|
||||
|
|
|
@ -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
|
||||
|
|
29
policycoreutils/sepolicy/sepolicy-gui.8
Normal 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)
|
|
@ -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>
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
10
policycoreutils/sepolicy/sepolicy.desktop
Normal 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;
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)):
|
||||
|
|
|
@ -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
|
||||
|
|
2833
policycoreutils/sepolicy/sepolicy/gui.py
Normal file
0
policycoreutils/sepolicy/sepolicy/help/__init__.py
Normal file
BIN
policycoreutils/sepolicy/sepolicy/help/booleans.png
Normal file
After Width: | Height: | Size: 71 KiB |
6
policycoreutils/sepolicy/sepolicy/help/booleans.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/booleans_more.png
Normal file
After Width: | Height: | Size: 61 KiB |
4
policycoreutils/sepolicy/sepolicy/help/booleans_more.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/booleans_more_show.png
Normal file
After Width: | Height: | Size: 34 KiB |
|
@ -0,0 +1 @@
|
|||
You are viewing the booleans page for the application domain.
|
BIN
policycoreutils/sepolicy/sepolicy/help/booleans_toggled.png
Normal file
After Width: | Height: | Size: 60 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/file_equiv.png
Normal file
After Width: | Height: | Size: 48 KiB |
20
policycoreutils/sepolicy/sepolicy/help/file_equiv.txt
Normal 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
|
BIN
policycoreutils/sepolicy/sepolicy/help/files_apps.png
Normal file
After Width: | Height: | Size: 80 KiB |
8
policycoreutils/sepolicy/sepolicy/help/files_apps.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/files_exec.png
Normal file
After Width: | Height: | Size: 66 KiB |
4
policycoreutils/sepolicy/sepolicy/help/files_exec.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/files_write.png
Normal file
After Width: | Height: | Size: 76 KiB |
9
policycoreutils/sepolicy/sepolicy/help/files_write.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/lockdown.png
Normal file
After Width: | Height: | Size: 49 KiB |
4
policycoreutils/sepolicy/sepolicy/help/lockdown.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/lockdown_permissive.png
Normal file
After Width: | Height: | Size: 29 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/lockdown_ptrace.png
Normal file
After Width: | Height: | Size: 29 KiB |
14
policycoreutils/sepolicy/sepolicy/help/lockdown_ptrace.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/lockdown_unconfined.png
Normal file
After Width: | Height: | Size: 27 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/login.png
Normal file
After Width: | Height: | Size: 39 KiB |
21
policycoreutils/sepolicy/sepolicy/help/login.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/login_default.png
Normal file
After Width: | Height: | Size: 41 KiB |
8
policycoreutils/sepolicy/sepolicy/help/login_default.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/ports_inbound.png
Normal file
After Width: | Height: | Size: 58 KiB |
6
policycoreutils/sepolicy/sepolicy/help/ports_inbound.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/ports_outbound.png
Normal file
After Width: | Height: | Size: 52 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/start.png
Normal file
After Width: | Height: | Size: 14 KiB |
6
policycoreutils/sepolicy/sepolicy/help/start.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system.png
Normal file
After Width: | Height: | Size: 49 KiB |
1
policycoreutils/sepolicy/sepolicy/help/system.txt
Normal file
|
@ -0,0 +1 @@
|
|||
This screen allows you to view modify the way SELinux is running on your system.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system_boot_mode.png
Normal file
After Width: | Height: | Size: 51 KiB |
13
policycoreutils/sepolicy/sepolicy/help/system_boot_mode.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system_current_mode.png
Normal file
After Width: | Height: | Size: 51 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system_export.png
Normal file
After Width: | Height: | Size: 52 KiB |
6
policycoreutils/sepolicy/sepolicy/help/system_export.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system_policy_type.png
Normal file
After Width: | Height: | Size: 53 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/system_relabel.png
Normal file
After Width: | Height: | Size: 52 KiB |
10
policycoreutils/sepolicy/sepolicy/help/system_relabel.txt
Normal 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
|
BIN
policycoreutils/sepolicy/sepolicy/help/transition_file.png
Normal file
After Width: | Height: | Size: 68 KiB |
15
policycoreutils/sepolicy/sepolicy/help/transition_file.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/transition_from.png
Normal file
After Width: | Height: | Size: 62 KiB |
10
policycoreutils/sepolicy/sepolicy/help/transition_from.txt
Normal 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.
|
After Width: | Height: | Size: 66 KiB |
|
@ -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.
|
After Width: | Height: | Size: 70 KiB |
|
@ -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.
|
After Width: | Height: | Size: 32 KiB |
|
@ -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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/transition_to.png
Normal file
After Width: | Height: | Size: 58 KiB |
10
policycoreutils/sepolicy/sepolicy/help/transition_to.txt
Normal 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.
|
BIN
policycoreutils/sepolicy/sepolicy/help/users.png
Normal file
After Width: | Height: | Size: 56 KiB |
20
policycoreutils/sepolicy/sepolicy/help/users.txt
Normal 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.
|
|
@ -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))
|
||||
|
|
|
@ -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']})
|
||||
|
|
|
@ -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
|
||||
|
|
58
policycoreutils/sepolicy/sepolicy/sedbus.py
Normal 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
|
5633
policycoreutils/sepolicy/sepolicy/sepolicy.glade
Normal file
|
@ -578,3 +578,6 @@ interface(`corenet_relabelto_TEMPLATETYPE_server_packets',`
|
|||
allow $1 TEMPLATETYPE_server_packet_t:packet relabelto;
|
||||
')
|
||||
"""
|
||||
|
||||
te_rules="""
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
119
policycoreutils/sepolicy/sepolicy/templates/test_module.py
Normal 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
|
||||
#
|
||||
|
||||
"""
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
')
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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']})
|
||||
|
|