diff --git a/src/transports/http.c b/src/transports/http.c index 6c116d8e7..964bafb19 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 4ac085ed3..780b84e45 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 0bc744013..6a46fa511 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"); }