aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-tcp-stream-openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-tcp-stream-openssl.c')
-rw-r--r--camel/camel-tcp-stream-openssl.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c
index 8066713db5..2702cd249b 100644
--- a/camel/camel-tcp-stream-openssl.c
+++ b/camel/camel-tcp-stream-openssl.c
@@ -166,6 +166,48 @@ camel_tcp_stream_openssl_new (CamelService *service, const char *expected_host)
return CAMEL_STREAM (stream);
}
+static void
+errlib_error_to_errno (int ret)
+{
+ long error;
+
+ error = ERR_get_error();
+ if (error == 0) {
+ if (ret == 0)
+ errno = EINVAL; /* unexpected EOF */
+ /* otherwise errno should be set */
+ } else
+ /* ok, we get the shaft now. */
+ errno = EIO;
+}
+
+static void
+ssl_error_to_errno (CamelTcpStreamOpenSSL *stream, int ret)
+{
+ /* hm, a CamelException might be useful right about now! */
+
+ switch (SSL_get_error (stream->priv->ssl, ret)) {
+ case SSL_ERROR_NONE:
+ errno = 0;
+ return;
+ case SSL_ERROR_ZERO_RETURN:
+ /* this one does not map well at all */
+ errno = EINVAL;
+ return;
+ case SSL_ERROR_WANT_READ: /* non-fatal; retry */
+ case SSL_ERROR_WANT_WRITE: /* non-fatal; retry */
+ case SSL_ERROR_WANT_X509_LOOKUP: /* non-fatal; retry */
+ errno = EAGAIN;
+ return;
+ case SSL_ERROR_SYSCALL:
+ errlib_error_to_errno (ret);
+ return;
+ case SSL_ERROR_SSL:
+ errlib_error_to_errno (-1);
+ return;
+ }
+}
+
static ssize_t
stream_read (CamelStream *stream, char *buffer, size_t n)
{
@@ -213,7 +255,10 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags);
}
-
+
+ if (nread == -1)
+ ssl_error_to_errno (tcp_stream_openssl, -1);
+
return nread;
}
@@ -263,6 +308,9 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags);
}
+ if (written == -1)
+ ssl_error_to_errno (tcp_stream_openssl, -1);
+
return written;
}
@@ -450,6 +498,7 @@ open_ssl_connection (CamelService *service, int sockfd, CamelTcpStreamOpenSSL *o
n = SSL_connect (ssl);
if (n != 1) {
+ ssl_error_to_errno (openssl, n);
SSL_shutdown (ssl);