Skip to content

Adds support for multiple SSH auth mechanisms being used sequentially#5305

Merged
pks-t merged 2 commits into
libgit2:masterfrom
exactly-one-kas:bugfix/multiple-auth
Jan 10, 2020
Merged

Adds support for multiple SSH auth mechanisms being used sequentially#5305
pks-t merged 2 commits into
libgit2:masterfrom
exactly-one-kas:bugfix/multiple-auth

Conversation

@exactly-one-kas

@exactly-one-kas exactly-one-kas commented Nov 16, 2019

Copy link
Copy Markdown

Needed to make eg. 2FA work

Fixes the following problem:

  • An SSH server has multiple authentication mechanisms configured (pubkey and keyboard-interactive, both are required).
  1. When connecting to the server it responds sends only pubkey as an available mechanism
  2. libgit correctly invokes cred_acquire_cb with GIT_CREDTYPE_SSH_KEY set and GIT_CREDTYPE_SSH_INTERACTIVE unset.
  3. The pubkey authentication is completed successfully, but the server responds with a failure code since not all mechanisms have successfully completed.
  4. The connection's available mechanisms are updated to only include keyboard-interactive on the server side.
  5. libgit incorrectly invokes cred_acquire_cb with GIT_CREDTYPE_SSH_KEY set and GIT_CREDTYPE_SSH_INTERACTIVE unset.
  • This repeats until the process is terminated by the server or cred_acquire_cb

@exactly-one-kas exactly-one-kas deleted the bugfix/multiple-auth branch November 16, 2019 22:21
@exactly-one-kas exactly-one-kas restored the bugfix/multiple-auth branch November 16, 2019 22:23
@pks-t

pks-t commented Dec 13, 2019

Copy link
Copy Markdown
Member

Thanks for your PR! I'm not that knowledgeable around our SSH backend, but maybe @tiennou can chime in here?

@tiennou tiennou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks sensible — I'd expect something like that to happen with more than one authentication method enforced by the server, though I've only skimmed the RFC 😉. This is part of the problem I have with #5253 : we don't carry around a "complete" SSH protocol suite, so there's a bunch of testing needed, and I haven't got around to reading that much documentation yet… (For the record, libssh2 has a Docker-powered clar-run openssh server helper).

I only have a minor comment on styling, but many thanks @kas-luthor for the fix, and the time taken to debug it.

Comment thread src/transports/ssh.c

error = _git_ssh_authenticate_session(session, cred);

if (error == GIT_EAUTH) {

@tiennou tiennou Dec 13, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can clobber error here, so no need to declare sub_error.

/* refresh auth methods */
if (error == GIT_EAUTH &&
    (error = list_auth_methods(…) < 0))
        goto done;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, with that change error will no longer be GIT_EAUTH after the call to list_auth_methods() and cancel the loop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually… there's nothing in here that actually prevents a server from swamping you into a loop by repeatedly switching auth methods and continuously failing to authenticate, so maybe that's something that needs to happen… Not really related, but you've just mentioned a loop, and I happened to completely miss its condition 😉.

So; I'm okay with your initial version then. If you happen to add a auth counter or something, that would be lovely. I'm not sure how it would really work though…

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So; I'm okay with your initial version then. If you happen to add a auth counter or something, that would be lovely. I'm not sure how it would really work though…

Does the server even need to switch auth methods? He could just refuse the authentication repeatedly, which would cause us to loop infinitely here until one manages to send the correct credentials. Or am I missing something?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pks-t Authentication can be cancelled by the callback by returning an error code

Comment thread src/transports/ssh.c

error = _git_ssh_authenticate_session(session, cred);

if (error == GIT_EAUTH) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually… there's nothing in here that actually prevents a server from swamping you into a loop by repeatedly switching auth methods and continuously failing to authenticate, so maybe that's something that needs to happen… Not really related, but you've just mentioned a loop, and I happened to completely miss its condition 😉.

So; I'm okay with your initial version then. If you happen to add a auth counter or something, that would be lovely. I'm not sure how it would really work though…

@pks-t pks-t merged commit dbb6429 into libgit2:master Jan 10, 2020
@pks-t

pks-t commented Jan 10, 2020

Copy link
Copy Markdown
Member

Thanks a lot for your work, @kas-luthor.

So; I'm okay with your initial version then. If you happen to add a auth counter or something, that would be lovely. I'm not sure how it would really work though…

I guess we can just wait for somebody to complain and add it later, if required at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants