-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add credential prompts for U2F-backed SSH keys #2239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for making this! I really appreciate the detailed PR description. The code looks good, and the change is simple enough. Regarding testing, I'll take your word for it that actually coming up with a key to test is hard, though I wonder if we could still add a test that takes a less direct approach. For example we could write a test which sets What are your thoughts on something like that? I'm happy to help out in any way I can. |
I'm not super sure why I didn't think of this approach, but it sounds viable in theory. I'll give it a whirl. I may be unavailable for a while this week and the next, so I'm not sure how soon I will be able to try this out and get something along those lines going. If you think it's best that I close this for now and reopen with testing (or upon deciding that adding tests is unlikely - although I'd really loath to do that), then let me know and I'll get out of your hair for the time being. |
Sweet! I'm happy to keep the PR up in the meantime |
I've successfully tried out this patch, however there is one thing I observed: lazygit fetches some repo data on start, you can see that the command log will ask you to enter the pin for the security key. We will probably want to have a prompt for those cases too. |
@marijanp You are correct, that said I do feel like that particular issue is out of scope for this pull request as I'm relatively sure the same will happen with a standard SSH key with a passphrase that you don't have cached in an SSH agent or otherwise. I'm basing this on the following trace of execution: Lines 529 to 532 in 924a152
lazygit/pkg/gui/global_handlers.go Lines 165 to 166 in 924a152
lazygit/pkg/commands/git_commands/sync.go Lines 81 to 82 in 924a152
which suggests that lazygit is designed to silently fail whenever a fetch is made, but the SSH key's credentials aren't readily available in cache. I personally have autofetch off and don't really need the feature, and I feel trying to fix that in this pull would muddy the waters. See also: #2235 (comment) |
@jesseduffield I've given writing a test a go today, but didn't get it to work as I wanted. This is the branch I ended up with, and this is an actual commit with a test. There is a working two-repository setup there, but the pull command I'm issuing isn't using the installed I'll give it another think in a few days but it's looking a bit grim. Google isn't helping much either to find out how to force git to go through the credential helper, since most results are about making it shut up (figures...). I may need to read up on git source to find the answer. |
@bdach nice work on making it this far. I'm playing around with the test locally and I'm also not getting the prompt. I think you might be right about needing to get the remote itself to prompt for a password. But I want to do some more digging to see if it really has to come to that |
so here's an idea: we could set GIT_SSH to the path of a bespoke script which itself invokes the core.askpass script. Then before starting the test we change set the url of our remote to some fake ssh url like Another approach could be to mock out git itself (we'd need to pass a modified PATH env var to lazygit to get the mocked git). Neither of these options strike me as very pleasant, I'm just spitballing. |
Why not just host a git repo locally for that test? It's as close to the real use case as it gets. |
Yeah the more I think about it, the more I think it might be worth biting the bullet and actually getting an git server going, so that we don't need to do anything hacky. But to do that in a sandboxed way we'd basically have to get docker involved (correct me if I'm wrong) which is a shame cos it's nice to be able to run tests without docker. That's a big task that I don't want to block this PR, so if we decide that's what's best, I'm happy for this to go in without an integration test |
@jesseduffield did you ever hear of our lord and savior Nix which allows for real sandboxing unlike stateful docker |
I don't really see how docker is stateful, unless you opt to use a volume. Even then you can mount a volume as read only so that nothing changes on the host system once you down the containers |
I've read the proposals above, then done some googling, and I can't say that I'm particularly thrilled to try any of the options proposed. Mocking an SSH client would involve somehow understanding the input/output format of any of the three available variants of SSH client that git supports, I guess? Which doesn't look to be documented anywhere in plain language, as far as I can tell, and is a moving target (if any of those change anything in terms of behaviour, then it's update test time). And that's just the authorisation step, without any of the actual file operations. And as stated spinning up an actual real server instance feels like shooting a fly with a bazooka in the context of this change. Not to mention that it likely doesn't even help that much because the problem still remains that the key type that this PR aims to support can't be instantiated without a corresponding hardware authenticator anyway, so we'd be at |
Agreed @bdach. Will merge after tests pass |
The 8.2 release of OpenSSH added support for FIDO/U2F hardware authenticators, which manifests in being able to create new types of SSH key, named `ecdsa-sk` nad `ed25519-sk`. This is relevant to lazygit, as those SSH keys can be used to authorise git operations over SSH, as well as signing git commits. Actual code changes are required for correct support, as the authentication process for these types of keys is different than the process for types supported previously. When an operation requiring credentials is initialised with a U2F authenticator-backed key, the first prompt is: Enter PIN for ${key_type} key ${path_to_key}: at which point the user is supposed to enter a numeric (and secret) PIN, specific to the particular FIDO/U2F authenticator using which the SSH keypair was generated. Upon entering the correct key, the user is supposed to physically interact with the authenticator to confirm presence. Sometimes this is accompanied by the following text prompt: Confirm user presence for key ${key_type} ${key_fingerprint} This second prompt does not always occur and it is presumed that the user will know to perform this step even if not prompted specifically. At this stage some authenticator devices may also begin to blink a LED to indicate that they're waiting for input. To facilitate lazygit's interoperability with these types of keys, add support for the first PIN prompt, which allows "fetch", "pull", and "push" git operations to complete.
0846274
to
1a1f042
Compare
- **PR Description** Similar to #2239, add credential prompts for PKCS11-based SSH keys. OpenSSH code reference is [here](https://github.com/openssh/openssh-portable/blob/2827b6ac304ded8f99e8fbc12e7299133fadb2c2/ssh-pkcs11.c#L263).
This would close #2230 for me. Apologies if unwanted, but the issue has been hanging there without a response for a bit now so I figure that maybe I can just PR this for everyone's sake and get things sorted this way?
PR Description
The 8.2 release of OpenSSH added support for FIDO/U2F hardware authenticators, which manifests in being able to create new types of SSH key, named
ecdsa-sk
naded25519-sk
. This is relevant to lazygit, as those SSH keys can be used to authorise git operations over SSH, as well as signing git commits. Actual code changes are required for correct support, as the authentication process for these types of keys is different than the process for types supported previously.When an operation requiring credentials is initialised with a U2F authenticator-backed key, the first prompt is:
at which point the user is supposed to enter a numeric (and secret) PIN, specific to the particular FIDO/U2F authenticator using which the SSH keypair was generated. Upon entering the correct key, the user is supposed to physically interact with the authenticator to confirm presence. Sometimes this is accompanied by the following text prompt:
This second prompt does not always occur and it is presumed that the user will know to perform this step even if not prompted specifically. At this stage some authenticator devices may also begin to blink a LED to indicate that they're waiting for input.
To facilitate lazygit's interoperability with these types of keys, add support for the first PIN prompt, which allows "fetch", "pull", and "push" git operations to complete.
Please check if the PR fulfills these requirements
go run scripts/cheatsheet/main.go generate
)docs/Config.md
) have been updated if necessaryPreview video
It probably doesn't help much to include this but I figure I might as well, as baseline proof that this patch does Something™:
2022-10-31.22-59-58.mp4