gboolean g_tls_connection_base_accept_peer_certificate (GTlsConnectionBase *tls, GTlsCertificate *peer_certificate, GTlsCertificateFlags peer_certificate_errors) { gboolean accepted = FALSE; if (G_IS_TLS_CLIENT_CONNECTION (tls)) { GTlsCertificateFlags validation_flags = g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (tls)); if ((peer_certificate_errors & validation_flags) == 0) accepted = TRUE; } if (!accepted) { accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (tls), peer_certificate, peer_certificate_errors); } return accepted; }
/** * g_tls_client_connection_set_use_ssl3: * @conn: the #GTlsClientConnection * @use_ssl3: whether to use SSL 3.0 * * If @use_ssl3 is %TRUE, this forces @conn to use SSL 3.0 rather than * trying to properly negotiate the right version of TLS or SSL to use. * This can be used when talking to servers that do not implement the * fallbacks correctly and which will therefore fail to handshake with * a "modern" TLS handshake attempt. * * Since: 2.28 */ void g_tls_client_connection_set_use_ssl3 (GTlsClientConnection *conn, gboolean use_ssl3) { g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); g_object_set (G_OBJECT (conn), "use-ssl3", use_ssl3, NULL); }
/** * g_tls_client_connection_set_server_identity: * @conn: the #GTlsClientConnection * @identity: a #GSocketConnectable describing the expected server identity * * Sets @conn's expected server identity, which is used both to tell * servers on virtual hosts which certificate to present, and also * to let @conn know what name to look for in the certificate when * performing %G_TLS_CERTIFICATE_BAD_IDENTITY validation, if enabled. * * Since: 2.28 */ void g_tls_client_connection_set_server_identity (GTlsClientConnection *conn, GSocketConnectable *identity) { g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); g_object_set (G_OBJECT (conn), "server-identity", identity, NULL); }
/** * g_tls_client_connection_set_validation_flags: * @conn: the #GTlsClientConnection * @flags: the #GTlsCertificateFlags to use * * Sets @conn's validation flags, to override the default set of * checks performed when validating a server certificate. By default, * %G_TLS_CERTIFICATE_VALIDATE_ALL is used. * * Since: 2.28 */ void g_tls_client_connection_set_validation_flags (GTlsClientConnection *conn, GTlsCertificateFlags flags) { g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); g_object_set (G_OBJECT (conn), "validation-flags", flags, NULL); }
/** * g_tls_client_connection_get_accepted_cas: * @conn: the #GTlsClientConnection * * Gets the list of distinguished names of the Certificate Authorities * that the server will accept certificates from. This will be set * during the TLS handshake if the server requests a certificate. * Otherwise, it will be %NULL. * * Each item in the list is a #GByteArray which contains the complete * subject DN of the certificate authority. * * Returns: (element-type GByteArray) (transfer full): the list of * CA DNs. You should unref each element with g_byte_array_unref() and then * the free the list with g_list_free(). * * Since: 2.28 */ GList * g_tls_client_connection_get_accepted_cas (GTlsClientConnection *conn) { GList *accepted_cas = NULL; g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), NULL); g_object_get (G_OBJECT (conn), "accepted-cas", &accepted_cas, NULL); return accepted_cas; }
/** * g_tls_client_connection_get_use_ssl3: * @conn: the #GTlsClientConnection * * Gets whether @conn will use SSL 3.0 rather than the * highest-supported version of TLS; see * g_tls_client_connection_set_use_ssl3(). * * Returns: whether @conn will use SSL 3.0 * * Since: 2.28 */ gboolean g_tls_client_connection_get_use_ssl3 (GTlsClientConnection *conn) { gboolean use_ssl3 = FALSE; g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); g_object_get (G_OBJECT (conn), "use-ssl3", &use_ssl3, NULL); return use_ssl3; }
/** * g_tls_client_connection_get_validation_flags: * @conn: the #GTlsClientConnection * * Gets @conn's validation flags * * Returns: the validation flags * * Since: 2.28 */ GTlsCertificateFlags g_tls_client_connection_get_validation_flags (GTlsClientConnection *conn) { GTlsCertificateFlags flags = 0; g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); g_object_get (G_OBJECT (conn), "validation-flags", &flags, NULL); return flags; }
/** * g_tls_client_connection_get_server_identity: * @conn: the #GTlsClientConnection * * Gets @conn's expected server identity * * Returns: (transfer none): a #GSocketConnectable describing the * expected server identity, or %NULL if the expected identity is not * known. * * Since: 2.28 */ GSocketConnectable * g_tls_client_connection_get_server_identity (GTlsClientConnection *conn) { GSocketConnectable *identity = NULL; g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); g_object_get (G_OBJECT (conn), "server-identity", &identity, NULL); if (identity) g_object_unref (identity); return identity; }
/* Called when a GTlsConnection (which this handler has been connected to) * has an error validating its certificate. * Returns TRUE if the certificate is already trusted, so the connection * can continue. * Returns FALSE if the certificate is not trusted, causing the * connection's handshake to fail, and then prompts the user to accept * the certificate. */ static gboolean accept_certificate_cb(GTlsConnection *conn, GTlsCertificate *peer_cert, GTlsCertificateFlags errors, gpointer user_data) { GTlsCertificate *trusted_cert; GSocketConnectable *connectable; const gchar *identity; g_return_val_if_fail(G_IS_TLS_CLIENT_CONNECTION(conn), FALSE); g_return_val_if_fail(G_IS_TLS_CERTIFICATE(peer_cert), FALSE); /* Get the certificate identity from the GTlsClientConnection */ connectable = g_tls_client_connection_get_server_identity( G_TLS_CLIENT_CONNECTION(conn)); g_return_val_if_fail(G_IS_SOCKET_CONNECTABLE(connectable), FALSE); /* identity is owned by the connectable */ if (G_IS_NETWORK_ADDRESS(connectable)) { identity = g_network_address_get_hostname( G_NETWORK_ADDRESS(connectable)); } else if (G_IS_NETWORK_SERVICE(connectable)) { identity = g_network_service_get_domain( G_NETWORK_SERVICE(connectable)); } else { g_return_val_if_reached(FALSE); } /* See if a trusted certificate matching the peer certificate exists */ trusted_cert = purple_tls_certificate_new_from_id(identity, NULL); if (trusted_cert != NULL && g_tls_certificate_is_same(peer_cert, trusted_cert)) { /* It's manually trusted. Accept certificate */ g_object_unref(trusted_cert); return TRUE; } g_clear_object(&trusted_cert); /* Certificate failed and isn't trusted. * Fail certificate and prompt user. */ request_accept_certificate(identity, peer_cert, errors); return FALSE; }