summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/network-openssl.c83
1 files changed, 66 insertions, 17 deletions
diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c
index 9e16b130..16375439 100644
--- a/src/core/network-openssl.c
+++ b/src/core/network-openssl.c
@@ -96,22 +96,40 @@ static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, X509 *cert)
static GIOStatus irssi_ssl_read(GIOChannel *handle, gchar *buf, gsize len, gsize *ret, GError **gerr)
{
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
- gint err;
+ gint ret1, err;
+ const char *errstr;
- err = SSL_read(chan->ssl, buf, len);
- if(err < 0)
+ ret1 = SSL_read(chan->ssl, buf, len);
+ if(ret1 <= 0)
{
*ret = 0;
- err = SSL_get_error(chan->ssl, err);
+ err = SSL_get_error(chan->ssl, ret1);
if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
return G_IO_STATUS_AGAIN;
+ else if(err == SSL_ERROR_ZERO_RETURN)
+ return G_IO_STATUS_EOF;
+ else if (err == SSL_ERROR_SYSCALL)
+ {
+ errstr = ERR_reason_error_string(ERR_get_error());
+ if (errstr == NULL && ret1 == -1)
+ errstr = strerror(errno);
+ if (errstr == NULL)
+ errstr = "server closed connection unexpectedly";
+ }
+ else
+ {
+ errstr = ERR_reason_error_string(ERR_get_error());
+ if (errstr == NULL)
+ errstr = "unknown SSL error";
+ }
+ g_warning("SSL read error: %s", errstr);
*gerr = g_error_new_literal(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
- ERR_reason_error_string(ERR_get_error()));
+ errstr);
return G_IO_STATUS_ERROR;
}
else
{
- *ret = err;
+ *ret = ret1;
return G_IO_STATUS_NORMAL;
}
/*UNREACH*/
@@ -121,22 +139,40 @@ static GIOStatus irssi_ssl_read(GIOChannel *handle, gchar *buf, gsize len, gsize
static GIOStatus irssi_ssl_write(GIOChannel *handle, const gchar *buf, gsize len, gsize *ret, GError **gerr)
{
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
- gint err;
+ gint ret1, err;
+ const char *errstr;
- err = SSL_write(chan->ssl, (const char *)buf, len);
- if(err < 0)
+ ret1 = SSL_write(chan->ssl, (const char *)buf, len);
+ if(ret1 <= 0)
{
*ret = 0;
- err = SSL_get_error(chan->ssl, err);
+ err = SSL_get_error(chan->ssl, ret1);
if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
return G_IO_STATUS_AGAIN;
+ else if(err == SSL_ERROR_ZERO_RETURN)
+ errstr = "server closed connection";
+ else if (err == SSL_ERROR_SYSCALL)
+ {
+ errstr = ERR_reason_error_string(ERR_get_error());
+ if (errstr == NULL && ret1 == -1)
+ errstr = strerror(errno);
+ if (errstr == NULL)
+ errstr = "server closed connection unexpectedly";
+ }
+ else
+ {
+ errstr = ERR_reason_error_string(ERR_get_error());
+ if (errstr == NULL)
+ errstr = "unknown SSL error";
+ }
+ g_warning("SSL write error: %s", errstr);
*gerr = g_error_new_literal(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
- ERR_reason_error_string(ERR_get_error()));
+ errstr);
return G_IO_STATUS_ERROR;
}
else
{
- *ret = err;
+ *ret = ret1;
return G_IO_STATUS_NORMAL;
}
/*UNREACH*/
@@ -320,12 +356,25 @@ int irssi_ssl_handshake(GIOChannel *handle)
ret = SSL_connect(chan->ssl);
if (ret <= 0) {
err = SSL_get_error(chan->ssl, ret);
- if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
- errstr = ERR_reason_error_string(ERR_get_error());
- g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "server closed connection");
- return -1;
+ switch (err) {
+ case SSL_ERROR_WANT_READ:
+ return 1;
+ case SSL_ERROR_WANT_WRITE:
+ return 3;
+ case SSL_ERROR_ZERO_RETURN:
+ g_warning("SSL handshake failed: %s", "server closed connection");
+ return -1;
+ case SSL_ERROR_SYSCALL:
+ errstr = ERR_reason_error_string(ERR_get_error());
+ if (errstr == NULL && ret == -1)
+ errstr = strerror(errno);
+ g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "server closed connection unexpectedly");
+ return -1;
+ default:
+ errstr = ERR_reason_error_string(ERR_get_error());
+ g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "unknown SSL error");
+ return -1;
}
- return err == SSL_ERROR_WANT_READ ? 1 : 3;
}
cert = SSL_get_peer_certificate(chan->ssl);