254 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash -efu
 | |
| # based on https://github.com/legionus/pinentry-bash/blob/master/pinentry-bash
 | |
| 
 | |
| ### This file is covered by the GNU General Public License,
 | |
| ### which should be included with libshell as the file LICENSE.
 | |
| ### All copyright information are listed in the COPYING.
 | |
| 
 | |
| #exec 2>/tmp/pinentry.log
 | |
| #set -x
 | |
| 
 | |
| VERSION='1.0'
 | |
| FLAVOR='bash'
 | |
| 
 | |
| ############################### PATCH #################################
 | |
| . ~/.config/bemenu/env.sh
 | |
| #######################################################################
 | |
| 
 | |
| keyinfo=''
 | |
| error=''
 | |
| timeout=0
 | |
| touch_file=''
 | |
| 
 | |
| readonly def_desc='Enter password for GPG key'
 | |
| readonly def_prompt='Password:'
 | |
| readonly def_title='GPG Key Credentials'
 | |
| readonly def_repeat='Confirm password for GPG key'
 | |
| readonly def_labelok='OK'
 | |
| readonly def_labelnotok='Do not do this'
 | |
| readonly def_labelcancel='Cancel'
 | |
| 
 | |
| # from /usr/include/gpg-error.h
 | |
| readonly GPG_ERR_NO_ERROR=0
 | |
| readonly GPG_ERR_TIMEOUT=62
 | |
| readonly GPG_ERR_CANCELED=99
 | |
| readonly GPG_ERR_NOT_CONFIRMED=114
 | |
| readonly GPG_ERR_ASS_PARAMETER=280
 | |
| 
 | |
| strerror()
 | |
| {
 | |
| 	case "$1" in
 | |
| 		$GPG_ERR_NO_ERROR)      echo "Success" ;;
 | |
| 		$GPG_ERR_TIMEOUT)       echo "Timeout" ;;
 | |
| 		$GPG_ERR_CANCELED)      echo "Operation cancelled" ;;
 | |
| 		$GPG_ERR_NOT_CONFIRMED) echo "Not confirmed" ;;
 | |
| 		$GPG_ERR_ASS_PARAMETER) echo "IPC parameter error" ;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| assuan_result()
 | |
| {
 | |
| 	[ "$1" -gt 0 ] &&
 | |
| 		echo -n "ERR $(( 5 << 24 | $1 )) " ||
 | |
| 		echo -n "OK "
 | |
| 	strerror "$1"
 | |
| }
 | |
| 
 | |
| cmd_settimeout()
 | |
| {
 | |
| 	[ -n "${1##0*}" ] && [ -n "${1##*[!0-9]*}" ] && [ "$1" -gt 0 ] 2>/dev/null ||
 | |
| 		return 0
 | |
| 	timeout="$1"
 | |
| 	assuan_result $GPG_ERR_NO_ERROR
 | |
| }
 | |
| 
 | |
| cmd_setkeyinfo()
 | |
| {
 | |
| 	[ "$1" = "--clear" ] &&
 | |
| 		keyinfo="" ||
 | |
| 		keyinfo="$1"
 | |
| 	assuan_result $GPG_ERR_NO_ERROR
 | |
| }
 | |
| 
 | |
| set_text_variable()
 | |
| {
 | |
| 	printf -v "$1" "${2//%/\\x}"
 | |
| 	eval "set_$1=1"
 | |
| 	assuan_result $GPG_ERR_NO_ERROR
 | |
| }
 | |
| 
 | |
| cmd_setoption()
 | |
| {
 | |
| 	case "$1" in
 | |
| 		default-prompt=*) set_text_variable prompt "${1#*=}"      ;;
 | |
| 		default-ok=*)     set_text_variable labelok "${1#*=}"     ;;
 | |
| 		default-cancel=*) set_text_variable labelcancel "${1#*=}" ;;
 | |
| 		touch-file=*)
 | |
| 			touch_file="${1#*=}"
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 		*)
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| cmd_getinfo()
 | |
| {
 | |
| 	case "$1" in
 | |
| 		version)
 | |
| 			echo "D $VERSION"
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 		pid)
 | |
| 			echo "D $BASHPID"
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 		flavor)
 | |
| 			echo "D $FLAVOR"
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 		ttyinfo)
 | |
| 			echo "D - - - - $(id -u 2>/dev/null || echo 0)/$(id -g 2>/dev/null || echo 0) -"
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 		*)
 | |
| 			assuan_result $GPG_ERR_ASS_PARAMETER
 | |
| 			;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| cmd_getpin()
 | |
| {
 | |
| 	local ret=0 result output password=1 repeatpassword=3
 | |
| 
 | |
| 	output="$(
 | |
| 		echo -n "|"
 | |
| ############################### PATCH #################################
 | |
| 		bemenu \
 | |
| 			--password indicator \
 | |
| 			--prompt "${prompt:-$def_prompt}" \
 | |
| 			</dev/null | tr -d '\n'
 | |
| 		ret=${PIPESTATUS[0]}
 | |
| #		yad \
 | |
| #			--splash \
 | |
| #			--no-markup \
 | |
| #			--title="${title:-$def_title}" \
 | |
| #			--form \
 | |
| #			--separator="\n" \
 | |
| #			--field="${desc:-$def_desc}:LBL" \
 | |
| #			--field="${prompt:-$def_prompt}:H" \
 | |
| #			${set_repeat:+--field="${repeat:-$def_repeat}:LBL"} \
 | |
| #			${set_repeat:+--field="${prompt-$def_prompt}:H"} \
 | |
| #			${error:+--field="$error:LBL"} \
 | |
| #			--button="${labelok:-$def_labelok}:0" \
 | |
| #			--button="${labelcancel:-$def_labelcancel}:1" \
 | |
| #			--timeout="${timeout:-0}" \
 | |
| #			</dev/null || ret=$?
 | |
| ######################################################################
 | |
| 		echo -n "|"
 | |
| 		exit $ret
 | |
| 	)" || ret=$?
 | |
| 
 | |
| 	set_error='' error=''
 | |
| 
 | |
| 	case "$ret" in
 | |
| 		1)  assuan_result $GPG_ERR_CANCELED; return 0; ;;
 | |
| 		70) assuan_result $GPG_ERR_TIMEOUT;  return 0; ;;
 | |
| 	esac
 | |
| 
 | |
| 	output="${output#|}"
 | |
| 	output="${output%|}"
 | |
| 
 | |
| ############################### PATCH #################################
 | |
| 	declare -A result
 | |
| 	result[$password]="$output"
 | |
| 	result[$repeatpassword]="$output"
 | |
| #	readarray -t result <<<"$output"
 | |
| #	output=''
 | |
| #
 | |
| #######################################################################
 | |
| 	if [ -n "${set_repeat-}" ]; then
 | |
| 		set_repeat='' repeat=''
 | |
| 
 | |
| 		if [ "${result[$password]}" != "${result[$repeatpassword]}" ]; then
 | |
| 			cmd_confirm --one-button "${repeaterror:-Error: Passwords did not match.}"
 | |
| 			assuan_result $GPG_ERR_NOT_CONFIRMED
 | |
| 			return
 | |
| 		fi
 | |
| 		echo "S PIN_REPEATED"
 | |
| 	fi
 | |
| 
 | |
| 	[ -z "$touch_file" ] ||
 | |
| 		touch "$touch_file"
 | |
| 
 | |
| 	echo "D ${result[$password]}"
 | |
| 	assuan_result $GPG_ERR_NO_ERROR
 | |
| }
 | |
| 
 | |
| cmd_confirm()
 | |
| {
 | |
| 	local ret=0 showmsg='' showcfm=1
 | |
| 
 | |
| 	if [ "$1" = '--one-button' ]; then
 | |
| 		shift
 | |
| 		showmsg=1
 | |
| 		showcfm=
 | |
| 	fi
 | |
| 
 | |
| 	yad \
 | |
| 		--splash \
 | |
| 		--no-markup \
 | |
| 		--title="${title:-$def_title}" \
 | |
| 		--text="${1:-${desc:-$def_desc}}" \
 | |
| 		${showmsg:+--button="${labelok:-$def_labelok}:0"} \
 | |
| 		${showcfm:+${error:+--field="$error:LBL"}} \
 | |
| 		--timeout="${timeout:-0}" \
 | |
| 		< /dev/null ||
 | |
| 		ret=$?
 | |
| 
 | |
| 	set_error='' error=''
 | |
| 
 | |
| 	case "$ret" in
 | |
| 		0)  assuan_result $GPG_ERR_NO_ERROR ;;
 | |
| 		1)  assuan_result $GPG_ERR_CANCELED ;;
 | |
| 		70) assuan_result $GPG_ERR_TIMEOUT ;;
 | |
| 		*)  assuan_result $GPG_ERR_NOT_CONFIRMED ;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| echo "OK Your orders please"
 | |
| 
 | |
| while :; do
 | |
| 	read -r cmd args 2>/dev/null ||
 | |
| 		continue
 | |
| 
 | |
| 	#echo >&2 "$cmd: $args"
 | |
| 
 | |
| 	case "$cmd" in
 | |
| 		BYE)
 | |
| 			echo "OK closing connection"
 | |
| 			exit 0
 | |
| 			;;
 | |
| 		GETPIN)         cmd_getpin ;;
 | |
| 		CONFIRM)        cmd_confirm "$args" ;;
 | |
| 		MESSAGE)        cmd_confirm --one-button ;;
 | |
| 		GETINFO)        cmd_getinfo "$args" ;;
 | |
| 		SETTIMEOUT)     cmd_settimeout "$args" ;;
 | |
| 		SETKEYINFO)     cmd_setkeyinfo "$args" ;;
 | |
| 		OPTION)         cmd_setoption "$args" ;;
 | |
| 		SETDESC)        set_text_variable desc "$args" ;;
 | |
| 		SETPROMPT)      set_text_variable prompt "$args" ;;
 | |
| 		SETTITLE)       set_text_variable title "$args" ;;
 | |
| 		SETOK)          set_text_variable labelok "$args" ;;
 | |
| 		SETCANCEL)      set_text_variable labelcancel "$args" ;;
 | |
| 		SETNOTOK)       set_text_variable labelnotok "$args" ;;
 | |
| 		SETERROR)       set_text_variable error "$args" ;;
 | |
| 		SETREPEAT)      set_text_variable repeat "$args" ;;
 | |
| 		SETREPEATERROR) set_text_variable repeaterror "$args" ;;
 | |
| 		*)
 | |
| 			assuan_result $GPG_ERR_NO_ERROR
 | |
| 			;;
 | |
| 	esac
 | |
| done
 |