[libsoup] New SoupMessageFlag to report whether it has dealt with a trusted certificate



commit 8fc961998706d3e8f18e9b6b096b583693d2f1b3
Author: Gustavo Noronha Silva <gustavo noronha collabora co uk>
Date:   Thu Feb 18 14:05:15 2010 -0200

    New SoupMessageFlag to report whether it has dealt with a trusted certificate
    
    https://bugzilla.gnome.org/show_bug.cgi?id=610374

 libsoup/soup-message-io.c |   11 +++++++++++
 libsoup/soup-message.c    |    4 ++++
 libsoup/soup-message.h    |    7 ++++---
 libsoup/soup-socket.c     |   31 +++++++++++++++++++++++++++++++
 libsoup/soup-socket.h     |   17 +++++++++--------
 5 files changed, 59 insertions(+), 11 deletions(-)
---
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 73c8ae6..fc0e14d 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -342,6 +342,17 @@ read_metadata (SoupMessage *msg, gboolean to_blank)
 		}
 	}
 
+	if (soup_socket_is_ssl (io->sock)) {
+		gboolean trusted_certificate;
+
+		g_object_get (io->sock,
+			      SOUP_SOCKET_TRUSTED_CERTIFICATE, &trusted_certificate,
+			      NULL);
+
+		if (trusted_certificate)
+			soup_message_set_flags (msg, priv->msg_flags | SOUP_MESSAGE_CERTIFICATE_TRUSTED);
+	}
+
 	return TRUE;
 }
 
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index ded0198..7c0b802 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -1258,6 +1258,7 @@ soup_message_cleanup_response (SoupMessage *req)
 		priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
 	}
 	priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
+	priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
 
 	req->status_code = SOUP_STATUS_NONE;
 	if (req->reason_phrase) {
@@ -1283,6 +1284,9 @@ soup_message_cleanup_response (SoupMessage *req)
  * indicate that it has removed the Content-Encoding on a message (and
  * so headers such as Content-Length may no longer accurately describe
  * the body).
+ * @SOUP_MESSAGE_CERTIFICATE_TRUSTED: if %TRUE after an https response
+ * has been received, indicates that the server's SSL certificate is
+ * trusted according to the session's CA.
  *
  * Various flags that can be set on a #SoupMessage to alter its
  * behavior.
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index 2638620..3f3ee14 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -105,11 +105,12 @@ SoupURI         *soup_message_get_first_party     (SoupMessage       *msg);
 void             soup_message_set_first_party     (SoupMessage       *msg,
 						   SoupURI           *first_party);
 typedef enum {
-	SOUP_MESSAGE_NO_REDIRECT      = (1 << 1),
+	SOUP_MESSAGE_NO_REDIRECT          = (1 << 1),
 #ifndef LIBSOUP_DISABLE_DEPRECATED
-	SOUP_MESSAGE_OVERWRITE_CHUNKS = (1 << 3),
+	SOUP_MESSAGE_OVERWRITE_CHUNKS     = (1 << 3),
 #endif
-	SOUP_MESSAGE_CONTENT_DECODED  = (1 << 4)
+	SOUP_MESSAGE_CONTENT_DECODED      = (1 << 4),
+	SOUP_MESSAGE_CERTIFICATE_TRUSTED  = (1 << 5)
 } SoupMessageFlags;
 
 void           soup_message_set_flags           (SoupMessage        *msg,
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 2bbf22d..4f570a7 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -69,6 +69,7 @@ enum {
 	PROP_SSL_STRICT,
 	PROP_ASYNC_CONTEXT,
 	PROP_TIMEOUT,
+	PROP_TRUSTED_CERTIFICATE,
 
 	LAST_PROP
 };
@@ -83,6 +84,7 @@ typedef struct {
 	guint timed_out:1;
 	gpointer ssl_creds;
 	gboolean ssl_strict;
+	gboolean trusted_certificate;
 
 	GMainContext   *async_context;
 	GSource        *watch_src;
@@ -368,6 +370,21 @@ soup_socket_class_init (SoupSocketClass *socket_class)
 				      TRUE,
 				      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 	/**
+	 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
+	 *
+	 * Alias for the #SoupSocket:trusted-certificate
+	 * property. Notice that this property's value is only useful
+	 * if the socket is for an SSL connection, and only reliable
+	 * after some data has been transferred to or from it.
+	 **/
+	g_object_class_install_property (
+		object_class, PROP_TRUSTED_CERTIFICATE,
+		g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
+				     "Trusted Certificate",
+				     "Whether the server certificate is trusted, if this is an SSL socket",
+				     FALSE,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	/**
 	 * SOUP_SOCKET_ASYNC_CONTEXT:
 	 *
 	 * Alias for the #SoupSocket:async-context property. (The
@@ -509,6 +526,9 @@ set_property (GObject *object, guint prop_id,
 	case PROP_SSL_STRICT:
 		priv->ssl_strict = g_value_get_boolean (value);
 		break;
+	case PROP_TRUSTED_CERTIFICATE:
+		priv->trusted_certificate = g_value_get_boolean (value);
+		break;
 	case PROP_ASYNC_CONTEXT:
 		priv->async_context = g_value_get_pointer (value);
 		if (priv->async_context)
@@ -548,6 +568,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_SSL_STRICT:
 		g_value_set_boolean (value, priv->ssl_strict);
 		break;
+	case PROP_TRUSTED_CERTIFICATE:
+		g_value_set_boolean (value, priv->trusted_certificate);
+		break;
 	case PROP_ASYNC_CONTEXT:
 		g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
 		break;
@@ -1011,6 +1034,12 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 	if (!ssl_chan)
 		return FALSE;
 
+	/* This is optimistic, we will set this to false if we get a
+	 * cert error from one of the I/O calls
+	 */
+	if (priv->ssl_creds)
+		priv->trusted_certificate = TRUE;
+
 	priv->iochannel = ssl_chan;
 	g_io_channel_unref (real_chan);
 
@@ -1245,6 +1274,7 @@ again:
 		if (g_error_matches (my_err, SOUP_SSL_ERROR,
 				     SOUP_SSL_ERROR_CERTIFICATE) &&
 		    !priv->ssl_strict) {
+			priv->trusted_certificate = FALSE;
 			g_clear_error (&my_err);
 			goto again;
 		}
@@ -1552,6 +1582,7 @@ again:
 		if (g_error_matches (my_err, SOUP_SSL_ERROR,
 				     SOUP_SSL_ERROR_CERTIFICATE) &&
 		    !priv->ssl_strict) {
+			priv->trusted_certificate = FALSE;
 			g_clear_error (&my_err);
 			goto again;
 		}
diff --git a/libsoup/soup-socket.h b/libsoup/soup-socket.h
index 4106e86..2e039d9 100644
--- a/libsoup/soup-socket.h
+++ b/libsoup/soup-socket.h
@@ -40,14 +40,15 @@ typedef struct {
 	void (*_libsoup_reserved4) (void);
 } SoupSocketClass;
 
-#define SOUP_SOCKET_LOCAL_ADDRESS    "local-address"
-#define SOUP_SOCKET_REMOTE_ADDRESS   "remote-address"
-#define SOUP_SOCKET_FLAG_NONBLOCKING "non-blocking"
-#define SOUP_SOCKET_IS_SERVER        "is-server"
-#define SOUP_SOCKET_SSL_CREDENTIALS  "ssl-creds"
-#define SOUP_SOCKET_SSL_STRICT       "ssl-strict"
-#define SOUP_SOCKET_ASYNC_CONTEXT    "async-context"
-#define SOUP_SOCKET_TIMEOUT          "timeout"
+#define SOUP_SOCKET_LOCAL_ADDRESS       "local-address"
+#define SOUP_SOCKET_REMOTE_ADDRESS      "remote-address"
+#define SOUP_SOCKET_FLAG_NONBLOCKING    "non-blocking"
+#define SOUP_SOCKET_IS_SERVER           "is-server"
+#define SOUP_SOCKET_SSL_CREDENTIALS     "ssl-creds"
+#define SOUP_SOCKET_SSL_STRICT          "ssl-strict"
+#define SOUP_SOCKET_TRUSTED_CERTIFICATE "trusted-certificate"
+#define SOUP_SOCKET_ASYNC_CONTEXT       "async-context"
+#define SOUP_SOCKET_TIMEOUT             "timeout"
 
 typedef void (*SoupSocketCallback)            (SoupSocket         *sock,
 					       guint               status,



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