gitbutler icon indicating copy to clipboard operation
gitbutler copied to clipboard

gpg signing is not working correctly

Open slamp opened this issue 1 year ago • 20 comments

Version

0.12.27

Operating System

Mac OS X

Distribution Method

dmg (Apple Silicon)

Describe the issue

Hello,

I'm trying to sign with GPG my commit. In project settings I got the error: "gpg: signing failed: Inappropriate ioctl for device" This could be solved by doing a export GPG_TTY=$TTY I have the export in my .zshrc configuration

gpg-signing-issue

How to reproduce

MacOS Apple M2 gpg (GnuPG) 2.4.5 libgcrypt 1.10.3

Go to 'Project settings', click 'Git', enable 'Sign commits' Define the 'signing program' to /opt/homebrew/bin/gpg Click 'Test signing'

Expected behavior

GPG signing is working

Relevant log output

Signing is not working correctly
Failed to sign GPG:  [GNUPG:] KEY_CONSIDERED xxxxxxxx 2
[GNUPG:] BEGIN_SIGNING H10
[GNUPG:] PINENTRY_LAUNCHED 30528 curses 1.3.1 - - - - 502/20 0
gpg: signing failed: Inappropriate ioctl for device
[GNUPG:] FAILURE sign 83918950
gpg: signing failed: Inappropriate ioctl for device

slamp avatar Oct 02 '24 13:10 slamp

Thanks for reporting!

Could you try to launch GitButler from a terminal window, for instance with /Applications/GitButler.app/Contents/MacOS/GitButler?

If that works, it's clearly an issue with GitButler, as windowed application, not seeing the necessary environment variables, which is a known issue.

Thanks for your help.

Byron avatar Oct 02 '24 18:10 Byron

By launching GitButler in commandline, gpg asked me the Passphrase gpg-sign and then I was able to sign a commit gitbutler-gpg-ok

So it works this way !

slamp avatar Oct 03 '24 09:10 slamp

That's great to hear!

Thanks also for showing a screenshot, as it makes clear that the password entry is bound to having a terminal. So even if everything was configured correctly even without having all the environment variables, gpg would still be unable to query the password if there is no underlying terminal.

In order for GitButler to be handling this, it would somehow have to provide a terminal session to the programs Git may launch while creating commits - maybe that's possible somehow.

Byron avatar Oct 03 '24 16:10 Byron

Sorry for the inconvenience!

There are three action points here:

  1. Investigate whether allowing the user to enter environment variables in the configuration could enable expert users to resolve situations like this on their own (perhaps there are some sensible defaults we can provide).
  2. Investigate whether there is another set of environments we should be providing to prompt this gpg program to use our askpass setup
  3. Document this work-around in our signing documentation page (good first issue).
  4. As Byron suggests, perhaps we can detect that the signing program is waiting on something from STDIN, and open up a small shell prompt.

Caleb-T-Owens avatar Oct 04 '24 18:10 Caleb-T-Owens

Hi, I want to let you know that even if my setup is a bit different (git and gpg setup using nix-darwin with home-manager), the gpg works if gitbutler is run from the command line (without asking for passphrase, because I think the passphrase is already saved in keychain)

Here is my workflow:

  • Use git in command line, commit signing works without asking for passphrase
  • Open gitbutler from command line, commit signing works without asking for passphrase
  • Open gitbutler from launchpad, commit signing doesn't work (no secret key)
gitbutler from launchpad gitbutler from cli

dParikesit avatar Dec 13 '24 01:12 dParikesit

Thanks for sharing!

The reason is probably some environment variable that is set in the terminal, but not when launched through other means.

Other Git clients, like Fork in this case, seem to fetch individual environment variables from well-known locations, optionally also from a login shell.

Screenshot 2024-12-13 at 14 14 44

This is what we would have to do as well.

Byron avatar Dec 13 '24 13:12 Byron

🤔 I wonder if what @ndom91 has been doing with bash/zsh/sh/pwsh execution is applicable / could also be applied here

Caleb-T-Owens avatar Dec 14 '24 08:12 Caleb-T-Owens

🤔 I wonder if what @ndom91 has been doing with bash/zsh/sh/pwsh execution is applicable / could also be applied here

You mean the getting the shell with gix to then execute the the following commands with bash -c ..., for example? Sounds plausible.

@Byron what do you think?

ndom91 avatar Dec 14 '24 09:12 ndom91

I don't know if that would always work as these shells aren't login shells. And even if so, the gix-command one acts like Git does, and it just uses sh without anything added to it, which typically isn't the shell people use as their login shell, so definitely won't be configuring itself similarly.

With that said, it might work better more often, so could be worth a shot.

Byron avatar Dec 14 '24 14:12 Byron

I don't know if that would always work as these shells aren't login shells. And even if so, the gix-command one acts like Git does, and it just uses sh without anything added to it, which typically isn't the shell people use as their login shell, so definitely won't be configuring itself similarly.

With that said, it might work better more often, so could be worth a shot.

I thought it was getting the user's default shell so we would get whatever was specified in their .zshrc (or other alternative). The idea behind using the user's default shell is that it would pick up any brew env initialisation or similar

Caleb-T-Owens avatar Dec 16 '24 14:12 Caleb-T-Owens

No, that's not what Git does. However, I have added a method on gix-command::Prepare::with_shell_program() to allow changing the name or path to the shell. That way it's easy to customise for non-Git use-cases that might be better suited here. Edit: the new method will become available with #5841.

(Git has no use for it as it's launched from login-shell, inheriting everything.)

Byron avatar Dec 17 '24 12:12 Byron

I see, sound good :+1:

Caleb-T-Owens avatar Dec 17 '24 13:12 Caleb-T-Owens

The linked PR will now enforce using the current users default shell, assuming it is picked up in the $SHELL environment variable, which should make signing more likely. And I say it carefully as my tests indicate that the environment of my login shell is actually already present in the GitButler application even when started through the finder. Thus, if launching these programs through a shell changes something, their effect is probably more subtle than environment variables.

In any case, at most a day after the PR gets merged one should be able to try it out in the nightly build.

Byron avatar Jan 09 '25 14:01 Byron

@Byron I tested the nightly build 0.5.989 and I have the same issue

image

It's working when I start gitbutler.tauri in commandline

However it's also working when I start gitbutler.tauri in commandline one time, click test signing, close gitbutler and start it from the /Application folder.

To reproduce the issue for this second case, I need to kill the gpg-agent before starting gitbutler image

I'm using zsh as shell:

echo $SHELL /bin/zsh

slamp avatar Jan 13 '25 13:01 slamp

Nightly build works perfectly for my nix-darwin based setup.

dParikesit avatar Jan 13 '25 13:01 dParikesit

Thanks so much for sharing, @slamp!

I think what's happening there is that GPG tries to launch the pinentry program, but when launched from GitButler there is no terminal that would be appropriate. When pinentry is rejected, the whole operation fails. This could possibly be solved by using a graphical pinentry program.

When launching GitButler from the terminal GPG is able to spawn its pinentry program, and from that point on it caches the credentials. This caching is also accessible when GitButler is launched from the desktop.

So in a way, I think it's working as well as it can even though GitButler could probably try to support these configurations better, possibly by detecting them and highlighting the shortcomings they might have.

Byron avatar Jan 14 '25 08:01 Byron

It will be nice if GitButler can catch the exception and display the reason for the error and a tip: "start gitbutler in command line"

slamp avatar Jan 14 '25 09:01 slamp

If anyone else is trying this. To work around with current builds, the following is needed:

  1. Open a terminal and run /Applications/GitButler.app/Contents/MacOS/gitbutler-tauri
  2. Leave the terminal running
  3. When you test the signing (or need to sign and enter a password), you'll have to enter the password in the terminal

It's definitely not great to need to run the terminal and flip back and forth for password entry.

paularmstrong avatar Apr 08 '25 15:04 paularmstrong

Thanks for sharing! Was this ever working? And if so, did that manage to popup a password prompt in the UI?

Byron avatar Apr 08 '25 17:04 Byron

Was this ever working? And if so, did that manage to popup a password prompt in the UI?

As far as I can tell, no, this never worked and no popup (outside of the terminal) was ever shown.

paularmstrong avatar Apr 09 '25 15:04 paularmstrong