Chris PeBenito 17de1b7
#!/usr/bin/python
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
# Author: Chris PeBenito <cpebenito@tresys.com>
Chris PeBenito 17de1b7
#
Chris PeBenito 17de1b7
# Copyright (C) 2006 Tresys Technology, LLC
Chris PeBenito 17de1b7
#      This program is free software; you can redistribute it and/or modify
Chris PeBenito 17de1b7
#      it under the terms of the GNU General Public License as published by
Chris PeBenito 17de1b7
#      the Free Software Foundation, version 2.
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
import sys,string,getopt,re
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
NETPORT = re.compile("^network_port\(\s*\w+\s*(\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*)+\s*\)\s*(#|$)")
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
DEFAULT_INPUT_PACKET = "server_packet_t"
Chris PeBenito 17de1b7
DEFAULT_OUTPUT_PACKET = "client_packet_t"
Chris PeBenito 17de1b7
DEFAULT_MCS = "s0"
Chris PeBenito 17de1b7
DEFAULT_MLS = "s0"
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
PACKET_INPUT = "_server_packet_t"
Chris PeBenito 17de1b7
PACKET_OUTPUT = "_client_packet_t"
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
class Port:
Chris PeBenito 17de1b7
	def __init__(self, proto, num, mls_sens, mcs_cats=""):
Chris PeBenito 17de1b7
		# protocol of the port
Chris PeBenito 17de1b7
		self.proto = proto
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		# port number
Chris PeBenito 17de1b7
		self.num = num
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		# MLS sensitivity
Chris PeBenito 17de1b7
		self.mls_sens = mls_sens
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		# MCS categories
Chris PeBenito 17de1b7
		# not currently supported, so we always get s0
Chris PeBenito 17de1b7
		self.mcs_cats = DEFAULT_MCS
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
class Packet:
Chris PeBenito 17de1b7
	def __init__(self, prefix, ports):
Chris PeBenito 17de1b7
		# prefix
Chris PeBenito 17de1b7
		self.prefix = prefix
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		# A list of Ports
Chris PeBenito 17de1b7
		self.ports = ports
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
def print_input_rules(packets,mls,mcs):
Chris PeBenito 5a7c06f
	line = "base -A selinux_new_input -j SECMARK --selctx system_u:object_r:"+DEFAULT_INPUT_PACKET
Chris PeBenito 17de1b7
	if mls:
Chris PeBenito 17de1b7
		line += ":"+DEFAULT_MLS
Chris PeBenito 17de1b7
	elif mcs:
Chris PeBenito 17de1b7
		line += ":"+DEFAULT_MCS
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	print line
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	for i in packets:
Chris PeBenito 17de1b7
		for j in i.ports:
Chris PeBenito 5a7c06f
			line="base -A selinux_new_input -p "+j.proto+" --dport "+j.num+" -j SECMARK --selctx system_u:object_r:"+i.prefix+PACKET_INPUT
Chris PeBenito 17de1b7
			if mls:
Chris PeBenito 17de1b7
				line += ":"+j.mls_sens
Chris PeBenito 17de1b7
			elif mcs:
Chris PeBenito 17de1b7
				line += ":"+j.mcs_cats
Chris PeBenito 17de1b7
			print line
Chris PeBenito 17de1b7
Chris PeBenito 5a7c06f
	print "post -A selinux_new_input -j CONNSECMARK --save"
Chris PeBenito 5a7c06f
	print "post -A selinux_new_input -j RETURN"
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
def print_output_rules(packets,mls,mcs):
Chris PeBenito 5a7c06f
	line = "base -A selinux_new_output -j SECMARK --selctx system_u:object_r:"+DEFAULT_OUTPUT_PACKET
Chris PeBenito 17de1b7
	if mls:
Chris PeBenito 17de1b7
		line += ":"+DEFAULT_MLS
Chris PeBenito 17de1b7
	elif mcs:
Chris PeBenito 17de1b7
		line += ":"+DEFAULT_MCS
Chris PeBenito 17de1b7
	print line
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	for i in packets:
Chris PeBenito 17de1b7
		for j in i.ports:
Chris PeBenito 5a7c06f
			line = "base -A selinux_new_output -p "+j.proto+" --dport "+j.num+" -j SECMARK --selctx system_u:object_r:"+i.prefix+PACKET_OUTPUT
Chris PeBenito 17de1b7
			if mls:
Chris PeBenito 17de1b7
				line += ":"+j.mls_sens
Chris PeBenito 17de1b7
			elif mcs:
Chris PeBenito 17de1b7
				line += ":"+j.mcs_cats
Chris PeBenito 17de1b7
			print line
Chris PeBenito 17de1b7
Chris PeBenito 5a7c06f
	print "post -A selinux_new_output -j CONNSECMARK --save"
Chris PeBenito 5a7c06f
	print "post -A selinux_new_output -j RETURN"
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
def parse_corenet(file_name):
Chris PeBenito 17de1b7
	packets = []
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	corenet_te_in = open(file_name, "r")
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	while True:
Chris PeBenito 17de1b7
		corenet_line = corenet_te_in.readline()
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		# If EOF has been reached:
Chris PeBenito 17de1b7
		if not corenet_line:
Chris PeBenito 17de1b7
			break
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
		if NETPORT.match(corenet_line):
Chris PeBenito 17de1b7
			corenet_line = corenet_line.strip();
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
			# parse out the parameters
Chris PeBenito 17de1b7
			openparen = string.find(corenet_line,'(')+1
Chris PeBenito 17de1b7
			closeparen = string.find(corenet_line,')',openparen)
Chris PeBenito 17de1b7
			parms = re.split('\W+',corenet_line[openparen:closeparen])
Chris PeBenito 17de1b7
			name = parms[0]
Chris PeBenito 17de1b7
			del parms[0];
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
			ports = []
Chris PeBenito 17de1b7
			while len(parms) > 0:
Chris PeBenito 17de1b7
				# add a port combination.
Chris PeBenito 17de1b7
				ports.append(Port(parms[0],parms[1],parms[2]))
Chris PeBenito 17de1b7
				del parms[:3]
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
			packets.append(Packet(name,ports))
Chris PeBenito 17de1b7
		
Chris PeBenito 17de1b7
	corenet_te_in.close()
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
	return packets
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
def print_netfilter_config(packets,mls,mcs):
Chris PeBenito 5a7c06f
	print "pre *mangle"
Chris PeBenito 5a7c06f
	print "pre :PREROUTING ACCEPT [0:0]"
Chris PeBenito 5a7c06f
	print "pre :INPUT ACCEPT [0:0]"
Chris PeBenito 5a7c06f
	print "pre :FORWARD ACCEPT [0:0]"
Chris PeBenito 5a7c06f
	print "pre :OUTPUT ACCEPT [0:0]"
Chris PeBenito 5a7c06f
	print "pre :POSTROUTING ACCEPT [0:0]"
Chris PeBenito 5a7c06f
	print "pre :selinux_input - [0:0]"
Chris PeBenito 5a7c06f
	print "pre :selinux_output - [0:0]"
Chris PeBenito 5a7c06f
	print "pre :selinux_new_input - [0:0]"
Chris PeBenito 5a7c06f
	print "pre :selinux_new_output - [0:0]"
Chris PeBenito 5a7c06f
	print "pre -A INPUT -j selinux_input"
Chris PeBenito 5a7c06f
	print "pre -A OUTPUT -j selinux_output"
Chris PeBenito 5a7c06f
	print "pre -A selinux_input -m state --state NEW -j selinux_new_input"
Chris PeBenito 5a7c06f
	print "pre -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore"
Chris PeBenito 5a7c06f
	print "pre -A selinux_output -m state --state NEW -j selinux_new_output"
Chris PeBenito 5a7c06f
	print "pre -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore"
Chris PeBenito 17de1b7
	print_input_rules(packets,mls,mcs)
Chris PeBenito 17de1b7
	print_output_rules(packets,mls,mcs)
Chris PeBenito 5a7c06f
	print "post COMMIT"
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
mls = False
Chris PeBenito 17de1b7
mcs = False
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
try:
Chris PeBenito 17de1b7
	opts, paths = getopt.getopt(sys.argv[1:],'mc',['mls','mcs'])
Chris PeBenito 17de1b7
except getopt.GetoptError, error:
Chris PeBenito 17de1b7
	print "Invalid options."
Chris PeBenito 17de1b7
	sys.exit(1)
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
for o, a in opts:
Chris PeBenito 17de1b7
	if o in ("-c","--mcs"):
Chris PeBenito 17de1b7
		mcs = True
Chris PeBenito 17de1b7
	if o in ("-m","--mls"):
Chris PeBenito 17de1b7
		mls = True
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
if len(paths) == 0:
Chris PeBenito 17de1b7
	sys.stderr.write("Need a path for corenetwork.te.in!\n")
Chris PeBenito 17de1b7
	sys.exit(1)
Chris PeBenito 17de1b7
elif len(paths) > 1:
Chris PeBenito 17de1b7
	sys.stderr.write("Ignoring extra specified paths\n")
Chris PeBenito 17de1b7
Chris PeBenito 17de1b7
packets=parse_corenet(paths[0])
Chris PeBenito 17de1b7
print_netfilter_config(packets,mls,mcs)