#!/bin/bash
#Copyright 2003 William Stearns <wstearns@pobox.com>
#Released under the GPL.

Me='established'
MyVersion='0.3.4'
DefaultActions='ACCEPT'

[ -r /etc/firebricks/firebricks.conf ] &&			. /etc/firebricks/firebricks.conf
[ -r /etc/firebricks/$Me.conf ] &&				. /etc/firebricks/$Me.conf
[ -r ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib ] &&	. ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib
if [ -z "$FBLibVer" ]; then
	echo 'It looks like firebrickslib was not loaded, why?  Exiting' >&2
	exit 1
fi

for OneTask in $Tasks ; do
	case "$OneTask" in
	link)
		$IptablesBin -N $Me >/dev/null 2>&1
		$IptablesBin $AppIn INPUT -i \! lo						-j $Me
		$IptablesBin $AppIn FORWARD							-j $Me
		$IptablesBin $AppIn OUTPUT							-j $Me
		;;
	unlink)
		$IptablesBin -D INPUT -i \! lo							-j $Me
		$IptablesBin -D FORWARD								-j $Me
		$IptablesBin -D OUTPUT								-j $Me
		$IptablesBin -X $Me >/dev/null 2>&1
		;;
	create)
		echo "Starting $Me" >&2
		FlushOrNewChain $Me
		LogAs='EstabOrRelat'	$Ipt -A $Me -m state --state ESTABLISHED,RELATED	$Tail
		;;
	destroy)
		echo "Stopping $Me" >&2
		DestroyChain $Me
		;;
	renamechain)
		TempChain="$Me-$RANDOM"
		echo "Replacing existing rules in $Me with new rules" >&2
		$IptablesBin -E $Me $TempChain
		;;
	replacelinks)
		if [ -z "$TempChain" ]; then
			echo "No temporary chain to relink in $Me replacelinks, replace operation incomplete." >&2
		elif ! $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "No $Me chain in $Me, replace operation incomplete." >&2
		elif ! $IptablesBin -L $TempChain -n >/dev/null 2>&1 ; then
			echo "No $TempChain chain in $Me, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in INPUT in $Me replacelinks, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in FORWARD in $Me replacelinks, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in OUTPUT in $Me replacelinks, replace operation incomplete." >&2
		else
			$IptablesBin -R INPUT `$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | awk '{print $1}'` -i \! lo		-j $Me
			$IptablesBin -R FORWARD `$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | awk '{print $1}'`		-j $Me
			$IptablesBin -R OUTPUT `$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | awk '{print $1}'`			-j $Me
			DestroyChain $TempChain
			unset TempChain
		fi
		;;
	status)
		if $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "$Me created" >&2
		else
			echo "$Me destroyed" >&2
		fi
		;;
	version)
		echo "$Me $MyVersion, firebrickslib $FBLibVer" >&2
		;;
	help)
		DefaultHelp
		cat <<EOTEXT >&2
	The $Me module allows all state ESTABLISHED or RELATED traffic
through.  It should go after checks for illegal packet characteristics
(which is the role of most of the other firebricks).  Rules and chains
following this one can then focus on the state NEW packets (the starting
packets of the conversation).

	Not only is this safe to use, but the stateful nature of
iptables firewalling provided by the state module actual improves the
security of a firewall.  The only circumstance in which this might not
be a good idea is if you have a firewall that is already straining to
handle a very high load.  In that case, stateful checks should be moved
to one or more additional firewalls behind the main one.
EOTEXT
		;;
	*)
		echo "Unknown action $Action in $Me, no action taken." >&2
		;;
	esac
done
