aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md100
-rw-r--r--pinentry-wsl-ps1.sh31
2 files changed, 118 insertions, 13 deletions
diff --git a/README.md b/README.md
index 9421256..617a2b0 100644
--- a/README.md
+++ b/README.md
@@ -13,24 +13,100 @@ with a GUI when running within WSL (Windows Subsystem for Linux)
* Works for all keys managed by gpg-agent (GPG, SSH, etc)
* Drop-in replacement GUI to pinentry-curses, pinentry-gtk-2, etc.
+
+## Requirements
+
+* Windows 10 Fall Creators Update (build 16299) or newer. You can check the version by `winver.exe`
+* WSL with Ubuntu 16.04 or newer. You can check the release version by `cat /etc/lsb-release`
+* GPG v2.1.11 or later. Earlier versions of 2.x (aka GPG2) or 1.x (aka GPG) have not been tested and are not recommended. You can check the version by `gpg2 --version`
+
## Setup
1. Save the `pinentry-wsl-ps1.sh` script and set its permissions to be executable
2. Configure gpg-agent to use this script for pinentry using
- one of the following methods
- * Set pinentry-program within ~/.gnupg/gpg-agent.conf to the script's path, e.g.
+ one of the following methods
+ 1. Set pinentry-program within ~/.gnupg/gpg-agent.conf to the script's path, e.g.
`pinentry-program /mnt/c/repos/pinentry-wsl-ps1/pinentry-wsl-ps1.sh`
- * ... or, set the path to this script when you launch gpg-agent, e.g.
+ 2. Or, set the path to this script when you launch gpg-agent, e.g.
`gpg-agent --pinentry-program /mnt/c/repos/pinentry-wsl-ps1/pinentry-wsl-ps1.sh`
-3. Optionally enable persistence of passwords.
- 1. Follow instructions https://github.com/davotronic5000/PowerShell_Credential_Manager
- to install the needed module from the Powershell Gallery or GitHub.
- 2. Note security perspectives like https://security.stackexchange.com/questions/119765/how-secure-is-the-windows-credential-manager
- 3. Edit the script and set `PERSISTENCE` to one of the values:
- * `""` no persistence
- * `"Session"` persists the password only for the current Windows login session
- * `"LocalMachine"` persists the password for the current Windows login on the local Windows computer
- * `"Enterprise"` persists the password for the current Windows login and requests Windows Credential Manager to synchronize it across Windows computers for that same Windows login
+3. Optionally _enable_ persistence of passwords.
+ 1. Follow instructions <https://github.com/davotronic5000/PowerShell_Credential_Manager>
+ to install the needed module from the Powershell Gallery or GitHub.
+ 2. Note security perspectives like <https://security.stackexchange.com/questions/119765/how-secure-is-the-windows-credential-manager>
+ 3. Edit the script and near the beginning of the file set `PERSISTENCE` to one of the values:
+ * `""` no persistence
+ * `"Session"` persists the password only for the current Windows login session
+ * `"LocalMachine"` persists the password for the current Windows login on the local Windows computer
+ * `"Enterprise"` persists the password for the current Windows login and requests Windows Credential Manager to synchronize it across Windows computers for that same Windows login
+4. Optionally _disable_ toast notification of password retrieval from Credential Manager. By default, this code notifies you with a toast notification every time gpg-agent retrieves a password from the Windows Credential Manager. Gpg-agent caches passwords by default (see gpg-agent settings like [`max-cache-ttl`](https://gnupg.org/documentation/manuals/gnupg/Agent-Options.html#Agent-Options)) so you may not see the notification with every usage.
+ * Disable: edit the script, near the top, set `TOAST` to the value `"0"`
+ * Enable: edit the script, near the top, set `TOAST` to the value `"1"`
+
+
+## Troubleshooting Ideas
+
+1. Run `gpg2 --version` and `gpg-agent --version`. If you don't have version 2.1.11 or newer for both versions, you may have unknown problems.
+2. I recommend you have a fully working GPG2 and GPG-agent setup using the default GPG2 configuration. Try two tests. If these both don't work, you first need to troubleshoot your install.
+ 1. `gpg2 --clearsign myfile.zip`. Your entire console window should clear and present you an isolated password entry field in a crudely drawn box. Type in your key's password and it should return to your normal console with no error. You should now have the newly signed `myfile.zip.asc` file.
+ 2. If you are using the SSH-compatibility feature of GPG-agent, ensure you are not running `ssh-agent`. Try `ssh-add ...` to add your SSH key for your favorite host. Then remove and stash in a protected location this ssh key file from your `~/.ssh` directory to ensure ssh isn't using that file instead of the agent. Now try to ssh to this host. It should automatically retrieve the private host key from gpg-agent.
+3. I discovered that there are many ways for gpg-agent to be started silently. The options passed to it are inconsistent across the methods (and across gpg versions). On my computer, I explicitly start gpg-agent. Below is the method I use in my `.profile`. Please be aware that `.profile` is not always run for all *nix shell scenarios and `.bashrc` may be better for your setup. The details on this are written in the [BASH man page](https://linux.die.net/man/1/bash) in the INVOCATION section.
+4. Configuration of GPG can become complicated if you diverge from what the GPG team considers a standard setup. You may need to read the [official GPG documentation](https://gnupg.org/documentation/index.html) to configure it for your specific computer setup.
+5. GIT uses `gpg` by default. To instruct GIT to use `gpg2`, you can easily configure it with `git config --global gpg.program gpg2`
+6. Enable a gpg-agent log file. Edit your `~/.gnupg/gpg-agent.conf` file and insert the following lines. Your user must have permission to write to this file path. Restart gpg-agent after you save this configuration.
+ ```crmsh
+ debug 1024
+ debug-pinentry
+ log-file /home/username/agent.log
+ ```
+7. Enable a log file specific to this pinentry code. Edit the script, near the top, set `DEBUGLOG` to a file path, e.g. `"$HOME/pintrace.log"`. Your user must have permission to write to this file path. Restart gpg-agent after you save this configuration.
+
+## Example configuration files
+
+Below are some examples from my configuration files. If you have a working GPG2 and gpg-agent setup, the only config change likely needed is the `pinentry-program` line from setup step 2.
+
+#### Part of my ~/.profile
+
+```bash
+if [ -z "$(pgrep gpg-agent)" ]; then
+ gpgconf --launch gpg-agent
+ # I use the above method because the following method
+ # doesn't set GPG_AGENT_INFO or GPG_TTY and has a bug
+ # setting SSH_AUTH_SOCK if you use socket redirection:
+ # eval $(gpg-agent --homedir $HOME/.gnupg --daemon)
+fi
+if [ -z "$(pgrep dirmngr)" ]; then
+ dirmngr --homedir $HOME/.gnupg --daemon >/dev/null 2>&1
+ # I use the above method to consistently set vars in .bashrc
+ # rather than the following:
+ # eval $(dirmngr --homedir $HOME/.gnupg --daemon)
+fi
+```
+
+#### Part of my ~/.bashrc
+
+```bash
+export GPGKEY=12345678 # set prefered gpg signing key
+PIDFOUND=$(pgrep gpg-agent)
+if [ -n "$PIDFOUND" ]; then
+ export GPG_AGENT_INFO="$HOME/.gnupg/S.gpg-agent:$PIDFOUND:1"
+ export GPG_TTY=$(tty)
+ export SSH_AUTH_SOCK="$HOME/.gnupg/S.gpg-agent.ssh"
+ unset SSH_AGENT_PID
+fi
+PIDFOUND=$(pgrep dirmngr)
+if [ -n "$PIDFOUND" ]; then
+ export DIRMNGR_INFO="$HOME/.gnupg/S.dirmngr:$PIDFOUND:1"
+fi
+unset PIDFOUND
+```
+
+#### My ~/.gnupg/gpg-agent.conf
+
+```
+enable-ssh-support
+disable-scdaemon
+pinentry-program /mnt/c/repos/pinentry-wsl-ps1/pinentry-wsl-ps1.sh
+```
## References
diff --git a/pinentry-wsl-ps1.sh b/pinentry-wsl-ps1.sh
index 0a7ab00..ceecb29 100644
--- a/pinentry-wsl-ps1.sh
+++ b/pinentry-wsl-ps1.sh
@@ -25,9 +25,11 @@
# Note security perspectives like https://security.stackexchange.com/questions/119765/how-secure-is-the-windows-credential-manager
# Possible values for PERSISTENCE are: "", "Session", "LocalMachine", or "Enterprise"
PERSISTENCE=""
+NOTIFY="1"
+DEBUGLOG=""
# Do not casually edit the below values
-VERSION="0.1.0"
+VERSION="0.2.0"
TIMEOUT="0"
DESCRIPTION="Enter password for GPG key"
PROMPT="Password:"
@@ -43,6 +45,7 @@ EXTPASSCACHE="0"
REPEATPASSWORD="0"
REPEATDESCRIPTION="Confirm password for GPG key"
REPEATERROR="Error: Passwords did not match."
+GRABKEYBOARD="0"
# convert Assuan protocol error into an ERR number, e.g. echo -n $(( (5 << 24) | $1 ))
assuan_result() {
@@ -119,6 +122,18 @@ DLM
out-null
DLM
)
+ # idea from http://thewindowscollege.com/display-toast-notifications-windows-10.html
+ # alt1: https://gist.github.com/loge5/7ec41e2e2f0e0293fdcc5155499e9072
+ # alt2: https://gist.github.com/Windos/9aa6a684ac583e0d38a8fa68196bc2dc
+ local cmd_toast=$(cat <<-DLM
+ [reflection.assembly]::loadwithpartialname("System.Windows.Forms")
+ [reflection.assembly]::loadwithpartialname("System.Drawing")
+ \$notify = new-object system.windows.forms.notifyicon
+ \$notify.icon = [System.Drawing.SystemIcons]::Information
+ \$notify.visible = \$true
+ \$notify.showballoontip(10, "GPG pinentry-wsl-ps1", "GPG password retrieved from Windows Credential Manager", [system.windows.forms.tooltipicon]::Info)
+DLM
+ )
local credpassword
local credpasswordrepeat
local passwordfromcache=0
@@ -129,6 +144,9 @@ DLM
credpassword="$(powershell.exe -nologo -noprofile -noninteractive -command "$cmd_lookup")"
if [ -n "$credpassword" ]; then
echo -e "S PASSWORD_FROM_CACHE\nD $credpassword\nOK"
+ if [ "$NOTIFY" == "1" ]; then
+ powershell.exe -nologo -noprofile -noninteractive -command "$cmd_toast" > /dev/null
+ fi
return
fi
fi
@@ -350,6 +368,14 @@ setoption() {
default-prompt)
setprompt "$value"
;;
+ grab)
+ GRABKEYBOARD="1"
+ echo "OK"
+ ;;
+ no-grab)
+ GRABKEYBOARD="0"
+ echo "OK"
+ ;;
*)
echo "OK"
;;
@@ -365,6 +391,9 @@ fi
# main loop to read stdin and respond
echo "OK Your orders please"
while IFS= read -r line; do
+ if [ -n "$DEBUGLOG" ]; then
+ echo "$line" >> "$DEBUGLOG"
+ fi
action="$(echo $line | cut -d' ' -f1)"
args="$(echo $line | cut -d' ' -s -f2-)"
case $action in