microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.35k stars 28.6k forks source link

Remote SSH - Git: gpg failed to sign the data #130415

Open doggy8088 opened 3 years ago

doggy8088 commented 3 years ago

Does this issue occur when all extensions are disabled?: Yes/No

Steps to Reproduce:

I'm using Remote - SSH from Windows 10 to Ubuntu 20.04 LTS.

  1. Add the following code to ~/.profile

    export GPG_TTY=$(tty)
  2. Configure git

    git config --global commit.gpgsign true
    git config --global --unset gpg.program
    git config --global --add gpg.program /usr/bin/gpg
  3. Enable Commit Signing

    image

  4. Commit

    image

  5. Open Git Log

    > git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file - -S
    error: gpg failed to sign the data
    fatal: failed to write commit object
    > git config --get-all user.name
    > git config --get-all user.email
  6. Show Command Output

    > git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file - -S
    error: gpg failed to sign the data
    fatal: failed to write commit object
vscodebot[bot] commented 3 years ago

(Experimental duplicate detection) Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

doggy8088 commented 3 years ago

I seems related with this issue: https://github.com/microsoft/vscode-remote-release/issues/1022

doggy8088 commented 3 years ago

As a workaround:

  1. Open Terminal and commit once

    export GPG_TTY=$(tty)
    git commit -m "OK" -S

    ...Enter your password...

  2. Git Reset

    git reset HEAD~
  3. Then you can use VSCode git commit signing

doggy8088 commented 3 years ago

I put export GPG_TTY=$(tty) into my ~/.profile, but opening Terminal in VSCode when using Remote SSH will not apply. So the git commit -S will fail. I have to run this export GPG_TTY=$(tty) manually after open Terminal. I don't know how to workaround that.

its-DomeE commented 3 years ago

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

aljaxus commented 2 years ago

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

Yup, can confirm the same behaviour in same environment (win10 -> Centos7).

swills1 commented 2 years ago

Same issue here. I am on Windows10 using SSH and developing on Fedora. The following gets it to work, but the steps must be repeated every time you re-open VSCode.

  1. Manually run export GPG_TTY=$(tty)
  2. Run echo "test" | gpg2 --clearsign enter password
  3. You can now perform signed commits using the Terminal and VSCode GUI. (If code signing is enabled / setup)

If you don't do step 1 and go straight to step 2, you get this error;

gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
altjx commented 2 years ago

Same here. Using VS Code from a MBP on Big Sur v11.6, along with the Remote SSH plugin and managing my git repo from the remote server. gpg signing always fails when committing in the source control area, but always succeeds after providing my passphrase using one of the commands above (e.g. echo "test" | gpg --clearsign or commit -S -m "message")

damian123 commented 2 years ago

Is there any update on this issue?

AndreHorst commented 2 years ago

Still no native solution. @swills1 answer is still valid.

What you can do is to overwrite the default timeout for the gpg cache. Open/Create ~/.gnupg/gpg-agent.conf and add the following lines:

max-cache-ttl 32400
default-cache-ttl 32400

This keeps you gpg key cached for 9 hours (32400 sec), starting from the first unlock (-> default-cache-ttl). After 9 hours, you need to unlock again, because that is the maximum time (max-cache-ttl).

It is a work-around to not be bothered during a work-day.

safalnpane commented 2 years ago

Guys seem like mine one was solved when I placed export GPG_TTY=$(tty) in ~/.bashrc instead of ~/.profile.

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.

This was an excerpt from the GNU bash reference manual. Please do take a look at it. https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html

swills1 commented 2 years ago

Guys seem like mine one was solved when I placed export GPG_TTY=$(tty) in ~/.bashrc instead of ~/.profile.

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.

This was an excerpt from the GNU bash reference manual. Please do take a look at it. https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html

Thank you for the post. When I had first replied to this topic, I was a bit ignorant which file my distro used. The ~/.bachrc probably will work, but for me, I put export GPG_TTY=$(tty) in ~/.bash_profile. I did this because this is where things profile related such as environment variables typically go in Fedora, which is the distro I use. Once I added export GPG_TTY=$(tty), I did source ~/.bash_profile to reload the file. After that I was able to perform a signed commit, close VSCode completely, re-open and perform a signed commit without performing any extra steps.

I think the overall issue was kind of a misunderstanding. Different distros expect env variables in different places. By manually running export GPG_TTY=$(tty), you're setting it for that session. Placing it in whichever profile file your distro uses and either rebooting or entering source ~/.bash_profile should solve it.

TLDR;

Fedora users put export GPG_TTY=$(tty) in ~/.bash_profile and run source ~/.bash_profile.

linroex commented 2 years ago

same problem: (macos -> debian)

Version: 1.68.1 (Universal)
Commit: 30d9c6cd9483b2cc586687151bcbcd635f373630
Date: 2022-06-14T12:52:13.188Z
Electron: 17.4.7
Chromium: 98.0.4758.141
Node.js: 16.13.0
V8: 9.8.177.13-electron.0
OS: Darwin arm64 22.0.0

Remote-SSH: v0.82.1
jaskirat8 commented 2 years ago

Any breakthrough here, its not working for windows 10 -> rhel

d0x7 commented 2 years ago

Fedora users put export GPG_TTY=$(tty) in ~/.bash_profile and run source ~/.bash_profile.

Not working on Debian for me. I just did what someone said earlier, but I need to do this every single time I re-connect/open up VSCode, so it's not really a solution: echo "test" | gpg --sign and after entering my pass, I can commit in VS Code.

What's interessting: my .bashrc does get executed on login, as I have many things in there alongside powerline, and powerline is usable/enabled from within vscode, so the "GPG_TTY" thing must not be the issue on debian I suppose?

Any update?

Nicryc commented 2 years ago

To avoid retyping export GPG_TTY=$(tty) manually you can tell VSCode to start bash like a login shell by passing the -l parameter to the bash command. You can do that by adding "args": ["-l"] in the terminal.integrated.profiles.linux setting of VSCode:

"terminal.integrated.profiles.linux": {
    "bash": {
        "path": "bash",
        "args": ["-l"],
        "icon": "terminal-bash"
    }
},
"terminal.integrated.defaultProfile.linux": "bash"
ahmedsalhin commented 2 years ago

Make sure echo "test" | gpg --clearsign runs successfully first before trying the below.

Very helpful to check what git commit is doing under the hood. Run the following commit with GIT_TRACE=1 as follow

GIT_TRACE=1 git commit -S -m "MESSAGE"

This will show what user name, email, and key git uses when committing.

In my case, I found that git was picking up the wrong user and key details for signing the commit. I mainly intended to use the local config of the repo rather than the global and adding the following to the local git config (located at "REPO_PATH/.git/config") got signing the commit to work both in Terminal and VSCode.

[user]
    name = USER NAME
    email = USER EMAIL
    signingKey = SIGNING KEY

It can also be set with the following:

git config --local user.name "USER NAME"
git config --local user.email "USER EMAIL"
git config --local user.signingkey "USIGNING KEY"
liqimore commented 2 years ago

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

I remote ssh into a linux VM. In the VM, I can commit with gpg, but Vscode does not work (same error). After executing echo "test" | gpg2 --clearsign and type my password, I could commit in Vscode with no issue. Thanks.

swills1 commented 1 year ago

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

I remote ssh into a linux VM. In the VM, I can commit with gpg, but Vscode does not work (same error). After executing echo "test" | gpg2 --clearsign and type my password, I could commit in Vscode with no issue. Thanks.

What OS?

crt0r commented 1 year ago

For all the people who're struggling with signing commits via remote VS Code sessions even after setting the GPG_TTY environment variable and the gpg program for git.

Try to expand the terminal window or move it to a tab. Increasing the terminal window size may help.

If you try to run something like "test" | gpg2 --clearsign as others in this thread stated, gpg may inform you about the insufficient screen/window size: gpg: signing failed: Screen or window too small.

gpg-sign-error

If you expand it, that may work.

gpg-sign-expanded-window

davideluque commented 1 year ago

Restarting VSCode worked for me when I confirmed it was working on my terminal (after adding export GPG_TTY=$(tty) to my .zshrc)

scott-laj-pfe commented 1 year ago

I've tried all the workarounds mentioned in this thread and still can't commit via VScode. In my case the remote host is an AWS linux ec2 instance.

markhc commented 1 year ago

I'm not sure this is even related to remote coding.

I am running VSCode on my Arch Linux machine, no remote connection at all, and still facing this same issue. Signing something once through the terminal once before trying to use the VSCode UI works, but that seems like a hack more than anything. Would be happy to see this properly fixed one day.

swills1 commented 1 year ago

This is in response to all of the recent replies. I genuinely don't feel like this is a bug. I feel like it is not knowing where to save your settings on your specific OS. If you use my reply before this as an example - my issue was simply that I wasn't saving the env variable in the right profile file. Once I did that, it has been fixed every since. I don't feel like this is a bug, and that this is being beaten to death.

I feel like a good way to solve would be to - look up where your OS saves env variables / profile info. Then set an env variable and test pulling that variable. If it comes back - you know you have the right place. Stick your signed commit line in there and you should be good to go.

globalhuman commented 1 year ago

I experienced the same issues when setting up GPG on macOS today. Launching via a terminal with the correct

export GPG_TTY=$(tty) worked, however when launching the app using the app icon it failed.

I followed the suggestions here https://github.com/microsoft/vscode/wiki/Commit-Signing and after a reboot(this is important) the environment variable has been picked up by vscode and I no longer encounter this issue

crt0r commented 1 year ago

after a reboot(this is important) the environment variable has been picked up by vscode and I no longer encounter this issue

You could also kill your VS Code Server and connect again without restarting the machine. To do this, open a command palette using Shift + Ctrl + P and type kill. There are a couple of options to choose from.

image

swills1 commented 1 year ago

I don't know if it was a fluke or something with Fedora 36. But I had put export GPG_TTY=$(tty) in ~/.bash_profile and run source ~/.bash_profile. And I was good for the longest time. Then suddenly I had to start doing this again;

export GPG_TTY=$(tty)
Run echo "test" | gpg2 --clearsign

After an upgrade to Fedora 37, things are working again without having to do those two steps. Just an FYI in case anyone on F36 saw something weird.

Key take away: Fedora 37 - adding export GPG_TTY=$(tty) in ~/.bash_profile and running source ~/.bash_profile allows you to sign commits without doing any manual steps.

jaanli commented 1 year ago

I experienced the same issues when setting up GPG on macOS today. Launching via a terminal with the correct

export GPG_TTY=$(tty) worked, however when launching the app using the app icon it failed.

I followed the suggestions here https://github.com/microsoft/vscode/wiki/Commit-Signing and after a reboot(this is important) the environment variable has been picked up by vscode and I no longer encounter this issue

Tried this and it's still not working on Mac :(

Quba1 commented 1 year ago

Using Ubuntu 22.10

Step 0: Workaround

(Works with pinentry-curses and pinentry-gtk2)

Inspired by this StackOverflow thread I added to my ~/.bashrc

export GPG_TTY=$(tty)
echo "" | gpg --clearsign

And now VSCode asks the startup in terminal for the passphrase that git later remembers. But this is unequivocally a workaround.

Step 1: The offender

However I also tried in the ssh terminal a command that (according to Git log) VSCode uses to commit

echo "commit message" | git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -

And it fails identically as in the VSCode. But when I remove --quiet flag passphrase window in ssh terminal appears and everything works fine.

Step 2: It works locally

Importantly, the same command (with --quiet) works fine when run locally both from VSCode and terminal. But significant difference is a fact that it opens a GUI passphrase prompt.

That GUI prompt looks similarly to the one opened (on default Ubuntu) by pkexec. In ssh terminal pkexec doesn't open a GUI prompt but asks for password in the terminal instead.

But git with --quiet flag instead of asking for passphrase in the ssh terminal opens a GUI prompt on the machine that I ssh into.

Edit: The problematic package that is responsible for the GUI prompt is pinentry-gnome3. Switching to pinentry-tty makes VSCode commit not work both locally and remotely. Edit 2: pinentry-qt doesn't work either. Edit 3: pinentry-gtk2 brings most improvement by working in local-VSCode, local-terminal and ssh-terminal but not in ssh-VSCode.

Step ?: Conclusion

So git/gpg not asking for the passphrase when connected remotely seems to be a result of ~unusual case of how git/gpg passphrase GUI prompt and X11 forwarding works~ how pinentry and VSCode and X11 forwarding (doesn't) work.

I genuinely don't feel like this is a bug. I feel like it is not knowing where to save your settings on your specific OS. If you use my reply before this as an example - my issue was simply that I wasn't saving the env variable in the right profile file. Once I did that, it has been fixed every since. I don't feel like this is a bug, and that this is being beaten to death.

In my opinion this is a bug of VSCode. And either --quiet flag should be removed or pinentry should be allowed to show prompt in the terminal. I think this should work out of the box without a need to reconfigure users system.

scruel commented 6 months ago
> export GPG_TTY=$(tty)
> echo test | gpg --clearsign --debug-level advanced
gpg: enabled debug flags: memstat trust extprog
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
gpg: signing failed: Timeout
gpg: [stdin]: clear-sign failed: Timeout
gpg: keydb: handles=2 locks=0 parse=2 get=2
gpg:        build=0 update=0 insert=0 delete=0
gpg:        reset=0 found=2 not=0 cache=0 not=0
gpg: kid_not_found_cache: count=0 peak=0 flushes=0
gpg: sig_cache: total=4 cached=4 good=4 bad=0
gpg: random usage: poolsize=600 mixed=1 polls=0/4 added=24/960
              outmix=0 getlvl1=0/0 getlvl2=0/0
gpg: rndjent stat: collector=0x0000000000000000 calls=0 bytes=0
gpg: secmem usage: 1344/65536 bytes in 2 blocks

Still won't work...

FrostleafChan commented 4 months ago

on ubuntu:

sudo apt install pinentry-gtk2
echo "pinentry-program /usr/bin/pinentry-x11" >> ~/.gnupg/gpg-agent.conf  #pinentry-gtk-2 is ok too
gpg-connect-agent reloadagent /bye

and it began asking for a passphrase in the graphic interface. Tested on WSL, may require Remote X11(SSH) extension and X11 Forwarding enabled on remote server when using SSH. image

really need pinentry input support on VSCode, even if pinentry-tty.

lgrachov commented 2 months ago

For those on macOS, trying to commit will give a Git: gpg failed to sign the data error.

gpgFailedToSign

The only way to commit without this error is if you do a commit from the command line:

$ git commit -m "Changed description"
$ git push

This error happens because Visual Studio Code does not ask for the passphrase.

jason-curtis commented 1 month ago

I can confirm that @FrostleafChan 's workaround (https://github.com/microsoft/vscode/issues/130415#issuecomment-2093371365) works for me on Win11+WSL+Ubuntu. Thank you!

SpeedyCraftah commented 3 weeks ago

Are no contributors/maintainers going to comment on this? It'd be great to get additional insight on the issue, or even some challenges that aren't obviously apparent on fixing this issue. I'm not exactly sure on a fix but running echo "test" | gpg2 --clearsign before every vscode remote session fixes the issue, which leads me to believe it's a vscode issue?