mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 00:43:41 +00:00
Enhance url parsing to include passwords
This commit is contained in:
parent
7602cb7c0e
commit
cf7038a65c
38
src/netops.c
38
src/netops.c
@ -578,11 +578,22 @@ int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
|
||||
return select((int)buf->socket->socket + 1, &fds, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
int gitno_extract_host_and_port(char **host, char **port, char **username, const char *url, const char *default_port)
|
||||
int gitno_extract_url_parts(
|
||||
char **host,
|
||||
char **port,
|
||||
char **username,
|
||||
char **password,
|
||||
const char *url,
|
||||
const char *default_port)
|
||||
{
|
||||
char *colon, *slash, *at, *delim;
|
||||
char *colon, *slash, *at, *end;
|
||||
const char *start;
|
||||
|
||||
/*
|
||||
*
|
||||
* ==> [user[:pass]@]hostname.tld[:port]/resource
|
||||
*/
|
||||
|
||||
colon = strchr(url, ':');
|
||||
slash = strchr(url, '/');
|
||||
at = strchr(url, '@');
|
||||
@ -592,6 +603,19 @@ int gitno_extract_host_and_port(char **host, char **port, char **username, const
|
||||
return -1;
|
||||
}
|
||||
|
||||
start = url;
|
||||
if (at && at < slash) {
|
||||
start = at+1;
|
||||
*username = git__strndup(url, at - url);
|
||||
}
|
||||
|
||||
if (colon && colon < at) {
|
||||
git__free(*username);
|
||||
*username = git__strndup(url, colon-url);
|
||||
*password = git__strndup(colon+1, at-colon-1);
|
||||
colon = strchr(at, ':');
|
||||
}
|
||||
|
||||
if (colon == NULL) {
|
||||
*port = git__strdup(default_port);
|
||||
} else {
|
||||
@ -599,15 +623,9 @@ int gitno_extract_host_and_port(char **host, char **port, char **username, const
|
||||
}
|
||||
GITERR_CHECK_ALLOC(*port);
|
||||
|
||||
delim = colon == NULL ? slash : colon;
|
||||
end = colon == NULL ? slash : colon;
|
||||
|
||||
start = url;
|
||||
if (at && at < slash) {
|
||||
start = at+1;
|
||||
*username = git__strndup(url, at - url);
|
||||
}
|
||||
|
||||
*host = git__strndup(start, delim - start);
|
||||
*host = git__strndup(start, end - start);
|
||||
GITERR_CHECK_ALLOC(*host);
|
||||
|
||||
return 0;
|
||||
|
@ -66,6 +66,12 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags);
|
||||
int gitno_close(gitno_socket *s);
|
||||
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
|
||||
|
||||
int gitno_extract_host_and_port(char **host, char **port, char **username, const char *url, const char *default_port);
|
||||
int gitno_extract_url_parts(
|
||||
char **host,
|
||||
char **port,
|
||||
char **username,
|
||||
char **password,
|
||||
const char *url,
|
||||
const char *default_port);
|
||||
|
||||
#endif
|
||||
|
@ -179,7 +179,7 @@ static int _git_uploadpack_ls(
|
||||
const char *url,
|
||||
git_smart_subtransport_stream **stream)
|
||||
{
|
||||
char *host, *port, *user;
|
||||
char *host, *port, *user, *pass;
|
||||
git_stream *s;
|
||||
|
||||
*stream = NULL;
|
||||
@ -192,7 +192,7 @@ static int _git_uploadpack_ls(
|
||||
|
||||
s = (git_stream *)*stream;
|
||||
|
||||
if (gitno_extract_host_and_port(&host, &port, &user, url, GIT_DEFAULT_PORT) < 0)
|
||||
if (gitno_extract_url_parts(&host, &port, &user, &pass, url, GIT_DEFAULT_PORT) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (gitno_connect(&s->socket, host, port, 0) < 0)
|
||||
@ -202,6 +202,7 @@ static int _git_uploadpack_ls(
|
||||
git__free(host);
|
||||
git__free(port);
|
||||
git__free(user);
|
||||
git__free(pass);
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
@ -234,7 +235,7 @@ static int _git_receivepack_ls(
|
||||
const char *url,
|
||||
git_smart_subtransport_stream **stream)
|
||||
{
|
||||
char *host, *port, *user;
|
||||
char *host, *port, *user, *pass;
|
||||
git_stream *s;
|
||||
|
||||
*stream = NULL;
|
||||
@ -247,7 +248,7 @@ static int _git_receivepack_ls(
|
||||
|
||||
s = (git_stream *)*stream;
|
||||
|
||||
if (gitno_extract_host_and_port(&host, &port, &user, url, GIT_DEFAULT_PORT) < 0)
|
||||
if (gitno_extract_url_parts(&host, &port, &user, &pass, url, GIT_DEFAULT_PORT) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (gitno_connect(&s->socket, host, port, 0) < 0)
|
||||
@ -257,6 +258,7 @@ static int _git_receivepack_ls(
|
||||
git__free(host);
|
||||
git__free(port);
|
||||
git__free(user);
|
||||
git__free(pass);
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
|
@ -61,6 +61,7 @@ typedef struct {
|
||||
char *host;
|
||||
char *port;
|
||||
char *user_from_url;
|
||||
char *pass_from_url;
|
||||
git_cred *cred;
|
||||
http_authmechanism_t auth_mechanism;
|
||||
unsigned connected : 1,
|
||||
@ -744,8 +745,8 @@ static int http_action(
|
||||
if (!default_port)
|
||||
return -1;
|
||||
|
||||
if ((ret = gitno_extract_host_and_port(&t->host, &t->port, &t->user_from_url,
|
||||
url, default_port)) < 0)
|
||||
if ((ret = gitno_extract_url_parts(&t->host, &t->port,
|
||||
&t->user_from_url, &t->pass_from_url, url, default_port)) < 0)
|
||||
return ret;
|
||||
|
||||
t->path = strchr(url, '/');
|
||||
@ -821,6 +822,16 @@ static int http_close(git_smart_subtransport *subtransport)
|
||||
t->port = NULL;
|
||||
}
|
||||
|
||||
if (t->user_from_url) {
|
||||
git__free(t->user_from_url);
|
||||
t->user_from_url = NULL;
|
||||
}
|
||||
|
||||
if (t->pass_from_url) {
|
||||
git__free(t->pass_from_url);
|
||||
t->pass_from_url = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,8 @@ static int winhttp_connect(
|
||||
t->use_ssl = 1;
|
||||
}
|
||||
|
||||
if ((ret = gitno_extract_host_and_port(&t->host, &t->port, &t->parent.user_from_url, url, default_port)) < 0)
|
||||
if ((ret = gitno_extract_url_parts(&t->host, &t->port, &t->parent.user_from_url,
|
||||
&t->parent.pass_from_url, url, default_port)) < 0)
|
||||
return ret;
|
||||
|
||||
t->path = strchr(url, '/');
|
||||
@ -944,6 +945,16 @@ static int winhttp_close(git_smart_subtransport *subtransport)
|
||||
t->port = NULL;
|
||||
}
|
||||
|
||||
if (t->user_from_url) {
|
||||
git__free(t->user_from_url);
|
||||
t->user_from_url = NULL;
|
||||
}
|
||||
|
||||
if (t->pass_from_url) {
|
||||
git__free(t->pass_from_url);
|
||||
t->pass_from_url = NULL;
|
||||
}
|
||||
|
||||
if (t->cred) {
|
||||
t->cred->free(t->cred);
|
||||
t->cred = NULL;
|
||||
|
78
tests-clar/network/urlparse.c
Normal file
78
tests-clar/network/urlparse.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "netops.h"
|
||||
|
||||
void test_network_urlparse__trivial(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"example.com/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "8080");
|
||||
cl_assert_equal_sz(user, NULL);
|
||||
cl_assert_equal_sz(pass, NULL);
|
||||
}
|
||||
|
||||
void test_network_urlparse__user(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"user@example.com/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "8080");
|
||||
cl_assert_equal_s(user, "user");
|
||||
cl_assert_equal_sz(pass, NULL);
|
||||
}
|
||||
|
||||
void test_network_urlparse__user_pass(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
/* user:pass@hostname.tld/resource */
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"user:pass@example.com/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "8080");
|
||||
cl_assert_equal_s(user, "user");
|
||||
cl_assert_equal_s(pass, "pass");
|
||||
}
|
||||
|
||||
void test_network_urlparse__port(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
/* hostname.tld:port/resource */
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"example.com:9191/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "9191");
|
||||
cl_assert_equal_sz(user, NULL);
|
||||
cl_assert_equal_sz(pass, NULL);
|
||||
}
|
||||
|
||||
void test_network_urlparse__user_port(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
/* user@hostname.tld:port/resource */
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"user@example.com:9191/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "9191");
|
||||
cl_assert_equal_s(user, "user");
|
||||
cl_assert_equal_sz(pass, NULL);
|
||||
}
|
||||
|
||||
void test_network_urlparse__user_pass_port(void)
|
||||
{
|
||||
char *host, *port, *user, *pass;
|
||||
|
||||
/* user:pass@hostname.tld:port/resource */
|
||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,
|
||||
"user:pass@example.com:9191/resource", "8080"));
|
||||
cl_assert_equal_s(host, "example.com");
|
||||
cl_assert_equal_s(port, "9191");
|
||||
cl_assert_equal_s(user, "user");
|
||||
cl_assert_equal_s(pass, "pass");
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
|
||||
#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
|
||||
#define BB_REPO_URL "https://libgit2@bitbucket.org/libgit2/testgitrepository.git"
|
||||
#define BB_REPO_URL_WITH_PASS "https://libgit2:libgit2@bitbucket.org/libgit2/testgitrepository.git"
|
||||
|
||||
static git_repository *g_repo;
|
||||
static git_clone_options g_options;
|
||||
@ -167,4 +168,8 @@ void test_online_clone__bitbucket_style(void)
|
||||
cl_git_pass(git_clone(&g_repo, BB_REPO_URL, "./foo", &g_options));
|
||||
git_repository_free(g_repo); g_repo = NULL;
|
||||
cl_fixture_cleanup("./foo");
|
||||
|
||||
cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_PASS, "./foo", &g_options));
|
||||
git_repository_free(g_repo); g_repo = NULL;
|
||||
cl_fixture_cleanup("./foo");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user