Hash :
ccb85c8f
Author :
Date :
2014-06-25T16:27:43
ssh: make sure to ask for a username and use the same one In order to know which authentication methods are supported/allowed by the ssh server, we need to send a NONE auth request, which needs a username associated with it. Most ssh server implementations do not allow switching the username between authentication attempts, which means we cannot use a dummy username and then switch. There are two ways around this. The first is to use a different connection, which an earlier commit implements, but this increases how long it takes to get set up, and without knowing the right username, we cannot guarantee that the list we get in response is the right one. The second is what's implemented here: if there is no username specified in the url, ask for it first. We can then ask for the list of auth methods and use the user's credentials in the same connection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
#include "git2/cred_helpers.h"
int git_cred_userpass(
git_cred **cred,
const char *url,
const char *user_from_url,
unsigned int allowed_types,
void *payload)
{
git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload;
const char *effective_username = NULL;
GIT_UNUSED(url);
if (!userpass || !userpass->password) return -1;
/* Username resolution: a username can be passed with the URL, the
* credentials payload, or both. Here's what we do. Note that if we get
* this far, we know that any password the url may contain has already
* failed at least once, so we ignore it.
*
* | Payload | URL | Used |
* +-------------+----------+-----------+
* | yes | no | payload |
* | yes | yes | payload |
* | no | yes | url |
* | no | no | FAIL |
*/
if (userpass->username)
effective_username = userpass->username;
else if (user_from_url)
effective_username = user_from_url;
else
return -1;
if (GIT_CREDTYPE_USERNAME & allowed_types)
return git_cred_username_new(cred, effective_username);
if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
git_cred_userpass_plaintext_new(cred, effective_username, userpass->password) < 0)
return -1;
return 0;
}