#!/bin/sh
#############################################
#This script was written by Shintao Fujiwara
#segatex SELinux tool.
#Copyright (C) 2007-2008 Shintaro Fujiwara 
#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
#############################################

MODULENAME_FLAG=FALSE
EXECUTABLE_FLAG=FALSE
PIDFILE_FLAG=FALSE
LOGFILE_FLAG=FALSE
VARLIBFILE_FLAG=FALSE
INITSCRIPT_FLAG=FALSE
NETWORK_FLAG=FALSE

MODULENAME=
EXECUTABLE_PATH=
PIDFILE_PATH=
LOGFILE_PATH=
VARLIBFILE_PATH=
INITSCRIPT=
NETWORK=
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 -i initscript{on|off} -n network{on|off}
	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_basic
File_context_basic(){
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)

" > $TMPDIR$FILECONTEXTFILE
}

#add file_context_file_pidfile
File_context_pidfile(){
echo "
$PIDFILE_PATH                  gen_context(system_u:object_r:$MODULENAME"_var_run_t",s0)
" >> $TMPDIR$FILECONTEXTFILE
}

#add file_context_file_logfile
File_context_logfile(){
echo "
$LOGFILE_PATH                  gen_context(system_u:object_r:$MODULENAME"_var_log_t",s0)
" >> $TMPDIR$FILECONTEXTFILE
}

#add file_context_file_varlibfile
File_context_varlibfile(){
echo "
$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:i:n: 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;;
		i)  INITSCRIPT_FLAG=TRUE
		    	INITSCRIPT=$OPTARG;;
		n)  NETWORK_FLAG=TRUE
		    	NETWORK=$OPTARG;;
		\?) Usage
		    exit 1 ;;
	esac
done
shift `expr $OPTIND - 1`
############### Now generate files ###########################

TYPEENFORCEMENTFILE=$MODULENAME".te"
FILECONTEXTFILE=$MODULENAME".fc"
INTERFACEFILE=$MODULENAME".if"
Basic_policy
if [ "$VARLIBFILE_PATH" != "" ]; then
	Basic_varlib_policy
fi
if [ "$LOGFILE_PATH" != "" ]; then
	Basic_log_policy
fi
if [ "$PIDFILE_PATH" != "" ]; then
	Basic_pid_policy
fi
Local_policy
if [ "$VARLIB_FILE" != "" ]; then
	Local_varlib_policy
fi
if [ "$LOGFILE_PATH" != "" ]; then
	Local_log_policy
fi
if [ "$PIDFILE_PATH" != "" ]; then
	Local_pid_policy
fi
if [ "$NETWORK" = "on" ]; then
	Local_network_policy
fi
if [ "$INITSCRIPT" = "on" ]; then
	Local_init_script_policy
fi

File_context_basic
if [ "$PIDFILE_PATH" != "" ]; then
	File_context_pidfile
fi
if [ "$LOGFILE_PATH" != "" ]; then
	File_context_logfile
fi
if [ "$VARLIBFILE_PATH" != "" ]; then
	File_context_varlibfile
fi

Interface

exit 0

