#!/bin/sh

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

. alterator-sh-functions

root_chpasswd()
{
    echo "root:$1"|/usr/sbin/chpasswd
    #little run-parts
    for f in "$hooks_dir"/*; do
	[ -f "$f" -a -x "$f" ] || continue
	[ "${f%.rpm*}" = "$f" -a "${f%\~}" = "$f" ] || continue

	echo "$1"|"$f" >&2
    done
}

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' '
}

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"
}

list_key()
{
    local line comment comment_field

    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
}

add_key()
{
    local new_line="$1" && shift
    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

    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"
}

del_key()
{
    local old_fp="$1";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"
}


on_message()
{
	case "$in_action" in
		list)
		    case "$in__objects" in
			avail_key) list_key;;
		    esac
		    ;;
		read)
		    write_string_param passwd_auto "$(pwqgen)"
		    ! test_bool "$in_auto"
		    write_bool_param auto "$?"
		    ;;
		write)
		    if [ -n "$in_commit" ];then
			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
		    elif [ -n "$in_add_key" -a -n "$in_key_file" ];then
			add_key "$in_key_file"
		    elif [ -n "$in_del_key" -a -n "$in_key" ];then
			del_key "$in_key"
		    fi
		    ;;
	esac
}

message_loop
# vim: set ts=8:
