}
}
+ 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;
}
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) {
* 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.
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,
PROP_SSL_STRICT,
PROP_ASYNC_CONTEXT,
PROP_TIMEOUT,
+ PROP_TRUSTED_CERTIFICATE,
LAST_PROP
};
guint timed_out:1;
gpointer ssl_creds;
gboolean ssl_strict;
+ gboolean trusted_certificate;
GMainContext *async_context;
GSource *watch_src;
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
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)
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;
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);
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;
}
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;
}
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,