#! /bin/bash
### BEGIN INIT INFO
# Provides:          xapissl
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: XenAPI server SSL proxy
# Description:       This file will initialize stunnel for
#                    the XenAPI server.
### END INIT INFO
#
# chkconfig: 2345 91 01
# description: XenAPI server SSL proxy
# processname: stunnel
# config: /etc/xcp/stunnel.conf
# pidfile: /var/run/xapissl.pid

# Source function library.
. /lib/lsb/init-functions

PEMFILE="/etc/xcp/xapi-ssl.pem"
SSLPIDFILE="/var/run/xapissl.pid"
SSLCONFFILE="/etc/xcp/xapi-ssl.conf"
XAPISSL_LOCK="/var/lock/xapissl"

# If stunnel4 exists, use it. Otherwise use stunnel.
[ $(which stunnel4) ] && STUNNEL=$(which stunnel4)
[ -z ${STUNNEL} ] && STUNNEL=$(which stunnel)

mgmt_ip() {
    . /etc/xcp/inventory
    if [ -n "${MANAGEMENT_INTERFACE}" ] &&
        [ "${MANAGEMENT_INTERFACE}" != "lo" ];
    then
        /sbin/ifconfig ${MANAGEMENT_INTERFACE} | \
            sed -ne 's/.*inet addr:\([^ ]*\).*/\1/p'
    fi
}

# Write out the stunnel config file. This requires the management
# interface, so it's done here rather than written statically.
writeconffile () {
    # Initial boilerplate which is valid whether the management
    # interface is enabled or disabled.
    cat > $SSLCONFFILE <<EOF
; Autogenerated by init.d/xapissl
pid = ${SSLPIDFILE}
socket = r:TCP_NODELAY=1
socket = a:TCP_NODELAY=1
socket = l:TCP_NODELAY=1
compression = zlib

[localhost-xapi]
accept = 127.0.0.1:443
connect = 80
cert = ${PEMFILE}
ciphers = !SSLv2:RSA+AES256-SHA:RSA+AES128-SHA:RSA+RC4-SHA:RSA+RC4-MD5:RSA+DES-CBC3-SHA
EOF

    . /etc/xcp/inventory
    # Only if the management interface is set ask stunnel to bind to it
    if [ -n "${MANAGEMENT_INTERFACE}" ] &&
        [ "${MANAGEMENT_INTERFACE}" != "lo" ];
    then
        MGMT_IP=`mgmt_ip`
        cat >> $SSLCONFFILE <<EOF

[xapi]
accept = ${MGMT_IP}:443
connect = 80
cert = ${PEMFILE}
ciphers = !SSLv2:RSA+AES256-SHA:RSA+AES128-SHA:RSA+RC4-SHA:RSA+RC4-MD5:RSA+DES-CBC3-SHA
TIMEOUTclose = 0
EOF

    fi
    return
}

start() {
    echo -n $"Starting xapi SSL: "
    if [ -e ${XAPISSL_LOCK} ]; then
        if [ -e ${SSLPIDFILE} ] && [ -e /proc/`cat ${SSLPIDFILE}` ]; then
            echo -n $"cannot start xapi SSL: xapi SSL is already running.";
            failure $"cannot start xapi SSL: xapi SSL already running.";
            echo
            return 1
        fi
    fi
    if [ ! -f ${PEMFILE} ]; then
        # generating a pem file
        CN=`hostname -f`

        case "${CN}" in
            localhost*)
                CN=`mgmt_ip`;;
            *.*)
                :;;
            *)
                CN=`mgmt_ip`;;
        esac
        "/usr/lib/xcp/lib/generate_ssl_cert" ${PEMFILE} ${CN}
    fi
    writeconffile
    start_daemon ${STUNNEL} ${SSLCONFFILE}
    RETVAL=$?

    echo
    [ $RETVAL -eq 0 ] && touch ${XAPISSL_LOCK};
    return $RETVAL
}

stop() {
    echo -n $"Stopping xapi SSL: "
    if [ ! -e ${XAPISSL_LOCK} ]; then
        echo -n $"cannot stop xapi SSL: xapi SSL is not running."
        failure $"cannot stop xapi: xapi SSL is not running."
        echo
        return 1;
    fi
    SSLPID=$(cat ${SSLPIDFILE})
    kill ${SSLPID}
    if [ $? -ne 0 ]; then
        echo -n $"stunnel already dead"
        failure $"stunnel already dead"
        return 1
    fi

    # Wait until the stunnel pid disappears
    RETRIES=180
    while [ ${RETRIES} -ne 0 ]; do
        RETRIES=$(( ${RETRIES} - 1 ))
        kill -0 $SSLPID 2> /dev/null
        if [ $? -eq 0 ]; then
            echo -n .
            kill ${SSLPID} # in case the first signal was missed
            sleep 1
        else
            echo
            rm -f ${XAPISSL_LOCK}
            return 0
        fi
    done

    # If stunnel still hasn't exited then kill it forcefully
    echo -n $"stunnel ($SSLPID) failed to terminate \
gracefully, terminating forcefully"
    failure $"stunnel ($SSLPID) failed to terminate \
gracefully, terminating forcefully"
    kill -9 ${SSLPID}
    rm -f ${XAPISSL_LOCK}
    return 1
}

status() {
    if [ -e ${XAPISSL_LOCK} ] &&
        [ -e ${SSLPIDFILE} ] &&
        [ -e /proc/`cat ${SSLPIDFILE}` ];
    then
        status_of_proc ${STUNNEL} `basename ${STUNNEL}` && exit 0 || exit $?
    else
        echo "stunnel is not running ... failed!"
        exit 1
    fi
}

restart() {
    stop
    start
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    status)
        status
        ;;
    condrestart)
        [ -f ${XAPISSL_LOCK} ] && restart || :
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart}"
        exit 1
esac
