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.
This commit is contained in:
Michael Schubert 2012-08-28 21:58:10 +02:00
parent 4deda91bda
commit 65ac67fbbd

View File

@ -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