#!/bin/sh
set -e

. /usr/share/debconf/confmodule
db_version 2.0

action="$1"

umask 022


get_config_option() {
	option="$1"

	[ -f /etc/ssh/sshd_config ] || return

	/usr/sbin/sshd -G | sed -n "s/^$option //Ip"
}


create_key() {
	msg="$1"
	shift
	hostkeys="$1"
	shift
	file="$1"
	shift

	if echo "$hostkeys" | grep -x "$file" >/dev/null && \
	   [ ! -f "$file" ] ; then
		printf %s "$msg"
		ssh-keygen -q -f "$file" -N '' "$@"
		echo
		if command -v restorecon >/dev/null 2>&1; then
			restorecon "$file" "$file.pub"
		fi
		ssh-keygen -l -f "$file.pub"
	fi
}


create_keys() {
	hostkeys="$(get_config_option HostKey)"

	create_key "Creating SSH2 RSA key; this may take some time ..." \
		"$hostkeys" /etc/ssh/ssh_host_rsa_key -t rsa
	create_key "Creating SSH2 DSA key; this may take some time ..." \
		"$hostkeys" /etc/ssh/ssh_host_dsa_key -t dsa
	create_key "Creating SSH2 ECDSA key; this may take some time ..." \
		"$hostkeys" /etc/ssh/ssh_host_ecdsa_key -t ecdsa
	create_key "Creating SSH2 ED25519 key; this may take some time ..." \
		"$hostkeys" /etc/ssh/ssh_host_ed25519_key -t ed25519
}


new_config=
workaround=

cleanup() {
	if [ "$new_config" ]; then
		rm -f "$new_config"
	fi
	if [ "$workaround" ]; then
		rm -f "$workaround"
	fi
}


create_sshdconfig() {
	prev_ver="$1"
	# XXX cjwatson 2016-12-24: This debconf template is very confusingly
	# named; its description is "Disable SSH password authentication for
	# root?", so true -> prohibit-password (the upstream default),
	# false -> yes.
	db_get openssh-server/permit-root-login
	permit_root_login="$RET"
	db_get openssh-server/password-authentication
	password_authentication="$RET"

	trap cleanup EXIT
	new_config="$(mktemp)"
	cp -aZ /usr/share/openssh/sshd_config "$new_config"
	if [ "$permit_root_login" != true ]; then
		sed -i 's/^#*PermitRootLogin .*/PermitRootLogin yes/' \
			"$new_config"
	fi
	if [ "$password_authentication" != true ]; then
		sed -i 's/^#PasswordAuthentication .*/PasswordAuthentication no/' \
			"$new_config"
	fi
	mkdir -pZ /etc/ssh

	# Workaround for LP: #1968873: if we have an sshd_config with a known
	# checksum, confirm it via ucf before applying the changes from
	# the new version.
	if dpkg --compare-versions "$prev_ver" lt-nl 1:9.0p1-1ubuntu7 \
	   && grep -q "^$(md5sum /etc/ssh/sshd_config | awk '{ print $1 }')" \
	              /usr/share/openssh/sshd_config.md5sum
	then
		workaround="$(mktemp)"
		sed -e'14,16d' "$new_config" > "$workaround"
		ucf --three-way --debconf-ok \
			--sum-file /usr/share/openssh/sshd_config.md5sum \
			"$workaround" /etc/ssh/sshd_config
	fi

	ucf --three-way --debconf-ok \
		--sum-file /usr/share/openssh/sshd_config.md5sum \
		"$new_config" /etc/ssh/sshd_config
	ucfr openssh-server /etc/ssh/sshd_config
}

setup_sshd_user() {
	if ! getent passwd sshd >/dev/null; then
		adduser --quiet --system --no-create-home --home /run/sshd --shell /usr/sbin/nologin sshd
	fi
}

if [ "$action" = configure ]; then
	create_sshdconfig "$2"
	create_keys
	setup_sshd_user
	if dpkg --compare-versions "$2" lt-nl 1:7.9p1-5 && \
	   [ -f /etc/ssh/moduli.dpkg-bak ]; then
	    # Handle /etc/ssh/moduli being moved from openssh-client to
	    # openssh-server.  If there were no user modifications, then we
	    # don't need to do anything special here; but if there were,
	    # then the dpkg-maintscript-helper calls from openssh-client's
	    # maintainer scripts will have saved the old file as .dpkg-bak,
	    # which we now move back into place.
	    mv /etc/ssh/moduli.dpkg-bak /etc/ssh/moduli
	fi
        if dpkg --compare-versions "$2" lt-nl 1:9.6p1-3ubuntu3~; then
                # Remove old socket activation drop-in configurations, if they exist.
                if [ -d /etc/systemd/system/ssh.socket.d ]; then
                        rm -f /etc/systemd/system/ssh.socket.d/addresses.conf
                        rmdir --ignore-fail-on-non-empty /etc/systemd/system/ssh.socket.d
                fi
                if [ -d /etc/systemd/system/ssh.service.d ]; then
                        rm -f /etc/systemd/system/ssh.service.d/00-socket.conf
                        rmdir --ignore-fail-on-non-empty /etc/systemd/system/ssh.service.d
                fi
                if [ -d /run/systemd/system ]; then
                        if dpkg --compare-versions "$2" ge 1:9.3p1-1ubuntu3~ && ! systemctl --quiet is-enabled ssh.socket; then
                                # If we are upgrading from a version that was
                                # already migrated, but ssh.socket is disabled,
                                # then leave it that way.
                                :
                        else
                                # Make sure ssh.service is disabled.
                                systemctl unmask ssh.service
                                systemctl disable --now ssh.service > /dev/null 2>&1

                                # sshd-socket-generator is invoked on daemon-reload.
                                systemctl daemon-reload
                                systemctl enable ssh.socket
                        fi
                fi
        fi
fi

# Automatically added by dh_installdeb/13.14.1ubuntu5
dpkg-maintscript-helper rm_conffile /etc/network/if-up.d/openssh-server 1:7.9p1-1\~ -- "$@"
# End automatically added section
# Automatically added by dh_installinit/13.14.1ubuntu5
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
	if [ -z "${DPKG_ROOT:-}" ] && [ -x "/etc/init.d/ssh" ]; then
		update-rc.d ssh defaults >/dev/null
		if [ -n "$2" ]; then
			_dh_action=restart
		else
			_dh_action=start
		fi
		invoke-rc.d --skip-systemd-native ssh $_dh_action || exit 1
	fi
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.14.1ubuntu5
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
	# The following line should be removed in trixie or trixie+1
	deb-systemd-helper unmask 'ssh.socket' >/dev/null || true

	# was-enabled defaults to true, so new installations run enable.
	if deb-systemd-helper --quiet was-enabled 'ssh.socket'; then
		# Enables the unit on first installation, creates new
		# symlinks on upgrades if the unit file has changed.
		deb-systemd-helper enable 'ssh.socket' >/dev/null || true
	else
		# Update the statefile to add new symlinks (if any), which need to be
		# cleaned up on purge. Also remove old symlinks.
		deb-systemd-helper update-state 'ssh.socket' >/dev/null || true
	fi
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.14.1ubuntu5
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
	if deb-systemd-helper debian-installed 'ssh.service'; then
		# The following line should be removed in trixie or trixie+1
		deb-systemd-helper unmask 'ssh.service' >/dev/null || true

		if deb-systemd-helper --quiet was-enabled 'ssh.service'; then
			# Create new symlinks, if any.
			deb-systemd-helper enable 'ssh.service' >/dev/null || true
		fi
	fi

	# Update the statefile to add new symlinks (if any), which need to be cleaned
	# up on purge. Also remove old symlinks.
	deb-systemd-helper update-state 'ssh.service' >/dev/null || true
fi
# End automatically added section


if [ -d /run/systemd/system ]; then
        # sshd-socket-generator is invoked on daemon-reload.
        systemctl daemon-reload

        if deb-systemd-helper --quiet was-enabled ssh.socket; then
                deb-systemd-invoke restart ssh.socket
        elif deb-systemd-helper --quiet was-enabled ssh.service; then
                deb-systemd-invoke restart ssh.service
        fi
fi

db_stop

exit 0
