Commit 7261d983 by Brad Morgan

Added support for ssh:// urls

parent 120b0122
...@@ -18,21 +18,22 @@ typedef struct transport_definition { ...@@ -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 * ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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)
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, "22", 0) < 0) if (gitno_connect(&s->socket, host, port, 0) < 0)
goto on_error; goto on_error;
if (t->owner->cred_acquire_cb(&t->cred, if (user && pass) {
t->owner->url, git_cred_userpass_plaintext_new(&t->cred, user, pass);
user, } else {
GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE, if (t->owner->cred_acquire_cb(&t->cred,
t->owner->cred_acquire_payload) < 0) t->owner->url,
return -1; user,
GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE,
t->owner->cred_acquire_payload) < 0)
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();
......
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