Commit 80fc7d6b by Edward Thomson

Propagate auth error codes as GIT_EUSER in winhttp

parent 87209444
...@@ -82,29 +82,35 @@ static int ensure_remote_name_is_valid(const char *name) ...@@ -82,29 +82,35 @@ static int ensure_remote_name_is_valid(const char *name)
return error; return error;
} }
static int get_check_cert(git_repository *repo) static int get_check_cert(int *out, git_repository *repo)
{ {
git_config *cfg; git_config *cfg;
const char *val; const char *val;
int check_cert; int error = 0;
assert(out && repo);
assert(repo); /* By default, we *DO* want to verify the certificate. */
*out = 1;
/* Go through the possible sources for SSL verification settings, from /* Go through the possible sources for SSL verification settings, from
* most specific to least specific. */ * most specific to least specific. */
/* GIT_SSL_NO_VERIFY environment variable */ /* GIT_SSL_NO_VERIFY environment variable */
if ((val = getenv("GIT_SSL_NO_VERIFY")) && if (val = getenv("GIT_SSL_NO_VERIFY"))
!git_config_parse_bool(&check_cert, val)) return git_config_parse_bool(out, val);
return !check_cert;
/* http.sslVerify config setting */ /* http.sslVerify config setting */
if (!git_repository_config__weakptr(&cfg, repo) && if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
!git_config_get_bool(&check_cert, cfg, "http.sslVerify")) return error;
return check_cert;
/* By default, we *DO* want to verify the certificate. */ if ((error = git_config_get_bool(out, cfg, "http.sslVerify")) == 0)
return 1; return 0;
else if (error != GIT_ENOTFOUND)
return error;
giterr_clear();
return 0;
} }
static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch) static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
...@@ -120,9 +126,11 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n ...@@ -120,9 +126,11 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
GITERR_CHECK_ALLOC(remote); GITERR_CHECK_ALLOC(remote);
remote->repo = repo; remote->repo = repo;
remote->check_cert = (unsigned)get_check_cert(repo);
remote->update_fetchhead = 1; remote->update_fetchhead = 1;
if (get_check_cert(&remote->check_cert, repo) < 0)
goto on_error;
if (git_vector_init(&remote->refs, 32, NULL) < 0) if (git_vector_init(&remote->refs, 32, NULL) < 0)
goto on_error; goto on_error;
...@@ -314,11 +322,13 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name) ...@@ -314,11 +322,13 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
GITERR_CHECK_ALLOC(remote); GITERR_CHECK_ALLOC(remote);
memset(remote, 0x0, sizeof(git_remote)); memset(remote, 0x0, sizeof(git_remote));
remote->check_cert = (unsigned)get_check_cert(repo);
remote->update_fetchhead = 1; remote->update_fetchhead = 1;
remote->name = git__strdup(name); remote->name = git__strdup(name);
GITERR_CHECK_ALLOC(remote->name); GITERR_CHECK_ALLOC(remote->name);
if ((error = get_check_cert(&remote->check_cert, repo)) < 0)
goto cleanup;
if ((git_vector_init(&remote->refs, 32, NULL) < 0) || if ((git_vector_init(&remote->refs, 32, NULL) < 0) ||
(git_vector_init(&remote->refspecs, 2, NULL) < 0) || (git_vector_init(&remote->refspecs, 2, NULL) < 0) ||
(git_vector_init(&remote->active_refspecs, 2, NULL) < 0)) { (git_vector_init(&remote->active_refspecs, 2, NULL) < 0)) {
...@@ -610,13 +620,14 @@ int git_remote_connect(git_remote *remote, git_direction direction) ...@@ -610,13 +620,14 @@ int git_remote_connect(git_remote *remote, git_direction direction)
git_transport *t; git_transport *t;
const char *url; const char *url;
int flags = GIT_TRANSPORTFLAGS_NONE; int flags = GIT_TRANSPORTFLAGS_NONE;
int error;
assert(remote); assert(remote);
t = remote->transport; t = remote->transport;
url = git_remote__urlfordirection(remote, direction); url = git_remote__urlfordirection(remote, direction);
if (url == NULL ) { if (url == NULL) {
giterr_set(GITERR_INVALID, giterr_set(GITERR_INVALID,
"Malformed remote '%s' - missing URL", remote->name); "Malformed remote '%s' - missing URL", remote->name);
return -1; return -1;
...@@ -624,17 +635,17 @@ int git_remote_connect(git_remote *remote, git_direction direction) ...@@ -624,17 +635,17 @@ int git_remote_connect(git_remote *remote, git_direction direction)
/* A transport could have been supplied in advance with /* A transport could have been supplied in advance with
* git_remote_set_transport */ * git_remote_set_transport */
if (!t && git_transport_new(&t, remote, url) < 0) if (!t && (error = git_transport_new(&t, remote, url)) < 0)
return -1; return error;
if (t->set_callbacks && if (t->set_callbacks &&
t->set_callbacks(t, remote->callbacks.progress, NULL, remote->callbacks.payload) < 0) (error = t->set_callbacks(t, remote->callbacks.progress, NULL, remote->callbacks.payload)) < 0)
goto on_error; goto on_error;
if (!remote->check_cert) if (!remote->check_cert)
flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT; flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT;
if (t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags) < 0) if ((error = t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags)) < 0)
goto on_error; goto on_error;
remote->transport = t; remote->transport = t;
...@@ -647,7 +658,7 @@ on_error: ...@@ -647,7 +658,7 @@ on_error:
if (t == remote->transport) if (t == remote->transport)
remote->transport = NULL; remote->transport = NULL;
return -1; return error;
} }
int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote) int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote)
...@@ -661,6 +672,7 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur ...@@ -661,6 +672,7 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
{ {
git_config *cfg; git_config *cfg;
const char *val; const char *val;
int error;
assert(remote); assert(remote);
...@@ -669,8 +681,8 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur ...@@ -669,8 +681,8 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
*proxy_url = NULL; *proxy_url = NULL;
if (git_repository_config__weakptr(&cfg, remote->repo) < 0) if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0)
return -1; return error;
/* Go through the possible sources for proxy configuration, from most specific /* Go through the possible sources for proxy configuration, from most specific
* to least specific. */ * to least specific. */
...@@ -679,28 +691,33 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur ...@@ -679,28 +691,33 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
if (remote->name && 0 != *(remote->name)) { if (remote->name && 0 != *(remote->name)) {
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
if (git_buf_printf(&buf, "remote.%s.proxy", remote->name) < 0) if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0)
return -1; return error;
if (!git_config_get_string(&val, cfg, git_buf_cstr(&buf)) && if ((error = git_config_get_string(&val, cfg, git_buf_cstr(&buf))) == 0 &&
val && ('\0' != *val)) { val && ('\0' != *val)) {
git_buf_free(&buf); git_buf_free(&buf);
*proxy_url = git__strdup(val); *proxy_url = git__strdup(val);
GITERR_CHECK_ALLOC(*proxy_url); GITERR_CHECK_ALLOC(*proxy_url);
return 0; return 0;
} } else if (error != GIT_ENOTFOUND)
return error;
giterr_clear();
git_buf_free(&buf); git_buf_free(&buf);
} }
/* http.proxy config setting */ /* http.proxy config setting */
if (!git_config_get_string(&val, cfg, "http.proxy") && if ((error = git_config_get_string(&val, cfg, "http.proxy")) == 0 &&
val && ('\0' != *val)) { val && ('\0' != *val)) {
*proxy_url = git__strdup(val); *proxy_url = git__strdup(val);
GITERR_CHECK_ALLOC(*proxy_url); GITERR_CHECK_ALLOC(*proxy_url);
return 0; return 0;
} } else if (error != GIT_ENOTFOUND)
return error;
giterr_clear();
/* HTTP_PROXY / HTTPS_PROXY environment variables */ /* HTTP_PROXY / HTTPS_PROXY environment variables */
val = use_ssl ? getenv("HTTPS_PROXY") : getenv("HTTP_PROXY"); val = use_ssl ? getenv("HTTPS_PROXY") : getenv("HTTP_PROXY");
......
...@@ -49,7 +49,7 @@ int git_smart__store_refs(transport_smart *t, int flushes) ...@@ -49,7 +49,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
if (error == GIT_EBUFS) { if (error == GIT_EBUFS) {
if ((recvd = gitno_recv(buf)) < 0) if ((recvd = gitno_recv(buf)) < 0)
return -1; return recvd;
if (recvd == 0 && !flush) { if (recvd == 0 && !flush) {
giterr_set(GITERR_NET, "Early EOF"); giterr_set(GITERR_NET, "Early EOF");
...@@ -164,10 +164,10 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf) ...@@ -164,10 +164,10 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf)
break; /* return the pkt */ break; /* return the pkt */
if (error < 0 && error != GIT_EBUFS) if (error < 0 && error != GIT_EBUFS)
return -1; return error;
if ((ret = gitno_recv(buf)) < 0) if ((ret = gitno_recv(buf)) < 0)
return -1; return ret;
} while (error); } while (error);
gitno_consume(buf, line_end); gitno_consume(buf, line_end);
...@@ -184,10 +184,11 @@ static int store_common(transport_smart *t) ...@@ -184,10 +184,11 @@ static int store_common(transport_smart *t)
{ {
git_pkt *pkt = NULL; git_pkt *pkt = NULL;
gitno_buffer *buf = &t->buffer; gitno_buffer *buf = &t->buffer;
int error;
do { do {
if (recv_pkt(&pkt, buf) < 0) if ((error = recv_pkt(&pkt, buf)) < 0)
return -1; return error;
if (pkt->type == GIT_PKT_ACK) { if (pkt->type == GIT_PKT_ACK) {
if (git_vector_insert(&t->common, pkt) < 0) if (git_vector_insert(&t->common, pkt) < 0)
...@@ -227,6 +228,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo) ...@@ -227,6 +228,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
if (git_reference_type(ref) == GIT_REF_SYMBOLIC) if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
continue; continue;
if (git_revwalk_push(walk, git_reference_target(ref)) < 0) if (git_revwalk_push(walk, git_reference_target(ref)) < 0)
goto on_error; goto on_error;
...@@ -436,10 +438,10 @@ static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack, ...@@ -436,10 +438,10 @@ static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack,
gitno_consume_n(buf, buf->offset); gitno_consume_n(buf, buf->offset);
if ((recvd = gitno_recv(buf)) < 0) if ((recvd = gitno_recv(buf)) < 0)
return -1; return recvd;
} while(recvd > 0); } while(recvd > 0);
if (writepack->commit(writepack, stats)) if (writepack->commit(writepack, stats) < 0)
return -1; return -1;
return 0; return 0;
...@@ -697,7 +699,7 @@ static int parse_report(gitno_buffer *buf, git_push *push) ...@@ -697,7 +699,7 @@ static int parse_report(gitno_buffer *buf, git_push *push)
if (error == GIT_EBUFS) { if (error == GIT_EBUFS) {
if ((recvd = gitno_recv(buf)) < 0) if ((recvd = gitno_recv(buf)) < 0)
return -1; return recvd;
if (recvd == 0) { if (recvd == 0) {
giterr_set(GITERR_NET, "Early EOF"); giterr_set(GITERR_NET, "Early EOF");
......
...@@ -640,8 +640,8 @@ replay: ...@@ -640,8 +640,8 @@ replay:
(!t->cred || 0 == (t->cred->credtype & allowed_types))) { (!t->cred || 0 == (t->cred->credtype & allowed_types))) {
if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types, if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types,
t->owner->cred_acquire_payload) < 0) t->owner->cred_acquire_payload) < 0)
return -1; return GIT_EUSER;
assert(t->cred); assert(t->cred);
......
...@@ -183,6 +183,39 @@ void test_online_clone__custom_remote_callbacks(void) ...@@ -183,6 +183,39 @@ void test_online_clone__custom_remote_callbacks(void)
cl_assert(callcount > 0); cl_assert(callcount > 0);
} }
static int cred_failure_cb(
git_cred **cred,
const char *url,
const char *username_from_url,
unsigned int allowed_types,
void *data)
{
return -1;
}
void test_online_clone__cred_callback_failure_is_euser(void)
{
const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
const char *remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT");
int error;
if (!remote_url) {
printf("GITTEST_REMOTE_URL unset; skipping clone test\n");
return;
}
if (!remote_user && !remote_default) {
printf("GITTEST_REMOTE_USER and GITTEST_REMOTE_DEFAULT unset; skipping clone test\n");
return;
}
g_options.remote_callbacks.credentials = cred_failure_cb;
cl_git_fail(error = git_clone(&g_repo, remote_url, "./foo", &g_options));
cl_assert_equal_i(error, GIT_EUSER);
}
void test_online_clone__credentials(void) void test_online_clone__credentials(void)
{ {
/* Remote URL environment variable must be set. User and password are optional. */ /* Remote URL environment variable must be set. User and password are optional. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment