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;
}
示例#2
0
/* 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;
}