diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | pinentry-rofi.sh | 52 | ||||
-rw-r--r-- | tests/foundational.bats | 73 |
3 files changed, 88 insertions, 38 deletions
@@ -3,3 +3,4 @@ # SPDX-License-Identifier: CC0-1.0 pinentry-rofi.log +.bats/ diff --git a/pinentry-rofi.sh b/pinentry-rofi.sh index 57e6022..7f01b2e 100755 --- a/pinentry-rofi.sh +++ b/pinentry-rofi.sh @@ -54,24 +54,32 @@ split_line() { echo "${out_arr[@]}" } -# Originally from https://www.baeldung.com/linux/decoding-encoded-urls -rfc3986-decode() { - strg="${*}" - printf '%s' "${strg%%[%+]*}" - j="${strg#"${strg%%[%+]*}"}" - strg="${j#?}" - case "${j}" in "%"* ) - printf '%b' "\\0$(printf '%o' "0x${strg%"${strg#??}"}")" - strg="${strg#??}" - ;; "+"* ) printf ' ' - ;; * ) return - esac - if [ -n "${strg}" ] ; then rfc3986-decode "${strg}"; fi +# Originally from https://github.com/sfinktah/bash/blob/master/rawurlencode.inc.sh +# There is also more explanation and documentation there +rawurlencode() { + local string="${1}" + local strlen=${#string} + local encoded="" + local pos c o + + for (( pos=0 ; pos<strlen ; pos++ )); do + c=${string:$pos:1} + case "$c" in + [-_.~a-zA-Z0-9] ) o="${c}" ;; + * ) printf -v o '%%%02x' "'$c" + esac + encoded+="${o}" + done + printf "%s" "${encoded}" # You can either set a return variable (FASTER) } -# This is something too clever, doesn’t work in the script -# from https://stackoverflow.com/a/70560850/164233 -# rfc3986decode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } +rawurldecode() { + # This is perhaps a risky gambit, but since all escape characters must be + # encoded, we can replace %NN with \xNN and pass the lot to printf -b, which + # will decode hex for us + + printf '%b' "${1//%/\\x}" +} rofi_cmd="rofi -dmenu -input /dev/null -password" INSIDE_BATS=${INSIDE_BATS:-0} @@ -156,7 +164,9 @@ while : ; do #SETDESC Please enter the passphrase for the ssh key%0A ke:yf:in:ge:rp:ri:nt IFS=" " line_arr=($(split_line "$line")) log_debug "line_arr: ${line_arr[*]}" - win_mesg="$(rfc3986-decode "${line_arr[*]}")" + temp_str="$(rawurldecode "${line_arr[*]}")" + log_debug "temp_str: ${temp_str}" + win_mesg="$(rawurlencode "${temp_str}")" assuan_send "OK" elif [[ "$line" =~ ^SETPROMPT ]] ; then #SETPROMPT Passphrase: @@ -164,6 +174,14 @@ while : ; do log_debug "line_arr: ${line_arr[*]}" win_prompt="${line_arr[0]}" assuan_send "OK" + elif [[ "$line" =~ ^SETTITLE ]] ; then + IFS=" " line_arr=($(split_line "$line")) + log_debug "line_arr: ${line_arr[*]}" + log_debug "line_arr: ${line_arr[*]}" + temp_str="$(rawurldecode "${line_arr[*]}")" + log_debug "temp_str: ${temp_str}" + win_title="$(rawurlencode "${temp_str}")" + assuan_send "OK" elif [[ "$line" =~ ^GETPIN ]] ; then passw=None sys_env="$(systemctl --user show-environment | tr -s " \t\n" " ")" diff --git a/tests/foundational.bats b/tests/foundational.bats index 29b8881..2d53b10 100644 --- a/tests/foundational.bats +++ b/tests/foundational.bats @@ -1,42 +1,73 @@ #!/usr/bin/env bats setup() { - export INSIDE_BATS=1 - DIR="$( cd "$(dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )" - source "$(readlink -f "${DIR}/../pinentry-rofi.sh")" + export INSIDE_BATS=1 + DIR="$( cd "$(dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )" + # shellcheck source=pinentry-rofi.sh + source "$(readlink -f "${DIR}/../pinentry-rofi.sh")" + + mapfile -d '' instr <<- EOF + Please enter the passphrase to unlock the OpenPGP secret key: + "Matěj Cepl <mcepl@cepl.eu>" + 4096-bit RSA key, ID 77D15A36BD4211B2, + created 2016-04-27 (main key ID 79205802880BC9D8). + EOF } log_debug() { - echo "$@" >> /dev/stderr + echo "$@" >> /dev/stderr } @test "split line" { - line_arr=($(split_line "GETINFO version")) - [ "${line_arr[0]}" = "version" ] + line_arr=($(split_line "GETINFO version")) + [ "${line_arr[0]}" = "version" ] } @test "split line rmfirst" { - line_arr=($(split_line "GETINFO version" 0)) - [ "${line_arr[0]}" = "version" ] + line_arr=($(split_line "GETINFO version" 0)) + [ "${line_arr[0]}" = "version" ] } @test "split line no-rmfirst" { - IFS=" " line_arr=($(split_line "GETINFO version" 1)) - [[ "$(declare -p line_arr)" == 'declare -'[aA]* ]] - [[ "${line_arr[0]}" == "GETINFO" ]] - [[ ${#line_arr[@]} -eq 2 ]] - [[ "${line_arr[1]}" == "version" ]] + IFS=" " line_arr=($(split_line "GETINFO version" 1)) + [[ "$(declare -p line_arr)" == 'declare -'[aA]* ]] + [[ "${line_arr[0]}" == "GETINFO" ]] + [[ ${#line_arr[@]} -eq 2 ]] + [[ "${line_arr[1]}" == "version" ]] } -@test "decode RFC-3986 encoded string" { - local instr="Please enter the passphrase to unlock the OpenPGP secret key:%0A%22Matěj Cepl <mcepl@cepl.eu>%22%0A4096-bit RSA key, ID 77D15A36BD4211B2,%0Acreated 2016-04-27 (main key ID 79205802880BC9D8).%0A" - local expected="Please enter the passphrase to unlock the OpenPGP secret key:\n\ +@test "decode example RFC-3986 encoded string" { + local instr="Please enter the passphrase to unlock the OpenPGP secret key:%0A%22Matěj Cepl <mcepl@cepl.eu>%22%0A4096-bit RSA key, ID 77D15A36BD4211B2,%0Acreated 2016-04-27 (main key ID 79205802880BC9D8).%0A" + local expected="Please enter the passphrase to unlock the OpenPGP secret key:\n\ \"Matěj Cepl <mcepl@cepl.eu>\"\n\ 4096-bit RSA key, ID 77D15A36BD4211B2,\n\ created 2016-04-27 (main key ID 79205802880BC9D8)." - log_debug "expected: ${expected}" - log_debug "instr: ${instr}" - observed=$(rfc3986-decode "${instr}") - log_debug "observed: ${observed}" - [[ "$observed" == "$expected" ]] || diff -u <(echo -e "$observed") <(echo -e "$expected") + log_debug "expected: ${expected}" + log_debug "instr: ${instr}" + observed=$(rawurldecode "${instr}") + log_debug "observed: ${observed}" + [[ "$observed" == "$expected" ]] || diff -u <(echo -e "$observed") <(echo -e "$expected") +} + +@test "encode into RFC-3986 encoded string" { + local expected + + expected="Please%20enter%20the%20passphrase%20to%20unlock%20the%20OpenPGP%20secret%20key%3a%0a%22Matěj%20Cepl%20%3cmcepl%40cepl.eu%3e%22%0a4096-bit%20RSA%20key%2c%20ID%2077D15A36BD4211B2%2c%0acreated%202016-04-27%20%28main%20key%20ID%2079205802880BC9D8%29.%0a" + log_debug "expected: ${expected}" + log_debug "instr: ${instr}" + observed=$(rawurlencode "${instr}") + log_debug "observed: ${observed}" + [[ "$observed" == "$expected" ]] || diff -u <(echo -e "$observed") <(echo -e "$expected") +} + +@test "encode/decode forth and back with RFC-3986 encoded string" { + local workstr observed + + log_debug "instr: ${instr}" + workstr=$(rawurlencode "${instr}") + log_debug "workstr: ${workstr}" + observed="$(rawurldecode "${workstr}")" + log_debug "observed: ${observed}" + # There is some mockery with trailing newlines + [[ "$observed" == "$instr" ]] || diff -u <(echo "$observed") <(printf "%s" "$instr") } |