microsoft / vscode

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

Git: Support git with private key password #13680

Closed lw-schick closed 2 years ago

lw-schick commented 7 years ago

Steps to Reproduce:

  1. Create a public-private key pair with password protection
  2. add them to your github account
  3. setup git to use the private key file
  4. try to push something with git

Result:

git pull
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
joaomoreno commented 7 years ago

Does it work from the command line? How exactly do you setup git to use the private key file?

lw-schick commented 7 years ago

It works from the command line. Actually I setup git via tortoise git - so I guess all is properly done.

lw-schick commented 7 years ago

image

joaomoreno commented 7 years ago

How do you launch the command line? Which command line?

lw-schick commented 7 years ago

I use git bash (MINGW64) on windows.

joaomoreno commented 7 years ago

Right. So, we might have to add a git.sshkey setting too, like Tortoise.

entr0cks commented 7 years ago

With Windows 10, Git 2.10.1.

Had problems using git on vscode with my production server, so I created a test server. At first, with a password protected user (no keys), same errors - no credential prompt pop ups or anything. Using the terminal inside vscode or any random cmd I can push, pull and it works - asks for password. With vscode I can only prepare commits. Pull, push, sync all fail because they aren't asking for password.

In production I'm using a passphrase protected key with a different 5 digit port for ssh. Also I have a few different ssh keys (including git) on one machine...

lw-schick commented 7 years ago

@joaomoreno Why did you moved it to the backlog?

joaomoreno commented 7 years ago

Just planning priorities. You can attempt a pull request though. 👍

ItachiSan commented 7 years ago

Waiting for it 😉

garambola commented 7 years ago

Any update on this? I'm having the same problem and it's pretty annoying 😞

hashhar commented 7 years ago

@joaomoreno I'm taking a stab at this. It affects me personally now as I recently moved to key based security.

People can track my progress here.

joaomoreno commented 7 years ago

@hashhar That's awesome! 🍻 Let me know if you hit some walls.

hashhar commented 7 years ago

@joaomoreno I was looking into the places that need change and found the following:

Current Scenario:

Proposed Changes:

No other changes will be necessary (from what I've currently seen) because the communication with the git endpoint is handled by git.exe not by vscode.

hashhar commented 7 years ago

Okay, my bad about the url parsing. Seems like node accepts urls like git+ssh://git@github.com:hashhar/vscode or ssh://git@github.com:hashhar/vscode but the ssh part has to be explicitly mentioned.

What should I do about this, should vscode just magically prepend ssh before urls that match user@server.tld:username/repo format. Or fail silently? (This still needs ssh-agent running though).

hashhar commented 7 years ago

Ping @joaomoreno. If you can find the time, do comment on the above issues I have. I have currently hacked together a proof of concept by starting the ssh-agent against a private key. It works but some polish is still needed.

joaomoreno commented 7 years ago

@hashhar Sorry for the delay... I'm actually quite busy at the moment. Feel free to create the PR and move the discussion there, we'll try to get it in for March.

andrewducker commented 7 years ago

It's not enough to just start ssh-agent, you need to also add the environment variables SSH_AGENT_PID and SSH_AUTH_SOCK so that Git knows where to look.

You'll then need to either store this somewhere, so that it can be used between restarts of VSCode, or you'll need to restart ssh-agent every time you restart VS Code.

It would be lovely if it could share this with Posh-Git (the Powershell Git module), which stores the values in ([System.IO.Path]::GetTempPath()) ".ssh\$key.env" - but possibly worth talking to that team to make sure that that location is something they're happy to be locked to.

hashhar commented 7 years ago

@andrewducker Thanks a lot for the additional input. I've haven't been working on this on the pace that I would like to because of my mid-sems. I'll get back to it by the end of the week. I'll let the Posh-Git team know.

hashhar commented 7 years ago

@joaomoreno I've got back to working on this. My previous approach was too naive and didn't work. I'm currently trying to find a suitable place to add a function that is called before performing any git command (ie. when VSCode starts up and the git provider is loading). Where do I do this? I can't seem to understand what is the flow of code.

andrewducker commented 7 years ago

Is there a piece of code which is called whenever a Git call is made? If so then you could ask for the password the first time it's called.

andrewducker commented 7 years ago

Looking at it, putting a hook into Git.ts would be the way to go, inside around any functions which would mean connecting to the server. (Like fetch, pull, push, etc).

(I'd offer to do this myself, but I've never written anything in TypeScript, or worked with VSCode extensions, so this is just based on me briefly digging through the code on GitHub.)

hashhar commented 7 years ago

The biggest problem is that on Windows the SSH_AUTH_SOCK and SSH_AUTH_PID variables may be available to all processes or just a single console session depending on how ssh-agent was started. So it is far easier to start a ssh-agent from within VSCode instead of reusing existing ones (at least on Windows).

In practical terms this means that the user will have to supply their passphrase ONCE before the first Git operation is done. The VSCode instances can share the ssh-agents among themselves if we can define a hardcoded place where SSH_AUTH_SOCK was going to be created so that other VSCode instances can look at them before starting their own agents.

This is turning out to be quite an interesting challenge for me. 😃

steveej commented 7 years ago

It would also be a viable option if vscode would honor an already existing SSH_AUTH_SOCK. I'm being asked for my private key password even though ssh-agent is already running on my system. Interestingly I can use git within the integrated vscode terminal (shell) fine. The git plugin and the terminal should behave the same for easier debugging.

EDIT: I'm on commit f9d0c687ff2ea7aabd85fb9a43129117c0ecf519 EDIT2: It works when I run vscode from a bash instead of using my window manager's launcher.

andrewducker commented 7 years ago

Yes - starting VSCode from a session that already has them set in the environment works perfectly (Launching from Powershell in my case). So if they're already set then there's nothing to do.

ezamelczyk commented 7 years ago

any progress on this?

hashhar commented 7 years ago

@ezamelczyk Nope. I'm sorry. I haven't been able to put enough time into it owing to college. Thanks for reminding me btw. I'll try to get some work done the coming week.

jimblue commented 7 years ago

Hi everyone,

Sadly I'm having the same kind of issue... 😭 Here is my config and the detailed scenario to reproduce it. I hope it'll help a little!

OS : macOSX Sierra Version 10.24.4 VScode: Version 1.11.1

In my .ssh folder I have those files:

The config file content:

Host gitlab.com
  HostName gitlab.com
  User git
  RSAAuthentication yes
  IdentityFile ~/.ssh/id_rsa_gitlab

Host github.com
  HostName github.com
  User git
  RSAAuthentication yes
  IdentityFile ~/.ssh/id_rsa_github

I can commit and push without any problem from the command line and tower. But I can't in VScode... it returns me this output message each time I try:

git pull Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.

Thanks for your help

MartinZubek commented 7 years ago

For me this is really a blocker. I like VSC, but without the ability to use git I can't use it as my daily editor.

andrewducker commented 7 years ago

@MartinZubek @jmbelloteau Does launching it from a command line where you've started SSH Agent fix it for you?

jimblue commented 7 years ago

@andrewducker

From terminal I've connect to my remote Git with the command:

ssh -T git@gitlab.com

...then I've open VScode from terminal with the command:

code

When I push from VScode I still get the same error... That's really a problem !

jimblue commented 7 years ago

@MartinZubek same here, VScode is amazing, much more than Atom. I love the speed the integrated terminal the UX and the possibility to use git.

But we also need connection to remote GIT to be secure. That's mean password protect SSH...

It makes sens... right?

MartinZubek commented 7 years ago

@andrewducker Indeed it does work for me this way. :) Any chance it will work natively without need to start it from command line?

jimblue commented 7 years ago

Hi @MartinZubek,

What does work for you? Can you be more specific? 😄

MartinZubek commented 7 years ago

@jmbelloteau Sure, it no longer ends with "Permission denied (publickey)" error and git pull/push works as they are supposed to. It uses the correct key from the ~/.ssh/config file and whenever the key passphrase is needed, this window pops-up: http://imgur.com/wpExMMP

jimblue commented 7 years ago

@MartinZubek so you can push from VScode?! That's great... Did you launch it from a command line where you've started SSH Agent? If yes how? I don't understand why it doesn't work on my environment

MartinZubek commented 7 years ago

@jmbelloteau Yes, I launched vscode from command line I use (it is the git-bash.exe which comes with git for windows by default, to be exact). I didn't have to start the ssh-agent or anything manually though. I guess it starts automatically with git-bash or something.

jimblue commented 7 years ago

@MartinZubek damn it...

Even like you said it doesn't work for me 😭

jimblue commented 7 years ago

@vscodeteam Any plan to handle this problem ?

hashhar commented 7 years ago

@jmbelloteau It's too damn difficult. It's also quite hit and miss. What I've tried implementing was to start a ssh-agent under the node process so that the env variables are available to VSCode but that means that multiple VSCode instances will need multiple ssh-agents and still require passphrases to be entered everytime.

I'm looking at a way to use the SSH_AUTH_SOCK variable instead. It works on Linux but have yet to test it on Windows.

There's the added issue of OpenSSH vs Windows Powershell SSH vs PuTTY.

If anybody is willing to test it, I can push the code to my fork and people can test it. It'll take some time though since I have used harcoded paths (proof of concept thing).

I think I'll have it up by Saturday or Sunday.

jimblue commented 7 years ago

Hi @hashhar !

Thanks for your answer. Indeed it seems really complicated. 😞

I'm not really developer so I can't really help you, I'll just keep around in case you found the magic and send you good luck !

ItachiSan commented 7 years ago

@hashhar regarding your comments, I do have 2 options to suggest:

  1. You can go for restarting the whole VSCode (including the ancestor node process) under ssh-agent, run by ssh-agent path/to/code; in this way, there is no need to run one instance of ssh-agent for each node process.
  2. You can run ssh-agent from a node process, get the environment variables (e.g. print them on a file) and share them through all the processes.

I can definetely test. Do I need something particular to build it? I have installed the official version. I can build it though :)

hashhar commented 7 years ago

@joaomoreno I think I have a partial fix ready.

In the file extensions/git/src/askpass.ts, I changed getEnv() to:

getEnv(): Promise<any> {
        return this.portPromise.then(port => ({
            ELECTRON_RUN_AS_NODE: '1',
            GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
            VSCODE_GIT_ASKPASS_NODE: process.execPath,
            VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js'),
            VSCODE_GIT_ASKPASS_PORT: String(port),
            SSH_AUTH_SOCK: process.env['SSH_AUTH_SOCK'],
            SSH_AGENT_PID: process.env['SSH_AGENT_PID'],
            SSH_ASKPASS: process.env['SSH_ASKPASS'] || '/usr/lib/ssh/x11-ssh-askpass'
        }));
    }

The SSH_AUTH_SOCK is picked from user's environment if set.

The following things are now possible:

ssh-agent ssh key loaded in agent result
$SSH_ASKPASS is executed
nothing happens

So to fix the issue in the 2nd row, we can set SSH_ASKPASS from askpass.ts too and that causes VSCode to launch the program on startup and ask for SSH keys passphrases.

For the final row though, we'd need to start a ssh-agent from within VSCode and set the proper variables.

Volunteers?

If somebody's willing to test this, you can clone my fork (https://github.com/hashhar/vscode), switch to the git-ssh-key branch and build it and run it. Please try checking what happens on all combinations from the table above. To keep the noise here minimum, you can comment on this issue.

joaomoreno commented 7 years ago

@hashhar The entire process.env is always passed to Git when spawning it:

https://github.com/Microsoft/vscode/blob/master/extensions/git/src/git.ts#L383

Don't those variables get passed without your snippet?

hashhar commented 7 years ago

@joaomoreno Okay. Digging deeper shows me two issues.

  1. VSCode apparently doesn't use the variable SSH_ASKPASS. It is hardcoded to '/usr/lib/ssh-ssh-askpass'. Basically the only issue is that VSCode doesn't assist Git by telling it how to launch a prompt for getting the user's ssh-key passphrase.

Most tools on linux provide a program symlinked to '/usr/lib/ssh/ssh-askpass' but many do not. So that's an issue that I think people are hitting.

I've been able to use VSCode with SSH as long as the ssh-key was already added to the ssh-agent keyring.

I think I've been stupid.

TODO:

  1. Extend vscode-askpass.ts etc. for ssh too.
  2. Start ssh-agent if not already running. This is just a convinience issue otherwise you'd have to enter the passphrase for each git operation.

I'm sorry for not working thoroughly.

joaomoreno commented 7 years ago

No worries, it's cool that you're jumping on this! 👍

thomasaarholt commented 7 years ago

I've been encountering this error for a while now, and thought it was me. Any more progress on this?

Megale commented 7 years ago

+1

ScreamZ commented 7 years ago

+1

rootman commented 7 years ago

+1