#! /bin/bash
# postinst script for strongswan
#
# see: dh_installdeb(1)

set -e

# summary of how this script can be called:
#        * <postinst> `configure' <most-recently-configured-version>
#        * <old-postinst> `abort-upgrade' <new version>
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
#          <new-version>
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
#          <failed-install-package> <version> `removing'
#          <conflicting-package> <version>
# for details, see /usr/share/doc/packaging-manual/
#
# quoting from the policy:
#     Any necessary prompting should almost always be confined to the
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
#          <failed-install-package> <version> `removing'
#          <conflicting-package> <version>
# for details, see /usr/share/doc/packaging-manual/
#
# quoting from the policy:
#     Any necessary prompting should almost always be confined to the
#     post-installation script, and should be protected with a conditional
#     so that unnecessary prompting doesn't happen if a package's
#     installation fails and the `postinst' is called with `abort-upgrade',
#     `abort-remove' or `abort-deconfigure'.

CONF_FILE=/var/lib/strongswan/ipsec.conf.inc
SECRETS_FILE=/var/lib/strongswan/ipsec.secrets.inc

insert_private_key_filename() {
	if [ ! -e $SECRETS_FILE ] || ! grep -q ": RSA $1" $SECRETS_FILE; then
            echo ": RSA $1" >> $SECRETS_FILE
        fi
}

IPSEC_SECRETS_PATTERN_1=': RSA	{'
IPSEC_SECRETS_PATTERN_2='	# yyy'
IPSEC_SECRETS_PATTERN_3='	}'
IPSEC_SECRETS_PATTERN_4='# do not change the indenting of that "}"'

# remove old, misguided attempts at a default ipsec.secrets files
repair_legacy_secrets() {
    if [ -e $SECRETS_FILE ] && grep -A 2 "$IPSEC_SECRETS_PATTERN_1" $SECRETS_FILE |
       tail --lines=2 |
       grep -A 1 "$IPSEC_SECRETS_PATTERN_2" |
       tail --lines=1 |
       grep "$IPSEC_SECRETS_PATTERN_3" >/dev/null; then
        echo "Old default config file detected, removing the old defaults now."
        umask 077 ; (
            # this is ugly, and someone maybe can formulate this in sed, but
            # this was the quickest way for me
            line=`grep -n "$IPSEC_SECRETS_PATTERN_2" $SECRETS_FILE | cut -d':' -f1`
            until=`expr $line - 1`
            head -n $until $SECRETS_FILE
            sum=`wc -l $SECRETS_FILE | cut -d ' ' -f1`
            from=`expr $sum - $line -1`
            tail -n $from $SECRETS_FILE
        ) > $SECRETS_FILE.tmp
        mv $SECRETS_FILE.tmp $SECRETS_FILE
        grep -v "$IPSEC_SECRETS_PATTERN_4" $SECRETS_FILE > $SECRETS_FILE.tmp
        mv $SECRETS_FILE.tmp $SECRETS_FILE
    fi
}

make_x509_cert() {
    if [ $# -ne 12 ]; then
        echo "Error in creating X.509 certificate"
        exit 1
    fi

    case $5 in
        false)
            certreq=$4.req
            selfsigned=""
        ;;
        true)
            certreq=$4
            selfsigned="-x509"
        ;;
        *)
            echo "Error in creating X.509 certificate"
            exit 1
        ;;
    esac

    echo -e "$6\n$7\n$8\n$9\n${10}\n${11}\n${12}\n\n\n" | \
      /usr/bin/openssl req -new -outform PEM -out $certreq \
                       -newkey rsa:$1 -nodes -keyout $3 -keyform PEM \
                       -days $2 $selfsigned >/dev/null
}

enable_daemon_start() {
    daemon=$1
    protocol=$2

    echo -n "Enabling ${protocol} support by pluto ... "
    if [ -e $CONF_FILE ] && egrep -q "^\w+${daemon}start=yes\w*$" $CONF_FILE; then
        echo "already enabled"
    elif [ -e $CONF_FILE ] && egrep -q "^\w+${daemon}start=no\w*$" $CONF_FILE; then
      	sed "s/${daemon}start=no/${daemon}start=yes/" < $CONF_FILE > $CONF_FILE.tmp
        cp $CONF_FILE.tmp $CONF_FILE
	rm $CONF_FILE.tmp
        echo "done"
    elif [ -e $CONF_FILE ] && egrep -q "^\w+#\w*${daemon}start=(yes|no)\w*$" $CONF_FILE; then
      	sed "s/^\w+#\w*${daemon}start=(yes|no)\w*$/\t${daemon}start=yes/" < $CONF_FILE > $CONF_FILE.tmp
        cp $CONF_FILE.tmp $CONF_FILE
	rm $CONF_FILE.tmp
        echo "done"
    elif [ ! -e $CONF_FILE ]; then
	echo -e "\t${daemon}start=yes" > $CONF_FILE
    else
        echo "ERROR: unknown or nonexistant ${daemon}start= directive, please fix manually!"
    fi
}

disable_daemon_start() {
    daemon=$1
    protocol=$2

    echo -n "Disabling ${protocol} support by pluto ... "
    if [ -e $CONF_FILE ] && ( egrep -q "^\w+${daemon}start=no\w*$" $CONF_FILE ||
       egrep -q "^\w+#\w*${daemon}start=(yes|no)\w*$" $CONF_FILE ); then
        echo "already disabled"
    elif [ -e $CONF_FILE ] && egrep -q "^\w+${daemon}start=yes\w*$" $CONF_FILE; then
      	sed "s/${daemon}start=yes/${daemon}start=no/" < $CONF_FILE > $CONF_FILE.tmp
        cp $CONF_FILE.tmp $CONF_FILE
	rm $CONF_FILE.tmp
        echo "done"
    elif [ ! -e $CONF_FILE ]; then
	echo -e "\t${daemon}start=yes" > $CONF_FILE
    else
        echo "ERROR: unknown or nonexistant ${daemon}start= directive, please fix manually!"
    fi
}

. /usr/share/debconf/confmodule

case "$1" in
    configure)
	db_get strongswan/create_rsa_key
	if [ "$RET" = "true" ]; then
            repair_legacy_secrets
 	    # OK, ipsec.secrets should now be correct
            # create a new keypair
	    host=`hostname`
	    newkeyfile="/etc/ipsec.d/private/${host}Key.pem"
       	    newcertfile="/etc/ipsec.d/certs/${host}Cert.pem"
            if [ -e $newcertfile -o -e $newkeyfile ]; then
                echo "Error: $newcertfile or $newkeyfile already exists."
                echo "Please remove them first an re-run dpkg-reconfigure to create a new keypair."
            else
     		# create a new certificate
       		db_get strongswan/rsa_key_length
       		keylength=$RET
       		db_get strongswan/x509_self_signed
       		selfsigned=$RET
       		db_get strongswan/x509_country_code
       		countrycode=$RET
       		if [ -z "$countrycode" ]; then countrycode="."; fi
       		db_get strongswan/x509_state_name
       		statename=$RET
       		if [ -z "$statename" ]; then statename="."; fi
       		db_get strongswan/x509_locality_name
       		localityname=$RET
       		if [ -z "$localityname" ]; then localityname="."; fi
       		db_get strongswan/x509_organization_name
       		orgname=$RET
       		if [ -z "$orgname" ]; then orgname="."; fi
       		db_get strongswan/x509_organizational_unit
       		orgunit=$RET
       		if [ -z "$orgunit" ]; then orgunit="."; fi
       		db_get strongswan/x509_common_name
       		commonname=$RET
       		if [ -z "$commonname" ]; then commonname="."; fi
       		db_get strongswan/x509_email_address
       		email=$RET
       		if [ -z "$email" ]; then email="."; fi
       		make_x509_cert $keylength 1500 "$newkeyfile" "$newcertfile" "$selfsigned" "$countrycode" "$statename" "$localityname" "$orgname" "$orgunit" "$commonname" "$email"
       		chmod 0600 "$newkeyfile"
       		umask 077
       		insert_private_key_filename "$newkeyfile"
       		echo "Successfully created x509 certificate."
       	    fi
        else
	    db_get strongswan/existing_x509_certificate
       	    if [ "$RET" = "true" ]; then
                if [ -e $newcertfile -o -e $newkeyfile ]; then
                     echo "Error: $newcertfile or $newkeyfile already exists."
                     echo "Please remove them first an re-run dpkg-reconfigure to create a new keypair."
                else
       			# existing certificate - use it
       			db_get strongswan/existing_x509_certificate_filename
       			certfile=$RET
       			db_get strongswan/existing_x509_key_filename
       			keyfile=$RET
       			if [ ! -r $certfile ] || [ ! -r $keyfile ]; then
       			    echo "Either the certificate or the key file could not be read !"
       			else
                            cp "$certfile" /etc/ipsec.d/certs
       			    umask 077
			    cp "$keyfile" "/etc/ipsec.d/private"
                            newkeyfile="/etc/ipsec.d/private/`basename $keyfile`"
			    chmod 0600 "$newkeyfile"
			    insert_private_key_filename "$newkeyfile"
			    echo "Successfully extracted RSA key from existing x509 certificate."
			fi
		fi
            fi
	fi

        # figure out the correct start time
        db_get strongswan/start_level
	if [ "$RET" = "earliest" ]; then
	    LEVELS="start 41 S . stop 34 0 6 ."
	elif [ "$RET" = "after NFS" ]; then
	    LEVELS="start 15 2 3 4 5 . stop 30 0 1 6 ."
	else
	    LEVELS="start 21 2 3 4 5 . stop 19 0 1 6 ."
	fi
	update-rc.d ipsec $LEVELS > /dev/null

        db_get strongswan/enable-oe
        if [ "$RET" != "true" ]; then
            echo -n "Disabling opportunistic encryption (OE) in config file ... "
            if [ -e $CONF_FILE ] && egrep -q "include /etc/ipsec.d/examples/no_oe.conf$" $CONF_FILE; then
                # also update to new-style config
                sed 's/.*include \/etc\/ipsec.d\/examples\/no_oe.conf/#include \/etc\/ipsec.d\/examples\/oe.conf/' < $CONF_FILE > $CONF_FILE.tmp
                mv $CONF_FILE.tmp $CONF_FILE
                echo -n "converted old config line to new format"
            fi
            if [ -e $CONF_FILE ] && egrep -q "^include /etc/ipsec.d/examples/oe.conf$" $CONF_FILE; then
            	sed 's/include \/etc\/ipsec.d\/examples\/oe.conf/#include \/etc\/ipsec.d\/examples\/oe.conf/' < $CONF_FILE > $CONF_FILE.tmp
                mv $CONF_FILE.tmp $CONF_FILE
                echo "done"
            elif [ ! -e $CONF_FILE ]; then
                echo "#include /etc/ipsec.d/examples/oe.conf" > $CONF_FILE
            else
                echo "already disabled"
            fi
	else
            echo -n "Enabling opportunistic encryption (OE) in config file ... "
            if [ -e $CONF_FILE ] && egrep -q "include /etc/ipsec.d/examples/no_oe.conf$" $CONF_FILE; then
                # also update to new-style config
            	sed 's/.*include \/etc\/ipsec.d\/examples\/no_oe.conf/include \/etc\/ipsec.d\/examples\/oe.conf/' < $CONF_FILE > $CONF_FILE.tmp
                mv $CONF_FILE.tmp $CONF_FILE
                echo -n "converted old config line to new format"
            fi
            if [ -e $CONF_FILE ] && egrep -q "^include /etc/ipsec.d/examples/oe.conf$" $CONF_FILE; then
                echo "already enabled"
            elif [ -e $CONF_FILE ] && egrep -q "^#.*include /etc/ipsec.d/examples/oe.conf$" $CONF_FILE; then
            	sed 's/#.*include \/etc\/ipsec.d\/examples\/oe.conf/include \/etc\/ipsec.d\/examples\/oe.conf/' < $CONF_FILE > $CONF_FILE.tmp
                mv $CONF_FILE.tmp $CONF_FILE
                echo "done"
            elif [ ! -e $CONF_FILE ]; then
                echo "include /etc/ipsec.d/examples/oe.conf" > $CONF_FILE
            else
                cat <<EOF >> $CONF_FILE
#Enable Opportunistic Encryption
include /etc/ipsec.d/examples/oe.conf
EOF
              echo "done"
            fi
        fi

	# disabled for now, until we can solve the don't-edit-conffiles issue
        #db_get strongswan/ikev1
        #if [ "$RET" != "true" ]; then
        #    enable_daemon_start "pluto" "IKEv1"
	#else
        #    disable_daemon_start "pluto" "IKEv1"
        #fi
        #db_get strongswan/ikev2
        #if [ "$RET" != "true" ]; then
        #    enable_daemon_start "charon" "IKEv2"
	#else
        #    disable_daemon_start "charon" "IKEv2"
        #fi

	if [ -z "$2" ]; then
	    # no old configured version - start strongswan now
            invoke-rc.d ipsec start || true
        else
  	    # does the user wish strongswan to restart?
	    db_get strongswan/restart
	    if [ "$RET" = "true" ]; then
	         invoke-rc.d ipsec restart || true # sure, we'll restart it for you
	    fi
	fi

        db_stop

    ;;

    abort-upgrade|abort-remove|abort-deconfigure)

    ;;

    *)
        echo "postinst called with unknown argument '$1'" >&2
        exit 0
    ;;
esac

# dh_installdeb will replace this with shell code automatically

#DEBHELPER#

exit 0