vim-gnupg icon indicating copy to clipboard operation
vim-gnupg copied to clipboard

Neovim compatibility (for terminal pinentry prompts)

Open ghallberg opened this issue 9 years ago • 32 comments

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.

ghallberg avatar Apr 20 '15 10:04 ghallberg

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

tarruda avatar Nov 09 '15 14:11 tarruda

Thanks for the tips, @tarruda. I'll take another look at this after I finish packaging neovim for Debian.

jamessan avatar Nov 09 '15 15:11 jamessan

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!

pmandera avatar Dec 17 '15 13:12 pmandera

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.

jamessan avatar Jan 27 '16 03:01 jamessan

Any update on this?

Yes, of course, I can help test this on Fedora/CentOS/Ubuntu ☺

kierun avatar Mar 24 '16 10:03 kierun

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.

sharethewisdom avatar Jun 15 '16 07:06 sharethewisdom

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.

galaux avatar Aug 25 '16 15:08 galaux

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.

sharethewisdom avatar Aug 25 '16 21:08 sharethewisdom

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 :-(

Integralist avatar Sep 17 '16 08:09 Integralist

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 avatar Sep 21 '16 02:09 jamessan

@jamessan I, for one, really appreciate all your hard work. Thank you very much.

kierun avatar Sep 21 '16 07:09 kierun

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.

hugomg avatar May 08 '17 22:05 hugomg

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 avatar Apr 10 '18 22:04 ELLIOTTCABLE

@ELLIOTTCABLE If you have access to an X11 display, you can use the GPG graphical prompt. If not, you have to use vim

kierun avatar Apr 11 '18 07:04 kierun

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.

jamessan avatar Apr 11 '18 19:04 jamessan

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.

kierun avatar Jun 27 '18 10:06 kierun

I don't see how --textmode helps here. That controls how gpg treats its input/output, not how pinentry interacts with the terminal.

jamessan avatar Jun 27 '18 12:06 jamessan

Is there any workaround for a headless server, where using an X11 pinentry program is not possible?

goerz avatar Mar 23 '19 18:03 goerz

@goerz Look into ~/.gnupg/gpg-agent.conf and set pinentry-program /usr/bin/pinentry-curses or where ever it resides on your system.

kierun avatar Mar 25 '19 08:03 kierun

@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.

sharethewisdom avatar Mar 26 '19 13:03 sharethewisdom

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 .

jgyurkovitz avatar Mar 26 '19 14:03 jgyurkovitz

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).

jamessan avatar Mar 27 '19 00:03 jamessan

... 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.

czocher avatar Mar 27 '19 07:03 czocher

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

maxigaz avatar Dec 26 '19 20:12 maxigaz

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 avatar Aug 30 '21 17:08 xanderdunn

@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 avatar Aug 31 '21 08:08 kblcuk

@kblcuk Setting pinentry-program /opt/homebrew/bin/pinentry-mac in ~/.gnupg/gpg-agent.conf did the trick for me, thanks!

xanderdunn avatar Aug 31 '21 17:08 xanderdunn

@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 avatar Mar 28 '22 06:03 molleweide

@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 😀

kblcuk avatar Mar 28 '22 17:03 kblcuk

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!

wakatara avatar Mar 31 '22 19:03 wakatara