#!/bin/bash
#
# lib/tls
# Functions to control the configuration and operation of the TLS proxy service

# !! source _before_ any services that use ``SERVICE_HOST``
#
# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR`` must be defined
# - ``HOST_IP``, ``SERVICE_HOST``
# - ``KEYSTONE_TOKEN_FORMAT`` must be defined

# Entry points:
#
# - configure_CA
# - init_CA
# - cleanup_CA

# - configure_proxy
# - start_tls_proxy

# - stop_tls_proxy
# - cleanup_CA

# - make_root_CA
# - make_int_CA
# - make_cert ca-dir cert-name "common-name" ["alt-name" ...]
# - start_tls_proxy HOST_IP 5000 localhost 5000
# - ensure_certificates
# - is_ssl_enabled_service
# - enable_mod_ssl

# Defaults
# --------

if is_service_enabled tls-proxy; then
    # TODO(dtroyer): revisit this below after the search for HOST_IP has been done
    TLS_IP=${TLS_IP:-$SERVICE_IP}
fi

DEVSTACK_HOSTNAME=$(hostname -f)
DEVSTACK_CERT_NAME=devstack-cert
DEVSTACK_CERT=$DATA_DIR/$DEVSTACK_CERT_NAME.pem

# CA configuration
ROOT_CA_DIR=${ROOT_CA_DIR:-$DATA_DIR/CA/root-ca}
INT_CA_DIR=${INT_CA_DIR:-$DATA_DIR/CA/int-ca}

ORG_NAME="OpenStack"
ORG_UNIT_NAME="DevStack"

# Stud configuration
STUD_PROTO="--tls"
STUD_CIPHERS='TLSv1+HIGH:!DES:!aNULL:!eNULL:@STRENGTH'


# CA Functions
# ============

# There may be more than one, get specific
OPENSSL=${OPENSSL:-/usr/bin/openssl}

# Do primary CA configuration
function configure_CA {
    # build common config file

    # Verify ``TLS_IP`` is good
    if [[ -n "$HOST_IP" && "$HOST_IP" != "$TLS_IP" ]]; then
        # auto-discover has changed the IP
        TLS_IP=$HOST_IP
    fi
}

# Creates a new CA directory structure
# create_CA_base ca-dir
function create_CA_base {
    local ca_dir=$1

    if [[ -d $ca_dir ]]; then
        # Bail out it exists
        return 0
    fi

    local i
    for i in certs crl newcerts private; do
        mkdir -p $ca_dir/$i
    done
    chmod 710 $ca_dir/private
    echo "01" >$ca_dir/serial
    cp /dev/null $ca_dir/index.txt
}


# Create a new CA configuration file
# create_CA_config ca-dir common-name
function create_CA_config {
    local ca_dir=$1
    local common_name=$2

    echo "
[ ca ]
default_ca = CA_default

[ CA_default ]
dir                     = $ca_dir
policy                  = policy_match
database                = \$dir/index.txt
serial                  = \$dir/serial
certs                   = \$dir/certs
crl_dir                 = \$dir/crl
new_certs_dir           = \$dir/newcerts
certificate             = \$dir/cacert.pem
private_key             = \$dir/private/cacert.key
RANDFILE                = \$dir/private/.rand
default_md              = default

[ req ]
default_bits            = 1024
default_md              = sha1

prompt                  = no
distinguished_name      = ca_distinguished_name

x509_extensions         = ca_extensions

[ ca_distinguished_name ]
organizationName        = $ORG_NAME
organizationalUnitName  = $ORG_UNIT_NAME Certificate Authority
commonName              = $common_name

[ policy_match ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied

[ ca_extensions ]
basicConstraints        = critical,CA:true
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer
keyUsage                = cRLSign, keyCertSign

" >$ca_dir/ca.conf
}

# Create a new signing configuration file
# create_signing_config ca-dir
function create_signing_config {
    local ca_dir=$1

    echo "
[ ca ]
default_ca = CA_default

[ CA_default ]
dir                     = $ca_dir
policy                  = policy_match
database                = \$dir/index.txt
serial                  = \$dir/serial
certs                   = \$dir/certs
crl_dir                 = \$dir/crl
new_certs_dir           = \$dir/newcerts
certificate             = \$dir/cacert.pem
private_key             = \$dir/private/cacert.key
RANDFILE                = \$dir/private/.rand
default_md              = default

[ req ]
default_bits            = 1024
default_md              = sha1

prompt                  = no
distinguished_name      = req_distinguished_name

x509_extensions         = req_extensions

[ req_distinguished_name ]
organizationName        = $ORG_NAME
organizationalUnitName  = $ORG_UNIT_NAME Server Farm

[ policy_match ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied

[ req_extensions ]
basicConstraints        = CA:false
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer
keyUsage                = digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage        = serverAuth, clientAuth
subjectAltName          = \$ENV::SUBJECT_ALT_NAME

" >$ca_dir/signing.conf
}

# Create root and intermediate CAs
# init_CA
function init_CA {
    # Ensure CAs are built
    make_root_CA $ROOT_CA_DIR
    make_int_CA $INT_CA_DIR $ROOT_CA_DIR

    # Create the CA bundle
    cat $ROOT_CA_DIR/cacert.pem $INT_CA_DIR/cacert.pem >>$INT_CA_DIR/ca-chain.pem
    cat $INT_CA_DIR/ca-chain.pem >> $SSL_BUNDLE_FILE

    if is_fedora; then
        sudo cp $INT_CA_DIR/ca-chain.pem /usr/share/pki/ca-trust-source/anchors/devstack-chain.pem
        sudo update-ca-trust
    elif is_ubuntu; then
        sudo cp $INT_CA_DIR/ca-chain.pem /usr/local/share/ca-certificates/devstack-int.crt
        sudo cp $ROOT_CA_DIR/cacert.pem /usr/local/share/ca-certificates/devstack-root.crt
        sudo update-ca-certificates
    fi
}

# Clean up the CA files
# cleanup_CA
function cleanup_CA {
    if is_fedora; then
        sudo rm -f /usr/share/pki/ca-trust-source/anchors/devstack-chain.pem
        sudo update-ca-trust
    elif is_ubuntu; then
        sudo rm -f /usr/local/share/ca-certificates/devstack-int.crt
        sudo rm -f /usr/local/share/ca-certificates/devstack-root.crt
        sudo update-ca-certificates
    fi
}

# Create an initial server cert
# init_cert
function init_cert {
    if [[ ! -r $DEVSTACK_CERT ]]; then
        if [[ -n "$TLS_IP" ]]; then
            # Lie to let incomplete match routines work
            TLS_IP="DNS:$TLS_IP"
        fi
        make_cert $INT_CA_DIR $DEVSTACK_CERT_NAME $DEVSTACK_HOSTNAME "$TLS_IP"

        # Create a cert bundle
        cat $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt $INT_CA_DIR/cacert.pem >$DEVSTACK_CERT
    fi
}


# make_cert creates and signs a new certificate with the given commonName and CA
# make_cert ca-dir cert-name "common-name" ["alt-name" ...]
function make_cert {
    local ca_dir=$1
    local cert_name=$2
    local common_name=$3
    local alt_names=$4

    # Only generate the certificate if it doesn't exist yet on the disk
    if [ ! -r "$ca_dir/$cert_name.crt" ]; then
        # Generate a signing request
        $OPENSSL req \
            -sha1 \
            -newkey rsa \
            -nodes \
            -keyout $ca_dir/private/$cert_name.key \
            -out $ca_dir/$cert_name.csr \
            -subj "/O=${ORG_NAME}/OU=${ORG_UNIT_NAME} Servers/CN=${common_name}"

        if [[ -z "$alt_names" ]]; then
            alt_names="DNS:${common_name}"
        else
            alt_names="DNS:${common_name},${alt_names}"
        fi

        # Sign the request valid for 1 year
        SUBJECT_ALT_NAME="$alt_names" \
        $OPENSSL ca -config $ca_dir/signing.conf \
            -extensions req_extensions \
            -days 365 \
            -notext \
            -in $ca_dir/$cert_name.csr \
            -out $ca_dir/$cert_name.crt \
            -subj "/O=${ORG_NAME}/OU=${ORG_UNIT_NAME} Servers/CN=${common_name}" \
            -batch
    fi
}


# Make an intermediate CA to sign everything else
# make_int_CA ca-dir signing-ca-dir
function make_int_CA {
    local ca_dir=$1
    local signing_ca_dir=$2

    # Create the root CA
    create_CA_base $ca_dir
    create_CA_config $ca_dir 'Intermediate CA'
    create_signing_config $ca_dir

    if [ ! -r "$ca_dir/cacert.pem" ]; then
        # Create a signing certificate request
        $OPENSSL req -config $ca_dir/ca.conf \
            -sha1 \
            -newkey rsa \
            -nodes \
            -keyout $ca_dir/private/cacert.key \
            -out $ca_dir/cacert.csr \
            -outform PEM

        # Sign the intermediate request valid for 1 year
        $OPENSSL ca -config $signing_ca_dir/ca.conf \
            -extensions ca_extensions \
            -days 365 \
            -notext \
            -in $ca_dir/cacert.csr \
            -out $ca_dir/cacert.pem \
            -batch
    fi
}

# Make a root CA to sign other CAs
# make_root_CA ca-dir
function make_root_CA {
    local ca_dir=$1

    # Create the root CA
    create_CA_base $ca_dir
    create_CA_config $ca_dir 'Root CA'

    # Create a self-signed certificate valid for 5 years
    $OPENSSL req -config $ca_dir/ca.conf \
        -x509 \
        -nodes \
        -newkey rsa \
        -days 21360 \
        -keyout $ca_dir/private/cacert.key \
        -out $ca_dir/cacert.pem \
        -outform PEM
}


# Certificate Input Configuration
# ===============================

# check to see if the service(s) specified are to be SSL enabled.
#
# Multiple services specified as arguments are ``OR``'ed together; the test
# is a short-circuit boolean, i.e it returns on the first match.
#
# Uses global ``SSL_ENABLED_SERVICES``
function is_ssl_enabled_service {
    local services=$@
    local service=""
    if [ "$USE_SSL" == "False" ]; then
        return 1
    fi
    for service in ${services}; do
        [[ ,${SSL_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
    done
    return 1
}


# Ensure that the certificates for a service are in place. This function does
# not check that a service is SSL enabled, this should already have been
# completed.
#
# The function expects to find a certificate, key and CA certificate in the
# variables {service}_SSL_CERT, {service}_SSL_KEY and {service}_SSL_CA. For
# example for keystone this would be KEYSTONE_SSL_CERT, KEYSTONE_SSL_KEY and
# KEYSTONE_SSL_CA.
#
# If it does not find these certificates then the devstack-issued server
# certificate, key and CA certificate will be associated with the service.
#
# If only some of the variables are provided then the function will quit.
function ensure_certificates {
    local service=$1

    local cert_var="${service}_SSL_CERT"
    local key_var="${service}_SSL_KEY"
    local ca_var="${service}_SSL_CA"

    local cert=${!cert_var}
    local key=${!key_var}
    local ca=${!ca_var}

    if [[ -z "$cert" && -z "$key" && -z "$ca" ]]; then
        local cert="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
        local key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
        local ca="$INT_CA_DIR/ca-chain.pem"
        eval ${service}_SSL_CERT=\$cert
        eval ${service}_SSL_KEY=\$key
        eval ${service}_SSL_CA=\$ca
        return # the CA certificate is already in the bundle
    elif [[ -z "$cert" || -z "$key" || -z "$ca" ]]; then
        die $LINENO "Missing either the ${cert_var} ${key_var} or ${ca_var}" \
                    "variable to enable SSL for ${service}"
    fi

    cat $ca >> $SSL_BUNDLE_FILE
}

# Enable the mod_ssl plugin in Apache
function enable_mod_ssl {
    echo "Enabling mod_ssl"

    if is_ubuntu; then
        sudo a2enmod ssl
    elif is_fedora; then
        # Fedora enables mod_ssl by default
        :
    fi
    if ! sudo `which httpd || which apache2ctl` -M | grep -w -q ssl_module; then
        die $LINENO "mod_ssl is not enabled in apache2/httpd, please check for it manually and run stack.sh again"
    fi
}


# Proxy Functions
# ===============

# Starts the TLS proxy for the given IP/ports
# start_tls_proxy front-host front-port back-host back-port
function start_tls_proxy {
    local f_host=$1
    local f_port=$2
    local b_host=$3
    local b_port=$4

    stud $STUD_PROTO -f $f_host,$f_port -b $b_host,$b_port $DEVSTACK_CERT 2>/dev/null
}


# Cleanup Functions
# =================


# Stops all stud processes. This should be done only after all services
# using tls configuration are down.
function stop_tls_proxy {
    killall stud
}


# Remove CA along with configuration, as well as the local server certificate
function cleanup_CA {
    rm -rf "$DATA_DIR/CA" "$DEVSTACK_CERT"
}

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
