static const gchar * get_server_identity (GTlsClientConnectionGnutls *gnutls) { if (G_IS_NETWORK_ADDRESS (gnutls->priv->server_identity)) return g_network_address_get_hostname (G_NETWORK_ADDRESS (gnutls->priv->server_identity)); else if (G_IS_NETWORK_SERVICE (gnutls->priv->server_identity)) return g_network_service_get_domain (G_NETWORK_SERVICE (gnutls->priv->server_identity)); else return NULL; }
/* 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; }