Commit 7affc2f7 by Carlos Martín Nieto

Include username in each credential type

Key-based authentication also needs an username, so include it in each
one.

Also stop assuming a default username of "git" in the ssh transport
which has no business making such a decision.
parent a25519ac
......@@ -59,6 +59,7 @@ typedef int (*git_cred_sign_callback)(void *, ...);
/* A ssh key file and passphrase */
typedef struct git_cred_ssh_keyfile_passphrase {
git_cred parent;
char *username;
char *publickey;
char *privatekey;
char *passphrase;
......@@ -67,13 +68,22 @@ typedef struct git_cred_ssh_keyfile_passphrase {
/* A ssh public key and authentication callback */
typedef struct git_cred_ssh_publickey {
git_cred parent;
char *username;
char *publickey;
size_t publickey_len;
size_t publickey_len;
void *sign_callback;
void *sign_data;
} git_cred_ssh_publickey;
/**
* Check whether a credential object contains username information.
*
* @param cred object to check
* @return 1 if the credential object has non-NULL username, 0 otherwise
*/
GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
/**
* Creates a new plain-text username and password credential object.
* The supplied credential parameter will be internally duplicated.
*
......@@ -92,6 +102,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
* @param username username to use to authenticate
* @param publickey The path to the public key of the credential.
* @param privatekey The path to the private key of the credential.
* @param passphrase The passphrase of the credential.
......@@ -99,6 +110,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
*/
GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new(
git_cred **out,
const char *username,
const char *publickey,
const char *privatekey,
const char *passphrase);
......@@ -108,6 +120,7 @@ GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new(
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
* @param username username to use to authenticate
* @param publickey The bytes of the public key.
* @param publickey_len The length of the public key in bytes.
* @param sign_fn The callback method for authenticating.
......@@ -116,6 +129,7 @@ GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new(
*/
GIT_EXTERN(int) git_cred_ssh_publickey_new(
git_cred **out,
const char *username,
const char *publickey,
size_t publickey_len,
git_cred_sign_callback sign_fn,
......
......@@ -9,6 +9,31 @@
#include "smart.h"
#include "git2/cred_helpers.h"
int git_cred_has_username(git_cred *cred)
{
int ret = 0;
switch (cred->credtype) {
case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
ret = !!c->username;
break;
}
case GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE: {
git_cred_ssh_keyfile_passphrase *c = (git_cred_ssh_keyfile_passphrase *)cred;
ret = !!c->username;
break;
}
case GIT_CREDTYPE_SSH_PUBLICKEY: {
git_cred_ssh_publickey *c = (git_cred_ssh_publickey *)cred;
ret = !!c->username;
break;
}
}
return ret;
}
static void plaintext_free(struct git_cred *cred)
{
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
......@@ -64,6 +89,7 @@ static void ssh_keyfile_passphrase_free(struct git_cred *cred)
git_cred_ssh_keyfile_passphrase *c =
(git_cred_ssh_keyfile_passphrase *)cred;
git__free(c->username);
git__free(c->publickey);
git__free(c->privatekey);
......@@ -82,6 +108,7 @@ static void ssh_publickey_free(struct git_cred *cred)
{
git_cred_ssh_publickey *c = (git_cred_ssh_publickey *)cred;
git__free(c->username);
git__free(c->publickey);
git__memzero(c, sizeof(*c));
......@@ -90,6 +117,7 @@ static void ssh_publickey_free(struct git_cred *cred)
int git_cred_ssh_keyfile_passphrase_new(
git_cred **cred,
const char *username,
const char *publickey,
const char *privatekey,
const char *passphrase)
......@@ -104,6 +132,11 @@ int git_cred_ssh_keyfile_passphrase_new(
c->parent.credtype = GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE;
c->parent.free = ssh_keyfile_passphrase_free;
if (username) {
c->username = git__strdup(username);
GITERR_CHECK_ALLOC(c->username);
}
c->privatekey = git__strdup(privatekey);
GITERR_CHECK_ALLOC(c->privatekey);
......@@ -123,6 +156,7 @@ int git_cred_ssh_keyfile_passphrase_new(
int git_cred_ssh_publickey_new(
git_cred **cred,
const char *username,
const char *publickey,
size_t publickey_len,
git_cred_sign_callback sign_callback,
......@@ -138,6 +172,11 @@ int git_cred_ssh_publickey_new(
c->parent.credtype = GIT_CREDTYPE_SSH_PUBLICKEY;
c->parent.free = ssh_publickey_free;
if (username) {
c->username = git__strdup(username);
GITERR_CHECK_ALLOC(c->username);
}
if (publickey_len > 0) {
c->publickey = git__malloc(publickey_len);
GITERR_CHECK_ALLOC(c->publickey);
......
......@@ -17,7 +17,6 @@
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
static const char prefix_ssh[] = "ssh://";
static const char default_user[] = "git";
static const char cmd_uploadpack[] = "git-upload-pack";
static const char cmd_receivepack[] = "git-receive-pack";
......@@ -214,11 +213,10 @@ static int git_ssh_extract_url_parts(
if (at) {
start = at+1;
*username = git__substrdup(url, at - url);
GITERR_CHECK_ALLOC(*username);
} else {
start = url;
*username = git__strdup(default_user);
*username = NULL;
}
GITERR_CHECK_ALLOC(*username);
*host = git__substrdup(start, colon - start);
GITERR_CHECK_ALLOC(*host);
......@@ -237,19 +235,23 @@ static int _git_ssh_authenticate_session(
switch (cred->credtype) {
case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
rc = libssh2_userauth_password(session, c->username, c->password);
user = c->username ? c->username : user;
rc = libssh2_userauth_password(session, user, c->password);
break;
}
case GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE: {
git_cred_ssh_keyfile_passphrase *c = (git_cred_ssh_keyfile_passphrase *)cred;
user = c->username ? c->username : user;
rc = libssh2_userauth_publickey_fromfile(
session, user, c->publickey, c->privatekey, c->passphrase);
session, c->username, c->publickey, c->privatekey, c->passphrase);
break;
}
case GIT_CREDTYPE_SSH_PUBLICKEY: {
git_cred_ssh_publickey *c = (git_cred_ssh_publickey *)cred;
user = c->username ? c->username : user;
rc = libssh2_userauth_publickey(
session, user, (const unsigned char *)c->publickey,
session, c->username, (const unsigned char *)c->publickey,
c->publickey_len, c->sign_callback, &c->sign_data);
break;
}
......@@ -351,9 +353,9 @@ static int _git_ssh_setup_conn(
}
assert(t->cred);
if (!user) {
user = git__strdup(default_user);
GITERR_CHECK_ALLOC(user);
if (!user && !git_cred_has_username(t->cred)) {
giterr_set_str(GITERR_NET, "Cannot authenticate without a username");
goto on_error;
}
if (_git_ssh_session_create(&session, s->socket) < 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment