summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-11-18 22:20:10 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2018-11-28 15:46:55 +0000
commitb2ed778ac0e964ebe5a77945b9c076ee28a93695 (patch)
tree1ca25748bfb6af54ad40afa2f6d77f334f4959db
parent2ce2315c9c4526b591997d4b2a0f1adbe9f589a5 (diff)
downloadlibgit2-b2ed778ac0e964ebe5a77945b9c076ee28a93695.tar.gz
http transport: reset error message on cert failure
Store the error message from the underlying TLS library before calling the certificate callback. If it refuses to act (demonstrated by returning GIT_PASSTHROUGH) then restore the error message. Otherwise, if the callback does not set an error message, set a sensible default that implicates the callback itself.
-rw-r--r--src/transports/http.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/transports/http.c b/src/transports/http.c
index 82ae77ddc..65b5f5f76 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -692,25 +692,25 @@ static int check_certificate(
void *cert_cb_payload)
{
git_cert *cert;
+ git_error_state last_error = {0};
int error;
if ((error = git_stream_certificate(&cert, stream)) < 0)
return error;
- giterr_clear();
- error = cert_cb(cert, is_valid, url->host, cert_cb_payload);
+ giterr_state_capture(&last_error, GIT_ECERTIFICATE);
- if (error == GIT_PASSTHROUGH)
- error = is_valid ? 0 : GIT_ECERTIFICATE;
+ error = cert_cb(cert, is_valid, url->host, cert_cb_payload);
- if (error) {
- if (!giterr_last())
- giterr_set(GITERR_NET, "user cancelled certificate check");
+ if (error == GIT_PASSTHROUGH && !is_valid)
+ return giterr_state_restore(&last_error);
+ else if (error == GIT_PASSTHROUGH)
+ error = 0;
+ else if (error && !giterr_last())
+ giterr_set(GITERR_NET, "user rejected certificate for %s", url->host);
- return error;
- }
-
- return 0;
+ giterr_state_free(&last_error);
+ return error;
}
static int http_connect(http_subtransport *t)