#####################################
#SELinux security policy for Airavat
#Indrajit Roy
#####################################

policy_module(airavat,1.0.0)
gen_require(`
                type user_t, user_devpts_t, user_home_t;
		attribute file_type, exec_type, userdomain;
       ')

########################################
#
# Declarations for Untrusted Domain
########################################

type airavatU_t;
type airavatU_exec_t, file_type, exec_type;
application_domain(airavatU_t, airavatU_exec_t)
role system_r types airavatU_t;
role user_r types airavatU_t;
role airavatuser_r types airavatU_t;

#Allow any user to transition to the untrusted domain
domain_auto_trans(userdomain, airavatU_exec_t, airavatU_t);
allow user_t self:process setexec;
domain_auto_trans(airavatuser_t, airavatU_exec_t, airavatU_t);


########################################
#
# airavat-Untrusted local policy
########################################

## internal communication is often done using fifo and unix sockets.
# Don't allow creation of pipes/sockets amongst untrusted processed
#allow airavatU_t self:fifo_file rw_file_perms;
#allow airavatU_t self:unix_stream_socket create_stream_socket_perms;

#However allow the untrusted code to talk to the trusted code
#Ofcourse, it means the trusted code should be careful about what it reads
#allow airavatU_t airavatT_t:fifo_file rw_file_perms;
allow airavatU_t airavatT_t:unix_stream_socket create_stream_socket_perms;
allow airavatU_t airavatT_pipe_r_t:fifo_file {open read};
allow airavatU_t airavatT_pipe_w_t:fifo_file {open write};


#Allow the untrusted code to read contents of trusted but non-secret files
#Ths will be used for initialization
allow airavatU_t airavatT_notsec_t:file {open read getattr};
#allow domain airavatT_notsec_t:file {open read};


libs_use_ld_so(airavatU_t)
libs_use_shared_libs(airavatU_t)

#This is unnecessary given that we are using domtrans
optional_policy(`
	gen_require(`
		type unconfined_t;
		role unconfined_r;
	')

	airavatU_run(unconfined_t, unconfined_r)
')

########################################
#
# Declarations for airavat trusted domain
########################################

type airavatT_t;
type airavatT_exec_t, file_type, exec_type;
application_domain(airavatT_t, airavatT_exec_t)
role system_r types airavatT_t;
role airavatuser_r types airavatT_t;

#TODO: Allow only trusted user to transition to the untrusted domain
domain_auto_trans(airavatuser_t, airavatT_exec_t, airavatT_t);
allow airavatuser_t self:process setexec;

#permissive airavatT_t;

#The label for all trusted data, including those that may contain secrets
#These files should not be readable or writable by anyone else except the
#trusted process
type airavatT_rw_t;
files_type(airavatT_rw_t)

#The type for all trusted files which do NOT contain secrets
#This type may be used for config. files.
#Untrusted code may read the files but not write to them
type airavatT_notsec_t;
files_type(airavatT_notsec_t)

#Create a trusted type that is used to label pipes
#This type is the only be read and written by untrusted code
#airavatT_pipe_r_t: untrusted code can only read this pipe
#airavatT_pipe_w_t: untrusted code can only write to this pipe

type airavatT_pipe_r_t;
files_type(airavatT_pipe_r_t)
type airavatT_pipe_w_t;
files_type(airavatT_pipe_w_t)


########################################
#
# airavatT local policy
########################################

## internal communication is often done using fifo and unix sockets.
allow airavatT_t self:fifo_file rw_file_perms;
allow airavatT_t self:unix_stream_socket create_stream_socket_perms;

#Allow printing to the terminal
allow airavatT_t airavatuser_t:process sigchld;
allow airavatT_t user_devpts_t:chr_file rw_file_perms;

#For now, trusted domain can write to user home directories
allow airavatT_t user_home_t:dir *;
allow airavatT_t user_home_t:file *;

files_read_etc_files(airavatT_t)

libs_use_ld_so(airavatT_t)
libs_use_shared_libs(airavatT_t)

miscfiles_read_localization(airavatT_t)


allow airavatT_t airavatT_rw_t:file *;
allow airavatT_t airavatT_rw_t:dir *;

allow airavatT_t airavatT_notsec_t:file manage_file_perms;
allow airavatT_t airavatT_notsec_t:dir create_dir_perms;

allow airavatT_t airavatT_pipe_r_t:fifo_file *;
allow airavatT_t airavatT_pipe_w_t:fifo_file *;

sysnet_dns_name_resolve(airavatT_t)
corenet_all_recvfrom_unlabeled(airavatT_t)

allow airavatT_t self:tcp_socket create_stream_socket_perms;
corenet_tcp_sendrecv_all_if(airavatT_t)
corenet_tcp_sendrecv_all_nodes(airavatT_t)
corenet_tcp_sendrecv_all_ports(airavatT_t)
corenet_tcp_bind_all_nodes(airavatT_t)
corenet_tcp_bind_all_unreserved_ports(airavatT_t)
corenet_tcp_connect_all_ports(airavatT_t)

allow airavatT_t self:udp_socket { create_socket_perms listen };
corenet_udp_sendrecv_all_if(airavatT_t)
corenet_udp_sendrecv_all_nodes(airavatT_t)
corenet_udp_sendrecv_all_ports(airavatT_t)
corenet_udp_bind_all_nodes(airavatT_t)
corenet_udp_bind_all_unreserved_ports(airavatT_t)

optional_policy(`
	gen_require(`
		type unconfined_t;
		role unconfined_r;
	')

	airavatT_run(unconfined_t, unconfined_r)
')

########################################
# Declarations for the airavat user
########################################
role airavatuser_r;
#userdom_restricted_user_template(airavatuser)
userdom_unpriv_user_template(airavatuser)

#TODO:Create the user. The following line does not compile.
#Instead use(on the command line as root):
#semanage user -a -L s0 -r s0-s0 -R airavatuser_r -P airavatuser airavatuser_u

#gen_user(airavatuser_u,airavatuser, airavatuser_r, s0, s0)

########################################
# airavatuser local policy
########################################

#Allow the user to listen and send at all ports
sysnet_dns_name_resolve(airavatuser_t)
corenet_all_recvfrom_unlabeled(airavatuser_t)

allow airavatuser_t self:tcp_socket create_stream_socket_perms;
corenet_tcp_sendrecv_all_if(airavatuser_t)
corenet_tcp_sendrecv_all_nodes(airavatuser_t)
corenet_tcp_sendrecv_all_ports(airavatuser_t)
corenet_tcp_bind_all_nodes(airavatuser_t)
corenet_tcp_bind_all_ports(airavatuser_t)
corenet_tcp_bind_all_unreserved_ports(airavatuser_t)
corenet_tcp_connect_all_ports(airavatuser_t)

allow airavatuser_t self:udp_socket { create_socket_perms listen };
corenet_udp_sendrecv_all_if(airavatuser_t)
corenet_udp_sendrecv_all_nodes(airavatuser_t)
corenet_udp_sendrecv_all_ports(airavatuser_t)
corenet_udp_bind_all_nodes(airavatuser_t)
corenet_udp_bind_all_ports(airavatuser_t)
corenet_udp_bind_all_unreserved_ports(airavatuser_t)

allow airavatuser_t self:netlink_audit_socket *;



