mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 14:36:16 +01:00
Add a request_certificate virtual method to GTlsInteraction
This allows GTlsConnection implementations to request a certificate from the user. Fix ups by Dan Winship <danw@gnome.org> https://bugzilla.gnome.org/show_bug.cgi?id=637257
This commit is contained in:
parent
1fba61981a
commit
65af7c47ff
@ -3567,10 +3567,15 @@ G_TYPE_TLS_PASSWORD_FLAGS
|
|||||||
<TITLE>GTlsInteraction</TITLE>
|
<TITLE>GTlsInteraction</TITLE>
|
||||||
GTlsInteraction
|
GTlsInteraction
|
||||||
GTlsInteractionResult
|
GTlsInteractionResult
|
||||||
|
GTlsCertificateRequestFlags
|
||||||
|
g_tls_interaction_invoke_ask_password
|
||||||
|
g_tls_interaction_invoke_request_certificate
|
||||||
g_tls_interaction_ask_password
|
g_tls_interaction_ask_password
|
||||||
g_tls_interaction_ask_password_async
|
g_tls_interaction_ask_password_async
|
||||||
g_tls_interaction_ask_password_finish
|
g_tls_interaction_ask_password_finish
|
||||||
g_tls_interaction_invoke_ask_password
|
g_tls_interaction_request_certificate
|
||||||
|
g_tls_interaction_request_certificate_async
|
||||||
|
g_tls_interaction_request_certificate_finish
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GTlsInteractionClass
|
GTlsInteractionClass
|
||||||
G_IS_TLS_INTERACTION
|
G_IS_TLS_INTERACTION
|
||||||
|
@ -1630,6 +1630,20 @@ typedef enum {
|
|||||||
G_TLS_DATABASE_LOOKUP_KEYPAIR = 1
|
G_TLS_DATABASE_LOOKUP_KEYPAIR = 1
|
||||||
} GTlsDatabaseLookupFlags;
|
} GTlsDatabaseLookupFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GTlsCertificateRequestFlags:
|
||||||
|
* @G_TLS_CERTIFICATE_REQUEST_NONE: No flags
|
||||||
|
*
|
||||||
|
* Flags for g_tls_interaction_request_certificate(),
|
||||||
|
* g_tls_interaction_request_certificate_async(), and
|
||||||
|
* g_tls_interaction_invoke_request_certificate().
|
||||||
|
*
|
||||||
|
* Since: 2.40
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
G_TLS_CERTIFICATE_REQUEST_NONE = 0
|
||||||
|
} GTlsCertificateRequestFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GIOModuleScopeFlags:
|
* GIOModuleScopeFlags:
|
||||||
* @G_IO_MODULE_SCOPE_NONE: No module scan flags
|
* @G_IO_MODULE_SCOPE_NONE: No module scan flags
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gtlscertificate.h"
|
||||||
|
#include "gtlsconnection.h"
|
||||||
#include "gtlsinteraction.h"
|
#include "gtlsinteraction.h"
|
||||||
#include "gtlspassword.h"
|
#include "gtlspassword.h"
|
||||||
#include "gasyncresult.h"
|
#include "gasyncresult.h"
|
||||||
@ -182,6 +184,55 @@ invoke_closure_wait_and_free (InvokeClosure *closure,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GTlsInteractionResult
|
||||||
|
invoke_closure_complete_and_free (GTlsInteraction *interaction,
|
||||||
|
InvokeClosure *closure,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GTlsInteractionResult result;
|
||||||
|
gboolean complete;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle the case where we've been called from within the main context
|
||||||
|
* or in the case where the main context is not running. This approximates
|
||||||
|
* the behavior of a modal dialog.
|
||||||
|
*/
|
||||||
|
if (g_main_context_acquire (interaction->priv->context))
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&closure->mutex);
|
||||||
|
complete = closure->complete;
|
||||||
|
g_mutex_unlock (&closure->mutex);
|
||||||
|
if (complete)
|
||||||
|
break;
|
||||||
|
g_main_context_iteration (interaction->priv->context, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_main_context_release (interaction->priv->context);
|
||||||
|
|
||||||
|
if (closure->error)
|
||||||
|
{
|
||||||
|
g_propagate_error (error, closure->error);
|
||||||
|
closure->error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = closure->result;
|
||||||
|
invoke_closure_free (closure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle the case where we're in a different thread than the main
|
||||||
|
* context and a main loop is running.
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = invoke_closure_wait_and_free (closure, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_tls_interaction_init (GTlsInteraction *interaction)
|
g_tls_interaction_init (GTlsInteraction *interaction)
|
||||||
{
|
{
|
||||||
@ -231,9 +282,9 @@ on_invoke_ask_password_sync (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_async_as_sync_complete (GObject *source,
|
on_ask_password_complete (GObject *source,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
InvokeClosure *closure = user_data;
|
InvokeClosure *closure = user_data;
|
||||||
GTlsInteractionClass *klass;
|
GTlsInteractionClass *klass;
|
||||||
@ -266,7 +317,7 @@ on_invoke_ask_password_async_as_sync (gpointer user_data)
|
|||||||
klass->ask_password_async (closure->interaction,
|
klass->ask_password_async (closure->interaction,
|
||||||
G_TLS_PASSWORD (closure->argument),
|
G_TLS_PASSWORD (closure->argument),
|
||||||
closure->cancellable,
|
closure->cancellable,
|
||||||
on_async_as_sync_complete,
|
on_ask_password_complete,
|
||||||
closure);
|
closure);
|
||||||
|
|
||||||
/* Note that we've used these */
|
/* Note that we've used these */
|
||||||
@ -318,7 +369,6 @@ g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction,
|
|||||||
GTlsInteractionResult result;
|
GTlsInteractionResult result;
|
||||||
InvokeClosure *closure;
|
InvokeClosure *closure;
|
||||||
GTlsInteractionClass *klass;
|
GTlsInteractionClass *klass;
|
||||||
gboolean complete;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
|
g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
|
||||||
g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
|
g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
|
||||||
@ -339,43 +389,7 @@ g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction,
|
|||||||
g_main_context_invoke (interaction->priv->context,
|
g_main_context_invoke (interaction->priv->context,
|
||||||
on_invoke_ask_password_async_as_sync, closure);
|
on_invoke_ask_password_async_as_sync, closure);
|
||||||
|
|
||||||
/*
|
result = invoke_closure_complete_and_free (interaction, closure, error);
|
||||||
* Handle the case where we've been called from within the main context
|
|
||||||
* or in the case where the main context is not running. This approximates
|
|
||||||
* the behavior of a modal dialog.
|
|
||||||
*/
|
|
||||||
if (g_main_context_acquire (interaction->priv->context))
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
g_mutex_lock (&closure->mutex);
|
|
||||||
complete = closure->complete;
|
|
||||||
g_mutex_unlock (&closure->mutex);
|
|
||||||
if (complete)
|
|
||||||
break;
|
|
||||||
g_main_context_iteration (interaction->priv->context, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_main_context_release (interaction->priv->context);
|
|
||||||
|
|
||||||
if (closure->error)
|
|
||||||
{
|
|
||||||
g_propagate_error (error, closure->error);
|
|
||||||
closure->error = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = closure->result;
|
|
||||||
invoke_closure_free (closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle the case where we're in a different thread than the main
|
|
||||||
* context and a main loop is running.
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = invoke_closure_wait_and_free (closure, error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -386,7 +400,6 @@ g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_tls_interaction_ask_password:
|
* g_tls_interaction_ask_password:
|
||||||
* @interaction: a #GTlsInteraction object
|
* @interaction: a #GTlsInteraction object
|
||||||
@ -531,3 +544,294 @@ g_tls_interaction_ask_password_finish (GTlsInteraction *interaction,
|
|||||||
return g_task_propagate_int (G_TASK (result), error);
|
return g_task_propagate_int (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_invoke_request_certificate_sync (gpointer user_data)
|
||||||
|
{
|
||||||
|
InvokeClosure *closure = user_data;
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_mutex_lock (&closure->mutex);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction);
|
||||||
|
g_assert (klass->request_certificate != NULL);
|
||||||
|
|
||||||
|
closure->result = klass->request_certificate (closure->interaction,
|
||||||
|
G_TLS_CONNECTION (closure->argument),
|
||||||
|
0,
|
||||||
|
closure->cancellable,
|
||||||
|
&closure->error);
|
||||||
|
|
||||||
|
closure->complete = TRUE;
|
||||||
|
g_cond_signal (&closure->cond);
|
||||||
|
g_mutex_unlock (&closure->mutex);
|
||||||
|
|
||||||
|
return FALSE; /* don't call again */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_request_certificate_complete (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
InvokeClosure *closure = user_data;
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_mutex_lock (&closure->mutex);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction);
|
||||||
|
g_assert (klass->request_certificate_finish != NULL);
|
||||||
|
|
||||||
|
closure->result = klass->request_certificate_finish (closure->interaction,
|
||||||
|
result, &closure->error);
|
||||||
|
|
||||||
|
closure->complete = TRUE;
|
||||||
|
g_cond_signal (&closure->cond);
|
||||||
|
g_mutex_unlock (&closure->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_invoke_request_certificate_async_as_sync (gpointer user_data)
|
||||||
|
{
|
||||||
|
InvokeClosure *closure = user_data;
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_mutex_lock (&closure->mutex);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction);
|
||||||
|
g_assert (klass->request_certificate_async);
|
||||||
|
|
||||||
|
klass->request_certificate_async (closure->interaction,
|
||||||
|
G_TLS_CONNECTION (closure->argument), 0,
|
||||||
|
closure->cancellable,
|
||||||
|
on_request_certificate_complete,
|
||||||
|
closure);
|
||||||
|
|
||||||
|
/* Note that we've used these */
|
||||||
|
closure->callback = NULL;
|
||||||
|
closure->user_data = NULL;
|
||||||
|
|
||||||
|
g_mutex_unlock (&closure->mutex);
|
||||||
|
|
||||||
|
return FALSE; /* don't call again */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_tls_interaction_invoke_request_certificate:
|
||||||
|
* @interaction: a #GTlsInteraction object
|
||||||
|
* @connection: a #GTlsConnection object
|
||||||
|
* @flags: flags providing more information about the request
|
||||||
|
* @cancellable: an optional #GCancellable cancellation object
|
||||||
|
* @error: an optional location to place an error on failure
|
||||||
|
*
|
||||||
|
* Invoke the interaction to ask the user to choose a certificate to
|
||||||
|
* use with the connection. It invokes this interaction in the main
|
||||||
|
* loop, specifically the #GMainContext returned by
|
||||||
|
* g_main_context_get_thread_default() when the interaction is
|
||||||
|
* created. This is called by called by #GTlsConnection when the peer
|
||||||
|
* requests a certificate during the handshake.
|
||||||
|
*
|
||||||
|
* Derived subclasses usually implement a certificate selector,
|
||||||
|
* although they may also choose to provide a certificate from
|
||||||
|
* elsewhere. Alternatively the user may abort this certificate
|
||||||
|
* request, which may or may not abort the TLS connection.
|
||||||
|
*
|
||||||
|
* The implementation can either be a synchronous (eg: modal dialog) or an
|
||||||
|
* asynchronous one (eg: modeless dialog). This function will take care of
|
||||||
|
* calling which ever one correctly.
|
||||||
|
*
|
||||||
|
* If the interaction is cancelled by the cancellation object, or by the
|
||||||
|
* user then %G_TLS_INTERACTION_FAILED will be returned with an error that
|
||||||
|
* contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may
|
||||||
|
* not support immediate cancellation.
|
||||||
|
*
|
||||||
|
* Returns: The status of the certificate request interaction.
|
||||||
|
*
|
||||||
|
* Since: 2.40
|
||||||
|
*/
|
||||||
|
GTlsInteractionResult
|
||||||
|
g_tls_interaction_invoke_request_certificate (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GTlsInteractionResult result;
|
||||||
|
InvokeClosure *closure;
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_return_val_if_fail (G_IS_TLS_CONNECTION (connection), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
|
||||||
|
closure = invoke_closure_new (interaction, G_OBJECT (connection), cancellable);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (interaction);
|
||||||
|
if (klass->request_certificate)
|
||||||
|
{
|
||||||
|
g_main_context_invoke (interaction->priv->context,
|
||||||
|
on_invoke_request_certificate_sync, closure);
|
||||||
|
result = invoke_closure_wait_and_free (closure, error);
|
||||||
|
}
|
||||||
|
else if (klass->request_certificate_async)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (klass->request_certificate_finish, G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_main_context_invoke (interaction->priv->context,
|
||||||
|
on_invoke_request_certificate_async_as_sync, closure);
|
||||||
|
|
||||||
|
result = invoke_closure_complete_and_free (interaction, closure, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = G_TLS_INTERACTION_UNHANDLED;
|
||||||
|
invoke_closure_free (closure);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_tls_interaction_request_certificate:
|
||||||
|
* @interaction: a #GTlsInteraction object
|
||||||
|
* @connection: a #GTlsConnection object
|
||||||
|
* @flags: flags providing more information about the request
|
||||||
|
* @cancellable: an optional #GCancellable cancellation object
|
||||||
|
* @error: an optional location to place an error on failure
|
||||||
|
*
|
||||||
|
* Run synchronous interaction to ask the user to choose a certificate to use
|
||||||
|
* with the connection. In general, g_tls_interaction_invoke_request_certificate()
|
||||||
|
* should be used instead of this function.
|
||||||
|
*
|
||||||
|
* Derived subclasses usually implement a certificate selector, although they may
|
||||||
|
* also choose to provide a certificate from elsewhere. Alternatively the user may
|
||||||
|
* abort this certificate request, which will usually abort the TLS connection.
|
||||||
|
*
|
||||||
|
* If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsConnection
|
||||||
|
* passed to g_tls_interaction_request_certificate() will have had its
|
||||||
|
* #GTlsConnection:certificate filled in.
|
||||||
|
*
|
||||||
|
* If the interaction is cancelled by the cancellation object, or by the
|
||||||
|
* user then %G_TLS_INTERACTION_FAILED will be returned with an error that
|
||||||
|
* contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may
|
||||||
|
* not support immediate cancellation.
|
||||||
|
*
|
||||||
|
* Returns: The status of the request certificate interaction.
|
||||||
|
*
|
||||||
|
* Since: 2.40
|
||||||
|
*/
|
||||||
|
GTlsInteractionResult
|
||||||
|
g_tls_interaction_request_certificate (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_return_val_if_fail (G_IS_TLS_CONNECTION (connection), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (interaction);
|
||||||
|
if (klass->request_certificate)
|
||||||
|
return (klass->request_certificate) (interaction, connection, flags, cancellable, error);
|
||||||
|
else
|
||||||
|
return G_TLS_INTERACTION_UNHANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_tls_interaction_request_certificate_async:
|
||||||
|
* @interaction: a #GTlsInteraction object
|
||||||
|
* @connection: a #GTlsConnection object
|
||||||
|
* @flags: flags providing more information about the request
|
||||||
|
* @cancellable: an optional #GCancellable cancellation object
|
||||||
|
* @callback: (allow-none): will be called when the interaction completes
|
||||||
|
* @user_data: (allow-none): data to pass to the @callback
|
||||||
|
*
|
||||||
|
* Run asynchronous interaction to ask the user for a certificate to use with
|
||||||
|
* the connection. In general, g_tls_interaction_invoke_request_certificate() should
|
||||||
|
* be used instead of this function.
|
||||||
|
*
|
||||||
|
* Derived subclasses usually implement a certificate selector, although they may
|
||||||
|
* also choose to provide a certificate from elsewhere. @callback will be called
|
||||||
|
* when the operation completes. Alternatively the user may abort this certificate
|
||||||
|
* request, which will usually abort the TLS connection.
|
||||||
|
*
|
||||||
|
* Since: 2.40
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_tls_interaction_request_certificate_async (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
|
g_return_if_fail (G_IS_TLS_INTERACTION (interaction));
|
||||||
|
g_return_if_fail (G_IS_TLS_CONNECTION (connection));
|
||||||
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (interaction);
|
||||||
|
if (klass->request_certificate_async)
|
||||||
|
{
|
||||||
|
g_return_if_fail (klass->request_certificate_finish);
|
||||||
|
(klass->request_certificate_async) (interaction, connection, flags,
|
||||||
|
cancellable, callback, user_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
task = g_task_new (interaction, cancellable, callback, user_data);
|
||||||
|
g_task_set_source_tag (task, g_tls_interaction_request_certificate_async);
|
||||||
|
g_task_return_int (task, G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_tls_interaction_request_certificate_finish:
|
||||||
|
* @interaction: a #GTlsInteraction object
|
||||||
|
* @result: the result passed to the callback
|
||||||
|
* @error: an optional location to place an error on failure
|
||||||
|
*
|
||||||
|
* Complete an request certificate user interaction request. This should be once
|
||||||
|
* the g_tls_interaction_request_certificate_async() completion callback is called.
|
||||||
|
*
|
||||||
|
* If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsConnection
|
||||||
|
* passed to g_tls_interaction_request_certificate_async() will have had its
|
||||||
|
* #GTlsConnection:certificate filled in.
|
||||||
|
*
|
||||||
|
* If the interaction is cancelled by the cancellation object, or by the
|
||||||
|
* user then %G_TLS_INTERACTION_FAILED will be returned with an error that
|
||||||
|
* contains a %G_IO_ERROR_CANCELLED error code.
|
||||||
|
*
|
||||||
|
* Returns: The status of the request certificate interaction.
|
||||||
|
*
|
||||||
|
* Since: 2.40
|
||||||
|
*/
|
||||||
|
GTlsInteractionResult
|
||||||
|
g_tls_interaction_request_certificate_finish (GTlsInteraction *interaction,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GTlsInteractionClass *klass;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
|
||||||
|
klass = G_TLS_INTERACTION_GET_CLASS (interaction);
|
||||||
|
if (klass->request_certificate_finish)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (klass->request_certificate_async != NULL, G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
|
||||||
|
return (klass->request_certificate_finish) (interaction, result, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (g_async_result_is_tagged (result, g_tls_interaction_request_certificate_async), G_TLS_INTERACTION_UNHANDLED);
|
||||||
|
|
||||||
|
return g_task_propagate_int (G_TASK (result), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -69,9 +69,26 @@ struct _GTlsInteractionClass
|
|||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
GTlsInteractionResult (* request_certificate) (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
void (* request_certificate_async) (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GTlsInteractionResult (* request_certificate_finish) (GTlsInteraction *interaction,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
gpointer padding[24];
|
gpointer padding[21];
|
||||||
};
|
};
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
@ -83,7 +100,6 @@ GTlsInteractionResult g_tls_interaction_invoke_ask_password (GTlsInteraction
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GTlsInteractionResult g_tls_interaction_ask_password (GTlsInteraction *interaction,
|
GTlsInteractionResult g_tls_interaction_ask_password (GTlsInteraction *interaction,
|
||||||
GTlsPassword *password,
|
GTlsPassword *password,
|
||||||
@ -102,6 +118,33 @@ GTlsInteractionResult g_tls_interaction_ask_password_finish (GTlsInteraction
|
|||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_40
|
||||||
|
GTlsInteractionResult g_tls_interaction_invoke_request_certificate (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_40
|
||||||
|
GTlsInteractionResult g_tls_interaction_request_certificate (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_40
|
||||||
|
void g_tls_interaction_request_certificate_async (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
GTlsCertificateRequestFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_40
|
||||||
|
GTlsInteractionResult g_tls_interaction_request_certificate_finish (GTlsInteraction *interaction,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_TLS_INTERACTION_H__ */
|
#endif /* __G_TLS_INTERACTION_H__ */
|
||||||
|
@ -403,6 +403,8 @@ CLEANFILES += gdbus-test-codegen-generated.[ch] gdbus-test-codegen-generated-doc
|
|||||||
endif # OS_UNIX
|
endif # OS_UNIX
|
||||||
endif # HAVE_DBUS_DAEMON
|
endif # HAVE_DBUS_DAEMON
|
||||||
|
|
||||||
|
tls_interaction_SOURCES = tls-interaction.c gtesttlsbackend.c gtesttlsbackend.h
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
if OS_WIN32
|
if OS_WIN32
|
||||||
|
@ -24,11 +24,18 @@
|
|||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gtesttlsbackend.h"
|
||||||
|
|
||||||
|
static GPtrArray *fixtures = NULL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Class virtual interaction methods */
|
/* Class virtual interaction methods */
|
||||||
gpointer ask_password_func;
|
gpointer ask_password_func;
|
||||||
gpointer ask_password_async_func;
|
gpointer ask_password_async_func;
|
||||||
gpointer ask_password_finish_func;
|
gpointer ask_password_finish_func;
|
||||||
|
gpointer request_certificate_func;
|
||||||
|
gpointer request_certificate_async_func;
|
||||||
|
gpointer request_certificate_finish_func;
|
||||||
|
|
||||||
/* Expected results */
|
/* Expected results */
|
||||||
GTlsInteractionResult result;
|
GTlsInteractionResult result;
|
||||||
@ -40,6 +47,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
GTlsInteraction *interaction;
|
GTlsInteraction *interaction;
|
||||||
GTlsPassword *password;
|
GTlsPassword *password;
|
||||||
|
GTlsConnection *connection;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
GThread *interaction_thread;
|
GThread *interaction_thread;
|
||||||
GThread *test_thread;
|
GThread *test_thread;
|
||||||
@ -213,6 +221,155 @@ test_interaction_ask_password_sync_failure (GTlsInteraction *interaction,
|
|||||||
return G_TLS_INTERACTION_FAILED;
|
return G_TLS_INTERACTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_interaction_request_certificate_async_success (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
gint unused_flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (G_IS_TLS_CONNECTION (connection));
|
||||||
|
g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
g_assert (unused_flags == 0);
|
||||||
|
|
||||||
|
task = g_task_new (self, cancellable, callback, user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRL would call g_tls_connection_set_certificate(). But here just touch
|
||||||
|
* the connection in a detectable way.
|
||||||
|
*/
|
||||||
|
g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate");
|
||||||
|
g_task_return_int (task, G_TLS_INTERACTION_HANDLED);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GTlsInteractionResult
|
||||||
|
test_interaction_request_certificate_finish_success (GTlsInteraction *interaction,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (g_task_is_valid (result, interaction));
|
||||||
|
g_assert (error != NULL);
|
||||||
|
g_assert (*error == NULL);
|
||||||
|
|
||||||
|
return g_task_propagate_int (G_TASK (result), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_interaction_request_certificate_async_failure (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
gint unused_flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (G_IS_TLS_CONNECTION (connection));
|
||||||
|
g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
g_assert (unused_flags == 0);
|
||||||
|
|
||||||
|
task = g_task_new (self, cancellable, callback, user_data);
|
||||||
|
|
||||||
|
g_task_return_new_error (task, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message");
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GTlsInteractionResult
|
||||||
|
test_interaction_request_certificate_finish_failure (GTlsInteraction *interaction,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (g_task_is_valid (result, interaction));
|
||||||
|
g_assert (error != NULL);
|
||||||
|
g_assert (*error == NULL);
|
||||||
|
|
||||||
|
if (g_task_propagate_int (G_TASK (result), error) != -1)
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
return G_TLS_INTERACTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GTlsInteractionResult
|
||||||
|
test_interaction_request_certificate_sync_success (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
gint unused_flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (G_IS_TLS_CONNECTION (connection));
|
||||||
|
g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
g_assert (error != NULL);
|
||||||
|
g_assert (*error == NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRL would call g_tls_connection_set_certificate(). But here just touch
|
||||||
|
* the connection in a detectable way.
|
||||||
|
*/
|
||||||
|
g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate");
|
||||||
|
return G_TLS_INTERACTION_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GTlsInteractionResult
|
||||||
|
test_interaction_request_certificate_sync_failure (GTlsInteraction *interaction,
|
||||||
|
GTlsConnection *connection,
|
||||||
|
gint unused_flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
TestInteraction *self;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
|
||||||
|
g_assert (g_thread_self () == self->test->interaction_thread);
|
||||||
|
|
||||||
|
g_assert (G_IS_TLS_CONNECTION (connection));
|
||||||
|
g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
g_assert (unused_flags == 0);
|
||||||
|
g_assert (error != NULL);
|
||||||
|
g_assert (*error == NULL);
|
||||||
|
|
||||||
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message");
|
||||||
|
return G_TLS_INTERACTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* ACTUAL TESTS
|
* ACTUAL TESTS
|
||||||
*/
|
*/
|
||||||
@ -344,6 +501,133 @@ test_ask_password (Test *test,
|
|||||||
g_main_loop_quit (test->loop);
|
g_main_loop_quit (test->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_request_certificate_async_call (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Test *test = user_data;
|
||||||
|
GTlsInteractionResult res;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (G_IS_TLS_INTERACTION (source));
|
||||||
|
g_assert (G_TLS_INTERACTION (source) == test->interaction);
|
||||||
|
|
||||||
|
/* Check that this callback is being run in the right place */
|
||||||
|
g_assert (g_thread_self () == test->interaction_thread);
|
||||||
|
|
||||||
|
res = g_tls_interaction_request_certificate_finish (test->interaction, result, &error);
|
||||||
|
|
||||||
|
/* Check that the results match the fixture */
|
||||||
|
g_assert_cmpuint (test->fixture->result, ==, res);
|
||||||
|
switch (test->fixture->result)
|
||||||
|
{
|
||||||
|
case G_TLS_INTERACTION_HANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_FAILED:
|
||||||
|
g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
|
||||||
|
g_assert_cmpstr (error->message, ==, test->fixture->error_message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_UNHANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signal the end of the test */
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_request_certificate_async (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
/* This test only works with a main loop */
|
||||||
|
g_assert (test->loop);
|
||||||
|
|
||||||
|
g_tls_interaction_request_certificate_async (test->interaction,
|
||||||
|
test->connection, 0, NULL,
|
||||||
|
on_request_certificate_async_call,
|
||||||
|
test);
|
||||||
|
|
||||||
|
/* teardown waits until g_main_loop_quit(). called from callback */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_invoke_request_certificate (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
GTlsInteractionResult res;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
res = g_tls_interaction_invoke_request_certificate (test->interaction,
|
||||||
|
test->connection,
|
||||||
|
0, NULL, &error);
|
||||||
|
|
||||||
|
/* Check that the results match the fixture */
|
||||||
|
g_assert_cmpuint (test->fixture->result, ==, res);
|
||||||
|
switch (test->fixture->result)
|
||||||
|
{
|
||||||
|
case G_TLS_INTERACTION_HANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_FAILED:
|
||||||
|
g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
|
||||||
|
g_assert_cmpstr (error->message, ==, test->fixture->error_message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_UNHANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This allows teardown to stop if running with loop */
|
||||||
|
if (test->loop)
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_request_certificate (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
GTlsInteractionResult res;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
res = g_tls_interaction_request_certificate (test->interaction, test->connection,
|
||||||
|
0, NULL, &error);
|
||||||
|
|
||||||
|
/* Check that the results match the fixture */
|
||||||
|
g_assert_cmpuint (test->fixture->result, ==, res);
|
||||||
|
switch (test->fixture->result)
|
||||||
|
{
|
||||||
|
case G_TLS_INTERACTION_HANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_FAILED:
|
||||||
|
g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
|
||||||
|
g_assert_cmpstr (error->message, ==, test->fixture->error_message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
break;
|
||||||
|
case G_TLS_INTERACTION_UNHANDLED:
|
||||||
|
g_assert_no_error (error);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This allows teardown to stop if running with loop */
|
||||||
|
if (test->loop)
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* TEST SETUP
|
* TEST SETUP
|
||||||
*/
|
*/
|
||||||
@ -354,6 +638,9 @@ setup_without_loop (Test *test,
|
|||||||
{
|
{
|
||||||
const Fixture *fixture = user_data;
|
const Fixture *fixture = user_data;
|
||||||
GTlsInteractionClass *klass;
|
GTlsInteractionClass *klass;
|
||||||
|
GTlsBackend *backend;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
test->fixture = fixture;
|
test->fixture = fixture;
|
||||||
|
|
||||||
test->interaction = g_object_new (TEST_TYPE_INTERACTION, NULL);
|
test->interaction = g_object_new (TEST_TYPE_INTERACTION, NULL);
|
||||||
@ -365,6 +652,14 @@ setup_without_loop (Test *test,
|
|||||||
klass->ask_password = fixture->ask_password_func;
|
klass->ask_password = fixture->ask_password_func;
|
||||||
klass->ask_password_async = fixture->ask_password_async_func;
|
klass->ask_password_async = fixture->ask_password_async_func;
|
||||||
klass->ask_password_finish = fixture->ask_password_finish_func;
|
klass->ask_password_finish = fixture->ask_password_finish_func;
|
||||||
|
klass->request_certificate = fixture->request_certificate_func;
|
||||||
|
klass->request_certificate_async = fixture->request_certificate_async_func;
|
||||||
|
klass->request_certificate_finish = fixture->request_certificate_finish_func;
|
||||||
|
|
||||||
|
backend = g_object_new (G_TYPE_TEST_TLS_BACKEND, NULL);
|
||||||
|
test->connection = g_object_new (g_tls_backend_get_server_connection_type (backend), NULL);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_object_unref (backend);
|
||||||
|
|
||||||
test->password = g_tls_password_new (0, "Description");
|
test->password = g_tls_password_new (0, "Description");
|
||||||
test->test_thread = g_thread_self ();
|
test->test_thread = g_thread_self ();
|
||||||
@ -384,6 +679,8 @@ teardown_without_loop (Test *test,
|
|||||||
|
|
||||||
g_object_add_weak_pointer (weak_pointer, &weak_pointer);
|
g_object_add_weak_pointer (weak_pointer, &weak_pointer);
|
||||||
|
|
||||||
|
g_object_unref (test->connection);
|
||||||
|
|
||||||
g_object_unref (test->password);
|
g_object_unref (test->password);
|
||||||
|
|
||||||
g_object_unref (test->interaction);
|
g_object_unref (test->interaction);
|
||||||
@ -507,11 +804,10 @@ teardown_with_normal_loop (Test *test,
|
|||||||
typedef void (*TestFunc) (Test *test, gconstpointer data);
|
typedef void (*TestFunc) (Test *test, gconstpointer data);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_with_async_ask_password_implementations (const gchar *name,
|
test_with_async_ask_password (const gchar *name,
|
||||||
TestFunc setup,
|
TestFunc setup,
|
||||||
TestFunc func,
|
TestFunc func,
|
||||||
TestFunc teardown,
|
TestFunc teardown)
|
||||||
GPtrArray *fixtures)
|
|
||||||
{
|
{
|
||||||
gchar *test_name;
|
gchar *test_name;
|
||||||
Fixture *fixture;
|
Fixture *fixture;
|
||||||
@ -541,12 +837,12 @@ test_with_async_ask_password_implementations (const gchar *name,
|
|||||||
g_free (test_name);
|
g_free (test_name);
|
||||||
g_ptr_array_add (fixtures, fixture);
|
g_ptr_array_add (fixtures, fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_with_unhandled_ask_password_implementations (const gchar *name,
|
test_with_unhandled_ask_password (const gchar *name,
|
||||||
TestFunc setup,
|
TestFunc setup,
|
||||||
TestFunc func,
|
TestFunc func,
|
||||||
TestFunc teardown,
|
TestFunc teardown)
|
||||||
GPtrArray *fixtures)
|
|
||||||
{
|
{
|
||||||
gchar *test_name;
|
gchar *test_name;
|
||||||
Fixture *fixture;
|
Fixture *fixture;
|
||||||
@ -564,11 +860,10 @@ test_with_unhandled_ask_password_implementations (const gchar *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_with_sync_ask_password_implementations (const gchar *name,
|
test_with_sync_ask_password (const gchar *name,
|
||||||
TestFunc setup,
|
TestFunc setup,
|
||||||
TestFunc func,
|
TestFunc func,
|
||||||
TestFunc teardown,
|
TestFunc teardown)
|
||||||
GPtrArray *fixtures)
|
|
||||||
{
|
{
|
||||||
gchar *test_name;
|
gchar *test_name;
|
||||||
Fixture *fixture;
|
Fixture *fixture;
|
||||||
@ -599,11 +894,122 @@ test_with_sync_ask_password_implementations (const gchar *name,
|
|||||||
g_ptr_array_add (fixtures, fixture);
|
g_ptr_array_add (fixtures, fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_with_all_ask_password (const gchar *name,
|
||||||
|
TestFunc setup,
|
||||||
|
TestFunc func,
|
||||||
|
TestFunc teardown)
|
||||||
|
{
|
||||||
|
test_with_unhandled_ask_password (name, setup, func, teardown);
|
||||||
|
test_with_async_ask_password (name, setup, func, teardown);
|
||||||
|
test_with_sync_ask_password (name, setup, func, teardown);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_with_async_request_certificate (const gchar *name,
|
||||||
|
TestFunc setup,
|
||||||
|
TestFunc func,
|
||||||
|
TestFunc teardown)
|
||||||
|
{
|
||||||
|
gchar *test_name;
|
||||||
|
Fixture *fixture;
|
||||||
|
|
||||||
|
/* Async implementation that succeeds */
|
||||||
|
fixture = g_new0 (Fixture, 1);
|
||||||
|
fixture->request_certificate_async_func = test_interaction_request_certificate_async_success;
|
||||||
|
fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_success;
|
||||||
|
fixture->request_certificate_func = NULL;
|
||||||
|
fixture->result = G_TLS_INTERACTION_HANDLED;
|
||||||
|
test_name = g_strdup_printf ("%s/async-implementation-success", name);
|
||||||
|
g_test_add (test_name, Test, fixture, setup, func, teardown);
|
||||||
|
g_free (test_name);
|
||||||
|
g_ptr_array_add (fixtures, fixture);
|
||||||
|
|
||||||
|
/* Async implementation that fails */
|
||||||
|
fixture = g_new0 (Fixture, 1);
|
||||||
|
fixture->request_certificate_async_func = test_interaction_request_certificate_async_failure;
|
||||||
|
fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_failure;
|
||||||
|
fixture->request_certificate_func = NULL;
|
||||||
|
fixture->result = G_TLS_INTERACTION_FAILED;
|
||||||
|
fixture->error_domain = G_FILE_ERROR;
|
||||||
|
fixture->error_code = G_FILE_ERROR_NOENT;
|
||||||
|
fixture->error_message = "Another message";
|
||||||
|
test_name = g_strdup_printf ("%s/async-implementation-failure", name);
|
||||||
|
g_test_add (test_name, Test, fixture, setup, func, teardown);
|
||||||
|
g_free (test_name);
|
||||||
|
g_ptr_array_add (fixtures, fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_with_unhandled_request_certificate (const gchar *name,
|
||||||
|
TestFunc setup,
|
||||||
|
TestFunc func,
|
||||||
|
TestFunc teardown)
|
||||||
|
{
|
||||||
|
gchar *test_name;
|
||||||
|
Fixture *fixture;
|
||||||
|
|
||||||
|
/* Unhandled implementation */
|
||||||
|
fixture = g_new0 (Fixture, 1);
|
||||||
|
fixture->request_certificate_async_func = NULL;
|
||||||
|
fixture->request_certificate_finish_func = NULL;
|
||||||
|
fixture->request_certificate_func = NULL;
|
||||||
|
fixture->result = G_TLS_INTERACTION_UNHANDLED;
|
||||||
|
test_name = g_strdup_printf ("%s/unhandled-implementation", name);
|
||||||
|
g_test_add (test_name, Test, fixture, setup, func, teardown);
|
||||||
|
g_free (test_name);
|
||||||
|
g_ptr_array_add (fixtures, fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_with_sync_request_certificate (const gchar *name,
|
||||||
|
TestFunc setup,
|
||||||
|
TestFunc func,
|
||||||
|
TestFunc teardown)
|
||||||
|
{
|
||||||
|
gchar *test_name;
|
||||||
|
Fixture *fixture;
|
||||||
|
|
||||||
|
/* Sync implementation that succeeds */
|
||||||
|
fixture = g_new0 (Fixture, 1);
|
||||||
|
fixture->request_certificate_async_func = NULL;
|
||||||
|
fixture->request_certificate_finish_func = NULL;
|
||||||
|
fixture->request_certificate_func = test_interaction_request_certificate_sync_success;
|
||||||
|
fixture->result = G_TLS_INTERACTION_HANDLED;
|
||||||
|
test_name = g_strdup_printf ("%s/sync-implementation-success", name);
|
||||||
|
g_test_add (test_name, Test, fixture, setup, func, teardown);
|
||||||
|
g_free (test_name);
|
||||||
|
g_ptr_array_add (fixtures, fixture);
|
||||||
|
|
||||||
|
/* Async implementation that fails */
|
||||||
|
fixture = g_new0 (Fixture, 1);
|
||||||
|
fixture->request_certificate_async_func = NULL;
|
||||||
|
fixture->request_certificate_finish_func = NULL;
|
||||||
|
fixture->request_certificate_func = test_interaction_request_certificate_sync_failure;
|
||||||
|
fixture->result = G_TLS_INTERACTION_FAILED;
|
||||||
|
fixture->error_domain = G_FILE_ERROR;
|
||||||
|
fixture->error_code = G_FILE_ERROR_NOENT;
|
||||||
|
fixture->error_message = "Another message";
|
||||||
|
test_name = g_strdup_printf ("%s/sync-implementation-failure", name);
|
||||||
|
g_test_add (test_name, Test, fixture, setup, func, teardown);
|
||||||
|
g_free (test_name);
|
||||||
|
g_ptr_array_add (fixtures, fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_with_all_request_certificate (const gchar *name,
|
||||||
|
TestFunc setup,
|
||||||
|
TestFunc func,
|
||||||
|
TestFunc teardown)
|
||||||
|
{
|
||||||
|
test_with_unhandled_request_certificate (name, setup, func, teardown);
|
||||||
|
test_with_async_request_certificate (name, setup, func, teardown);
|
||||||
|
test_with_sync_request_certificate (name, setup, func, teardown);
|
||||||
|
}
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
GPtrArray *fixtures;
|
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
@ -611,52 +1017,44 @@ main (int argc,
|
|||||||
fixtures = g_ptr_array_new_with_free_func (g_free);
|
fixtures = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
|
||||||
/* Tests for g_tls_interaction_invoke_ask_password */
|
/* Tests for g_tls_interaction_invoke_ask_password */
|
||||||
|
test_with_all_ask_password ("/tls-interaction/ask-password/invoke-with-loop",
|
||||||
test_with_unhandled_ask_password_implementations ("/tls-interaction/ask-password/invoke-with-loop",
|
setup_with_thread_loop, test_invoke_ask_password, teardown_with_thread_loop);
|
||||||
setup_with_thread_loop, test_invoke_ask_password,
|
test_with_all_ask_password ("/tls-interaction/ask-password/invoke-without-loop",
|
||||||
teardown_with_thread_loop, fixtures);
|
setup_without_loop, test_invoke_ask_password, teardown_without_loop);
|
||||||
test_with_async_ask_password_implementations ("/tls-interaction/ask-password/invoke-with-loop",
|
test_with_all_ask_password ("/tls-interaction/ask-password/invoke-in-loop",
|
||||||
setup_with_thread_loop, test_invoke_ask_password,
|
setup_with_normal_loop, test_invoke_ask_password, teardown_with_normal_loop);
|
||||||
teardown_with_thread_loop, fixtures);
|
|
||||||
test_with_sync_ask_password_implementations ("/tls-interaction/ask-password/invoke-with-loop",
|
|
||||||
setup_with_thread_loop, test_invoke_ask_password,
|
|
||||||
teardown_with_thread_loop, fixtures);
|
|
||||||
|
|
||||||
test_with_unhandled_ask_password_implementations ("/tls-interaction/ask-password/invoke-without-loop",
|
|
||||||
setup_without_loop, test_invoke_ask_password,
|
|
||||||
teardown_without_loop, fixtures);
|
|
||||||
test_with_async_ask_password_implementations ("/tls-interaction/ask-password/invoke-without-loop",
|
|
||||||
setup_without_loop, test_invoke_ask_password,
|
|
||||||
teardown_without_loop, fixtures);
|
|
||||||
test_with_sync_ask_password_implementations ("/tls-interaction/ask-password/invoke-without-loop",
|
|
||||||
setup_without_loop, test_invoke_ask_password,
|
|
||||||
teardown_without_loop, fixtures);
|
|
||||||
|
|
||||||
test_with_unhandled_ask_password_implementations ("/tls-interaction/ask-password/invoke-in-loop",
|
|
||||||
setup_with_normal_loop, test_invoke_ask_password,
|
|
||||||
teardown_with_normal_loop, fixtures);
|
|
||||||
test_with_async_ask_password_implementations ("/tls-interaction/ask-password/invoke-in-loop",
|
|
||||||
setup_with_normal_loop, test_invoke_ask_password,
|
|
||||||
teardown_with_normal_loop, fixtures);
|
|
||||||
test_with_sync_ask_password_implementations ("/tls-interaction/ask-password/invoke-in-loop",
|
|
||||||
setup_with_normal_loop, test_invoke_ask_password,
|
|
||||||
teardown_with_normal_loop, fixtures);
|
|
||||||
|
|
||||||
/* Tests for g_tls_interaction_ask_password */
|
/* Tests for g_tls_interaction_ask_password */
|
||||||
test_with_unhandled_ask_password_implementations ("/tls-interaction/ask-password/sync",
|
test_with_unhandled_ask_password ("/tls-interaction/ask-password/sync",
|
||||||
setup_without_loop, test_ask_password,
|
setup_without_loop, test_ask_password, teardown_without_loop);
|
||||||
teardown_without_loop, fixtures);
|
test_with_sync_ask_password ("/tls-interaction/ask-password/sync",
|
||||||
test_with_sync_ask_password_implementations ("/tls-interaction/ask-password/sync",
|
setup_without_loop, test_ask_password, teardown_without_loop);
|
||||||
setup_without_loop, test_ask_password,
|
|
||||||
teardown_without_loop, fixtures);
|
|
||||||
|
|
||||||
/* Tests for g_tls_interaction_ask_password_async */
|
/* Tests for g_tls_interaction_ask_password_async */
|
||||||
test_with_unhandled_ask_password_implementations ("/tls-interaction/ask-password/async",
|
test_with_unhandled_ask_password ("/tls-interaction/ask-password/async",
|
||||||
setup_with_normal_loop, test_ask_password_async,
|
setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop);
|
||||||
teardown_with_normal_loop, fixtures);
|
test_with_async_ask_password ("/tls-interaction/ask-password/async",
|
||||||
test_with_async_ask_password_implementations ("/tls-interaction/ask-password/async",
|
setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop);
|
||||||
setup_with_normal_loop, test_ask_password_async,
|
|
||||||
teardown_with_normal_loop, fixtures);
|
/* Tests for g_tls_interaction_invoke_request_certificate */
|
||||||
|
test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-with-loop",
|
||||||
|
setup_with_thread_loop, test_invoke_request_certificate, teardown_with_thread_loop);
|
||||||
|
test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-without-loop",
|
||||||
|
setup_without_loop, test_invoke_request_certificate, teardown_without_loop);
|
||||||
|
test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-in-loop",
|
||||||
|
setup_with_normal_loop, test_invoke_request_certificate, teardown_with_normal_loop);
|
||||||
|
|
||||||
|
/* Tests for g_tls_interaction_ask_password */
|
||||||
|
test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/sync",
|
||||||
|
setup_without_loop, test_request_certificate, teardown_without_loop);
|
||||||
|
test_with_sync_request_certificate ("/tls-interaction/request-certificate/sync",
|
||||||
|
setup_without_loop, test_request_certificate, teardown_without_loop);
|
||||||
|
|
||||||
|
/* Tests for g_tls_interaction_ask_password_async */
|
||||||
|
test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/async",
|
||||||
|
setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop);
|
||||||
|
test_with_async_request_certificate ("/tls-interaction/request-certificate/async",
|
||||||
|
setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop);
|
||||||
|
|
||||||
ret = g_test_run();
|
ret = g_test_run();
|
||||||
g_ptr_array_free (fixtures, TRUE);
|
g_ptr_array_free (fixtures, TRUE);
|
||||||
|
Loading…
Reference in New Issue
Block a user