mirror of
https://git.proxmox.com/git/libgit2
synced 2025-10-19 11:16:15 +00:00
Added support for ssh:// urls
This commit is contained in:
parent
120b0122c5
commit
7261d9837e
@ -18,21 +18,22 @@ typedef struct transport_definition {
|
|||||||
void *param;
|
void *param;
|
||||||
} transport_definition;
|
} transport_definition;
|
||||||
|
|
||||||
static transport_definition local_transport_definition = { "file://", 1, git_transport_local, NULL };
|
|
||||||
static transport_definition dummy_transport_definition = { NULL, 1, git_transport_dummy, NULL };
|
|
||||||
|
|
||||||
static git_smart_subtransport_definition http_subtransport_definition = { git_smart_subtransport_http, 1 };
|
static git_smart_subtransport_definition http_subtransport_definition = { git_smart_subtransport_http, 1 };
|
||||||
static git_smart_subtransport_definition git_subtransport_definition = { git_smart_subtransport_git, 0 };
|
static git_smart_subtransport_definition git_subtransport_definition = { git_smart_subtransport_git, 0 };
|
||||||
static git_smart_subtransport_definition ssh_subtransport_definition = { git_smart_subtransport_ssh, 0 };
|
static git_smart_subtransport_definition ssh_subtransport_definition = { git_smart_subtransport_ssh, 0 };
|
||||||
|
|
||||||
|
static transport_definition local_transport_definition = { "file://", 1, git_transport_local, NULL };
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
static transport_definition dummy_transport_definition = { NULL, 1, git_transport_dummy, NULL };
|
||||||
|
#endif
|
||||||
|
static transport_definition ssh_transport_definition = { "ssh://", 1, git_transport_smart, &ssh_subtransport_definition };
|
||||||
|
|
||||||
static transport_definition transports[] = {
|
static transport_definition transports[] = {
|
||||||
{"git://", 1, git_transport_smart, &git_subtransport_definition},
|
{"git://", 1, git_transport_smart, &git_subtransport_definition},
|
||||||
{"http://", 1, git_transport_smart, &http_subtransport_definition},
|
{"http://", 1, git_transport_smart, &http_subtransport_definition},
|
||||||
{"https://", 1, git_transport_smart, &http_subtransport_definition},
|
{"https://", 1, git_transport_smart, &http_subtransport_definition},
|
||||||
{"file://", 1, git_transport_local, NULL},
|
{"file://", 1, git_transport_local, NULL},
|
||||||
{"git+ssh://", 1, git_transport_smart, &ssh_subtransport_definition},
|
{"ssh://", 1, git_transport_smart, &ssh_subtransport_definition},
|
||||||
{"ssh+git://", 1, git_transport_smart, &ssh_subtransport_definition},
|
|
||||||
{"git@", 1, git_transport_smart, &ssh_subtransport_definition},
|
|
||||||
{NULL, 0, 0}
|
{NULL, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
|
|||||||
/* It could be a SSH remote path. Check to see if there's a :
|
/* It could be a SSH remote path. Check to see if there's a :
|
||||||
* SSH is an unsupported transport mechanism in this version of libgit2 */
|
* SSH is an unsupported transport mechanism in this version of libgit2 */
|
||||||
if (!definition && strrchr(url, ':'))
|
if (!definition && strrchr(url, ':'))
|
||||||
definition = &dummy_transport_definition;
|
definition = &ssh_transport_definition;
|
||||||
|
|
||||||
/* Check to see if the path points to a file on the local file system */
|
/* Check to see if the path points to a file on the local file system */
|
||||||
if (!definition && git_path_exists(url) && git_path_isdir(url))
|
if (!definition && git_path_exists(url) && git_path_isdir(url))
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
|
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
|
||||||
|
|
||||||
static const char prefix_ssh[] = "ssh://";
|
static const char prefix_ssh[] = "ssh://";
|
||||||
static const char prefix_git[] = "git@";
|
static const char default_user[] = "git";
|
||||||
static const char cmd_uploadpack[] = "git-upload-pack";
|
static const char cmd_uploadpack[] = "git-upload-pack";
|
||||||
static const char cmd_receivepack[] = "git-receive-pack";
|
static const char cmd_receivepack[] = "git-receive-pack";
|
||||||
|
|
||||||
@ -26,7 +26,6 @@ typedef struct {
|
|||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
char *url;
|
char *url;
|
||||||
char *path;
|
|
||||||
unsigned sent_command : 1;
|
unsigned sent_command : 1;
|
||||||
} ssh_stream;
|
} ssh_stream;
|
||||||
|
|
||||||
@ -42,8 +41,21 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* For example: git-upload-pack '/libgit2/libgit2'
|
* For example: git-upload-pack '/libgit2/libgit2'
|
||||||
*/
|
*/
|
||||||
static int gen_proto(git_buf *request, const char *cmd, const char *repo)
|
static int gen_proto(git_buf *request, const char *cmd, const char *url)
|
||||||
{
|
{
|
||||||
|
char *repo;
|
||||||
|
|
||||||
|
if (!git__prefixcmp(url, prefix_ssh)) {
|
||||||
|
url = url + strlen(prefix_ssh);
|
||||||
|
repo = strchr(url, '/');
|
||||||
|
} else {
|
||||||
|
repo = strchr(url, ':');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!repo) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int len = strlen(cmd) + 1 /* Space */ + 1 /* Quote */ + strlen(repo) + 1 /* Quote */ + 1;
|
int len = strlen(cmd) + 1 /* Space */ + 1 /* Quote */ + strlen(repo) + 1 /* Quote */ + 1;
|
||||||
|
|
||||||
git_buf_grow(request, len);
|
git_buf_grow(request, len);
|
||||||
@ -61,7 +73,7 @@ static int send_command(ssh_stream *s)
|
|||||||
int error;
|
int error;
|
||||||
git_buf request = GIT_BUF_INIT;
|
git_buf request = GIT_BUF_INIT;
|
||||||
|
|
||||||
error = gen_proto(&request, s->cmd, s->path);
|
error = gen_proto(&request, s->cmd, s->url);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -183,18 +195,15 @@ static int ssh_stream_alloc(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temp */
|
static int git_ssh_extract_url_parts(
|
||||||
static int gitssh_extract_url_parts(
|
|
||||||
char **host,
|
char **host,
|
||||||
char **username,
|
char **username,
|
||||||
char **path,
|
|
||||||
const char *url)
|
const char *url)
|
||||||
{
|
{
|
||||||
char *colon, *at;
|
char *colon, *at;
|
||||||
const char *start;
|
const char *start;
|
||||||
|
|
||||||
colon = strchr(url, ':');
|
colon = strchr(url, ':');
|
||||||
at = strchr(url, '@');
|
|
||||||
|
|
||||||
if (colon == NULL) {
|
if (colon == NULL) {
|
||||||
giterr_set(GITERR_NET, "Malformed URL: missing :");
|
giterr_set(GITERR_NET, "Malformed URL: missing :");
|
||||||
@ -202,15 +211,15 @@ static int gitssh_extract_url_parts(
|
|||||||
}
|
}
|
||||||
|
|
||||||
start = url;
|
start = url;
|
||||||
|
at = strchr(url, '@');
|
||||||
if (at) {
|
if (at) {
|
||||||
start = at+1;
|
start = at+1;
|
||||||
*username = git__substrdup(url, at - url);
|
*username = git__substrdup(url, at - url);
|
||||||
} else {
|
} else {
|
||||||
*username = "git";
|
*username = git__strdup(default_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
*host = git__substrdup(start, colon - start);
|
*host = git__substrdup(start, colon - start);
|
||||||
*path = colon+1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -222,7 +231,8 @@ static int _git_ssh_setup_conn(
|
|||||||
git_smart_subtransport_stream **stream
|
git_smart_subtransport_stream **stream
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char *host, *user=NULL;
|
char *host, *port, *user=NULL, *pass=NULL;
|
||||||
|
const char *default_port = "22";
|
||||||
ssh_stream *s;
|
ssh_stream *s;
|
||||||
|
|
||||||
*stream = NULL;
|
*stream = NULL;
|
||||||
@ -231,21 +241,35 @@ static int _git_ssh_setup_conn(
|
|||||||
|
|
||||||
s = (ssh_stream *)*stream;
|
s = (ssh_stream *)*stream;
|
||||||
|
|
||||||
if (gitssh_extract_url_parts(&host, &user, &s->path, url) < 0)
|
if (!git__prefixcmp(url, prefix_ssh)) {
|
||||||
goto on_error;
|
url = url + strlen(prefix_ssh);
|
||||||
|
if (gitno_extract_url_parts(&host, &port, &user, &pass, url, default_port) < 0)
|
||||||
if (gitno_connect(&s->socket, host, "22", 0) < 0)
|
return -1;
|
||||||
|
} else {
|
||||||
|
if (git_ssh_extract_url_parts(&host, &user, url) < 0)
|
||||||
|
goto on_error;
|
||||||
|
port = git__strdup(default_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gitno_connect(&s->socket, host, port, 0) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
|
if (user && pass) {
|
||||||
|
git_cred_userpass_plaintext_new(&t->cred, user, pass);
|
||||||
|
} else {
|
||||||
if (t->owner->cred_acquire_cb(&t->cred,
|
if (t->owner->cred_acquire_cb(&t->cred,
|
||||||
t->owner->url,
|
t->owner->url,
|
||||||
user,
|
user,
|
||||||
GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE,
|
GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE,
|
||||||
t->owner->cred_acquire_payload) < 0)
|
t->owner->cred_acquire_payload) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
assert(t->cred);
|
assert(t->cred);
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
user = git__strdup(default_user);
|
||||||
|
}
|
||||||
|
|
||||||
git_cred_ssh_keyfile_passphrase *cred = (git_cred_ssh_keyfile_passphrase *)t->cred;
|
git_cred_ssh_keyfile_passphrase *cred = (git_cred_ssh_keyfile_passphrase *)t->cred;
|
||||||
|
|
||||||
LIBSSH2_SESSION* session = libssh2_session_init();
|
LIBSSH2_SESSION* session = libssh2_session_init();
|
||||||
|
Loading…
Reference in New Issue
Block a user