From 10d67b6504766508d14f56a93e31ff8be4f5b7dd Mon Sep 17 00:00:00 2001 From: Narrat Date: Fri, 26 Sep 2025 12:15:18 +0200 Subject: [PATCH 1/2] gpg_decrypt: drop GnuPG 1.4.11 workaround Remove last remnant of 9e820f3de6a1b3ecab0662d0ae30c0b79d6d4e43 The latest release of gpg1 is 1.4.23 from 2018. It is safe to assume, that there is no modern distribution, which ships this specific gpg1 version. As the workaround itself only applies to 1.4.11, any version before or after seem to be safe. This removal doesn't remove support for gpg1 in general as it isn't end-of-life. All the options in use are available with gpg1 and only a broken --status-fd seemed to be of concern. Closes #581 --- tomb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tomb b/tomb index 157512d2..b454daa4 100755 --- a/tomb +++ b/tomb @@ -1152,7 +1152,7 @@ _load_key() { # contains tweaks for different gpg versions # support both symmetric and asymmetric encryption gpg_decrypt() { - # fix for gpg 1.4.11 where the --status-* options don't work ;^/ + # gpg version check necessary for <2.1.x (although those aren't supported anymore) local gpgver=$(gpg --version --no-permission-warning | awk '/^gpg/ {print $3}') local gpgpass="$1\n$TOMBKEY" local tmpres ret @@ -1174,15 +1174,6 @@ gpg_decrypt() { } } - [[ $gpgver == "1.4.11" ]] && { - _verbose "GnuPG is version 1.4.11 - adopting status fix." - TOMBSECRET=`print - "$gpgpass" | \ - gpg --decrypt ${gpgpopt[@]}` - ret=$? - unset gpgpass - return $ret - } - _tmp_create tmpres=$TOMBTMP TOMBSECRET=`print - "$gpgpass" | \ @@ -1196,7 +1187,6 @@ gpg_decrypt() { [[ "$i" =~ "DECRYPTION_OKAY" ]] && ret=0; done return $ret - } From 164f0c7a1ff33002468e3d1a879a1a7b79e63c9b Mon Sep 17 00:00:00 2001 From: Narrat Date: Fri, 26 Sep 2025 14:54:28 +0200 Subject: [PATCH 2/2] Switch password input for gpg operations Formerly a combined password+key divided by a newline was piped into the gpg operation which sets --passphrase-fd 0 to get the password from STDIN. This gets stripped from from the pipe and only the encrypted data remains. This has some consequences for entered passwords in general. Mainly \ and % related. \ can be used for control sequences like \n, \t and \f. If those are used in passwords various stuff can happen. \n not at the end: Only the password up to the backslash is used and valid. \n at the end: \t not at the end: \t at the end: \f \f In that regard change how gpg gets the password. Two ways for improvements: 1) use a specific file descriptor --passphrase-fd 3 and redirect the password via "3<<<$password". 2) switch to --passphrase-file and use an anonymous pipe <(print -R -n - "$password") In general the use of --passphrase-file is discouraged, but that should only apply if a real file is used. With the pipe only the respective file descriptor should be seen and not its content. Which only gpg is allowed to have access. And if gpg is completed the pipe and its content is gone. This solutions uses the second way as it isn't completly sure if the content of the redirect will be visible or not. What changes: \n not at the end: Assuan still outputs a formated password, but the complete password is used. \n at the end: \t not at the end: password is functional \t at the end: \f \f --- tomb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tomb b/tomb index b454daa4..3814f088 100755 --- a/tomb +++ b/tomb @@ -571,7 +571,7 @@ ask_password() { return 1 } - print "$password" + print -R -n - "$password" return 0 } @@ -1154,10 +1154,10 @@ _load_key() { gpg_decrypt() { # gpg version check necessary for <2.1.x (although those aren't supported anymore) local gpgver=$(gpg --version --no-permission-warning | awk '/^gpg/ {print $3}') - local gpgpass="$1\n$TOMBKEY" + local gpgpass="$1" local tmpres ret typeset -a gpgopt - gpgpopt=(--batch --no-tty --passphrase-fd 0 --no-options) + gpgpopt=(--batch --no-tty --no-options --no-mdc-warning --no-permission-warning --no-secmem-warning) { option_is_set -g } && { gpgpass="$TOMBKEY" @@ -1176,10 +1176,9 @@ gpg_decrypt() { _tmp_create tmpres=$TOMBTMP - TOMBSECRET=`print - "$gpgpass" | \ - gpg --decrypt ${gpgpopt[@]} \ - --status-fd 2 --no-mdc-warning --no-permission-warning \ - --no-secmem-warning 2> $tmpres` + TOMBSECRET=`print - "$TOMBKEY" | \ + gpg --decrypt ${gpgpopt[@]} --status-fd 2 \ + --passphrase-file <(print -R -n - "$gpgpass") 2> $tmpres` unset gpgpass ret=1 for i in ${(f)"$(cat $tmpres)"}; do @@ -1528,18 +1527,16 @@ gen_key() { print $header >> "$1" # Set gpg inputs and options - gpgpass="${tombpass}\n$TOMBSECRET" gpgopt=(--passphrase-fd 0 --symmetric --no-options) opt='-n' fi _tmp_create local tmpres=$TOMBTMP - print $opt - "$gpgpass" \ + print $opt - "$TOMBSECRET" \ | gpg --openpgp --force-mdc --cipher-algo ${algo} \ - --batch --no-tty ${gpgopt} \ + --batch --no-tty ${gpgopt} --passphrase-file <(print -R -n - "$tombpass") \ --status-fd 2 -o - --armor 2> $tmpres >> "$1" - unset gpgpass # check result of gpg operation for i in ${(f)"$(cat $tmpres)"}; do _verbose "$i"