#! /bin/sh -
# -*- mode:sh -*-
# $Id: $
# Copyright (c) 2007 Travis H.
# <URL:http://www.subspacefield.org/~travis/safety/>
# Standard GPL
# Meant for Red Hat Linux and netfilter

# set base filename for prepending to errors
argv0=$(basename "$0")
#
usage="\
$argv0 [editor]"

# TODO: allow specifying the time spec
# TODO: allow specifying the working conf filename
# TODO: allow specifying the new conf filename

PATH=/usr/sbin:/sbin:/usr/local/sbin:$PATH

# This is the canonical place for the iptables rules.
ipt=/etc/sysconfig/iptables

# This is always a backup of the last config safety was able to
# verify.
working=$ipt-working
if test -e "$working"
then
    :
else
    echo <<EOF >&2
Warning: $working does not exist, safety probably has never
been run here, assuming $ipt is okay
EOF
    cp "$ipt" "$working"
fi

# This is where we will store our new candidate
new=$ipt-safety

if test "$#" -gt 1
then
	EDITOR="$1"
	shift
fi

if test "$#" -ne 0
then
	echo "$usage" >&2
	exit 1
fi

# This is just used to flag that the at job ran.
tmpfn="$(mktemp)"
rm "$tmpfn"
export new working pf tmpfn

if cmp "$working" "$ipt"
then
    test -e "$new" || cp "$ipt" "$new"
    ${EDITOR:-vi} $new || exit 1
else
    echo "Warning: $ipt is not the same as $working; probably last edit was not done with safety." >&2
    echo "Thus, this time I will test it and you must run safety again to modify it." >&2
    cp "$ipt" "$new"
fi

# Set up an at job to restore working configuration
id="$( (echo iptables-restore $working; echo touch $tmpfn) | at now + 2 minutes 2>&1 | (read job id rest; echo $id) )"

# Try out the new config
iptables-restore "$new"

echo -n "Is it everything you hoped for? (Y/n): "
read response

# TODO: Figure out what to do if at job ran, but
# user says everything is okay.

case "$response" in
n*) echo "Okay, I will pretend this never happened." ;;
*)
    echo "Installing new ruleset..."
    cp "$new" "$working"
    cp "$new" "$ipt"
    ;;
esac

at -r "$id"

exit 0
