mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-13 16:52:39 +00:00
Merge pull request #3555 from cbargren/ssh-git-protocols
Support for ssh+git and git+ssh protocols
This commit is contained in:
commit
b7809b8469
5
deps/http-parser/http_parser.c
vendored
5
deps/http-parser/http_parser.c
vendored
@ -444,6 +444,9 @@ parse_url_char(enum state s, const char ch)
|
|||||||
return s_req_path;
|
return s_req_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The schema must start with an alpha character. After that, it may
|
||||||
|
* consist of digits, '+', '-' or '.', followed by a ':'.
|
||||||
|
*/
|
||||||
if (IS_ALPHA(ch)) {
|
if (IS_ALPHA(ch)) {
|
||||||
return s_req_schema;
|
return s_req_schema;
|
||||||
}
|
}
|
||||||
@ -451,7 +454,7 @@ parse_url_char(enum state s, const char ch)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case s_req_schema:
|
case s_req_schema:
|
||||||
if (IS_ALPHA(ch)) {
|
if (IS_ALPHANUM(ch) || ch == '+' || ch == '-' || ch == '.') {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ static transport_definition transports[] = {
|
|||||||
{ "file://", git_transport_local, NULL },
|
{ "file://", git_transport_local, NULL },
|
||||||
#ifdef GIT_SSH
|
#ifdef GIT_SSH
|
||||||
{ "ssh://", git_transport_smart, &ssh_subtransport_definition },
|
{ "ssh://", git_transport_smart, &ssh_subtransport_definition },
|
||||||
|
{ "ssh+git://", git_transport_smart, &ssh_subtransport_definition },
|
||||||
|
{ "git+ssh://", git_transport_smart, &ssh_subtransport_definition },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#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 *ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" };
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
@ -63,17 +64,24 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
|
|||||||
{
|
{
|
||||||
char *repo;
|
char *repo;
|
||||||
int len;
|
int len;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if (!git__prefixcmp(url, prefix_ssh)) {
|
for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) {
|
||||||
url = url + strlen(prefix_ssh);
|
const char *p = ssh_prefixes[i];
|
||||||
|
|
||||||
|
if (!git__prefixcmp(url, p)) {
|
||||||
|
url = url + strlen(p);
|
||||||
repo = strchr(url, '/');
|
repo = strchr(url, '/');
|
||||||
if (repo && repo[1] == '~')
|
if (repo && repo[1] == '~')
|
||||||
++repo;
|
++repo;
|
||||||
} else {
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
repo = strchr(url, ':');
|
repo = strchr(url, ':');
|
||||||
if (repo) repo++;
|
if (repo) repo++;
|
||||||
}
|
|
||||||
|
|
||||||
|
done:
|
||||||
if (!repo) {
|
if (!repo) {
|
||||||
giterr_set(GITERR_NET, "Malformed git protocol URL");
|
giterr_set(GITERR_NET, "Malformed git protocol URL");
|
||||||
return -1;
|
return -1;
|
||||||
@ -500,6 +508,7 @@ static int _git_ssh_setup_conn(
|
|||||||
char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
|
char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
|
||||||
const char *default_port="22";
|
const char *default_port="22";
|
||||||
int auth_methods, error = 0;
|
int auth_methods, error = 0;
|
||||||
|
size_t i;
|
||||||
ssh_stream *s;
|
ssh_stream *s;
|
||||||
git_cred *cred = NULL;
|
git_cred *cred = NULL;
|
||||||
LIBSSH2_SESSION* session=NULL;
|
LIBSSH2_SESSION* session=NULL;
|
||||||
@ -515,16 +524,22 @@ static int _git_ssh_setup_conn(
|
|||||||
s->session = NULL;
|
s->session = NULL;
|
||||||
s->channel = NULL;
|
s->channel = NULL;
|
||||||
|
|
||||||
if (!git__prefixcmp(url, prefix_ssh)) {
|
for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) {
|
||||||
|
const char *p = ssh_prefixes[i];
|
||||||
|
|
||||||
|
if (!git__prefixcmp(url, p)) {
|
||||||
if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
|
if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
|
||||||
|
goto post_extract;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
|
if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
port = git__strdup(default_port);
|
port = git__strdup(default_port);
|
||||||
GITERR_CHECK_ALLOC(port);
|
GITERR_CHECK_ALLOC(port);
|
||||||
}
|
|
||||||
|
|
||||||
|
post_extract:
|
||||||
if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
|
if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
|
||||||
(error = git_stream_connect(s->io)) < 0)
|
(error = git_stream_connect(s->io)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -44,8 +44,13 @@ void test_transport_register__custom_transport_ssh(void)
|
|||||||
|
|
||||||
#ifndef GIT_SSH
|
#ifndef GIT_SSH
|
||||||
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
|
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
|
||||||
|
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1);
|
||||||
|
cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1);
|
||||||
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
|
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
|
||||||
#else
|
#else
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath"));
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"));
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"));
|
||||||
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
|
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
|
||||||
transport->free(transport);
|
transport->free(transport);
|
||||||
#endif
|
#endif
|
||||||
@ -60,8 +65,13 @@ void test_transport_register__custom_transport_ssh(void)
|
|||||||
|
|
||||||
#ifndef GIT_SSH
|
#ifndef GIT_SSH
|
||||||
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
|
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
|
||||||
|
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1);
|
||||||
|
cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1);
|
||||||
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
|
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
|
||||||
#else
|
#else
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath"));
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"));
|
||||||
|
cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"));
|
||||||
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
|
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
|
||||||
transport->free(transport);
|
transport->free(transport);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user