#!/usr/bin/env bash
# .sh/bin/newssl 20160121 - 20230527
# Copyright (C) 1995-2023 Mark Constable <markc@renta.net> (AGPL-3.0)

# Depends on nginx and DNS already resolving to requested (sub)domains

# Provide DHOOK env for dns-01 invocation, ex; use 'se' and add...
#
#export DHOOK=hook.sh
#export CF_EMAIL=your@email.address
#export CF_KEY=Xbd63051f5f80a73790c3cddea812f735615X
#
#Login to Cloudflare for CF_KEY then go to https://www.cloudflare.com/a/account/my-account
#cd $LECFG; wget https://raw.githubusercontent.com/BotoX/dehydrated-cloudflare-hook/master/hook.sh

[[ -z $1 || $1 =~ -h ]] &&
    echo "Usage: newssl domain [subd subd...[--force][--nocfg][0.0.0.0]]" && exit 1

VHOST=$1
_ARGS="$2 $3 $4 $5 $6 $7 $8 $9"
IPREG="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
IPARG=
NOCFG=

[[ $DEBUG ]] && set -x

for SUB in $_ARGS; do
    [[ $SUB =~ $IPREG ]] && IPARG="$SUB:" && continue
    [[ $SUB == '--force' ]] && SUBDS="$SUBDS --force" && continue
    [[ $SUB == '--nocfg' ]] && NOCFG=yes && continue
    SUBDS="$SUBDS -d $SUB.$VHOST"
done

AHOST=$(hostname -f | tr 'A-Z' 'a-z')
VPATH="/home/u"
WPATH="$VPATH/$AHOST/var/www/html"
WACME="$WPATH/.well-known/acme-challenge"
LEGIT="https://github.com/lukas2511/dehydrated.git"
LECFG="/etc/dehydrated"
C_SSL="/etc/ssl"
C_WEB="/etc/nginx"

[[ ! -d $WPATH ]] && echo "ERROR: $WPATH does not exist" && exit 2

[[ ! -d $LECFG ]] &&
    mkdir $LECFG &&
    git clone --depth 1 $LEGIT $LECFG &&
    chmod +x $LECFG/dehydrated &&
    ln -s $C_SSL $LECFG/certs >/dev/null

[[ ! -f $LECFG/accounts/*/account_key.pem ]] &&
    $LECFG/dehydrated --register --accept-terms >/dev/null

if [[ ! -d $WACME ]]; then
    mkdir -p $WACME
    chown $(stat -c "%u:%g" $WPATH) -R $WPATH/.well-known
fi

cd $LECFG
echo "CONTACT_EMAIL=$AMAIL" >config

if [[ $DHOOK ]]; then
    echo "CHALLENGETYPE=dns-01" >>config
    echo "HOOK=/etc/dehydrated/$DHOOK" >>config
else
    echo "WELLKNOWN=$WACME" >>config
fi

./dehydrated -c -d $VHOST$SUBDS

if [[ $? -eq 0 ]]; then
    if [[ -z $NOCFG ]]; then
        if [[ ! -f $C_WEB/sites-enabled/$VHOST ]]; then

            if grep -q autoconfig. <<<"$SUBDS"; then
                cat <<EOS >>$C_WEB/sites-enabled/$VHOST
server {
    listen                      ${IPARG}443 ssl http2;
    server_name                 autoconfig.$VHOST;
    location                    ~* /mail/config-v1.1.xml {
        root                    /home/u/$MHOST/var/www/.well-known/;
        try_files               /autodiscover.php =404;
        fastcgi_pass            unix:/home/u/$MHOST/var/run/fpm.sock;
        include                 fastcgi.conf;
        fastcgi_param           SERVER_ADDR "";
        fastcgi_param           REMOTE_ADDR \$http_x_real_ip;
    }
    ssl_certificate             $C_SSL/$VHOST/fullchain.pem;
    ssl_certificate_key         $C_SSL/$VHOST/privkey.pem;
    ssl_trusted_certificate     $C_SSL/$VHOST/chain.pem;
}
EOS
            fi

            if grep -q autodiscover. <<<"$SUBDS"; then
                cat <<EOS >>$C_WEB/sites-enabled/$VHOST
server {
    listen                      ${IPARG}443 ssl http2;
    server_name                 autodiscover.$VHOST;
    location                    ~* /autodiscover/autodiscover.xml {
        root                    /home/u/$MHOST/var/www/.well-known/;
        try_files               /autodiscover.php =404;
        fastcgi_pass            unix:/home/u/$MHOST/var/run/fpm.sock;
        include                 fastcgi.conf;
        fastcgi_param           SERVER_ADDR "";
        fastcgi_param           REMOTE_ADDR \$http_x_real_ip;
    }
    ssl_certificate             $C_SSL/$VHOST/fullchain.pem;
    ssl_certificate_key         $C_SSL/$VHOST/privkey.pem;
    ssl_trusted_certificate     $C_SSL/$VHOST/chain.pem;
}
EOS
            fi

            if grep -q mail. <<<"$SUBDS"; then
                cat <<EOS >>$C_WEB/sites-enabled/$VHOST
server {
    listen                      ${IPARG}443 ssl http2;
    server_name                 mail.$VHOST;
    include                     $C_WEB/hcp.conf;
    include                     $C_WEB/common.conf;
    ssl_certificate             $C_SSL/$VHOST/fullchain.pem;
    ssl_certificate_key         $C_SSL/$VHOST/privkey.pem;
    ssl_trusted_certificate     $C_SSL/$VHOST/chain.pem;
}
EOS
            fi

            if grep -q www. <<<"$SUBDS"; then
                cat <<EOS >>$C_WEB/sites-enabled/$VHOST
server {
    listen                      ${IPARG}443 ssl http2;
    server_name                 www.$VHOST;
    ssl_certificate             $C_SSL/$VHOST/fullchain.pem;
    ssl_certificate_key         $C_SSL/$VHOST/privkey.pem;
    return 301                  https://$VHOST\$request_uri;
}
EOS
            fi

            cat <<EOS >>$C_WEB/sites-enabled/$VHOST
server {
    listen                      ${IPARG}443 ssl http2;
    server_name                 $VHOST;
    include                     $C_WEB/common.conf;
    ssl_certificate             $C_SSL/$VHOST/fullchain.pem;
    ssl_certificate_key         $C_SSL/$VHOST/privkey.pem;
    ssl_trusted_certificate     $C_SSL/$VHOST/chain.pem;
}
EOS
        fi
        # Cleanup any dangling left over self signed certificates
        if [[ -n "$(find $C_WEB/sites-enabled -maxdepth 1 -name '*.selfsigned' -print -quit)" ]]; then
            echo "### Remove $C_WEB/sites-enabled/*.selfsigned"
            rm $C_WEB/sites-enabled/*.selfsigned
        fi
        chmod 755 $C_SSL/$VHOST
    else
        echo "### Warning: not creating $C_WEB/sites-enabled/$VHOST"
    fi
fi

[[ $DEBUG ]] && set +x