vim-gnupg
vim-gnupg copied to clipboard
Neovim compatibility (for terminal pinentry prompts)
neovim spawns shell commands connected to pipes, which prevents vim-gnupg from receiving input when asking for passphrase.
To make vim-gnupg work with neovim it would be great to see an updated version using termopen
.
FWIW, I'm a long time vim-gnupg user and have been using it with neovim since day 1. I never had problems because I use gpg-agent which by defaults displays a x11 prompt to get the password(The GPG_TTY warning can be safely ignored).
With that said, it should be easy to make vim-gnupg compatible with neovim: You simply need to call jobstart
passing the pty
option, which will spawn the job in a headless pseudo terminal, and with jobwait
you can wait for a job to finish. Here's a function that simulates system()
but uses a new pty to run the program:
let s:Shell = {}
function s:Shell.on_stdout(jobid, data)
let self.output .= a:data[0]
for str in a:data[1:]
let self.output .= "\n".str
endfor
endfunction
let s:Shell.on_stderr = s:Shell.on_stdout
function! PTYSystem(cmd, ...)
let s = extend({'output': '', 'pty': 1}, s:Shell)
let job = jobstart(a:cmd, s)
if a:0
" send data plus newline plus ctrl+d to the terminal
call jobsend(job, a:1."\n\x04")
endif
let [g:shell_error] = jobwait([job])
return s.output
endfunction
This would require prompting the passwords with the inputsecret()
function and feeding as the second argument of PTYSystem
Thanks for the tips, @tarruda. I'll take another look at this after I finish packaging neovim for Debian.
Hello! I was wondering if there is any progress with this issue? I am using neovim via tmux so the x11 prompt often does not work in this case and neovim hangs an entire window when asking for passpharse. Thanks for the great plugin anyway!
Ok, I finally got Neovim packaged in Debian and will start taking a look at this.
Just as an FYI, neovim isn't actually hung. When encrypting a new file, you can type into the gpg prompt but you aren't going to see what's being typed. Other than that, it works fine. I've successfully created new encrypted files and opened existing files just fine.
Yes, it's not optimal but it is functional.
Any update on this?
Yes, of course, I can help test this on Fedora/CentOS/Ubuntu ☺
Yes, it's not optimal but it is functional.
I've been playing around with the job control and pseudo terminal for a while now but I still didn't get it to work. I just wanted to point out that using pinentry-curses in a non-login shell, I need to keep an eye on the wildcards and count them: apart from the fact that the letters aren't always input into dialogue, some characters are also put into the decrypted file :anguished:. (I don't call that functional.)
Maybe the keys are passed through and the input is result of normal mode "i" command? (not sure)
This is likely insecure, and may not work, but I wanted to share the idea all the same: using pexpect in a remote plugin one could wait for the the spawned process (started with gpg2 -d --no-tty
, no -q) to print ^gpg: encrypted with.*
as a sign of successful decryption, then delete the first few lines and passing the file contents to stdout, where neovim should pick it up and load it into a buffer.
As a complement/clarification to tarruda's comment, I would like to add that one can make vim-gnupg to work with NeoViM if one does not set gpg-agent to use pinentry-curses
but any other X pinentry (make sure /usr/bin/pinentry
points at pinentry-gtk-2
for instance and that setting pinentry-program
is not set to …/pinentry-curses
in ~/.gnupg/gpg-agent.conf
).
Kind of a workaround of course but worth to be mentioned in my opinion.
any other X pinentry ...
Thanks but rather not, running a terminal using a compositor for Wayland, I would prefer to stick to a curses interface. If I can use it from other curses programs and for other uses, like signing commits and email, it feels like it should be possible to have a curses pinentry work from neovim.
The issue, I think, for me with neovim is that pinentry-curses
seems to be running on /dev/ttyx
, which obviously isn't the terminal connected to stdin.
I'm using NeoVim on my mac 10.11.6
and it's NeoVim version v0.1.6-109-gdc6cc47
and when it asks me the passphrase I see nothing typed out and the program hangs. I can't quit it and need to shut my terminal tab down :-(
Thanks to all the suggestions so far. I've already pushed some commits to fix issues related to the 'encoding'
option, which will become more important once neovim/neovim#2905 is merged.
apart from the fact that the letters aren't always input into dialogue, some characters are also put into the decrypted file :anguished:. (I don't call that functional.)
Agreed. I don't know if I was just lucky before or didn't notice it, but it is essentially non-functional. The input randomly makes it to either nvim or the pinentry process.
This would require prompting the passwords with the inputsecret() function and feeding as the second argument of PTYSystem
I really don't like the idea of doing the password prompting in the plugin and passing it through. I removed a bunch of code that was just shuttling data between Vim and gpg when I took over maintenance of the plugin. I don't see a reason to reimplement what gpg already does just fine, and has the ability to do more securely.
That being said, I know that something needs to be done here and I'll be trying to focus my available FOSS time on this.
@jamessan I, for one, really appreciate all your hard work. Thank you very much.
One issue I encountered on Fedora 25 (GNOME with X, not Wayland) is that by default gnupg would not try to use the graphical password prompt, which seems to be the recommended workaround for this bug at the moment. I think this is due to this part of the script.
if (str2float(gpgversion) >= 2.1 || (exists("$GPG_AGENT_INFO") && g:GPGUseAgent == 1))
"... stuff ...
let s:GPGCommand .= " --use-agent"
else
let s:GPGCommand .= " --no-use-agent"
endif
On my system, vim-gnupg tries to use gpg version 1.4 by default and the GPG_AGENT_INFO variable was unset so it falls into the "--no-use-agent" branch of the code. A workaround that worked for me was to edit my .config/nvim/init.vim to tell vim-gnupg that it should use gpg 2.1 instead:
let g:GPGExecutable = "gpg2 --trust-model always"
I hope this information might be helpful.
I'm kinda a GPG newbie, and can't quite suss out a tl;dr from this Issue — is there a current path to editing GPG-encrypted messages in Neovim (well, VimR, for me) instead of Vim 8, on macOS?
(It sounds like some of you got it to work, but perhaps only on Linuxes?)
@ELLIOTTCABLE If you have access to an X11 display, you can use the GPG graphical prompt. If not, you have to use vim
…
kierun's advice is correct. The longer term solution is to use --pinentry-mode loopback
, which I haven't gotten to yet. I'll probably end up doing that along with a conversion to using job control for better management of stdout/stderr.
Any update on this?
Using mutt
, I now use the gpg […] --textmode
which works fine on console. Could you use that? ← I am clueless about that code.
I don't see how --textmode
helps here. That controls how gpg treats its input/output, not how pinentry interacts with the terminal.
Is there any workaround for a headless server, where using an X11 pinentry program is not possible?
@goerz Look into ~/.gnupg/gpg-agent.conf
and set pinentry-program /usr/bin/pinentry-curses
or where ever it resides on your system.
@kierun @goerz note that pinentry-curses from vim in a non-login shell still seems problematic (see my comment above). I'm not sure how this works through ssh in a login shell.
I've been following this thread and I don't believe that this is an issue that vim-gnupg needs to address as it's native to the gpg-agent, and should be handled by the used. However; here is a possible solution, https://askubuntu.com/questions/858347/disable-gnome-from-asking-passphrase-in-gui-when-using-ssh-and-gpg-from-terminal
Specifically:
~/.local/bin/my-smart-pinentry:
#!/bin/sh set -eu
Configuration -- adjust these to your liking
PINENTRY_TERMINAL='/usr/bin/pinentry-curses' PINENTRY_X11='/usr/bin/pinentry-x11'
Action happens below!
if [ -n "${DISPLAY-}" -a -z "${TERM-}" ]; then exec "$PINENTRY_X11" "$@" else exec "$PINENTRY_TERMINAL" "$@" fi
On Tue, Mar 26, 2019, 06:35 Bart De Roy [email protected] wrote:
@kierun https://github.com/kierun @goerz https://github.com/goerz note that pinentry-curses from vim in a non-login shell still seems problematic (see my comment above). I'm not sure how this works through ssh in a login shell.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jamessan/vim-gnupg/issues/32#issuecomment-476638189, or mute the thread https://github.com/notifications/unsubscribe-auth/AAfRzM4Ovp1gWPF6C5W1mpxtrDNXDQcmks5vaiIngaJpZM4EEMFy .
I've been following this thread and I don't believe that this is an issue that vim-gnupg needs to address
It's not necessary for vim-gnupg to address it, but the biggest problem with Neovim support is that both pinentry and neovim are trying to use the same tty at the same time.
The current workaround is to use an X11 pinentry, which doesn't work when you're SSHing (unless you do X forwarding).
... which doesn't work when you're SSHing (unless you do X forwarding).
It's enough to do a gpg-agent forwarding, you don't have to have X on the remote system: https://wiki.gnupg.org/AgentForwarding When you do that gpg will ask for the PIN on your local computer (where you probably have X). Also it uses your local gpg-keyring, which means you don't have to upload your keys to the remote system and you can use a local gpg-smartcard plugged in into your local computer.
I’ve tried the plugin with Neovim running inside Kitty and Termux. In Kitty, about every 2nd and 3rd keypress is registered by the passphrase prompt, while in Termux, the prompt doesn’t appear at all; instead, I receive a “Message could not be decrypted!” error in Neovim’s status bar.
Since using an X11-based prompt on Termux is a no-go (at least locally), I went down a different road and tried running gpg --decrypt foo.bar.asc > /dev/null
before opening it in Neovim. It works well in both cases, so I added the following keyboard shortcut to my ranger configuration for easy access:
map cg shell gpg --decrypt %s > /dev/null; nvim %s
macOS 11.5.2 iTerm2 3.4.8 bash 5.1.8(1)-release gpg 2.3.2 vim-gpg main branch:
commit 96be0be1240a848da56d665b38e1b0fe7ee3f1af (grafted, HEAD -> main, origin/main, origin/HEAD)
Author: James McCoy <[email protected]>
Date: Wed Nov 11 15:57:22 2020 -0500
Clean up the README
Signed-off-by: James McCoy <[email protected]>
In my ~/.profile:
export "GPG_TTY=$(tty)"
I'm experiencing the same issue described above by several users: Some of my keystrokes on passphrase input are randomly not received. If I'm extremely patient and press some keys over and over until it's received I can eventually get through my whole passphrase. If I successfully open the text file, the passphrase keystrokes that weren't received by the pin entry are inserted into my text file. If I kill the pin entry capture, the missing keystrokes appear in my terminal prompt. This seems like particularly poor security given that many of the characters of my passphrase I'm typing are being piped to god-knows-where.
Setting pinentry-program /opt/homebrew/bin/pinentry-curses
in ~/.gnupg/gpg-agent.conf
had no effect on the problem.
Reading through the above comments I didn't find a workaround for my situation. I don't have X since I'm on macOS. Is the only solution to just not use the neovim terminal pin entry to unlock the gpg agent, as suggested by @maxigaz?
@xanderdunn at least I got everything working locally with pinentry-mac
and following Signing your git commits gist on M1 Air/Big Sur. Hopefully it will work for you as well!
@kblcuk Setting pinentry-program /opt/homebrew/bin/pinentry-mac
in ~/.gnupg/gpg-agent.conf
did the trick for me, thanks!
@kblcuk and @xanderdunn, when using pinentry-mac
do you guys get prompted for the password inside neovim?
I switched to pinentry-mac
now and it works but I don't get prompted for the password at all, even if I restart the gpg agent. So however, my commits are being signed, which is nice, but I don't understand how this works since I don't get prompted for the password. When I write that I don't get prompted for the password, this also applies to creating the commit in the CLI and not in Neovim, ie. I don't get prompted for pass either in Neovim or in the CLI.
@molleweide if I recall correctly, it prompted for the password first time, and there was an option to save password to MacOS keychain, which I did. Also the gist I linked to seems to support this theory 😀
I am using pinentry-mac with gpg (GnuPG) 2.3.4 libgcrypt 1.10.1 neovim 0.6.1 and OSX 12.3 on an M1 chipped Mac (and homebrew installed as native M1 so gpg and pinentry-mac both native)
Howver, I am simply triyng to transparently decrypt a fil ein neovim. I get promoted for the pinetry password (or at least did the first time) but I only get the ecnrypted text in neovim.
Interstingly enough, having installed the plugin now also in straight up vim, it does work, but for obvious reasons, since I have a number of neovim only plugins installed in neovim, I'd love to get it working in neovim as well.
Could someone point me at how I can help diagnose the issue considering its obviously related to neovim and the plugin since I can confirm it working with old-school vim 8.2.
thanks!