#! /bin/sh
# user interface to automatic keying and Pluto in general
# Copyright (C) 1998, 1999, 2000  Henry Spencer.
# Copyright (C) 2014-2017 Paul Wouters <pwouters@redhat.com>
# Copyright (C) 2015-2018 Tuomo Soini <tis@foobar.fi>
#
# 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.  See <https://www.gnu.org/licenses/gpl2.txt>.
#
# 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.

IPSEC_RUNDIR="${IPSEC_RUNDIR:-/run/pluto}"
CTLSOCKET="${IPSEC_RUNDIR}/pluto.ctl"

me='ipsec auto'
usage="Usage:
	${me} [--showonly] [--asynchronous] --up connectionname \\
		[--remote-host ipaddr]
	${me} [--showonly] [--asynchronous] --down connectionname
	${me} [--showonly] --{add|delete|replace|start} connectionname
	${me} [--showonly] --{route|unroute|ondemand} connectionname
	${me} [--showonly] --{ready|status|rereadsecrets|rereadgroups}
	${me} [--showonly] --{rereadcrls|rereadall}
	${me} [--showonly] [--utc] --{listpubkeys|listcerts}
	${me} [--showonly] [--utc] --checkpubkeys
	${me} [--showonly] [--utc] --{listcacerts|listgroups}
	${me} [--showonly] [--utc] --{listcrls|listall}
	${me} [--showonly] [--utc] --purgeocsp

	other options: [--config ipsecconfigfile] [--verbose] [--ctlsocket <file>]"

config=
async=
op=
argc=
utc=
verbose=
remote=

while [ $# != 0 ]
do
    case "$1" in
	--help)
	    echo "${usage}"
	    exit 0
	    ;;
	--version)
	    echo "${me} $IPSEC_VERSION"
	    exit 0
	    ;;
	--show)
	    ;;
	--showonly)
	    showonly='echo '
	    ;;
	--utc)
	    utc="$1"
	    ;;
	--config)
	    config="--config $2"
	    shift
	    ;;
	--ctlsocket)
	    CTLSOCKET="$2"
	    shift
	    ;;
	--remote-host)
	    remote="--remote-host $2"
	    shift
	    ;;
	--asynchronous)
	    async="--asynchronous"
	    ;;
	--verbose)
	    verbose=" --verbose "
	    ;;
	--up|--down|--add|--delete|--replace|--route|--unroute|\
	--start|--ondemand)
	    if [ " ${op}" != " " ]; then
		echo "${usage}" >&2
		exit 2
	    fi
	    op="$1"
	    argc=1
	    ;;
	--ready|--status|--rereadsecrets|--rereadgroups|\
	--rereadcacerts|--rereadcrls|--rereadall|\
	--listpubkeys|--listcerts|\
	--checkpubkeys|\
	--listcacerts|--listgroups|\
	--listcrls|--listall|--purgeocsp)
	    if [ " ${op}" != " " ]; then
		echo "${usage}" >&2
		exit 2
	    fi
	    op="$1"
	    argc=0
	    ;;
	--)
	    shift
	    break
	    ;;
	-*)
	    echo "${me}: unknown option \"$1\"" >&2
	    exit 2
	    ;;
	*)
	    break
	    ;;
    esac
    shift
done

names=
case "${op}$#:$1:$2" in
    2:*:up|2:*:down|2:*:add|2:*:delete|2:*:replace|2:*:start|\
    2:*:route|2:*:unroute)
	echo "${me}: warning: obsolete command syntax used" >&2
	names="$1"
	op="--$2"
	;;
    1:ready:|1:status:|1:rereadsecrets:|\
    1:rereadcacerts:|1:rereadcrls:|1:rereadall:|\
    1:listpubkeys:|1:listcerts:|\
    1:listcacerts:|1:listgroups:|\
    1:listcrls:|1:listall:)
	echo "${me}: warning: obsolete command syntax used" >&2
	op="--$1"
	;;
    --*)
	if [ " $argc" -ne $# ];	then
	    echo "${usage}" >&2
	    exit 2
	fi
	names="$*"
	;;
    *)
	echo "${usage}" >&2
	exit 2
	;;
esac

case "${op}" in
    --ready)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --listen
	exit
	;;
    --rereadsecrets)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --rereadsecrets
	exit
	;;
    --rereadgroups)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --listen
	exit
	;;
    --rereadcacerts)
	${showonly} ipsec whack  --ctlsocket "${CTLSOCKET}" --rereadcacerts
	exit
	;;
    --rereadcrls)
	echo "ipsec auto --rereadcrls has been obsoleted - please see: ipsec crls"
	exit 1
	;;
    --rereadall)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --rereadall
	exit
	;;
    --listpubkeys)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listpubkeys
	exit
	;;
    --checkpubkeys)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --checkpubkeys
	exit
	;;
    --listcerts)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listcerts
	exit
	;;
    --listcacerts)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listcacerts
	exit
	;;
    --listgroups)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listgroups
	exit
	;;
    --listcrls)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listcrls
	exit
	;;
    --listall)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listall
	exit
	;;
    --purgeocsp)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${utc} --listall --purgeocsp
	exit
	;;
    --up)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${async} --name ${names} --initiate ${remote}
	exit
	;;
    --start)
	${showonly} ipsec addconn --ctlsocket "${CTLSOCKET}" ${verbose} ${config} ${names}
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" ${async} --name ${names} --initiate ${remote}
	exit
	;;
    --down)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --terminate
	exit
	;;
    --delete)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --delete
	exit
	;;
    --route)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --route
	exit
	;;
    --ondemand)
	${showonly} ipsec addconn --ctlsocket "${CTLSOCKET}" ${verbose} ${config} ${names}
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --route
	exit
	;;
    --unroute)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --unroute
	exit
	;;
    --status)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --status
	exit
	;;
    --replace)
	${showonly} ipsec whack --ctlsocket "${CTLSOCKET}" --name ${names} --delete
	${showonly} ipsec addconn --ctlsocket "${CTLSOCKET}" ${verbose} ${config} ${names}
	exit
	;;
esac

${showonly} ipsec addconn --ctlsocket "${CTLSOCKET}" ${verbose} ${config} ${names}
