#!/bin/sh
LPM_BASE="/var/lib/lpm" export LPM_BASE
LPM_VERSION="1.0.22"
LPM_ARCH="`uname -m`"
lpmlog()
{
	msg="$1"
	logger -t lpm-key -p info "$msg"
}


lpm_dellock()
{
	plock="$LPM_BASE/lock"
	rm -f "$plock"
}

lpm_getlock()
{
	plock="$LPM_BASE/lock"
	if [ -f "$plock" ]
	then
		return 1
	fi
	touch "$plock"
	if [ -f "$plock" ]
	then
		return 0
	else
		return 2
	fi
}

key_add()
{
	if [ -r "$crt" ]
	then
		openssl x509  -in "$crt" -noout
		rc=$?
		if [ "$rc" != "0" ]
		then
			echo "Error reading certificate" >&2
			return $rc
		fi
	else
		echo "Error: $crt was not fould" >&2
		return 1
	fi
	crt_subj="`openssl x509 -in "$crt" -subject -noout |cut -f2- -d ' '`"
	crt_sign="`openssl x509 -in "$crt" -issuer -noout |cut -f2- -d ' '`"
	if [ "$crt_subj" != "$crt_sign" ]
	then
		echo "Error: Certificate is not self-signed" >&2
		return 3
	fi
	crt_name="`echo "$crt_subj"|sed -e 's,^/CN=\([^/]*\)/emailAddress=.*$,\1,g'`"
	if [ "x$crt_name" = "x$crt_subj" ]
	then
		echo "Error parsing certificate" >&2
		return 4
	fi
	crt_mail="`echo "$crt_subj"|sed -e 's,^/CN=[^/]*/emailAddress=\(.*\)$,\1,g'`"
	if [ "x$crt_name" = "x$crt_subj" ]
	then
		echo "Error parsing certificate" >&2
		return 4
	fi
	crt_hash="`openssl x509 -hash -in "$crt" -noout`"
	if [ "x$crt_name" = "x" ] || [ "x$crt_mail" = "x" ] || [ "x$crt_hash" = "x" ]
	then
		echo "Error parsing certificate" >&2
		return 4
	fi
	fingerprint="`openssl x509 -in $crt -fingerprint -noout |cut -f2 -d '='`"
	if [ -r "$LPM_BASE/certstore/$crt_hash.crt" ]
	then
		echo "Error: A certificate with this hash is already installed" >&2
		return 5
	fi
	
	if [ "$force" = "0" ]
	then
		printf "\nName        : %s\n" "$crt_name"
		printf "Mailaddress : %s\n" "$crt_mail"
		printf "Fingerprint : %s\n\n" "$fingerprint"
		printf "Do you want to install this certificate to the certstore? [y/N] "
		read usr_ans
		printf "\n"
		if [ "x$usr_ans" != "xy" ]
		then
			echo "Not installing certificate" >&2
			return 0
		fi
	fi
	lpm_getlock
	rc=$?
	if [ "$rc" != "0" ]
	then
		echo "error: failed to get exclusive repository lock" >&2
		return 2
	fi
	if [ "$verbose" = "1" ]
	then
		echo "installing key for $crt_name <$crt_mail> as $crt_hash"
	fi
	lpmlog "installing key for $crt_name <$crt_mail> as $crt_hash"
	cp "$crt" "$LPM_BASE/certstore/$crt_hash.crt"
	lpm_dellock
	exit $rc
}

key_del()
{
	echo "Deleting of keys is not yet implemented" >&2
	return 1
}

key_lst()
{
	if [ "$verbose" = "0" ]
	then
		printf "%-8s %-35s %-35s\n" "Hash" "Name" "Mailaddress"
		printf "%-8s %-35s %-35s\n" "----" "----" "-----------"
	fi
	for crt in $(ls -1tr $LPM_BASE/certstore/*.crt)
	do
		crt_subj="`openssl x509 -in "$crt" -subject -noout |cut -f2- -d ' '`"
		crt_name="`echo "$crt_subj"|sed -e 's,^/CN=\([^/]*\)/emailAddress=.*$,\1,g'`"
		crt_mail="`echo "$crt_subj"|sed -e 's,^/CN=[^/]*/emailAddress=\(.*\)$,\1,g'`"
		crt_hash="`openssl x509 -hash -in "$crt" -noout`"
		fingerprint="`openssl x509 -in $crt -fingerprint -noout |cut -f2 -d '='`"

		if [ "$verbose" = "1" ]
		then
			printf "\nName        : %s\n" "$crt_name"
			printf "Mailaddress : %s\n" "$crt_mail"
			printf "Hash        : %s\n" "$crt_hash"
			printf "Fingerprint : %s\n\n" "$fingerprint"
		else
			printf "%-8s %-35s %-35s\n" "$crt_hash" "$crt_name" "$crt_mail"
		fi
	done
	return 0
}
	



usage()
{
    echo "$0 : laconian package manager key manager"
    echo "Usage: "
    echo "$OPTUSG"
    return
}

OPTSTR="A:D:LfvVh"
OPTUSG="
    -h            hlp
    -v            verbose
    -V            version
    -A keyfile    add a key to the keystore
    -D keyid      delete a key from the keystore
    -L            list all installed keys
    -f            force, don't ask
"
force=0
lst=0
add=0
del=0

verbose=0
options=""

while getopts "$OPTSTR" opt
do
    case "$opt" in
        h) usage $progname; exit 0;;
        A) crt="$OPTARG"; add=1 ;;
        D) key="$OPTARG"; del=1 ;;
        L) lst=1 ;;
		V) echo "lpm-key $LPM_VERSION"; exit 0;;
        v) verbose=1 ;;
        f) force=1 ;;
        *) usage; exit 1;;
    esac
done
if [ "x$OPTIND" != "x" ] && [ "$OPTIND" != "0" ]
then
	CURR_OPT="1"
	while ( [ "$CURR_OPT" != "$OPTIND" ] )
	do
		shift
		CURR_OPT="`expr $CURR_OPT + 1`"
	done
fi

if [ "$lst" = "1" ]
then
	key_lst
	exit $?
fi

if [ "$add" = "1" ]
then
	key_add
	exit $?
fi

if [ "$del" = "1" ]
then
	key_del
	exit $?
fi


if [ "$verbose" = "1" ]
then
        verbarg="-v"
else
        verbarg=""
fi

