summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schubert <schu@schu.io>2012-08-28 21:58:10 +0200
committerMichael Schubert <schu@schu.io>2012-09-04 00:22:12 +0200
commit65ac67fbbdb1a980aefb46bfdde918f43515acaf (patch)
tree35c075fc8275eb8d58c5f610a1058ac9f5689ba5
parent4deda91bda034d330fd20c1000ef2d3d2972bd0e (diff)
downloadlibgit2-65ac67fbbdb1a980aefb46bfdde918f43515acaf.tar.gz
netops: be more careful with SSL errors
SSL_get_error() allows to receive a result code for various SSL operations. Depending on the return value (see man (3) SSL_get_error) there might be additional information in the OpenSSL error queue. Return the queued message if available, otherwise set an error message corresponding to the return code.
-rw-r--r--src/netops.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/netops.c b/src/netops.c
index a0d2bf3a..df502e61 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -55,8 +55,44 @@ static void net_set_error(const char *str)
static int ssl_set_error(gitno_ssl *ssl, int error)
{
int err;
+ unsigned long e;
+
err = SSL_get_error(ssl->ssl, error);
- giterr_set(GITERR_NET, "SSL error: %s", ERR_error_string(err, NULL));
+
+ assert(err != SSL_ERROR_WANT_READ);
+ assert(err != SSL_ERROR_WANT_WRITE);
+
+ switch (err) {
+ case SSL_ERROR_WANT_CONNECT:
+ case SSL_ERROR_WANT_ACCEPT:
+ giterr_set(GITERR_NET, "SSL error: connection failure\n");
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ giterr_set(GITERR_NET, "SSL error: x509 error\n");
+ break;
+ case SSL_ERROR_SYSCALL:
+ e = ERR_get_error();
+ if (e > 0) {
+ giterr_set(GITERR_NET, "SSL error: %s",
+ ERR_error_string(e, NULL));
+ break;
+ } else if (error < 0) {
+ giterr_set(GITERR_OS, "SSL error: syscall failure");
+ break;
+ }
+ giterr_set(GITERR_NET, "SSL error: received early EOF");
+ break;
+ case SSL_ERROR_SSL:
+ e = ERR_get_error();
+ giterr_set(GITERR_NET, "SSL error: %s",
+ ERR_error_string(e, NULL));
+ break;
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ default:
+ giterr_set(GITERR_NET, "SSL error: unknown error");
+ break;
+ }
return -1;
}
#endif