#!/bin/bash
#
# Univention Setup
#  regenerate SSL certificates
#
# Copyright 2009-2021 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

force_recreate=0

while [ "$#" -gt 0 ]; do
	case $1 in
		--force-recreate)
			force_recreate=1
			shift 1
			;;
		*)
			echo "WARNING: Unknown parameter $1"
			shift 1
			;;
	esac
done

. /usr/lib/univention-system-setup/scripts/setup_utils.sh

eval "$(univention-config-registry shell)"

# SSL certificate can only be created on a Primary Directory Node
if [ "$server_role" != "domaincontroller_master" ]; then
	exit 0
fi

info_header "$0" "$(gettext "Generating SSL certificate")"

new_ssl_common=$(get_profile_var "ssl/common")
new_ssl_locality=$(get_profile_var "ssl/locality")
new_ssl_organization=$(get_profile_var "ssl/organization")
new_ssl_country=$(get_profile_var "ssl/country")
new_ssl_state=$(get_profile_var "ssl/state")
new_ssl_organizationalunit=$(get_profile_var "ssl/organizationalunit")
new_ssl_email=$(get_profile_var "ssl/email")

for var in "common" "locality" "organization" "country" "state" "organizationalunit" "email"; do
	old="ssl_$var"
	new="new_ssl_$var"

	if [ -n "${!new}" -a "${!old}" != "${!new}" ]; then
		recreate="yes"
		break
	fi
done

if [ "$recreate" = "yes" -o "$force_recreate" = "1" ]; then
	progress_steps 10
	progress_next_step 2
	progress_msg "$(gettext "Backing up old SSL certificate")"

	# remove old backup
	if [ -d /etc/univention/ssl.orig ]; then
		rm -rf /etc/univention/ssl.orig
	fi

	# backup old SSL certificates
	mv /etc/univention/ssl /etc/univention/ssl.orig

	if ! is_profile_var_true "ad/member"; then
		# try to set the clock before generating the root CA, otherwise it
		# is possible that the certificate is not valid at the end of the
		# installation Bug #13549
		timeout -k 5 15 rdate time.fu-berlin.de ||
			timeout -k 5 15 rdate 130.133.1.10 ||
			true
	fi

	# set UCR variables
	for var in "common" "locality" "organization" "country" "state" "organizationalunit" "email"; do
		old="ssl_$var"
		new="new_ssl_$var"
		if [ -n "${!new}" ]; then
			univention-config-registry set "${old/_//}=${!new}"
		fi
	done

	_certificate_creation_failed() {
		progress_next_step 10
		if [ -d /etc/univention/ssl ]; then
			rm -rf /etc/univention/ssl
		fi
		mv /etc/univention/ssl.orig /etc/univention/ssl

		progress_error "$(gettext "The SSL certificate creation failed. The old certificates have been restored.")"
		exit 1
	}

	# create new CA und certificates
	progress_next_step 5
	progress_msg "$(gettext "Generating SSL CA certificate.")"
	. /usr/share/univention-ssl/make-certificates.sh
	init || _certificate_creation_failed

	progress_next_step 7
	[ -d /etc/univention/ssl.orig ] && (
		cd /etc/univention/ssl.orig
		for fqdn in *; do
			# just check directories for certificates
			if [ ! -d "$fqdn" ]; then
				continue
			fi
			# ignore ucsCA and directory not containing a dot
			if [ "$fqdn" = "ucsCA" ] || ! echo "$fqdn" | grep '\.' &>/dev/null; then
				continue
			fi
			# if there is no certificate, ignore it
			if [ ! -e "$fqdn/cert.pem" ]; then
				continue
			fi
			# Do not regenerate the certificate for default directory
			if [ "$fqdn" = "unassigned-hostname.unassigned-domain" ]; then
				continue
			fi
			# get the hostname
			progress_msg "$(printf "$(gettext 'Recreate SSL certificate for %s')" "$fqdn")"
			host=$(echo "$fqdn" | sed 's/\([^.]*\)\..*/\1/')
			univention-certificate new -name "$fqdn" || progress_error "$(printf "$(gettext 'Could not recreate SSL certificate for %s.')" "$fqdn")"
			ln -snf "$host.$domainname" "/etc/univention/ssl/$host"
		done
	)
	progress_next_step 9

	# restart services
	systemctl restart slapd apache2 postfix

	progress_next_step 10
fi

exit 0
