summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2013-01-31 14:04:21 -0800
committerBen Straub <bs@github.com>2013-01-31 14:04:21 -0800
commitcf7038a65cb080a2946202fe6cbbe52aefae1fd4 (patch)
tree379e3be397c781f7af8e06d89f4fb024bd8c05db /src
parent7602cb7c0ea0d69efd30640af234be20393bf57c (diff)
downloadlibgit2-cf7038a65cb080a2946202fe6cbbe52aefae1fd4.tar.gz
Enhance url parsing to include passwords
Diffstat (limited to 'src')
-rw-r--r--src/netops.c38
-rw-r--r--src/netops.h8
-rw-r--r--src/transports/git.c10
-rw-r--r--src/transports/http.c15
-rw-r--r--src/transports/winhttp.c13
5 files changed, 66 insertions, 18 deletions
diff --git a/src/netops.c b/src/netops.c
index 12738141f..fd788bc1d 100644
--- a/src/netops.c
+++ b/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;
-
- start = url;
- if (at && at < slash) {
- start = at+1;
- *username = git__strndup(url, at - url);
- }
+ end = colon == NULL ? slash : colon;
- *host = git__strndup(start, delim - start);
+ *host = git__strndup(start, end - start);
GITERR_CHECK_ALLOC(*host);
return 0;
diff --git a/src/netops.h b/src/netops.h
index bb2624abe..d352bf3b6 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -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
diff --git a/src/transports/git.c b/src/transports/git.c
index 5c816e127..21de4d789 100644
--- a/src/transports/git.c
+++ b/src/transports/git.c
@@ -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:
diff --git a/src/transports/http.c b/src/transports/http.c
index 144906474..6c116d8e7 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -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;
}
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 544e52f4d..4ac085ed3 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -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;