#!/bin/sh

MODULENAME_FLAG=FALSE
EXECUTABLE_FLAG=FALSE
PIDFILE_FLAG=FALSE
LOGFILE_FLAG=FALSE
VARLIBFILE_FLAG=FALSE

MODULENAME=
EXECUTABLE_PATH=
PIDFILE_PATH=
LOGFILE_PATH=
VARLIBFILE_PATH=
TYPEENFORCEMENTFILE=
FILECONTEXTFILE=
INTERFACEFILE=
TMPDIR="/root/segatex/"
OPT=

#error message
Usage() {
	cat 1>&2 <<- EOF
		Usage: $0 -m modulename -e executable -p pidfile -l logfile -v varlibfile
	EOF
}

#add basic_policy
Basic_policy(){
echo "
policy_module($MODULENAME,1.0.0)

########################################
#
# Declarations
#

type $MODULENAME"_t";
type $MODULENAME"_exec_t";
domain_type($MODULENAME"_t")
init_daemon_domain($MODULENAME"_t", $MODULENAME"_exec_t")
" > $TMPDIR$TYPEENFORCEMENTFILE
}

#add basic_varlib_policy
Basic_varlib_policy(){
echo "
# var/lib files
type $MODULENAME"_var_lib_t";
files_type($MODULENAME"_var_lib_t")
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add basic_log_policy
Basic_log_policy(){
echo "
# log files
type $MODULENAME"_var_log_t";
logging_log_file($MODULENAME"_var_log_t")
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add basic_pid_policy
Basic_pid_policy(){
echo "
# pid files
type $MODULENAME"_var_run_t";
files_pid_file($MODULENAME"_var_run_t")
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add local_policy
Local_policy(){
echo "
########################################
#
# $MODULENAME local policy
#
# Check in /etc/selinux/refpolicy/include for macros to use instead of allow rules.

# Some common macros (you might be able to remove some)
files_read_etc_files($MODULENAME"_t")
libs_use_ld_so($MODULENAME"_t")
libs_use_shared_libs($MODULENAME"_t")
miscfiles_read_localization($MODULENAME"_t")
## internal communication is often done using fifo and unix sockets.
allow $MODULENAME"_t" self:fifo_file { read write };
allow $MODULENAME"_t" self:unix_stream_socket create_stream_socket_perms;
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add local_varlib_policy
Local_varlib_policy(){
echo "
# var/lib files for $MODULENAME
allow $MODULENAME"_t" $MODULENAME"_var_lib_t":file create_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_lib_t":sock_file create_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_lib_t":dir create_dir_perms;
files_var_lib_filetrans($MODULENAME"_t",$MODULENAME"_var_lib_t", { file dir sock_file })
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add local_log_policy
Local_log_policy(){
echo "
# log files
allow $MODULENAME"_t" $MODULENAME"_var_log_t":file create_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_log_t":sock_file create_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_log_t":dir { rw_dir_perms setattr };
logging_log_filetrans($MODULENAME"_t",$MODULENAME"_var_log_t",{ sock_file file dir })
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add local_pid_policy
Local_pid_policy(){
echo "
# pid file
allow $MODULENAME"_t" $MODULENAME"_var_run_t":file manage_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_run_t":sock_file manage_file_perms;
allow $MODULENAME"_t" $MODULENAME"_var_run_t":dir rw_dir_perms;
files_pid_filetrans($MODULENAME"_t",$MODULENAME"_var_run_t", { file sock_file })
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add local_network_policy
Local_network_policy(){
echo "
## Networking basics (adjust to your needs!)
sysnet_dns_name_resolve($MODULENAME"_t")
corenet_tcp_sendrecv_all_if($MODULENAME"_t")
corenet_tcp_sendrecv_all_nodes($MODULENAME"_t")
corenet_tcp_sendrecv_all_ports($MODULENAME"_t")
corenet_non_ipsec_sendrecv($MODULENAME"_t")
corenet_tcp_connect_http_port($MODULENAME"_t")
#corenet_tcp_connect_all_ports($MODULENAME"_t")
## if it is a network daemon, consider these:
#corenet_tcp_bind_all_ports($MODULENAME"_t")
#corenet_tcp_bind_all_nodes($MODULENAME"_t")
allow $MODULENAME"_t" self:tcp_socket { listen accept };
" >> $TMPDIR$TYPEENFORCEMENTFILE
}


#add local_init_script_policy
Local_init_script_policy(){
echo "
# Init script handling
init_use_fds($MODULENAME"_t")
init_use_script_ptys($MODULENAME"_t")
domain_use_interactive_fds($MODULENAME"_t")
" >> $TMPDIR$TYPEENFORCEMENTFILE
}

#add file_context_file
File_context(){
echo "
# $MODULENAME executable will have:
# label: system_u:object_r:$MODULENAME"_exec_t"
# MLS sensitivity: s0
# MCS categories: <none>

$EXECUTABLE_PATH         --      gen_context(system_u:object_r:$MODULENAME"_exec_t",s0)
$PIDFILE_PATH                  gen_context(system_u:object_r:$MODULENAME"_var_run_t",s0)
$LOGFILE_PATH                  gen_context(system_u:object_r:$MODULENAME"_var_log_t",s0)
$VARLIBFILE_PATH                    gen_context(system_u:object_r:$MODULENAME"_var_lib_t",s0)

" > $TMPDIR$FILECONTEXTFILE
}

#add interface_file
Interface(){
echo "
## <summary>policy for $MODULENAME</summary>

########################################
## <summary>
##      Execute a domain transition to run $MODULENAME.
## </summary>
## <param name="domain">
## <summary>
##      Domain allowed to transition.
## </summary>
## </param>
#
interface(\`$MODULENAME"_domtrans"',\`
	gen_require(\`
		type $MODULENAME"_t", $MODULENAME"_exec_t";
	')

	domain_auto_trans(\$"1",$MODULENAME"_exec_t",$MODULENAME"_t")

	allow $MODULENAME"_t" $1:fd use;
	allow $MODULENAME"_t" $1:fifo_file rw_file_perms;
	allow $MODULENAME"_t" $1:process sigchld;
')

" > $TMPDIR$INTERFACEFILE
}

while getopts m:e:p:l:v: OPT
do
	case $OPT in
		m)  MODULENAME_FLAG=TRUE
		    	MODULENAME=$OPTARG;;
		e)  EXECUTABLE_FLAG=TRUE
		    	EXECUTABLE_PATH=$OPTARG;;
		p)  PIDFILE_FLAG=TRUE
		    	PIDFILE_PATH=$OPTARG;;
		l)  LOGFILE_FLAG=TRUE
		    	LOGFILE_PATH=$OPTARG;;
		v)  VARLIBFILE_FLAG=TRUE
		    	VARLIBFILE_PATH=$OPTARG;;
		\?) Usage
		    exit 1 ;;
	esac
done
shift `expr $OPTIND - 1`
############### Now generate files ###########################

TYPEENFORCEMENTFILE=$MODULENAME".te"
FILECONTEXTFILE=$MODULENAME".fc"
INTERFACEFILE=$MODULENAME".if"
Basic_policy
Basic_varlib_policy
Basic_log_policy
Basic_pid_policy
Local_policy
Local_varlib_policy
Local_log_policy
Local_pid_policy
Local_network_policy
Local_init_script_policy

File_context

Interface

exit 0

