#!/bin/sh
#
# Install packages as root via sudo. Callers may be granted password-less
# sudo for THIS wrapper only (see etc/sudoers.d/install), so every argument
# is checked before it reaches apt: a bare package specifier is allowed;
# the limited options -U, -t RELEASE, --target-release[=RELEASE] and
# --default-release[=RELEASE] are accepted (with strict validation); but
# general apt options ("-o Dir::...", "--"), paths ("/x", "./crafted.deb")
# and any shell metacharacter ("|", "&", ";", ...) are refused --
# otherwise a caller could escalate to full root (swap dpkg, run maintainer
# scripts, smuggle commands, ...).

if [ "$(id -u)" != 0 ]; then
	exec sudo "$0" "$@"
fi

# Refuse the archaic BSD getopt: it neither permutes nor quote-escapes, so
# `eval set --` would be unsafe and interspersed options wouldn't parse.
# Enhanced util-linux getopt returns non-zero from `-T`; the legacy one
# returns zero, which is the case we must abort on.
getopt -T >/dev/null 2>&1 && {
	printf '%s: enhanced getopt (util-linux) required\n' "${0##*/}" >&2
	exit 2
}

# Accept only name[:arch][=version]-style specifiers, optionally ending in
# "*" for globbing.
ok_arg()
{
	case "$1" in
		''|-*|/*|./*|*/*)				return 1 ;;
		*[!a-zA-Z0-9_.+:=*~-]*)			return 1 ;;
		[a-zA-Z0-9]*)					return 0 ;;
		*)								return 1 ;;
	esac
}

# Accept a -t/--target-release/--default-release token: a suite or codename
# such as "bookworm", "bookworm-backports" or "stable/main".
ok_release()
{
	case "$1" in
		''|-*|*[!a-zA-Z0-9_./-]*|*../*|*/..|*//*|*/)
										return 1 ;;
		*)								return 0 ;;
	esac
}

OPTS=$(getopt -o Ut: -l target-release:,default-release: -n "${0##*/}" -- "$@") ||
	exit 2
eval set -- "$OPTS"

U=
T=
while [ $# -gt 0 ]; do
	case "$1" in
	-U)
		U=y
		shift
		;;
	-t|--target-release|--default-release)
		T=$2
		shift 2
		;;
	--)
		shift
		break
		;;
	*)
		printf '%s: internal parse error: %s\n' "${0##*/}" "$1" >&2
		exit 2
		;;
	esac
done

if [ -n "$T" ] && ! ok_release "$T"; then
	printf '%s: refusing suspicious -t release argument: %s\n' \
		"${0##*/}" "$T" >&2
	exit 2
fi

for a in "$@"; do
	if ! ok_arg "$a"; then
		printf '%s: refusing suspicious package argument: %s\n' \
			"${0##*/}" "$a" >&2
		exit 2
	fi
done

# Prepend the validated -t token so it reaches apt ahead of the packages.
if [ -n "$T" ]; then
	set -- -t "$T" "$@"
fi

test -z "$U" || eatmydata apt update -qq
exec eatmydata apt install -y --no-remove "$@"
