HTTP: use creds in url if available
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
diff --git a/src/transports/http.c b/src/transports/http.c
index 6c116d8..964bafb 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -63,6 +63,7 @@ typedef struct {
char *user_from_url;
char *pass_from_url;
git_cred *cred;
+ git_cred *url_cred;
http_authmechanism_t auth_mechanism;
unsigned connected : 1,
use_ssl : 1;
@@ -146,6 +147,14 @@ static int gen_request(
apply_basic_credential(buf, t->cred) < 0)
return -1;
+ /* Use url-parsed basic auth if username and password are both provided */
+ if (!t->cred && t->user_from_url && t->pass_from_url) {
+ if (!t->url_cred &&
+ git_cred_userpass_plaintext_new(&t->url_cred, t->user_from_url, t->pass_from_url) < 0)
+ return -1;
+ if (apply_basic_credential(buf, t->url_cred) < 0) return -1;
+ }
+
git_buf_puts(buf, "\r\n");
if (git_buf_oom(buf))
@@ -812,6 +821,11 @@ static int http_close(git_smart_subtransport *subtransport)
t->cred = NULL;
}
+ if (t->url_cred) {
+ t->url_cred->free(t->url_cred);
+ t->url_cred = NULL;
+ }
+
if (t->host) {
git__free(t->host);
t->host = NULL;
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 4ac085e..780b84e 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -960,6 +960,11 @@ static int winhttp_close(git_smart_subtransport *subtransport)
t->cred = NULL;
}
+ if (t->url_cred) {
+ t->url_cred->free(t->url_cred);
+ t->url_cred = NULL;
+ }
+
if (t->connection) {
if (!WinHttpCloseHandle(t->connection)) {
giterr_set(GITERR_OS, "Unable to close connection");
diff --git a/tests-clar/online/clone.c b/tests-clar/online/clone.c
index 0bc7440..6a46fa5 100644
--- a/tests-clar/online/clone.c
+++ b/tests-clar/online/clone.c
@@ -8,6 +8,7 @@
#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"
+#define BB_REPO_URL_WITH_WRONG_PASS "https://libgit2:wrong@bitbucket.org/libgit2/testgitrepository.git"
static git_repository *g_repo;
static git_clone_options g_options;
@@ -169,7 +170,15 @@ void test_online_clone__bitbucket_style(void)
git_repository_free(g_repo); g_repo = NULL;
cl_fixture_cleanup("./foo");
+ /* User and pass from URL */
+ user_pass.password = "wrong";
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");
+
+ /* Wrong password in URL, fall back to user_pass */
+ user_pass.password = "libgit2";
+ cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_WRONG_PASS, "./foo", &g_options));
+ git_repository_free(g_repo); g_repo = NULL;
+ cl_fixture_cleanup("./foo");
}