Mailing List Archive

How can I 'echo' into fd 3 to be able to use it on a gpg cmd line?
... (Windows 10) [DOS] cmd ... [*NOT* powershell]
... cygwin gpg ...

How can I 'echo' into fd 3 to be able to use it on a gpg cmd line?
e.g. 'echo "Secret data" | gpg.exe -c -passphrase-fd 3 3< echo %PASSWORD%'

[.Ignore the need, or not, for --batch and/or --pinentry-mode loopback,
I can wrestle with those separately.]
(I am trying to avoid the passphrase from appearing in cleartext
within tasklists, etc.)


I am working on a BitWarden(-cli) backup script. So the 'echo "Secret
data"' above is actually something like:
bitwarden-cli --export json | gpg -c ... >...bitwarden_backup.json.pgp
- the hangup seems to be how to echo into 3< to be able to use it as
input, for ' -passphrase-fd 3'.

[.Or 7< echo %PASSWORD%, for that matter - it seems powershell uses 3-6
for stdwarn|verbose|debug|info, and probably best to avoid potential
future conflicts.]

_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gnupg-users
Re: How can I 'echo' into fd 3 to be able to use it on a gpg cmd line? [ In reply to ]
=====
Prologue:
--------
Re-reading https://web.archive.org/web/20171225062127id_/http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true
, I now notice '<& Reads the input from one handle and writes it to
the output of another handle.' (Read from one, write to another.)

So 'echo %passphrase% <&3' would seem to input from stdin and output it to fd 3.
- I can’t think how to test this (under %COMSPEC%), though, and under
everything else it doesn’t matter. [If it doesn’t work there, there
are workarounds.]
- Under %COMSPEC%, file descriptors being broken – as below.
=====


Answer / Solution: How can I 'echo' into fd 3 to be able to use it on
a gpg cmd line?

Summary:
- [outside of %COMSPEC%], short answer: mkfifo myfifo; echo
%passphrase% > myfifo & ; echo data | gpg ... 3< myfifo; unset
passphrase ; rm myfifo.
- [inside of %COMSPEC%], short answer: you can’t (*). %COMSPEC% file
descriptors are broken. See thread ending at
https://lists.gnupg.org/pipermail/gnupg-users/2024-March/067020.html
- cygwin64 is gnupg unsupported, and cygwin32 is deprecated. See
https://lists.gnupg.org/pipermail/gnupg-users/2024-March/067014.html
for why.
- even GnuWin (https://sourceforge.net/projects/gnuwin32/)
[https://getgnuwin32.sourceforge.net/] is of no help, the root cause
being %COMPEC%, everything run therein remains broken (in this regard)
– at least in terms of pipelining file descriptors outside of 0, 1, 2
== ‘stdin, out, err’. So, for example, 3, 4, 5, 6, and beyond ==
‘stdwarn, verb, debug, info’ [per
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection]
- use wsl, instead. [https://learn.microsoft.com/en-us/windows/wsl/install]

(*) Afterward:
- Werner kindly appended to the
https://lists.gnupg.org/pipermail/gnupg-users/2024-March/067020.html
thread above, at
https://lists.gnupg.org/pipermail/gnupg-users/2024-March/067021.html,
indicating that a workaround for this %COMSPEC% issue will be included
in gnu2.6 – with the addition of a ‘--disable-fd-translation’ optional
parameter.


(Proof of Concept) Goal (Reminder):
- echo secret data | gpg –pinentry-mode loopback –passphrase-fd 3 -c
3< $(echo %passphrase%) ; unset passphrase
[.i.e. without any unencrypted data landing within your filesystems,
pipe your sensitive data directly into gpg, towards direct secure
storage. e.g. (web) BitWarden backup towards secure (local) storage
should BitWarden servers ever become incommunicado (e.g. broken wi-fi
or internet provider). BitWarden phones home before unlocking – if it
can’t get there, you’re S.O.L.
- Nevermind the duplicate functionality of gpg vs Bitwarden, this is a
backup, and Bitwarden offers turnkey cross-machine consistency out of
the gate.
- - But thank all that is holy for what GnuPG was, is, and will be.
You want to have both applications to hand.


Proof of Concept example script solutions:
=====
gpggetpin-wsl.cmd:
-----
@rem #! %COMSPEC%
@echo off
set "GOTPASSPHRASE="
for /f "delims=" %%p in ('wsl /mnt/c/bin/gpggetpin.bash') do set
"GOTPASSPHRASE=%%p"
set /p "scratch=%GOTPASSPHRASE%" < nul:
set “ GOTPASSPHRASE=”
=====
gpggetpin.bash:
-----
#! /usr/bin/env bash

# gpggetpin.bash:
# SHORT VERSION:
# GPG_TTY=$(tty) ; printf "GETPIN\n" | pinentry -T "${GPG_TTY}" | sed
-e "s/^OK.*$//" -e "/^[[:space:]]*$/d" -e "s/^D //"


bash -n "${0}" || true
shellcheck -W 0 -Calways "${0}" || true

# printf "getpin\n" | pinentry -g -T "$(tty)" # - NOT HAPPY!

declare -g GPG_TERM ; GPG_TERM="${TERM}" ; export GPG_TERM
declare -g GPG_TTY ; GPG_TTY="$(tty)" ; export GPG_TTY
declare -g gs_passphrase="-1"
declare -gi gi_0=-1

gs_passphrase=\
"$( \
printf "SETDESC My description\nSETPROMPT My prompt\nSETTITLE My
window title, iif there is a window\nGETPIN\nBYE\n" \
| pinentry --debug --ttyname "${GPG_TTY}" --ttytype "${GPG_TERM}"
--lc-ctype "en_ca.UTF-8" --lc-messages "en_ca.UTF-8" \
| sed -e "s/^OK.*$//" -e "/^[[:space:]]*$/d" -e "s/^D //" \
)"
gi_0="${?}"


# USELESS - too many progs (retcodes) between source and end.
if false ; then
{
(( ! gi_0 )) && { printf "\n:: passphrase retrieval failed (%d),
exiting.\n\n" "${gi_0}" ; exit "${gi_0}" ; }
} ; fi

case "${gs_passphrase}" in
( "-1" );&
( "" );&
( "ERR 83886179 Operation cancelled <Pinentry>" )
# printf ":: no valid password retrieved (%d)[%d]. Exiting.\n\n"
"${gi_0}" "${#gs_passphrase}"
exit "${gi_0}"
;;
(*);;
esac

# printf ":: passphrase retrieved (%d)[%d].\n\n" "${gi_0}" "${#gs_passphrase}"
# printf "\n|%s|\n\n" "${gs_passphrase}"

printf "%s" "${gs_passphrase}"

unset gs_passphrase
=====
gpgtest-wsl.cmd:
-----
@rem #! %COMSPEC%
@echo off
wsl /mnt/c/bin/gpgtest.bash
=====
gpgtest.bash:
-----
#! /usr/bin/env bash
printf "\n"

set -vx

declare -g gs_mysecretpassphrase="KXhtctw4_zFfhRop" # More usually
acquired somehow else.

declare -g gs_myfifo="$(mktemp -ut fifo.XXX)"
mkfifo -m 0600 "${gs_myfifo}"

printf "%s" "${gs_mysecretpassphrase}" > "${gs_myfifo}" &

## Proof of concept, herein, being passphrase as passphrase being used
upon passphrase as data, encrypted to stdout.
## - $0 Caller redirecting stdout into desired destination filename.

printf "%s" "${gs_mysecretpassphrase}" | gpg --pinentry-mode
loopback --passphrase-fd 3 -c 3< "${gs_myfifo}" ; printf "\n"

rm "${gs_myfifo}"

set +xv

unset gs_mysecretpassphrase
=====
-30-

On Mon, Mar 18, 2024 at 5:51?PM B.S. <bs27975@gmail.com> wrote:
>
> ... (Windows 10) [DOS] cmd ... [*NOT* powershell]
> ... cygwin gpg ...
>
> How can I 'echo' into fd 3 to be able to use it on a gpg cmd line?
> e.g. 'echo "Secret data" | gpg.exe -c -passphrase-fd 3 3< echo %PASSWORD%'
>
> [.Ignore the need, or not, for --batch and/or --pinentry-mode loopback,
> I can wrestle with those separately.]
> (I am trying to avoid the passphrase from appearing in cleartext
> within tasklists, etc.)
>
>
> I am working on a BitWarden(-cli) backup script. So the 'echo "Secret
> data"' above is actually something like:
> bitwarden-cli --export json | gpg -c ... >...bitwarden_backup.json.pgp
> - the hangup seems to be how to echo into 3< to be able to use it as
> input, for ' -passphrase-fd 3'.
>
> [.Or 7< echo %PASSWORD%, for that matter - it seems powershell uses 3-6
> for stdwarn|verbose|debug|info, and probably best to avoid potential
> future conflicts.]


_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gnupg-users