#!/bin/sh

alterator_api_version=1
authorizedkeys_file=/etc/openssh/authorized_keys/root
hooks_dir=/usr/lib/alterator/hooks/root.d/

. alterator-sh-functions

## installer support, $ALTERATOR_DESTDIR - exported by installer.

DESTDIR=""
CHROOT_EXEC=""

if [ -d "${ALTERATOR_DESTDIR:-}" ]; then
    DESTDIR="$ALTERATOR_DESTDIR"
    CHROOT_EXEC="chroot $DESTDIR"
fi

## SSH keys management

fingerprint()
{
    local line="$1";shift
    local tempfile="$(mktemp -t alterator-root.XXXXXX)"

    echo "$line">"$tempfile"
    local v=
    v="$(ssh-keygen -l -f "$tempfile")" &&
	echo "$v"|cut -f2 -d' '
    rm -f -- "$tempfile"
}

parse_authorized_keys()
{
    local line="$1" && shift
    local opts= keytype= key= comment=
    local tempfile="$(mktemp -t alterator-root.XXXXXX)"

    printf '%s\n' "$line" >"$tempfile"
    case "$line" in
	ssh-*)
	    IFS=' ' read keytype key comment <"$tempfile"
	    ;;
	*)
	    IFS=' ' read opts keytype key comment <"$tempfile"
	;;
    esac

    case "$1" in
	options)
	    printf '%s' "$opts"
	    ;;
	type)
	    printf '%s' "$keytype"
	    ;;
	key)
	    printf '%s' "$key"
	    ;;
	comment)
	    printf '%s' "$comment"
	    ;;
	*)
	    printf '%s\t%s\t%s\t%s' "$opts" "$keytype" "$key" "$comment"
	    ;;
    esac

    rm -rf -- "$tempfile"
}

ssh_key_list()
{
    local line comment comment_field

    [ ! -s "$authorizedkeys_file" ] ||
	while IFS=' ' read -r line; do
	    comment="$(parse_authorized_keys "$line" comment)"
	    case "$comment" in
		alterator-trust@*)
		    ;;
		*)
		    fingerprint "$line"
		    ;;
	    esac
	done<"$authorizedkeys_file"|
	    write_enum
}

ssh_key_add()
{
    [ -s "$in_key_file" ] || return 0

    local new_line="$(cat "$in_key_file")"
    local new_fp="$(fingerprint "$new_line")"
    local comment

    comment="$(parse_authorized_keys "$new_line" comment)"
    if [ -z "$new_fp" -o '(' -n "$comment" -a -z "${comment##alterator-trust@*}" ')' ];then
	write_error "`_ "Invalid ssh key"`"
	return
    fi

    [ ! -s "$authorizedkeys_file" ] ||
	while IFS=' ' read -r line; do
	    local fp="$(fingerprint "$line")"
	    if [ "$fp" = "$new_fp" ];then
		write_error "`_ "Same ssh key already exists"`"
		return
	    fi
	done<"$authorizedkeys_file"

    echo "$new_line" >>"$authorizedkeys_file"
}

ssh_key_del()
{
    [ -s "$authorizedkeys_file" -a -n "$in_key" ] || return

    local old_fp="$in_key";shift
    local tempfile="$(mktemp -t alterator-root.XXXXXX)"

    while IFS=' ' read -r line; do
	local fp="$(fingerprint "$line")"
	local comment="$(parse_authorized_keys "$line" comment)"
	[ "$fp" = "$old_fp" -o '(' -n "$comment" -a -z "${comment##alterator-trust@*}" ')'  ] ||
	    echo "$line"
    done<"$authorizedkeys_file" >"$tempfile"

    mv -f "$tempfile" "$authorizedkeys_file"
}

## root's password management

root_chpasswd()
{
    echo "root:$1" | $CHROOT_EXEC "/usr/sbin/chpasswd"

    #little run-parts
    for f in "$DESTDIR/$hooks_dir"/*; do
	[ -f "$f" -a -x "$f" ] || continue
	[ "${f%.rpm*}" = "$f" -a "${f%\~}" = "$f" ] || continue

	echo "$1"| $CHROOT_EXEC "${f#$DESTDIR}" >&2
    done
}

change_password()
{
    if test_bool "$in_auto" && [ -z "$in_passwd_auto" ]; then
	write_error "`_ "You should define a password for system administrator"`"
    elif test_bool "$in_auto" && [ -n "$in_passwd_auto" ]; then
	root_chpasswd "$in_passwd_auto"
    elif [ -z "$in_passwd_1" -a -z "$in_passwd_2" ]; then
	write_error "`_ "You should define a password for system administrator"`"
    elif [ "$in_passwd_1" != "$in_passwd_2" ]; then
	write_error "`_ "Passwords mismatch"`"
    else
	root_chpasswd "$in_passwd_1"
    fi
}

generate_password()
{
    write_string_param passwd_auto "$(pwqgen)"
}

alterator_export_proc ssh_key_add
alterator_export_proc ssh_key_del
alterator_export_proc ssh_key_list

alterator_export_proc change_password
alterator_export_proc generate_password

message_loop
