Codebase list kwalletcli / lintian-fixes/main kwalletcli_getpin
lintian-fixes/main

Tree @lintian-fixes/main (Download .tar.gz)

kwalletcli_getpin @lintian-fixes/mainraw · history · blame

#!/usr/bin/env mksh
# $MirOS: contrib/hosted/tg/code/kwalletcli/kwalletcli_getpin,v 1.23 2016/08/30 17:38:44 tg Exp $
#-
# Copyright © 2009, 2010, 2011, 2016
#	mirabilos <m@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission
# is granted to deal in this work without restriction, including un‐
# limited rights to use, publicly perform, distribute, sell, modify,
# merge, give away, or sublicence.
#
# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
# the utmost extent permitted by applicable law, neither express nor
# implied; without malicious intent or gross negligence. In no event
# may a licensor, author or contributor be held liable for indirect,
# direct, other damage, loss, or other issues arising in any way out
# of dealing in the work, even if advised of the possibility of such
# damage or existence of a defect, except proven that it results out
# of said person’s immediate fault when using the work as intended.

unset LC_ALL LANGUAGE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY \
    LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION
[[ -z $LC_CTYPE ]] && LC_CTYPE=en_US.UTF-8
export LANG=C LC_CTYPE LC_MESSAGES GPG_TERM GPG_TTY
set -U

quiet=0
nl='
'

function die {
	local rv=$1

	shift
	(( quiet )) || print -u2 -r -- "$@"
	exit $rv
}

function checkline {
	local res

	print -pr -- "$@"
	read -p res || die 3 pinentry died
	[[ $res = OK@(| *) ]] || die 4 "got '$res' for '$*'"
}

function toutf8 {
	local intext="$*" outtext=''
	typeset -i i=0 n=${#intext}
	typeset -i1 c
	typeset -Uui16 -Z5 x

	while (( i < n )); do
		c=1#${intext:(i++):1}
		if (( (c & 0xFF80) == 0xEF80 )); then
			(( c &= 0xFF ))
		fi
		if (( c < 32 || c == 1#% || c == 1#_ )); then
			let x=c
			outtext=${outtext}%${x#16#}
		elif (( c > 0x7E && c < 0xA0 )); then
			outtext=${outtext}
		else
			outtext=${outtext}${c#1#}
		fi
	done

	print -nr -- "$outtext"
}

function tolat1 {
	local intext="$*" outtext=''
	typeset -i i=0 n=${#intext}
	typeset -i1 c
	typeset -Uui16 -Z5 x

	while (( i < n )); do
		c=1#${intext:(i++):1}
		(( c = c < 0x80 ? c : (c & 0xFF80) == 0xEF80 ? c :
		    c < 0x0100 ? c | 0xEF00 : 0xEFFF ))
		outtext=${outtext}${c#1#}
	done

	print -nr -- "$outtext"
}

function usage {
	print -u2 "Usage:\tkwalletcli_getpin [-q] [-b | -m | -p prompt]"
	print -u2 "\t[-E | -e errortext] [-N NoBtn] [-t desctext] [-Y YesBtn]"
	print -u2 "Returns: 0=ok (pw on stdout), 1=cancel, 2+=error"
	exit 2
}

function get_tty {
	GPG_TTY=$(tty) || GPG_TTY=
	[[ -n $GPG_TTY ]] || die 5 Please set GPG_TTY yourself
}


asktext='Hast Du das Paßwort?'
askprompt='Code:'
askerror=''
askbool=0
btnyes=
btnno=

while getopts 'bEe:hmN:p:qt:Y:' ch; do
	case $ch {
	(b)	askbool=1 ;;
	(E)	askerror='' ;;
	(e)	askerror=$OPTARG ;;
	(m)	askbool=2 ;;
	(N)	btnno=$OPTARG ;;
	(p)	askprompt=$OPTARG ;;
	(q)	quiet=1 ;;
	(t)	asktext=$OPTARG ;;
	(Y)	btnyes=$OPTARG ;;
	(*)	usage ;;
	}
done
shift $((OPTIND - 1))
(( $# )) && usage

set -A pe_args
if [[ -n $DISPLAY ]]; then
	pe_args[${#pe_args[*]}]=--display
	pe_args[${#pe_args[*]}]=$DISPLAY
fi

[[ -n $PINENTRY ]] || PINENTRY=pinentry
if "${PINENTRY%-kwallet}" --version >/dev/null 2>&1; then
	"${PINENTRY%-kwallet}" "${pe_args[@]}" |&
	subpid=$?
	read -p res || die 3 pinentry died
	[[ $res = OK@(| *) ]] || die 4 "got '$res' for '$*'"
	got_pe=1
	trap "kill $subpid; die 6 caught SIGHUP" 1
	trap "kill $subpid; die 6 caught SIGINT" 2
	trap "kill $subpid; die 6 caught SIGQUIT" 3
	trap "kill $subpid; die 6 caught SIGTRAP" 5
	trap "kill $subpid; die 6 caught SIGPIPE" 13
	trap "kill $subpid; die 6 caught SIGTERM" 15
else
	got_pe=0
fi

[[ -z $DISPLAY && -z $GPG_TTY ]] && get_tty
[[ -z $GPG_TERM ]] && GPG_TERM=${TERM:-vt100}

if (( !got_pe )); then
	thetext=
	sep=
	(( askbool )) || if [[ -n $askerror ]]; then
		thetext="*ERROR*: $(toutf8 "$askerror")"
		sep=$nl$nl
	fi
	if [[ -n $asktext ]]; then
		thetext=$thetext$sep$(toutf8 "$asktext")
		sep=$nl$nl
	fi
	(( askbool )) || if [[ -n $askprompt ]]; then
		thetext=$thetext$sep$(toutf8 "$askprompt")
	fi

	whence -p xmessage >/dev/null || unset DISPLAY
	if (( askbool )) && [[ -n $DISPLAY ]]; then
		buttons=${btnyes:-OK},${btnno:-Cancel}
		(( askbool == 2 )) && buttons=${btnyes:-OK}
		LC_ALL=C xmessage -nearmouse -buttons "$buttons" \
		    -default "${btnyes:-OK}" "$(tolat1 "$thetext")"
		rc=$?
		(( rc == 101 )) && exit 0
		(( rc == 102 )) && exit 1
		die 3 xmessage errored out
	fi
	if (( askbool == 2 )); then
		thetext="$thetext$nl${nl}[OK${btnyes:+=$btnyes}] "
	elif (( askbool )); then
		thetext="$thetext$nl${nl}[Y${btnyes:+=$btnyes}|N${btnno:+=$btnno}] "
	elif [[ -n $askprompt ]]; then
		thetext="$thetext "
	else
		thetext=$thetext$nl
	fi
	trap 'stty echo; exit 1' 1 2 3 13 15
	[[ -n $GPG_TTY ]] || get_tty
	while :; do
		print -nru2 -- "$thetext"
		stty -echo
		IFS= read -r resp
		rc=$?
		print -u2
		stty echo
		if (( rc )); then
			exit 3
		elif (( askbool == 2 )); then
			exit 0
		elif (( !askbool )); then
			print -nr -- "$resp"
			exit 0
		fi
		[[ $resp = ?(1|-1|[Tt]?([Rr][Uu][Ee])|[Yy]?([Ee][Ss])) ]] && \
		    exit 0
		[[ $resp = @(0|[Ff]?([Aa][Ll][Ss][Ee])|[Nn]?([Oo])) ]] && \
		    exit 1
		print -u2 "Try again: 1/T[rue]/Y[es] vs 0/F[alse]/N[o]"
	done 0<>$GPG_TTY 2>&0
fi

[[ -z $GPG_TTY ]] || checkline "OPTION ttyname=$GPG_TTY"
[[ -z $GPG_TERM ]] || checkline "OPTION ttytype=$GPG_TERM"
[[ -z $LC_CTYPE ]] || checkline "OPTION lc-ctype=$LC_CTYPE"
[[ -z $LC_MESSAGES ]] || checkline "OPTION lc-messages=$LC_MESSAGES"

[[ -n $asktext ]] && checkline "SETDESC $(toutf8 "$asktext")"
[[ -n $askprompt ]] && checkline "SETPROMPT $(toutf8 "$askprompt")"
[[ -n $askerror ]] && checkline "SETERROR $(toutf8 "$askerror")"

[[ -n $btnyes ]] && checkline "SETOK $(toutf8 "$btnyes")"
[[ -n $btnno ]] && checkline "SETCANCEL $(toutf8 "$btnno")"

if (( askbool == 2 )); then
	print -p MESSAGE
elif (( askbool )); then
	print -p CONFIRM
else
	print -p GETPIN
fi
read -p res || die 3 pinentry died
if [[ $res = @(D )* ]]; then
	pass=${res#D }
	read -p res || die 3 pinentry died
else
	pass=
fi
if [[ $res = OK@(| *) ]]; then
	rv=0
	print -nr -- "$pass"
else
	rv=1
fi
exec 3>&p; exec 3>&-
exit $rv