#!/usr/bin/env bash
set -uo pipefail

# shellcheck disable=SC1091
source /usr/lib/biglinux-livecd/kernel-options

live_marker=/livefs-pkgs.txt
console_path=/dev/console
mkinitcpio_path=/usr/bin/mkinitcpio
mkinitcpio_shim=/usr/lib/biglinux-livecd/shims/mkinitcpio
systemctl_bin=/usr/bin/systemctl
mount_bin=/usr/bin/mount
mountpoint_bin=/usr/bin/mountpoint
chpasswd_bin=/usr/bin/chpasswd
sshd_bin=/usr/sbin/sshd
keygen_bin=/usr/bin/ssh-keygen
sshd_config=/etc/ssh/sshd_config
sshd_config_directory=/etc/ssh/sshd_config.d
sshd_dropin=$sshd_config_directory/90-biglinux-live.conf
sshd_include_pattern='^[[:space:]]*Include[[:space:]]+/etc/ssh/sshd_config\.d/\*\.conf'
sed_bin=/usr/bin/sed
lightdm_wallpaper_config=/etc/lightdm/lightdm.conf.d/99-comm-sync-wallpaper.conf
lightdm_autologin_pam=/etc/pam.d/lightdm-autologin
python_bin=/usr/bin/python
wizard_directory=/usr/share/biglinux/livecd

log() {
	printf 'biglinux-livecd: %s\n' "$*" >&2
}

disable_free_driver_detection() {
	"$systemctl_bin" mask --runtime --now mhwd-live.service
}

install_runtime_mkinitcpio_shim() {
	if [[ ! -x $mkinitcpio_path || ! -x $mkinitcpio_shim ]]; then
		log "mkinitcpio or its live shim is unavailable"
		return 1
	fi
	if "$mountpoint_bin" --quiet "$mkinitcpio_path"; then
		return 0
	fi
	"$mount_bin" --bind "$mkinitcpio_shim" "$mkinitcpio_path"
}

enable_live_ssh() {
	local warning live_user temporary_dropin effective
	live_user=$(id -nu 1000 2>/dev/null) || {
		log 'the default live user (UID 1000) was not found'
		return 1
	}
	[[ $live_user != root && $live_user =~ ^[a-z_][a-z0-9_-]*[$]?$ ]] || {
		log 'the default live user is invalid'
		return 1
	}
	printf -v warning '%s' 'WARNING: Live SSH enabled with the documented support password; disconnect untrusted networks.'
	printf '%s\n' "$warning" >"$console_path" || true
	log "$warning User: $live_user"
	printf '%s:%s\n' "$live_user" big | "$chpasswd_bin" || return 1

	[[ -f $sshd_config && ! -L $sshd_config ]] || {
		log 'sshd_config is missing or unsafe'
		return 1
	}
	/usr/bin/grep -Eq "$sshd_include_pattern" "$sshd_config" || {
		log 'sshd_config does not include the runtime drop-in directory'
		return 1
	}
	[[ -d $sshd_config_directory && ! -L $sshd_config_directory ]] || return 1
	temporary_dropin=$(mktemp "$sshd_config_directory/.biglinux-live.XXXXXX") || return 1
	if ! printf '%s\n' \
		'PermitRootLogin no' \
		"Match User $live_user" \
		'    PasswordAuthentication yes' \
		'    KbdInteractiveAuthentication no' \
		'Match All' >"$temporary_dropin"; then
		unlink -- "$temporary_dropin"
		return 1
	fi
	chmod 0644 -- "$temporary_dropin"
	mv -T -- "$temporary_dropin" "$sshd_dropin" || return 1
	# The live media ships no host keys, and sshd refuses to even check its
	# configuration without them.
	"$keygen_bin" -A || return 1
	"$sshd_bin" -t || return 1
	effective=$("$sshd_bin" -T -C "user=$live_user,addr=127.0.0.1,host=localhost") || return 1
	grep -Eiq '^passwordauthentication yes$' <<<"$effective" || return 1
	grep -Eiq '^kbdinteractiveauthentication no$' <<<"$effective" || return 1
	effective=$("$sshd_bin" -T -C 'user=root,addr=127.0.0.1,host=localhost') || return 1
	grep -Eiq '^permitrootlogin no$' <<<"$effective" || return 1
	"$systemctl_bin" restart sshd.service || return 1
	"$systemctl_bin" is-active --quiet sshd.service
}

is_owned_regular_file() {
	local path=$1
	[[ -f $path && ! -L $path && $(stat -c '%u' -- "$path") == "$EUID" ]]
}

remove_live_login_delays() {
	if is_owned_regular_file "$lightdm_wallpaper_config"; then
		"$sed_bin" -i '/^[[:space:]]*display-setup-script=/d' \
			"$lightdm_wallpaper_config"
	fi
	if is_owned_regular_file "$lightdm_autologin_pam"; then
		"$sed_bin" -i '/pam_gnome_keyring\.so/d; /pam_kwallet5\.so/d' \
			"$lightdm_autologin_pam"
	fi
}

preload_wizard_runtime() {
	[[ -x $python_bin && -f $wizard_directory/application.py ]] || return 0
	PYTHONPATH=$wizard_directory "$python_bin" -c 'import application' \
		</dev/null >/dev/null 2>&1 || log "Wizard preload failed; continuing normally"
}

main() {
	[[ -e $live_marker ]] || return 0
	remove_live_login_delays || return 1
	preload_wizard_runtime
	local driver
	driver=$(kernel_driver)
	case $driver in
	free) disable_free_driver_detection || return 1 ;;
	nonfree) install_runtime_mkinitcpio_shim || return 1 ;;
	esac
	if kernel_has_argument sshenable; then
		enable_live_ssh || log 'live SSH could not be enabled'
	fi
}

if [[ ${BASH_SOURCE[0]} == "$0" ]]; then
	main "$@"
fi
