#!/bin/sh

# Below come some pieces of ssh_config(5), taken from version 9.3p1-1 of the
# openssh-client package.
#
# ~~~~~~~~
#
# Ciphers
#   Specifies the ciphers allowed and their order of preference.
#
# HostKeyAlgorithms
#   Specifies the host key signature algorithms that the client wants to use in
#   order of preference.
#
# KexAlgorithms
#   Specifies the available KEX (Key Exchange) algorithms.
#
# MACs
#   Specifies the MAC (message authentication code) algorithms in order of
#   preference.
#
# PubkeyAcceptedAlgorithms
#   Specifies the signature algorithms that will be used for public key
#   authentication
#
# ~~~~~~~~
#
# For each of these options, this script gives us ALL the items available,
# sorted as such: 1) the items that are enabled by default, ordered as they are
# by default (order of preference) then 2) the items that are disabled by
# default, sorted alphabetically.

# WARNING!  The SSH client configuration is documented in ssh_config(5), but
# that's not the whole story. There are third-party (programs or library) that
# read and parse this configuration, and they might not support fully the
# syntax.
#
# Therefore, it's best to refrain from using syntax that was recently added, or
# that is poorly documented (such as wildcards). Otherwise we get bug reports
# such as [1].
#
# Example of third-party libraries which parse the ssh_config file:
# * libssh: doesn't support +,-,^ signs in version 0.10.x or below, cf [2]
# * libssh2: no idea what or what's not supported
# * paramiko: no idea either
#
# [1]: https://github.com/vanhauser-thc/thc-hydra/issues/792
# [2]: https://gitlab.com/libssh/libssh-mirror/-/merge_requests/319

set -eu

export LC_ALL=C

get_all() {
	# Enabled items, sorted per order of preference
	ssh -T -F none -G '*' | grep -i "^$1 " | cut -d' ' -f2- | tr , '\n' > $1.enabled
	# Enabled items, alphabetically sorted
	sort -u < $1.enabled > $1.enabled.sorted
	# All items, alphabetically sorted
	ssh -T -Q $1 | sort -u > $1.all.sorted
	# Disabled items, alphabetically sorted
	comm -13 $1.enabled.sorted $1.all.sorted > $1.disabled.sorted
	# Final output: enabled items per order of preference,
	# followed by disabled items, alphabetically sorted.
	cat $1.enabled $1.disabled.sorted
}

cd $(mktemp -d)
trap "rm -fr $(pwd)" EXIT

Ciphers=$(get_all ciphers | paste -d, -s)
HostKeyAlgorithms=$(get_all hostkeyalgorithms | paste -d, -s)
KexAlgorithms=$(get_all kexalgorithms | paste -d, -s)
MACs=$(get_all macs | paste -d, -s)
PubkeyAcceptedAlgorithms=$(get_all pubkeyacceptedalgorithms | paste -d, -s)

cat << EOF
# The configuration below enables legacy ciphers and algorithms,
# to allow interacting with old servers that still use those.
#
# If the setting(s) in this file are not desirable, do NOT
# modify this file. Instead, start 'kali-tweaks' in a
# terminal and change the setting from there.

Host *
    Ciphers $Ciphers
    KexAlgorithms $KexAlgorithms
    HostKeyAlgorithms $HostKeyAlgorithms
    MACs $MACs
    PubkeyAcceptedAlgorithms $PubkeyAcceptedAlgorithms
EOF
