Daniel J Walsh de82d8
#! /usr/bin/env python
Daniel J Walsh de82d8
# Copyright (C) 2006 Red Hat 
Daniel J Walsh de82d8
# see file 'COPYING' for use and warranty information
Daniel J Walsh de82d8
#
Daniel J Walsh de82d8
# policygentool is a tool for the initial generation of SELinux policy
Daniel J Walsh de82d8
#
Daniel J Walsh de82d8
#    This program is free software; you can redistribute it and/or
Daniel J Walsh de82d8
#    modify it under the terms of the GNU General Public License as
Daniel J Walsh de82d8
#    published by the Free Software Foundation; either version 2 of
Daniel J Walsh de82d8
#    the License, or (at your option) any later version.
Daniel J Walsh de82d8
#
Daniel J Walsh de82d8
#    This program is distributed in the hope that it will be useful,
Daniel J Walsh de82d8
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
Daniel J Walsh de82d8
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Daniel J Walsh de82d8
#    GNU General Public License for more details.
Daniel J Walsh de82d8
#
Daniel J Walsh de82d8
#    You should have received a copy of the GNU General Public License
Daniel J Walsh de82d8
#    along with this program; if not, write to the Free Software
Daniel J Walsh de82d8
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
Daniel J Walsh de82d8
#                                        02111-1307  USA
Daniel J Walsh de82d8
#
Daniel J Walsh de82d8
#  
Daniel J Walsh de82d8
import os, sys, getopt
Daniel J Walsh de82d8
import re
Daniel J Walsh de82d8
Daniel J Walsh de82d8
########################### Interface File #############################
Daniel J Walsh 575aa9
interface="""\
Daniel J Walsh 575aa9
## <summary>policy for TEMPLATETYPE</summary>
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
########################################
Daniel J Walsh 575aa9
## <summary>
Daniel J Walsh 575aa9
##	Execute a domain transition to run TEMPLATETYPE.
Daniel J Walsh 575aa9
## </summary>
Daniel J Walsh 575aa9
## <param name=\"domain\">
jantill eaccf7
## <summary>
Daniel J Walsh 575aa9
##	Domain allowed to transition.
jantill eaccf7
## </summary>
Daniel J Walsh 575aa9
## </param>
Daniel J Walsh 575aa9
#
Daniel J Walsh 575aa9
interface(`TEMPLATETYPE_domtrans',`
Daniel J Walsh 575aa9
	gen_requires(`
Daniel J Walsh 575aa9
		type TEMPLATETYPE_t, TEMPLATETYPE_exec_t;
Daniel J Walsh 575aa9
	')
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
	domain_auto_trans($1,TEMPLATETYPE_exec_t,TEMPLATETYPE_t)
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
	allow $1 TEMPLATETYPE_t:fd use;
Daniel J Walsh 575aa9
	allow TEMPLATETYPE_t $1:fd use;
Daniel J Walsh 575aa9
	allow TEMPLATETYPE_t:$1:fifo_file rw_file_perms;
Daniel J Walsh 575aa9
	allow TEMPLATETYPE_t $1:process sigchld;
Daniel J Walsh 575aa9
')
Daniel J Walsh 575aa9
"""
Daniel J Walsh de82d8
Daniel J Walsh de82d8
########################### Type Enforcement File #############################
Daniel J Walsh 575aa9
te="""\
Daniel J Walsh 575aa9
policy_module(TEMPLATETYPE,1.0.0)
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
########################################
Daniel J Walsh 575aa9
#
Daniel J Walsh 575aa9
# Declarations
Daniel J Walsh 575aa9
#
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
type TEMPLATETYPE_t;
Daniel J Walsh 575aa9
type TEMPLATETYPE_exec_t;
Daniel J Walsh 575aa9
domain_type(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
init_daemon_domain(TEMPLATETYPE_t, TEMPLATETYPE_exec_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_pidfile="""
Daniel J Walsh 575aa9
# pid files
Daniel J Walsh 575aa9
type TEMPLATETYPE_var_run_t;
Daniel J Walsh 575aa9
files_pid_file(TEMPLATETYPE_var_run_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_logfile="""
Daniel J Walsh 575aa9
# log files
Daniel J Walsh 575aa9
type TEMPLATETYPE_var_log_t;
Daniel J Walsh 575aa9
logging_log_file(TEMPLATETYPE_var_log_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_libfile="""
Daniel J Walsh 575aa9
# var/lib files
Daniel J Walsh 575aa9
type TEMPLATETYPE_var_lib_t;
Daniel J Walsh 575aa9
files_type(TEMPLATETYPE_var_lib_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_sep="""
Daniel J Walsh 575aa9
########################################
Daniel J Walsh 575aa9
#
Daniel J Walsh 575aa9
# TEMPLATETYPE local policy
Daniel J Walsh 575aa9
#
Daniel J Walsh 575aa9
# Check in /etc/selinux/refpolicy/include for macros to use instead of allow rules.
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
# Some common macros (you might be able to remove some)
Daniel J Walsh 575aa9
files_read_etc_files(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
libs_use_ld_so(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
libs_use_shared_libs(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
miscfiles_read_localization(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
## internal communication is often done using fifo and unix sockets.
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t self:fifo_file { read write };
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t self:unix_stream_socket create_stream_socket_perms;
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_pidfile2="""
Daniel J Walsh 575aa9
# pid file
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_run_t:file manage_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_run_t:sock_file manage_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_run_t:dir rw_dir_perms;
Daniel J Walsh 575aa9
files_pid_filetrans(TEMPLATETYPE_t,TEMPLATETYPE_var_run_t, { file sock_file })
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_logfile2="""
Daniel J Walsh 575aa9
# log files
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_log_t:file create_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_log_t:sock_file create_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_log_t:dir { rw_dir_perms setattr };
Daniel J Walsh 575aa9
logging_log_filetrans(TEMPLATETYPE_t,TEMPLATETYPE_var_log_t,{ sock_file file dir })
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_libfile2="""
Daniel J Walsh 575aa9
# var/lib files for TEMPLATETYPE
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_lib_t:file create_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_lib_t:sock_file create_file_perms;
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t TEMPLATETYPE_var_lib_t:dir create_dir_perms;
Daniel J Walsh 575aa9
files_var_filetrans(TEMPLATETYPE_t,TEMPLATETYPE_var_lib_t,{ file dir sock_file })
Daniel J Walsh 575aa9
files_var_lib_filetrans(TEMPLATETYPE_t,TEMPLATETYPE_var_lib_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_network2="""
Daniel J Walsh 575aa9
## Networking basics (adjust to your needs!)
Daniel J Walsh 575aa9
sysnet_dns_name_resolve(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
corenet_tcp_sendrecv_all_if(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
corenet_tcp_sendrecv_all_nodes(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
corenet_tcp_sendrecv_all_ports(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
corenet_non_ipsec_sendrecv(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
corenet_tcp_connect_http_port(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
#corenet_tcp_connect_all_ports(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
## if it is a network daemon, consider these:
Daniel J Walsh 575aa9
#corenet_tcp_bind_all_ports(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
#corenet_tcp_bind_all_nodes(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
allow TEMPLATETYPE_t self:tcp_socket { listen accept };
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
te_initsc2="""
Daniel J Walsh 575aa9
# Init script handling
Daniel J Walsh 414d6d
init_use_fds(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
init_use_script_ptys(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
domain_use_interactive_fds(TEMPLATETYPE_t)
Daniel J Walsh 575aa9
"""
Daniel J Walsh de82d8
Daniel J Walsh de82d8
########################### File Context ##################################
Daniel J Walsh 575aa9
fc="""\
Daniel J Walsh 575aa9
# TEMPLATETYPE executable will have:
Daniel J Walsh 575aa9
# label: system_u:object_r:TEMPLATETYPE_exec_t
Daniel J Walsh 575aa9
# MLS sensitivity: s0
Daniel J Walsh 575aa9
# MCS categories: <none>
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
EXECUTABLE		--	gen_context(system_u:object_r:TEMPLATETYPE_exec_t,s0)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
fc_pidfile="""\
Daniel J Walsh 575aa9
FILENAME			gen_context(system_u:object_r:TEMPLATETYPE_var_run_t,s0)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
fc_logfile="""\
Daniel J Walsh 575aa9
FILENAME			gen_context(system_u:object_r:TEMPLATETYPE_var_log_t,s0)
Daniel J Walsh 575aa9
"""
Daniel J Walsh 575aa9
fc_libfile="""\
Daniel J Walsh 575aa9
FILENAME			gen_context(system_u:object_r:TEMPLATETYPE_var_lib_t,s0)
Daniel J Walsh 575aa9
"""
Daniel J Walsh de82d8
def errorExit(error):
Daniel J Walsh de82d8
	sys.stderr.write("%s: " % sys.argv[0])
Daniel J Walsh de82d8
	sys.stderr.write("%s\n" % error)
Daniel J Walsh de82d8
	sys.stderr.flush()
Daniel J Walsh de82d8
	sys.exit(1)
Daniel J Walsh de82d8
Daniel J Walsh de82d8
Daniel J Walsh 575aa9
def write_te_file(module, pidfile, logfile, libfile, network, initsc):
Daniel J Walsh de82d8
	file="%s.te" % module
Daniel J Walsh de82d8
	newte=re.sub("TEMPLATETYPE", module, te)
Daniel J Walsh 575aa9
	if pidfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_pidfile)
Daniel J Walsh 575aa9
	if logfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_logfile)
Daniel J Walsh 575aa9
	if libfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_libfile)
Daniel J Walsh 575aa9
	newte= newte + re.sub("TEMPLATETYPE", module, te_sep)
Daniel J Walsh 575aa9
	if pidfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_pidfile2)
Daniel J Walsh 575aa9
	if logfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_logfile2)
Daniel J Walsh 575aa9
	if libfile:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_libfile2)
Daniel J Walsh 575aa9
	if network:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_network2)
Daniel J Walsh 575aa9
	if initsc:
Daniel J Walsh 575aa9
		newte= newte + re.sub("TEMPLATETYPE", module, te_initsc2)
Daniel J Walsh de82d8
	if os.path.exists(file):
Daniel J Walsh de82d8
		errorExit("%s already exists" % file)
Daniel J Walsh de82d8
	fd = open(file, 'w')
Daniel J Walsh de82d8
	fd.write(newte)
Daniel J Walsh de82d8
	fd.close()
Daniel J Walsh de82d8
Daniel J Walsh de82d8
def write_if_file(module):
Daniel J Walsh de82d8
	file="%s.if" % module
Daniel J Walsh de82d8
	newif=re.sub("TEMPLATETYPE", module, interface)
Daniel J Walsh de82d8
	if os.path.exists(file):
Daniel J Walsh de82d8
		errorExit("%s already exists" % file)
Daniel J Walsh de82d8
	fd = open(file, 'w')
Daniel J Walsh de82d8
	fd.write(newif)
Daniel J Walsh de82d8
	fd.close()
Daniel J Walsh de82d8
Daniel J Walsh 575aa9
def write_fc_file(module, executable, pidfile, logfile, libfile):
Daniel J Walsh de82d8
	file="%s.fc" % module
Daniel J Walsh 575aa9
	temp=re.sub("TEMPLATETYPE", module, fc)
Daniel J Walsh 575aa9
	newfc=re.sub("EXECUTABLE", executable, temp)
Daniel J Walsh 575aa9
	if pidfile:
Daniel J Walsh 575aa9
		temp=re.sub("TEMPLATETYPE", module, fc_pidfile)
Daniel J Walsh 575aa9
		newfc=newfc + re.sub("FILENAME", pidfile, temp)
Daniel J Walsh 575aa9
	if logfile:
Daniel J Walsh 575aa9
		temp=re.sub("TEMPLATETYPE", module, fc_logfile)
Daniel J Walsh 575aa9
		newfc=newfc + re.sub("FILENAME", logfile, temp)
Daniel J Walsh 575aa9
	if libfile:
Daniel J Walsh 575aa9
		temp=re.sub("TEMPLATETYPE", module, fc_libfile)
Daniel J Walsh 575aa9
		newfc=newfc + re.sub("FILENAME", libfile, temp)
Daniel J Walsh de82d8
	if os.path.exists(file):
Daniel J Walsh de82d8
		errorExit("%s already exists" % file)
Daniel J Walsh de82d8
	fd = open(file, 'w')
Daniel J Walsh de82d8
	fd.write(newfc)
Daniel J Walsh de82d8
	fd.close()
Daniel J Walsh de82d8
Daniel J Walsh 575aa9
def gen_policy(module, executable, pidfile, logfile, libfile, initsc, network):
Daniel J Walsh 575aa9
	write_te_file(module, pidfile, logfile, libfile, initsc, network)
Daniel J Walsh de82d8
	write_if_file(module)
Daniel J Walsh 575aa9
	write_fc_file(module, executable, pidfile, logfile, libfile)
Daniel J Walsh de82d8
	
Daniel J Walsh de82d8
if __name__ == '__main__':
Daniel J Walsh de82d8
	def usage(message = ""):
Daniel J Walsh de82d8
		print '%s ModuleName Executable' % sys.argv[0]
Daniel J Walsh de82d8
		sys.exit(1)
Daniel J Walsh de82d8
		
Daniel J Walsh de82d8
	if len(sys.argv) != 3:
Daniel J Walsh de82d8
		usage()
Daniel J Walsh de82d8
Daniel J Walsh 575aa9
	print """\n
Daniel J Walsh 575aa9
This tool generate three files for policy development, A Type Enforcement (te)
Daniel J Walsh 575aa9
file, a File Context (fc), and a Interface File(if).  Most of the policy rules
Daniel J Walsh 575aa9
will be written in the te file.  Use the File Context file to associate file
Daniel J Walsh 575aa9
paths with security context.  Use the interface rules to allow other protected
Daniel J Walsh 575aa9
domains to interact with the newly defined domains.
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
After generating these files use the /usr/share/selinux/devel/Makefile to
Daniel J Walsh 575aa9
compile your policy package.  Then use the semodule tool to load it.
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
# /usr/share/selinux/devel/policygentool myapp /usr/bin/myapp
Daniel J Walsh 575aa9
# make -f /usr/share/selinux/devel/Makefile
Daniel J Walsh 575aa9
# semodule -l myapp.pp
Daniel J Walsh 575aa9
# restorecon -R -v /usr/bin/myapp "all files defined in myapp.fc"
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
Now you can turn on permissive mode, start your application and avc messages
Daniel J Walsh 575aa9
will be generated.  You can use audit2allow to help translate the avc messages
Daniel J Walsh 575aa9
into policy.
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
# setenforce 0
Daniel J Walsh 575aa9
# service myapp start
Daniel J Walsh 575aa9
# audit2allow -R -i /var/log/audit/audit.log
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
Return to continue:"""
Daniel J Walsh 575aa9
        sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
	print 'If the module uses pidfiles, what is the pidfile called?'
Daniel J Walsh 575aa9
	pidfile = sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
	if pidfile == "":
Daniel J Walsh 575aa9
		pidfile = None
Daniel J Walsh 575aa9
	print 'If the module uses logfiles, where are they stored?'
Daniel J Walsh 575aa9
	logfile = sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
	if logfile == "":
Daniel J Walsh 575aa9
		logfile = None
Daniel J Walsh 575aa9
	print 'If the module has var/lib files, where are they stored?'
Daniel J Walsh 575aa9
	libfile = sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
	if libfile == "":
Daniel J Walsh 575aa9
		libfile = None
Daniel J Walsh 575aa9
	print 'Does the module have a init script? [yN]'
Daniel J Walsh 575aa9
	initsc = sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
	if initsc == "" or initsc == "n" or initsc == "N":
Daniel J Walsh 575aa9
		initsc = False
Daniel J Walsh 575aa9
	elif initsc == "y" or initsc == "Y":
Daniel J Walsh 575aa9
		initsc = True
Daniel J Walsh 575aa9
	else:
Daniel J Walsh 575aa9
		raise "Please answer with 'y' or 'n'!"
Daniel J Walsh 575aa9
	print 'Does the module use the network? [yN]'
Daniel J Walsh 575aa9
	network = sys.stdin.readline().rstrip()
Daniel J Walsh 575aa9
	if network == "" or network == "n" or network == "N":
Daniel J Walsh 575aa9
		network = False
Daniel J Walsh 575aa9
	elif network == "y" or network == "Y":
Daniel J Walsh 575aa9
		network = True
Daniel J Walsh 575aa9
	else:
Daniel J Walsh 575aa9
		raise "Please answer with 'y' or 'n'!"
Daniel J Walsh 575aa9
Daniel J Walsh 575aa9
	gen_policy(
Daniel J Walsh 575aa9
		module=sys.argv[1],
Daniel J Walsh 575aa9
		executable=sys.argv[2],
Daniel J Walsh 575aa9
		pidfile=pidfile,
Daniel J Walsh 575aa9
		logfile=logfile,
Daniel J Walsh 575aa9
		libfile=libfile,
Daniel J Walsh 575aa9
		initsc=initsc,
Daniel J Walsh 575aa9
		network=network
Daniel J Walsh 575aa9
	)
Daniel J Walsh de82d8
Daniel J Walsh de82d8