#!/bin/bash

set -eu

CONFDIR=/usr/share/kali-defaults/etc/ssh/ssh_config.d

###############################################################################
# The drop-in config file will become out-of-date every now and then, whenever
# new versions of openssh hit Kali Rolling. We want the test to fail in this
# situation, to force developers to update the drop-in config file, and release
# a new version of kali-defaults.
###############################################################################

# The drop-in file must exist
if ! [ -e $CONFDIR/kali-wide-compat.conf ]; then
	echo "ERROR: $CONFDIR/kali-wide-compat.conf doesn't exist" >&2
	exit 1
fi

# The drop-in file must be up-to-date, with regard to SSH
./bin/update-ssh-config > generated.conf
if ! cmp $CONFDIR/kali-wide-compat.conf generated.conf; then
	echo "ERROR: $CONFDIR/kali-wide-compat.conf is outdated, probably due" >&2
	echo "to a change in openssh-client. Diff below:" >&2
	diff $CONFDIR/kali-wide-compat.conf generated.conf >&2
	exit 1
fi
rm generated.conf

###############################################################################
# Out of the box, Kali's SSH has no special configuration, it's just a standard
# SSH client, meaning that legacy algorithms and ciphers must be disabled. Note
# that we don't try to be exhaustive in those tests, we just test a few algos
# and ciphers.
#
# For reference, some links for various deprecations:
# * https://www.openssh.com/txt/release-7.0: diffie-hellman-group1-sha1, ssh-dss
# * https://www.openssh.com/txt/release-7.2: aes256-cbc
# * https://www.openssh.com/txt/release-8.8: ssh-rsa
###############################################################################

get_values() {
	local values=
	# ssh complains that "Pseudo-terminal will not be allocated ..." on
	# stderr, causing the test to fail. Needs '-T' to fix it.
	values=$(ssh -q -T -G '*' | grep -i "^$1 " | cut -d" " -f2-)
	if [ -z "$values" ]; then
		echo "ERROR: Failed to get option $1" >&2
		exit 1
	fi
	echo "$values"
}

assert_disabled() {
	if get_values $1 | grep -q -E "(^|,)$2(,|$)"; then
		echo "ERROR: $1: $2 is enabled" >&2
		exit 1
	fi
}

# Test
assert_disabled KexAlgorithms diffie-hellman-group1-sha1
assert_disabled HostKeyAlgorithms ssh-dss
assert_disabled PubkeyAcceptedAlgorithms ssh-dss
assert_disabled Ciphers aes256-cbc
assert_disabled HostKeyAlgorithms ssh-rsa
assert_disabled PubkeyAcceptedAlgorithms ssh-rsa

###############################################################################
# When the "Wide Compatibility" mode is enabled, the algos and ciphers listed
# above should be enabled.
#
# As of OpenSSH 9.8p1, DSA keys are no longer supported, so we no longer test
# ssh-dss.
###############################################################################

assert_enabled() {
	if ! get_values $1 | grep -q -E "(^|,)$2(,|$)"; then
		echo "ERROR: $1: $2 is NOT enabled" >&2
		exit 1
	fi
}

# Let's enable SSH wide compat mode
cp $CONFDIR/kali-wide-compat.conf /etc/ssh/ssh_config.d/

# Test again
assert_enabled KexAlgorithms diffie-hellman-group1-sha1
#assert_enabled HostKeyAlgorithms ssh-dss
#assert_enabled PubkeyAcceptedAlgorithms ssh-dss
assert_enabled Ciphers aes256-cbc
assert_enabled HostKeyAlgorithms ssh-rsa
assert_enabled PubkeyAcceptedAlgorithms ssh-rsa

# Cleanup (probably not needed)
rm /etc/ssh/ssh_config.d/kali-wide-compat.conf

exit 0
