#!/bin/sh
# prefix command to run stuff from our programs directory
# Copyright (C) 1998-2002  Henry Spencer.
# Copyright (C) 2013       Tuomo Soini <tis@foobar.fi>
# Copyright (C) 2013-2014  Paul Wouters <pwouters@redhat.com>
# 
# 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 <http://www.fsf.org/copyleft/gpl.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.
#

test "${IPSEC_INIT_SCRIPT_DEBUG}" && set -v -x

# where the private directory and the config files are
IPSEC_CONF="${IPSEC_CONF:-/etc/ipsec.conf}"
IPSEC_EXECDIR="${IPSEC_EXECDIR:-/usr/libexec/ipsec}"
IPSEC_SBINDIR="${IPSEC_SBINDIR:-/usr/sbin}"
IPSEC_CONFDDIR="${IPSEC_CONFDDIR:-/etc/ipsec.d}"

IPSEC_DIR="${IPSEC_EXECDIR}"
export IPSEC_DIR IPSEC_EXECDIR IPSEC_CONF

# standardize PATH, and export it for everything else's benefit
PATH="${IPSEC_SBINDIR}":/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin
export PATH

# supress ElectricFence banner changing our reference testing output
export EF_DISABLE_BANNER=1

# things not to be listed in --help command list
DONTMENTION='^(ipsec|_.*|.*\.old|.*\.orig|.*~)$'

# version numbering (details filled in by build)
# Possibly should call a C program to invoke the version_code() function
# instead, but for performance's sake, we inline it here (and only here).
version="3.12"

# export the version information
IPSEC_VERSION="${version}"
export IPSEC_VERSION

# function for the funky user/kernel version stuff
fixversion() {
    if [ -f /proc/net/ipsec_version ]; then
	stack=" (klips)"
	kv="$(awk '{print $NF}' /proc/net/ipsec_version)"
    else
	if [ -f /proc/net/pfkey ]; then
	    stack=" (netkey)"
	    kv="${version}"
	else
	    if [ -f /mach_kernel ]; then
		stack=" (OSX)"
		kv="$(uname -r)"
	    else
		kv="(no kernel code presently loaded)"
	    fi
	fi
    fi
    if [ "${kv}" != "${version}" ]; then
	version="U${version}/K${kv}"
    fi
    version="${version}${stack} on $(uname -r)"
}

case "${1}" in
    '')
	echo "Usage: ipsec <command> <argument ...>"
	echo "Use --help for a list of commands, or see the ipsec(8) manual page"
	echo "Most commands have their own manual pages, e.g. ipsec_auto(8)."
	echo "See <http://www.libreswan.org> for more general info."
	fixversion
	echo "Linux Libreswan ${version}"
	exit 0
	;;
    status|--status)
	exec ipsec auto --status
	;;
    start|--start)
	exec ipsec setup start
	;;
    stop|--stop)
	exec ipsec setup stop
	;;
    restart|--restart)
	# restart does not work when stoped in systemd - it's dumb
	ipsec setup stop 
	exec ipsec setup start
	;;
    help|--help)
	echo "Usage: ipsec <command> <argument ...>"
	echo "where <command> is one of:"
	echo ""
	GOTTWO=""
	for f in start stop restart status import initnss checknss $(ls "${IPSEC_EXECDIR}" | egrep -v -i "${DONTMENTION}"); do
		if [ -z "${GOTTWO}" ]; then
		    # first of two entries
		    GOTTWO="${f}"
		else
		    # second of two entries, we can print
		    echo -n "	${GOTTWO}"
		    if [ "${#GOTTWO}" -ge 16 ]; then
			echo -e -n  "\t"
		    elif [ "${#GOTTWO}" -ge 8 ]; then
			echo -e -n "\t\t"
		    else
			echo -e -n "\t\t\t"
		    fi
		    echo "${f}"
		    GOTTWO=""
		fi
	done
	if [ -n "${GOTTWO}" ]; then
	    # leftover entry
	    echo "	${GOTTWO}"
	fi
	echo
	echo "See also: man ipsec <command> or ipsec <command> --help"
	echo "See <https://libreswan.org/> for more general info."
	fixversion
	echo "Linux Libreswan ${version}"
	exit 0
	;;
    # some ubuntu/debian scripts use --versioncode, so let's keep the alias
    version|--version|--versioncode)
	fixversion
	echo "Linux Libreswan ${version}"
	exit 0
	;;
    --directory)
	echo "${IPSEC_DIR}"
	exit 0
	;;
    import|--import)
	if [ $(id -u) -ne 0 ]; then
	    echo "permision denied on nss operation (must be superuser)"
	    exit 4
	fi
	if [ -z "${2}" ]; then
	    echo "usage: ipsec import /path/to/pkcs.12" >&2
	    exit 1
	else
	    if [ ! -f "${2}" ]; then
		echo "usage: ipsec import /path/to/pkcs.12"  >&2
		exit 1
	    fi
	fi
	# this hardcoded ipsec.d needs to get fixed once we pass IPSECD properly
	pk12util -i "${2}" -d "${IPSEC_CONFDDIR}"
	if [ -x /usr/sbin/restorecon ]; then
	    restorecon -Rv "${IPSEC_CONFDDIR}"
	fi
	exit 0
	;;
    initnss|--initnss|checknss|--checknss)
	if [ $(id -u) -ne 0 ]; then
	    echo "permision denied on nss operation (must be superuser)"
	    exit 4
	fi
	if [ -n "${2}" ]; then
	    # A lot of nss commands use -d or --configdir to specify NSS db location
	    if [ "${2}" = "-d" -o "${2}" = "--configdir" ]; then
	       IPSEC_CONFDDIR="${3}"
            else
	       IPSEC_CONFDDIR="${2}"
	    fi
	fi
	if [ ! -d "${IPSEC_CONFDDIR}" ]; then
	   mkdir -p "${IPSEC_CONFDDIR}"
	fi
	if [ -f "${IPSEC_CONFDDIR}/cert8.db" -o \
	    -f "${IPSEC_CONFDDIR}/cert9.db" -o \
	    -f "${IPSEC_CONFDDIR}/key3.db" -o \
	    -f "${IPSEC_CONFDDIR}/key4.db" -o \
	    -f "${IPSEC_CONFDDIR}/secmod.db" ]; then
	    # if just checking, silently quit
	    [ "${1}" = "checknss" -o "${1}" = "--checknss" ] && exit 0
	    echo "NSS database already initialised - aborted"
	    echo "To wipe the old NSS database, issue: rm ${IPSEC_CONFDDIR}/*.db"
	    exit 42
	fi

	echo "Initializing NSS database"
	echo "See 'man pluto' if you want to protect the NSS database with a password"
	echo ""

	TEMPFILE=$(/bin/mktemp "${IPSEC_CONFDDIR}/nsspw.XXXXXXX")
	[ $? -gt 0 ] && TEMPFILE="${IPSEC_CONFDDIR}/nsspw.$$"
	echo > ${TEMPFILE}
	certutil -N -f "${TEMPFILE}" -d "${IPSEC_CONFDDIR}"
	rm -f ${TEMPFILE}
	if [ -x /usr/sbin/restorecon ]; then
	    restorecon -Rv "${IPSEC_CONFDDIR}"
	fi
	exit 0
	;;
    --*)
	echo "${0}: unknown option \"${1}\" (perhaps command name was omitted?)" >&2
	exit 1
	;;
esac

cmd="${1}"
shift

path="${IPSEC_EXECDIR}/${cmd}"

if [ ! -x "${path}" ]; then
    path="${IPSEC_EXECDIR}/${cmd}"
    if [ ! -x "${path}" ]; then
	echo "${0}: unknown IPsec command \"${cmd}\" (\"ipsec --help\" for list)" >&2
	exit 1
    fi
fi

exec "${path}" "$@"
