/**
 * g_tls_interaction_ask_password_async:
 * @interaction: a #GTlsInteraction object
 * @password: a #GTlsPassword object
 * @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 password. In general,
 * g_tls_interaction_invoke_ask_password() should be used instead of this
 * function.
 *
 * Derived subclasses usually implement a password prompt, although they may
 * also choose to provide a password from elsewhere. The @password value will
 * be filled in and then @callback will be called. Alternatively the user may
 * abort this password request, which will usually abort the TLS connection.
 *
 * 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.
 *
 * Certain implementations may not support immediate cancellation.
 *
 * Since: 2.30
 */
void
g_tls_interaction_ask_password_async (GTlsInteraction    *interaction,
                                      GTlsPassword       *password,
                                      GCancellable       *cancellable,
                                      GAsyncReadyCallback callback,
                                      gpointer            user_data)
{
  GTlsInteractionClass *klass;
  GSimpleAsyncResult *res;

  g_return_if_fail (G_IS_TLS_INTERACTION (interaction));
  g_return_if_fail (G_IS_TLS_PASSWORD (password));
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

  klass = G_TLS_INTERACTION_GET_CLASS (interaction);
  if (klass->ask_password_async)
    {
      g_return_if_fail (klass->ask_password_finish);
      (klass->ask_password_async) (interaction, password, cancellable,
                                   callback, user_data);
    }
  else
    {
      res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
                                       g_tls_interaction_ask_password_async);
      g_simple_async_result_complete_in_idle (res);
      g_object_unref (res);
    }
}
/**
 * g_tls_interaction_ask_password_finish:
 * @interaction: a #GTlsInteraction object
 * @result: the result passed to the callback
 * @error: an optional location to place an error on failure
 *
 * Complete an ask password user interaction request. This should be once
 * the g_tls_interaction_ask_password_async() completion callback is called.
 *
 * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsPassword passed
 * to g_tls_interaction_ask_password() will have its password 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 ask password interaction.
 *
 * Since: 2.30
 */
GTlsInteractionResult
g_tls_interaction_ask_password_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);

  /* If it's one of our simple unhandled async results, handle here */
  if (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
                                      g_tls_interaction_ask_password_async))
    {
      return G_TLS_INTERACTION_UNHANDLED;
    }

  /* Invoke finish of derived class */
  else
    {
      klass = G_TLS_INTERACTION_GET_CLASS (interaction);
      g_return_val_if_fail (klass->ask_password_finish, G_TLS_INTERACTION_UNHANDLED);
      return (klass->ask_password_finish) (interaction, result, error);
    }
}
static gboolean
on_invoke_ask_password_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->ask_password_async);

  klass->ask_password_async (closure->interaction,
                             G_TLS_PASSWORD (closure->argument),
                             closure->cancellable,
                             on_async_as_sync_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 */
}
Example #4
0
/**
 * g_tls_interaction_ask_password_async:
 * @interaction: a #GTlsInteraction object
 * @password: a #GTlsPassword object
 * @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 password. In general,
 * g_tls_interaction_invoke_ask_password() should be used instead of this
 * function.
 *
 * Derived subclasses usually implement a password prompt, although they may
 * also choose to provide a password from elsewhere. The @password value will
 * be filled in and then @callback will be called. Alternatively the user may
 * abort this password request, which will usually abort the TLS connection.
 *
 * 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.
 *
 * Certain implementations may not support immediate cancellation.
 *
 * Since: 2.30
 */
void
g_tls_interaction_ask_password_async (GTlsInteraction    *interaction,
                                      GTlsPassword       *password,
                                      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_PASSWORD (password));
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

  klass = G_TLS_INTERACTION_GET_CLASS (interaction);
  if (klass->ask_password_async)
    {
      g_return_if_fail (klass->ask_password_finish);
      (klass->ask_password_async) (interaction, password, cancellable,
                                   callback, user_data);
    }
  else
    {
      task = g_task_new (interaction, cancellable, callback, user_data);
      g_task_set_source_tag (task, g_tls_interaction_ask_password_async);
      g_task_return_int (task, G_TLS_INTERACTION_UNHANDLED);
      g_object_unref (task);
    }
}
/**
 * g_tls_interaction_ask_password:
 * @interaction: a #GTlsInteraction object
 * @password: a #GTlsPassword object
 * @cancellable: an optional #GCancellable cancellation object
 * @error: an optional location to place an error on failure
 *
 * Run synchronous interaction to ask the user for a password. In general,
 * g_tls_interaction_invoke_ask_password() should be used instead of this
 * function.
 *
 * Derived subclasses usually implement a password prompt, although they may
 * also choose to provide a password from elsewhere. The @password value will
 * be filled in and then @callback will be called. Alternatively the user may
 * abort this password request, which will usually abort the TLS connection.
 *
 * 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 ask password interaction.
 *
 * Since: 2.30
 */
GTlsInteractionResult
g_tls_interaction_ask_password (GTlsInteraction    *interaction,
                                GTlsPassword       *password,
                                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_PASSWORD (password), 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->ask_password)
    return (klass->ask_password) (interaction, password, cancellable, error);
  else
    return G_TLS_INTERACTION_UNHANDLED;
}
static void
on_async_as_sync_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->ask_password_finish);

  closure->result = klass->ask_password_finish (closure->interaction,
                                                result,
                                                &closure->error);

  closure->complete = TRUE;
  g_cond_signal (closure->cond);
  g_mutex_unlock (closure->mutex);
}
static gboolean
on_invoke_ask_password_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->ask_password);

  closure->result = klass->ask_password (closure->interaction,
                                         G_TLS_PASSWORD (closure->argument),
                                         closure->cancellable,
                                         &closure->error);

  closure->complete = TRUE;
  g_cond_signal (closure->cond);
  g_mutex_unlock (closure->mutex);

  return FALSE; /* don't call again */
}
Example #8
0
/**
 * g_tls_interaction_ask_password_finish:
 * @interaction: a #GTlsInteraction object
 * @result: the result passed to the callback
 * @error: an optional location to place an error on failure
 *
 * Complete an ask password user interaction request. This should be once
 * the g_tls_interaction_ask_password_async() completion callback is called.
 *
 * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsPassword passed
 * to g_tls_interaction_ask_password() will have its password 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 ask password interaction.
 *
 * Since: 2.30
 */
GTlsInteractionResult
g_tls_interaction_ask_password_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->ask_password_finish)
    {
      g_return_val_if_fail (klass->ask_password_async != NULL, G_TLS_INTERACTION_UNHANDLED);

      return (klass->ask_password_finish) (interaction, result, error);
    }
  else
    {
      g_return_val_if_fail (g_async_result_is_tagged (result, g_tls_interaction_ask_password_async), G_TLS_INTERACTION_UNHANDLED);

      return g_task_propagate_int (G_TASK (result), error);
    }
}
/**
 * g_tls_interaction_invoke_ask_password:
 * @interaction: a #GTlsInteraction object
 * @password: a #GTlsPassword object
 * @cancellable: an optional #GCancellable cancellation object
 * @error: an optional location to place an error on failure
 *
 * Invoke the interaction to ask the user for a password. 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 or #GTlsDatabase to ask the user
 * for a password.
 *
 * Derived subclasses usually implement a password prompt, although they may
 * also choose to provide a password from elsewhere. The @password value will
 * be filled in and then @callback will be called. Alternatively the user may
 * abort this password request, which will usually 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 ask password interaction.
 *
 * Since: 2.30
 */
GTlsInteractionResult
g_tls_interaction_invoke_ask_password (GTlsInteraction    *interaction,
                                       GTlsPassword       *password,
                                       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_PASSWORD (password), 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 (password), cancellable);

  klass = G_TLS_INTERACTION_GET_CLASS (interaction);
  if (klass->ask_password)
    {
      g_main_context_invoke (interaction->priv->context,
                             on_invoke_ask_password_sync, closure);
      result = invoke_closure_wait_and_free (closure, error);
    }
  else if (klass->ask_password_async)
    {
      g_return_val_if_fail (klass->ask_password_finish, G_TLS_INTERACTION_UNHANDLED);
      g_main_context_invoke (interaction->priv->context,
                             on_invoke_ask_password_async_as_sync, closure);

      /*
       * 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))
        {
          while (!closure->complete)
            {
              g_mutex_unlock (closure->mutex);
              g_main_context_iteration (interaction->priv->context, TRUE);
              g_mutex_lock (closure->mutex);
            }
          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
    {
      result = G_TLS_INTERACTION_UNHANDLED;
      invoke_closure_free (closure);
    }

  return result;
}