#!/usr/bin/env bash
# ssl/import -- use a certificate bought elsewhere
#
# The pair is copied into the state directory with 0600 permissions and the
# vhost is generated from the registry, so a later regeneration keeps working.
set -o pipefail
SELF=$(readlink -f "${BASH_SOURCE[0]}")
NV_BASE=$(cd "$(dirname "$SELF")/../../.." && pwd)
export NV_BASE
# shellcheck source=/dev/null
. "$NV_BASE/lib/core/bootstrap.sh"

nv_require_root || exit 1
ui_header "$(t ssl_m_import)"

site_pick_domain "${1:-}" || exit $?
domain=$SITE_DOMAIN

printf '  %s: ' "$(t ssl_import_cert_path)"
read -r cert_src || exit 130
printf '  %s: ' "$(t ssl_import_key_path)"
read -r key_src || exit 130
cert_src=$(nv_trim "$cert_src"); key_src=$(nv_trim "$key_src")

[ -r "$cert_src" ] || { ui_err "$(t ssl_import_no_file "$cert_src")"; exit 2; }
[ -r "$key_src" ]  || { ui_err "$(t ssl_import_no_file "$key_src")"; exit 2; }

if ! openssl x509 -noout -in "$cert_src" 2>/dev/null; then
    ui_err "$(t ssl_import_bad_cert)"
    exit 2
fi

# certificate and key must belong together
cert_mod=$(openssl x509 -noout -modulus -in "$cert_src" 2>/dev/null | openssl md5)
key_mod=$(openssl rsa -noout -modulus -in "$key_src" 2>/dev/null | openssl md5)
if [ -z "$cert_mod" ] || [ "$cert_mod" != "$key_mod" ]; then
    ui_err "$(t ssl_import_mismatch)"
    exit 2
fi

subject=$(openssl x509 -noout -subject -in "$cert_src" 2>/dev/null | sed 's/^subject=//')
end=$(openssl x509 -noout -enddate -in "$cert_src" 2>/dev/null | cut -d= -f2)
ui_kv "$(t ssl_import_subject)" "$subject"
ui_kv "$(t ssl_expires)" "$end"
ui_blank
ui_confirm "$(t ssl_import_confirm)" n || exit 0

dir="$NV_STATE_DIR/certs/$domain"
install -d -m 0700 "$dir"
cp -a "$cert_src" "$dir/fullchain.pem"
cp -a "$key_src"  "$dir/privkey.pem"
chmod 0600 "$dir/privkey.pem" "$dir/fullchain.pem"

prev_ssl=$(nv_site_get "$domain" ssl none)
nv_site_set "$domain" ssl custom
nv_site_set "$domain" ssl_cert "$dir/fullchain.pem"
nv_site_set "$domain" ssl_key  "$dir/privkey.pem"

if ! site_apply_vhost "$domain"; then
    nv_site_set "$domain" ssl "$prev_ssl"
    site_apply_vhost "$domain" >/dev/null 2>&1 || true
    exit 1
fi
svc_reload nginx
nv_trace ssl-import "$domain"

ui_ok "$(t ssl_import_done "$domain")"
ui_info "$(t ssl_import_renew_note)"
exit 0
