[evolution-data-server] rehandshake_ssl(): Be more responsive to cancellations.



commit d8b557c29751f00fa627cd4a6b708518ccf95fc5
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Dec 1 09:17:17 2011 -0600

    rehandshake_ssl(): Be more responsive to cancellations.

 camel/camel-tcp-stream-ssl.c                |   44 +++++++++++++++++++++-----
 camel/camel-tcp-stream-ssl.h                |    1 +
 camel/providers/imap/camel-imap-store.c     |    3 +-
 camel/providers/imapx/camel-imapx-server.c  |    4 ++-
 camel/providers/pop3/camel-pop3-store.c     |    2 +-
 camel/providers/smtp/camel-smtp-transport.c |    3 +-
 6 files changed, 44 insertions(+), 13 deletions(-)
---
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 1e75466..55fc9cf 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -426,6 +426,13 @@ get_nickname (CERTCertificate *cert)
 }
 #endif
 
+static void
+tcp_stream_cancelled (GCancellable *cancellable,
+                      PRThread *thread)
+{
+	PR_Interrupt (thread);
+}
+
 static SECStatus
 ssl_bad_cert (gpointer data,
               PRFileDesc *sockfd)
@@ -718,21 +725,38 @@ enable_ssl_or_close_fd (CamelTcpStreamSSL *ssl,
 
 static gboolean
 rehandshake_ssl (PRFileDesc *fd,
+                 GCancellable *cancellable,
                  GError **error)
 {
-	if (SSL_ResetHandshake (fd, FALSE) == SECFailure) {
-		_set_errno_from_pr_error (PR_GetError ());
-		_set_g_error_from_errno (error, FALSE);
+	SECStatus status = SECSuccess;
+	gulong cancel_id = 0;
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 		return FALSE;
-	}
 
-	if (SSL_ForceHandshake (fd) == SECFailure) {
+	if (G_IS_CANCELLABLE (cancellable))
+		cancel_id = g_cancellable_connect (
+			cancellable, G_CALLBACK (tcp_stream_cancelled),
+			PR_GetCurrentThread (), (GDestroyNotify) NULL);
+
+	if (status == SECSuccess)
+		status = SSL_ResetHandshake (fd, FALSE);
+
+	if (status == SECSuccess)
+		status = SSL_ForceHandshake (fd);
+
+	if (cancel_id > 0)
+		g_cancellable_disconnect (cancellable, cancel_id);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+		status = SECFailure;
+
+	} else if (status == SECFailure) {
 		_set_errno_from_pr_error (PR_GetError ());
 		_set_g_error_from_errno (error, FALSE);
-		return FALSE;
 	}
 
-	return TRUE;
+	return (status == SECSuccess);
 }
 
 static gint
@@ -767,7 +791,7 @@ tcp_stream_ssl_connect (CamelTcpStream *stream,
 		} else {
 			d (g_print ("  re-handshaking SSL\n"));
 
-			if (!rehandshake_ssl (ssl_fd, error)) {
+			if (!rehandshake_ssl (ssl_fd, cancellable, error)) {
 				d (g_print ("  failed\n"));
 				return -1;
 			}
@@ -865,6 +889,7 @@ camel_tcp_stream_ssl_new_raw (CamelSession *session,
 /**
  * camel_tcp_stream_ssl_enable_ssl:
  * @ssl: a #CamelTcpStreamSSL object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Toggles an ssl-capable stream into ssl mode (if it isn't already).
@@ -873,6 +898,7 @@ camel_tcp_stream_ssl_new_raw (CamelSession *session,
  **/
 gint
 camel_tcp_stream_ssl_enable_ssl (CamelTcpStreamSSL *ssl,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	PRFileDesc *fd, *ssl_fd;
@@ -891,7 +917,7 @@ camel_tcp_stream_ssl_enable_ssl (CamelTcpStreamSSL *ssl,
 		_camel_tcp_stream_raw_replace_file_desc (CAMEL_TCP_STREAM_RAW (ssl), ssl_fd);
 		ssl->priv->ssl_mode = TRUE;
 
-		if (!rehandshake_ssl (ssl_fd, error))
+		if (!rehandshake_ssl (ssl_fd, cancellable, error))
 			return -1;
 	}
 
diff --git a/camel/camel-tcp-stream-ssl.h b/camel/camel-tcp-stream-ssl.h
index c8e4a4f..4cde08f 100644
--- a/camel/camel-tcp-stream-ssl.h
+++ b/camel/camel-tcp-stream-ssl.h
@@ -73,6 +73,7 @@ CamelStream *	camel_tcp_stream_ssl_new_raw	(CamelSession *session,
 						 const gchar *expected_host,
 						 CamelTcpStreamSSLFlags flags);
 gint		camel_tcp_stream_ssl_enable_ssl	(CamelTcpStreamSSL *ssl,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 2c66bb8..add9a99 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -415,7 +415,8 @@ connect_to_server (CamelService *service,
 	camel_imap_response_free_without_processing (store, response);
 
 	/* Okay, now toggle SSL/TLS mode */
-	if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream), error) == -1) {
+	if (camel_tcp_stream_ssl_enable_ssl (
+		CAMEL_TCP_STREAM_SSL (tcp_stream), cancellable, error) == -1) {
 		g_prefix_error (
 			error,
 			_("Failed to connect to IMAP server %s in secure mode: "),
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index d8261a4..b06648b 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -3163,7 +3163,9 @@ imapx_connect_to_server (CamelIMAPXServer *is,
 
 		camel_imapx_command_free (ic);
 
-		if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream), &local_error) == -1) {
+		if (camel_tcp_stream_ssl_enable_ssl (
+			CAMEL_TCP_STREAM_SSL (tcp_stream),
+			cancellable, &local_error) == -1) {
 			g_prefix_error (
 				&local_error,
 				_("Failed to connect to IMAP server %s in secure mode: "),
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index afb4c4b..8618b11 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -176,7 +176,7 @@ connect_to_server (CamelService *service,
 
 	/* Okay, now toggle SSL/TLS mode */
 	ret = camel_tcp_stream_ssl_enable_ssl (
-		CAMEL_TCP_STREAM_SSL (tcp_stream), error);
+		CAMEL_TCP_STREAM_SSL (tcp_stream), cancellable, error);
 
 	if (ret == -1) {
 		g_prefix_error (
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 41d41a6..a838d46 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -221,7 +221,8 @@ connect_to_server (CamelService *service,
 	} while (*(respbuf+3) == '-'); /* if we got "220-" then loop again */
 
 	/* Okay, now toggle SSL/TLS mode */
-	if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream), error) == -1) {
+	if (camel_tcp_stream_ssl_enable_ssl (
+		CAMEL_TCP_STREAM_SSL (tcp_stream), cancellable, error) == -1) {
 		g_prefix_error (
 			error,
 			_("Failed to connect to SMTP server %s in secure mode: "),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]