#!/bin/bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# SPDX-FileCopyrightText: 2021 grommunio GmbH

SSL_BUNDLE_T="/etc/grommunio-common/ssl/server-bundle.pem"
SSL_KEY_T="/etc/grommunio-common/ssl/server.key"

selfcert()
{

  echo "Using CN=${FQDN}, SAN=DNS:${FQDN},DNS:autodiscover.${DOMAIN}" >>"${LOGFILE}" 2>&1

  SELFCERT_MSG="\
(Scroll this dialog with the 'j' and 'k' keys)

The certificate validity period starts at $(date).
If any of the clocks of this host, or the client, is inaccurate, the certificate may be flagged for that.

When creating the profile, Outlook will present a dialog similar to:

   ┌──
     X  The security certificate was issued by a
        company you have not chosen to trust.
    ok  The security certificate date is valid
    ok  The security certificate has a valid name

    Do you want to proceed? [Yes/No/View Certificate]
                                                    ──┘

On that dialog, you must choose \"View Certificate\" and explicitly install the self-signed certificate to use it succesfully."

  dialog --no-mouse --colors --cr-wrap --clear \
    --backtitle "grommunio Setup" \
    --title "TLS certificate (self-signed)" \
    --yes-label "Continue" \
    --no-label "Cancel" \
    --yesno "${SELFCERT_MSG}" 0 0 \
    && STATUS=$? || STATUS=$?
  dialog_exit $STATUS

  openssl req -x509 -new -nodes -out "${SSL_BUNDLE_T}" -keyout "${SSL_KEY_T}" \
          -subj "/CN=${FQDN}" -addext "subjectAltName = DNS:${FQDN}, DNS:autodiscover.${DOMAIN}" >>"${LOGFILE}" 2>&1

  cp -f "${SSL_BUNDLE_T}" "/usr/local/share/ca-certificates/"
  update-ca-certificates

}

fullca()
{

  export SSL_COUNTRY SSL_STATE SSL_LOCALITY SSL_ORG SSL_OU SSL_EMAIL SSL_PASS SSL_DAYS
  export FQDN DOMAIN SSL_BUNDLE_T SSL_KEY_T
  if ! "$DATADIR/common/fullca.sh" >>"${LOGFILE}" 2>&1; then
    echo "Certificate generation was not successful. Check "${LOGFILE}"."
    return 1
  fi
  return 0
  cp -f "${SSL_BUNDLE_T}" "/usr/local/share/ca-certificates/"
  update-ca-certificates

}

owncert() {

  if [ -z "${SSL_BUNDLE}" ] || [ -z "${SSL_KEY}" ] ; then
    echo "TLS certificate and/or key not provided."
    return 1
  fi
  cp -f "${SSL_BUNDLE}" "${SSL_BUNDLE_T}"
  cp -f "${SSL_KEY}" "${SSL_KEY_T}"
  cp -f "${SSL_BUNDLE_T}" "/usr/local/share/ca-certificates/"
  update-ca-certificates
  return 0

}

letsencrypt() {
  local PROG_MSG="Getting a Let's Encrypt certificate..."
  local SERVER_ARGS=''

  if [ -n "$GSETUP_ACME_SERVER_URL" ]; then
	  SERVER_ARGS="--server ${GSETUP_ACME_SERVER_URL}"
  fi

  progress 0 "$PROG_MSG"
  apt-get install -y python3-yaml python3-certbot python3-certbot-nginx nginx >>"${LOGFILE}" 2>&1
  progress 60 "$PROG_MSG"
  {
    firewall-cmd --add-port=80/tcp --zone=public --permanent
    firewall-cmd --add-service=https --zone=public --permanent
    firewall-cmd --reload
  } >>"${LOGFILE}" 2>&1

  [ -e "/etc/nginx/conf.d/grommunio.conf" ] && mv "/etc/nginx/conf.d/grommunio.conf" "/etc/nginx/conf.d/grommunio.conf.grommunio-setup"

  progress 75 "$PROG_MSG"
  local CERTBOT_OUT=''
  while ! CERTBOT_OUT=$(certbot certonly -n --nginx --agree-tos \
    --preferred-challenges http \
    --cert-name="${FQDN}" \
    -d "${SSL_DOMAINS}" \
    -m "${SSL_EMAIL}" \
    ${SERVER_ARGS} 2>&1); do

    writelog "Certbot output: '$CERTBOT_OUTPUT'"
    dialog --no-mouse --colors --cr-wrap --clear --backtitle "grommunio Setup" \
           --title "TLS certificate (Let's Encrypt)" \
           --yes-label "Retry" \
           --no-label "Exit" \
           --yesno "(Scroll this dialog with the 'j' and 'k' keys)\n\nIt seems the Let's Encrypt certificate could not be generated correctly. Examine the certbot output below, correct the problem, then retry OR exit and rerun setup later on a fresh system.\nThe command used to generate the certificates:\n\ncertbot certonly -n --standalone --agree-tos --preferred-challenges http --cert-name=\"${FQDN}\" -d \"${SSL_DOMAINS}\" -m \"${SSL_EMAIL}\"\n\ncertbot output was:\n\n${CERTBOT_OUT}" 0 0 \
           && STATUS=$? || STATUS=$?
    dialog_exit $STATUS
    progress 75 "Retrying getting an LE certificate..."
    writelog "Retrying certbot execution"
  done

  progress 95 "$PROG_MSG"

  [ -e "/etc/nginx/conf.d/grommunio.conf.grommunio-setup" ] && mv "/etc/nginx/conf.d/grommunio.conf.grommunio-setup" "/etc/nginx/conf.d/grommunio.conf"

  writelog "Fix /etc/letsencrypt directory perms - certbot documentation says you can do this"
  chmod -v 0755 /etc/letsencrypt/live /etc/letsencrypt/archive /etc/letsencrypt/renewal-hooks/deploy >>"${LOGFILE}" 2>&1

  # You only have to symlink the letsencrypt cert
  ln -snf "/etc/letsencrypt/live/${FQDN}/fullchain.pem" "${SSL_BUNDLE_T}"
  # Copy key so that gromox:gromox can be made to access it
  # - by default it does not change across renewals
  cp -f  "/etc/letsencrypt/live/${FQDN}/privkey.pem" "${SSL_KEY_T}"

  # set up certbot renewal hook
  local CONFIG="no_sans: false
sans: [${SSL_DOMAINS}]
systemd_reload: []
systemd_restart: [postfix, gromox-http, gromox-imap, gromox-pop3, gromox-delivery-queue]
"
  echo "$CONFIG" > /etc/grommunio-common/grommunio-certbot-deploy-hook.conf
  ln -snf /usr/share/grommunio-common/scripts/grommunio-certbot-deploy-hook /etc/letsencrypt/renewal-hooks/deploy/80-grommunio-certbot-deploy-hook
  echo "Letsencrypt Certbot certs installed" >> "${LOGFILE}" 2>&1

}
