|
Packit |
79f644 |
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
Packit |
79f644 |
/*
|
|
Packit |
79f644 |
* Copyright © 2012 – 2017 Red Hat, Inc.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
79f644 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
79f644 |
* License as published by the Free Software Foundation; either
|
|
Packit |
79f644 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
79f644 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
79f644 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
79f644 |
* Lesser General Public License for more details.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* You should have received a copy of the GNU Lesser General
|
|
Packit |
79f644 |
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "config.h"
|
|
Packit |
79f644 |
#include <glib/gi18n-lib.h>
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "goaprovider.h"
|
|
Packit |
79f644 |
#include "goaprovider-priv.h"
|
|
Packit |
79f644 |
#include "goakerberosprovider.h"
|
|
Packit |
79f644 |
#include "goautils.h"
|
|
Packit |
79f644 |
#include "goaidentity.h"
|
|
Packit |
79f644 |
#include "goaidentitymanagererror.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include <gcr/gcr.h>
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "org.gnome.Identity.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
struct _GoaKerberosProvider
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaProvider parent_instance;
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
typedef struct _GoaKerberosProviderClass GoaKerberosProviderClass;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
struct _GoaKerberosProviderClass
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaProviderClass parent_class;
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GoaIdentityServiceManager *identity_manager;
|
|
Packit |
79f644 |
static GMutex identity_manager_mutex;
|
|
Packit |
79f644 |
static GCond identity_manager_condition;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GDBusObjectManager *object_manager;
|
|
Packit |
79f644 |
static GMutex object_manager_mutex;
|
|
Packit |
79f644 |
static GCond object_manager_condition;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void ensure_identity_manager (void);
|
|
Packit |
79f644 |
static void ensure_object_manager (void);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static char *sign_in_identity_sync (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
const char *identifier,
|
|
Packit |
79f644 |
const char *password,
|
|
Packit |
79f644 |
const char *preauth_source,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GError **error);
|
|
Packit |
79f644 |
static void sign_in_thread (GTask *result,
|
|
Packit |
79f644 |
GoaKerberosProvider *self,
|
|
Packit |
79f644 |
gpointer task_data,
|
|
Packit |
79f644 |
GCancellable *cancellable);
|
|
Packit |
79f644 |
static GoaIdentityServiceIdentity *get_identity_from_object_manager (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
const char *identifier);
|
|
Packit |
79f644 |
static gboolean dbus_proxy_reload_properties_sync (GDBusProxy *proxy,
|
|
Packit |
79f644 |
GCancellable *cancellable);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void goa_kerberos_provider_module_init (void);
|
|
Packit |
79f644 |
static void create_object_manager (void);
|
|
Packit |
79f644 |
static void create_identity_manager (void);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
G_DEFINE_TYPE_WITH_CODE (GoaKerberosProvider, goa_kerberos_provider, GOA_TYPE_PROVIDER,
|
|
Packit |
79f644 |
goa_kerberos_provider_module_init ();
|
|
Packit |
79f644 |
goa_provider_ensure_extension_points_registered ();
|
|
Packit |
79f644 |
g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
|
|
Packit |
79f644 |
g_define_type_id,
|
|
Packit |
79f644 |
GOA_KERBEROS_NAME,
|
|
Packit |
79f644 |
0));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
goa_kerberos_provider_module_init (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
create_object_manager ();
|
|
Packit |
79f644 |
create_identity_manager ();
|
|
Packit |
79f644 |
g_debug ("activated kerberos provider");
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static const gchar *
|
|
Packit |
79f644 |
get_provider_type (GoaProvider *provider)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return GOA_KERBEROS_NAME;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gchar *
|
|
Packit |
79f644 |
get_provider_name (GoaProvider *provider, GoaObject *object)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return g_strdup(_("Enterprise Login (Kerberos)"));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GoaProviderGroup
|
|
Packit |
79f644 |
get_provider_group (GoaProvider *_provider)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return GOA_PROVIDER_GROUP_TICKETING;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GoaProviderFeatures
|
|
Packit |
79f644 |
get_provider_features (GoaProvider *_provider)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return GOA_PROVIDER_FEATURE_TICKETING;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GIcon *
|
|
Packit |
79f644 |
get_provider_icon (GoaProvider *provider, GoaObject *object)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return g_themed_icon_new_with_default_fallbacks ("dialog-password-symbolic");
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
typedef struct
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GtkDialog *dialog;
|
|
Packit |
79f644 |
GMainLoop *loop;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GtkWidget *cluebar;
|
|
Packit |
79f644 |
GtkWidget *cluebar_label;
|
|
Packit |
79f644 |
GtkWidget *connect_button;
|
|
Packit |
79f644 |
GtkWidget *progress_grid;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GtkWidget *principal;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gchar *account_object_path;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
} SignInRequest;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
translate_error (GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (!g_dbus_error_is_remote_error (*error))
|
|
Packit |
79f644 |
return;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_dbus_error_strip_remote_error (*error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
sign_in_identity (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
const char *identifier,
|
|
Packit |
79f644 |
const char *password,
|
|
Packit |
79f644 |
const char *preauth_source,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GAsyncReadyCallback callback,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *operation_result;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
operation_result = g_task_new (self, cancellable, callback, user_data);
|
|
Packit |
79f644 |
g_task_set_source_tag (operation_result, (gpointer) identifier);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_set_data (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"password",
|
|
Packit |
79f644 |
(gpointer)
|
|
Packit |
79f644 |
password);
|
|
Packit |
79f644 |
g_object_set_data_full (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"preauthentication-source",
|
|
Packit |
79f644 |
g_strdup (preauth_source),
|
|
Packit |
79f644 |
g_free);
|
|
Packit |
79f644 |
g_task_run_in_thread (operation_result, (GTaskThreadFunc) sign_in_thread);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (operation_result);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gchar *
|
|
Packit |
79f644 |
sign_in_identity_finish (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (self), NULL);
|
|
Packit |
79f644 |
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
|
Packit |
79f644 |
task = G_TASK (result);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_task_propagate_pointer (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
get_ticket_sync (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GoaObject *object,
|
|
Packit |
79f644 |
gboolean is_interactive,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GVariant *credentials = NULL;
|
|
Packit |
79f644 |
GError *lookup_error;
|
|
Packit |
79f644 |
GError *sign_in_error;
|
|
Packit |
79f644 |
GoaAccount *account;
|
|
Packit |
79f644 |
GoaTicketing *ticketing;
|
|
Packit |
79f644 |
GVariant *details;
|
|
Packit |
79f644 |
const char *identifier;
|
|
Packit |
79f644 |
const char *password;
|
|
Packit |
79f644 |
const char *preauth_source;
|
|
Packit |
79f644 |
char *object_path = NULL;
|
|
Packit |
79f644 |
gboolean ret = FALSE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
account = goa_object_get_account (object);
|
|
Packit |
79f644 |
identifier = goa_account_get_identity (account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ticketing = goa_object_get_ticketing (object);
|
|
Packit |
79f644 |
if (ticketing == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_set_error (error,
|
|
Packit |
79f644 |
GOA_ERROR,
|
|
Packit |
79f644 |
GOA_ERROR_NOT_SUPPORTED,
|
|
Packit |
79f644 |
_("Ticketing is disabled for account"));
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
details = goa_ticketing_get_details (ticketing);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
preauth_source = NULL;
|
|
Packit |
79f644 |
g_variant_lookup (details, "preauthentication-source", "&s", &preauth_source);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
password = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
lookup_error = NULL;
|
|
Packit |
79f644 |
credentials = goa_utils_lookup_credentials_sync (GOA_PROVIDER (self),
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
&lookup_error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (credentials == NULL && !is_interactive)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (lookup_error != NULL)
|
|
Packit |
79f644 |
g_propagate_error (error, lookup_error);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
g_set_error (error,
|
|
Packit |
79f644 |
GOA_ERROR,
|
|
Packit |
79f644 |
GOA_ERROR_NOT_AUTHORIZED,
|
|
Packit |
79f644 |
_("Could not find saved credentials for principal “%s” in keyring"), identifier);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else if (credentials != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
gboolean has_password;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
has_password = g_variant_lookup (credentials, "password", "&s", &password);
|
|
Packit |
79f644 |
if (!has_password && !is_interactive)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_set_error (error,
|
|
Packit |
79f644 |
GOA_ERROR,
|
|
Packit |
79f644 |
GOA_ERROR_NOT_AUTHORIZED,
|
|
Packit |
79f644 |
_("Did not find password for principal “%s” in credentials"),
|
|
Packit |
79f644 |
identifier);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
sign_in_error = NULL;
|
|
Packit |
79f644 |
object_path = sign_in_identity_sync (self,
|
|
Packit |
79f644 |
identifier,
|
|
Packit |
79f644 |
password,
|
|
Packit |
79f644 |
preauth_source,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
&sign_in_error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (sign_in_error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_propagate_error (error, sign_in_error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ret = TRUE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&account);
|
|
Packit |
79f644 |
g_clear_object (&ticketing);
|
|
Packit |
79f644 |
g_free (object_path);
|
|
Packit |
79f644 |
g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref);
|
|
Packit |
79f644 |
return ret;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
notify_is_temporary_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaAccount *account;
|
|
Packit |
79f644 |
gboolean is_temporary;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
account = GOA_ACCOUNT (object);
|
|
Packit |
79f644 |
is_temporary = goa_account_get_is_temporary (account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Toggle IsTemporary */
|
|
Packit |
79f644 |
goa_utils_keyfile_set_boolean (account, "IsTemporary", is_temporary);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Set/unset SessionId */
|
|
Packit |
79f644 |
if (is_temporary)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GDBusConnection *connection;
|
|
Packit |
79f644 |
const gchar *guid;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
connection = G_DBUS_CONNECTION (user_data);
|
|
Packit |
79f644 |
guid = g_dbus_connection_get_guid (connection);
|
|
Packit |
79f644 |
goa_utils_keyfile_set_string (account, "SessionId", guid);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
goa_utils_keyfile_remove_key (account, "SessionId");
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
on_handle_get_ticket (GoaTicketing *interface,
|
|
Packit |
79f644 |
GDBusMethodInvocation *invocation)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaObject *object;
|
|
Packit |
79f644 |
GoaAccount *account;
|
|
Packit |
79f644 |
GoaProvider *provider;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
gboolean got_ticket;
|
|
Packit |
79f644 |
const gchar *id;
|
|
Packit |
79f644 |
const gchar *method_name;
|
|
Packit |
79f644 |
const gchar *provider_type;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface)));
|
|
Packit |
79f644 |
account = goa_object_peek_account (object);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
id = goa_account_get_id (account);
|
|
Packit |
79f644 |
provider_type = goa_account_get_provider_type (account);
|
|
Packit |
79f644 |
method_name = g_dbus_method_invocation_get_method_name (invocation);
|
|
Packit |
79f644 |
g_debug ("Handling %s for account (%s, %s)", method_name, provider_type, id);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
provider = goa_provider_get_for_provider_type (provider_type);
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
got_ticket = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
TRUE /* Allow interaction */,
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
&error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!got_ticket)
|
|
Packit |
79f644 |
g_dbus_method_invocation_take_error (invocation, error);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
goa_ticketing_complete_get_ticket (interface, invocation);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (provider);
|
|
Packit |
79f644 |
return TRUE;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
build_object (GoaProvider *provider,
|
|
Packit |
79f644 |
GoaObjectSkeleton *object,
|
|
Packit |
79f644 |
GKeyFile *key_file,
|
|
Packit |
79f644 |
const gchar *group,
|
|
Packit |
79f644 |
GDBusConnection *connection,
|
|
Packit |
79f644 |
gboolean just_added,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaAccount *account;
|
|
Packit |
79f644 |
GoaTicketing *ticketing = NULL;
|
|
Packit |
79f644 |
gboolean ticketing_enabled;
|
|
Packit |
79f644 |
gboolean ret = FALSE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!GOA_PROVIDER_CLASS (goa_kerberos_provider_parent_class)->build_object (provider,
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
key_file,
|
|
Packit |
79f644 |
group,
|
|
Packit |
79f644 |
connection,
|
|
Packit |
79f644 |
just_added,
|
|
Packit |
79f644 |
error))
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
account = goa_object_get_account (GOA_OBJECT (object));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ticketing = goa_object_get_ticketing (GOA_OBJECT (object));
|
|
Packit |
79f644 |
ticketing_enabled = g_key_file_get_boolean (key_file, group, "TicketingEnabled", NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (ticketing_enabled)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (ticketing == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
char *preauthentication_source;
|
|
Packit |
79f644 |
GVariantBuilder details;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ticketing = goa_ticketing_skeleton_new ();
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_signal_connect (ticketing,
|
|
Packit |
79f644 |
"handle-get-ticket",
|
|
Packit |
79f644 |
G_CALLBACK (on_handle_get_ticket),
|
|
Packit |
79f644 |
NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_object_skeleton_set_ticketing (object, ticketing);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
preauthentication_source = g_key_file_get_string (key_file, group, "PreauthenticationSource", NULL);
|
|
Packit |
79f644 |
if (preauthentication_source)
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauthentication_source);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_set (G_OBJECT (ticketing), "details", g_variant_builder_end (&details), NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else if (ticketing != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
goa_object_skeleton_set_ticketing (object, NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (just_added)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
goa_account_set_ticketing_disabled (account, !ticketing_enabled);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_signal_connect (account,
|
|
Packit |
79f644 |
"notify::is-temporary",
|
|
Packit |
79f644 |
G_CALLBACK (notify_is_temporary_cb),
|
|
Packit |
79f644 |
connection);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_signal_connect (account,
|
|
Packit |
79f644 |
"notify::ticketing-disabled",
|
|
Packit |
79f644 |
G_CALLBACK (goa_util_account_notify_property_cb),
|
|
Packit |
79f644 |
(gpointer) "TicketingEnabled");
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ret = TRUE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&ticketing);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return ret;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
add_entry (GtkWidget *grid,
|
|
Packit |
79f644 |
gint row,
|
|
Packit |
79f644 |
const gchar *text,
|
|
Packit |
79f644 |
GtkWidget **out_entry)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GtkStyleContext *context;
|
|
Packit |
79f644 |
GtkWidget *label;
|
|
Packit |
79f644 |
GtkWidget *entry;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
label = gtk_label_new_with_mnemonic (text);
|
|
Packit |
79f644 |
context = gtk_widget_get_style_context (label);
|
|
Packit |
79f644 |
gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
|
|
Packit |
79f644 |
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
|
Packit |
79f644 |
gtk_widget_set_hexpand (label, TRUE);
|
|
Packit |
79f644 |
gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
entry = gtk_entry_new ();
|
|
Packit |
79f644 |
gtk_widget_set_hexpand (entry, TRUE);
|
|
Packit |
79f644 |
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
|
Packit |
79f644 |
gtk_grid_attach (GTK_GRID (grid), entry, 1, row, 3, 1);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
|
|
Packit |
79f644 |
if (out_entry != NULL)
|
|
Packit |
79f644 |
*out_entry = entry;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gchar *
|
|
Packit |
79f644 |
normalize_principal (const gchar *principal, gchar **out_realm)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
gchar *domain = NULL;
|
|
Packit |
79f644 |
gchar *realm = NULL;
|
|
Packit |
79f644 |
gchar *ret = NULL;
|
|
Packit |
79f644 |
gchar *username = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!goa_utils_parse_email_address (principal, &username, &domain))
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
realm = g_utf8_strup (domain, -1);
|
|
Packit |
79f644 |
ret = g_strconcat (username, "@", realm, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (out_realm != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
*out_realm = realm;
|
|
Packit |
79f644 |
realm = NULL;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_free (domain);
|
|
Packit |
79f644 |
g_free (realm);
|
|
Packit |
79f644 |
g_free (username);
|
|
Packit |
79f644 |
return ret;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_principal_changed (GtkEditable *editable, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
SignInRequest *request = user_data;
|
|
Packit |
79f644 |
gboolean can_add;
|
|
Packit |
79f644 |
const gchar *principal;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
principal = gtk_entry_get_text (GTK_ENTRY (request->principal));
|
|
Packit |
79f644 |
can_add = goa_utils_parse_email_address (principal, NULL, NULL);
|
|
Packit |
79f644 |
gtk_dialog_set_response_sensitive (request->dialog, GTK_RESPONSE_OK, can_add);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
show_progress_ui (GtkContainer *container, gboolean progress)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GList *children;
|
|
Packit |
79f644 |
GList *l;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
children = gtk_container_get_children (container);
|
|
Packit |
79f644 |
for (l = children; l != NULL; l = l->next)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GtkWidget *widget = GTK_WIDGET (l->data);
|
|
Packit |
79f644 |
gdouble opacity;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
opacity = progress ? 1.0 : 0.0;
|
|
Packit |
79f644 |
gtk_widget_set_opacity (widget, opacity);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_list_free (children);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
create_account_details_ui (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GtkDialog *dialog,
|
|
Packit |
79f644 |
GtkWidget *vbox,
|
|
Packit |
79f644 |
gboolean new_account,
|
|
Packit |
79f644 |
SignInRequest *request)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GtkWidget *grid0;
|
|
Packit |
79f644 |
GtkWidget *grid1;
|
|
Packit |
79f644 |
GtkWidget *label;
|
|
Packit |
79f644 |
GtkWidget *spinner;
|
|
Packit |
79f644 |
gint row;
|
|
Packit |
79f644 |
gint width;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_utils_set_dialog_title (GOA_PROVIDER (self), dialog, new_account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
grid0 = gtk_grid_new ();
|
|
Packit |
79f644 |
gtk_container_set_border_width (GTK_CONTAINER (grid0), 5);
|
|
Packit |
79f644 |
gtk_widget_set_margin_bottom (grid0, 6);
|
|
Packit |
79f644 |
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid0), GTK_ORIENTATION_VERTICAL);
|
|
Packit |
79f644 |
gtk_grid_set_row_spacing (GTK_GRID (grid0), 12);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (vbox), grid0);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
request->cluebar = gtk_info_bar_new ();
|
|
Packit |
79f644 |
gtk_info_bar_set_message_type (GTK_INFO_BAR (request->cluebar), GTK_MESSAGE_ERROR);
|
|
Packit |
79f644 |
gtk_widget_set_hexpand (request->cluebar, TRUE);
|
|
Packit |
79f644 |
gtk_widget_set_no_show_all (request->cluebar, TRUE);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (grid0), request->cluebar);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
request->cluebar_label = gtk_label_new ("");
|
|
Packit |
79f644 |
gtk_label_set_line_wrap (GTK_LABEL (request->cluebar_label), TRUE);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (request->cluebar))),
|
|
Packit |
79f644 |
request->cluebar_label);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
grid1 = gtk_grid_new ();
|
|
Packit |
79f644 |
gtk_grid_set_column_spacing (GTK_GRID (grid1), 12);
|
|
Packit |
79f644 |
gtk_grid_set_row_spacing (GTK_GRID (grid1), 12);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (grid0), grid1);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
row = 0;
|
|
Packit |
79f644 |
add_entry (grid1, row++, _("_Principal"), &request->principal);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_widget_grab_focus (request->principal);
|
|
Packit |
79f644 |
g_signal_connect (request->principal, "changed", G_CALLBACK (on_principal_changed), request);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_dialog_add_button (request->dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
|
|
Packit |
79f644 |
request->connect_button = gtk_dialog_add_button (request->dialog, _("C_onnect"), GTK_RESPONSE_OK);
|
|
Packit |
79f644 |
gtk_dialog_set_default_response (request->dialog, GTK_RESPONSE_OK);
|
|
Packit |
79f644 |
gtk_dialog_set_response_sensitive (request->dialog, GTK_RESPONSE_OK, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
request->progress_grid = gtk_grid_new ();
|
|
Packit |
79f644 |
gtk_orientable_set_orientation (GTK_ORIENTABLE (request->progress_grid), GTK_ORIENTATION_HORIZONTAL);
|
|
Packit |
79f644 |
gtk_grid_set_column_spacing (GTK_GRID (request->progress_grid), 3);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (grid0), request->progress_grid);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
spinner = gtk_spinner_new ();
|
|
Packit |
79f644 |
gtk_widget_set_opacity (spinner, 0.0);
|
|
Packit |
79f644 |
gtk_widget_set_size_request (spinner, 20, 20);
|
|
Packit |
79f644 |
gtk_spinner_start (GTK_SPINNER (spinner));
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (request->progress_grid), spinner);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
label = gtk_label_new (_("Connecting…"));
|
|
Packit |
79f644 |
gtk_widget_set_opacity (label, 0.0);
|
|
Packit |
79f644 |
gtk_container_add (GTK_CONTAINER (request->progress_grid), label);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_window_get_size (GTK_WINDOW (request->dialog), &width, NULL);
|
|
Packit |
79f644 |
gtk_window_set_default_size (GTK_WINDOW (request->dialog), width, -1);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
add_account_cb (GoaManager *manager,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
SignInRequest *request = user_data;
|
|
Packit |
79f644 |
goa_manager_call_add_account_finish (manager,
|
|
Packit |
79f644 |
&request->account_object_path,
|
|
Packit |
79f644 |
result,
|
|
Packit |
79f644 |
&request->error);
|
|
Packit |
79f644 |
if (request->error != NULL)
|
|
Packit |
79f644 |
translate_error (&request->error);
|
|
Packit |
79f644 |
g_main_loop_quit (request->loop);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request->connect_button, TRUE);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request->principal, TRUE);
|
|
Packit |
79f644 |
show_progress_ui (GTK_CONTAINER (request->progress_grid), FALSE);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
remove_account_cb (GoaAccount *account,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GMainLoop *loop)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
goa_account_call_remove_finish (account, result, NULL);
|
|
Packit |
79f644 |
g_main_loop_quit (loop);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
refresh_account (GoaProvider *provider,
|
|
Packit |
79f644 |
GoaClient *client,
|
|
Packit |
79f644 |
GoaObject *object,
|
|
Packit |
79f644 |
GtkWindow *parent,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
|
|
Packit |
79f644 |
gboolean got_ticket;
|
|
Packit |
79f644 |
GError *ticket_error = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (provider), FALSE);
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
|
|
Packit |
79f644 |
g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
|
|
Packit |
79f644 |
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
got_ticket = get_ticket_sync (self,
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
TRUE /* Allow interaction */,
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
&ticket_error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (ticket_error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
translate_error (&ticket_error);
|
|
Packit |
79f644 |
g_propagate_error (error, ticket_error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return got_ticket;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_initial_sign_in_done (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GTask *operation_result)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
gboolean remember_password;
|
|
Packit |
79f644 |
GoaObject *object;
|
|
Packit |
79f644 |
char *object_path;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
object = g_task_get_source_tag (operation_result);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
remember_password = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"remember-password"));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
object_path = sign_in_identity_finish (self, result, &error);
|
|
Packit |
79f644 |
if (error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (operation_result, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (remember_password)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GVariantBuilder builder;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (object_path != NULL && object != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GcrSecretExchange *secret_exchange;
|
|
Packit |
79f644 |
const char *password;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
secret_exchange = g_object_get_data (G_OBJECT (operation_result), "secret-exchange");
|
|
Packit |
79f644 |
password = gcr_secret_exchange_get_secret (secret_exchange, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* FIXME: we go to great lengths to keep the password in non-pageable memory,
|
|
Packit |
79f644 |
* and then just duplicate it into a gvariant here
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
|
Packit |
79f644 |
g_variant_builder_add (&builder,
|
|
Packit |
79f644 |
"{sv}",
|
|
Packit |
79f644 |
"password",
|
|
Packit |
79f644 |
g_variant_new_string (password));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (self),
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
g_variant_builder_end (&builder),
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_task_return_boolean (operation_result, TRUE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_free (object_path);
|
|
Packit |
79f644 |
g_object_unref (operation_result);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_system_prompt_answered_for_initial_sign_in (GcrPrompt *prompt,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GTask *operation_result)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaKerberosProvider *self;
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
const char *principal;
|
|
Packit |
79f644 |
const char *password;
|
|
Packit |
79f644 |
const char *preauth_source;
|
|
Packit |
79f644 |
GcrSecretExchange *secret_exchange;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
self = GOA_KERBEROS_PROVIDER (g_task_get_source_object (operation_result));
|
|
Packit |
79f644 |
principal = g_object_get_data (G_OBJECT (operation_result), "principal");
|
|
Packit |
79f644 |
cancellable = g_task_get_cancellable (operation_result);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* We currently don't prompt the user to choose a preauthentication source during initial sign in
|
|
Packit |
79f644 |
* so we assume there's no preauthentication source
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
preauth_source = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
password = gcr_prompt_password_finish (prompt, result, &error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (password == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
gcr_system_prompt_close (GCR_SYSTEM_PROMPT (prompt), NULL, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (operation_result, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_new_error (operation_result,
|
|
Packit |
79f644 |
G_IO_ERROR,
|
|
Packit |
79f644 |
G_IO_ERROR_CANCELLED,
|
|
Packit |
79f644 |
_("Operation was cancelled"));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (operation_result);
|
|
Packit |
79f644 |
return;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
secret_exchange = gcr_system_prompt_get_secret_exchange (GCR_SYSTEM_PROMPT (prompt));
|
|
Packit |
79f644 |
g_object_set_data_full (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"secret-exchange",
|
|
Packit |
79f644 |
g_object_ref (secret_exchange),
|
|
Packit |
79f644 |
(GDestroyNotify)
|
|
Packit |
79f644 |
g_object_unref);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_set_data (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"remember-password",
|
|
Packit |
79f644 |
GINT_TO_POINTER (gcr_prompt_get_choice_chosen (prompt)));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gcr_system_prompt_close (GCR_SYSTEM_PROMPT (prompt), NULL, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
sign_in_identity (self,
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
password,
|
|
Packit |
79f644 |
preauth_source,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
on_initial_sign_in_done,
|
|
Packit |
79f644 |
operation_result);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_system_prompt_open_for_initial_sign_in (GcrSystemPrompt *system_prompt,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GTask *operation_result)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
GcrPrompt *prompt = NULL;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
cancellable = g_task_get_cancellable (operation_result);
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
prompt = gcr_system_prompt_open_finish (result, &error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (prompt == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (operation_result, error);
|
|
Packit |
79f644 |
g_object_unref (operation_result);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gcr_prompt_set_title (prompt, _("Log In to Realm"));
|
|
Packit |
79f644 |
gcr_prompt_set_description (prompt, _("Please enter your password below."));
|
|
Packit |
79f644 |
gcr_prompt_set_choice_label (prompt, _("Remember this password"));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gcr_prompt_password_async (prompt,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
on_system_prompt_answered_for_initial_sign_in,
|
|
Packit |
79f644 |
operation_result);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&prompt);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
perform_initial_sign_in (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GoaObject *object,
|
|
Packit |
79f644 |
const char *principal,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GAsyncReadyCallback callback,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GTask *operation_result;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
operation_result = g_task_new (self, cancellable, callback, user_data);
|
|
Packit |
79f644 |
g_task_set_source_tag (operation_result, object);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_set_data (G_OBJECT (operation_result),
|
|
Packit |
79f644 |
"principal",
|
|
Packit |
79f644 |
(gpointer)
|
|
Packit |
79f644 |
principal);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gcr_system_prompt_open_async (-1,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
on_system_prompt_open_for_initial_sign_in,
|
|
Packit |
79f644 |
operation_result);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
perform_initial_sign_in_finish (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (self), FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
|
|
Packit |
79f644 |
task = G_TASK (result);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_task_propagate_boolean (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_account_signed_in (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
SignInRequest *request)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
perform_initial_sign_in_finish (self, result, &request->error);
|
|
Packit |
79f644 |
g_main_loop_quit (request->loop);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GoaObject *
|
|
Packit |
79f644 |
add_account (GoaProvider *provider,
|
|
Packit |
79f644 |
GoaClient *client,
|
|
Packit |
79f644 |
GtkDialog *dialog,
|
|
Packit |
79f644 |
GtkBox *vbox,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
|
|
Packit |
79f644 |
SignInRequest request;
|
|
Packit |
79f644 |
GVariantBuilder credentials;
|
|
Packit |
79f644 |
GVariantBuilder details;
|
|
Packit |
79f644 |
GoaObject *object = NULL;
|
|
Packit |
79f644 |
GoaAccount *account;
|
|
Packit |
79f644 |
char *realm = NULL;
|
|
Packit |
79f644 |
const char *principal_text;
|
|
Packit |
79f644 |
const char *provider_type;
|
|
Packit |
79f644 |
gchar *principal = NULL;
|
|
Packit |
79f644 |
gint response;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
memset (&request, 0, sizeof (SignInRequest));
|
|
Packit |
79f644 |
request.cancellable = g_cancellable_new ();
|
|
Packit |
79f644 |
request.loop = g_main_loop_new (NULL, FALSE);
|
|
Packit |
79f644 |
request.dialog = dialog;
|
|
Packit |
79f644 |
request.error = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
create_account_details_ui (self, dialog, GTK_WIDGET (vbox), TRUE, &request);
|
|
Packit |
79f644 |
gtk_widget_show_all (GTK_WIDGET (vbox));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
start_over:
|
|
Packit |
79f644 |
response = gtk_dialog_run (dialog);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (response != GTK_RESPONSE_OK)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_set_error (&request.error,
|
|
Packit |
79f644 |
GOA_ERROR,
|
|
Packit |
79f644 |
GOA_ERROR_DIALOG_DISMISSED,
|
|
Packit |
79f644 |
_("Dialog was dismissed"));
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
principal_text = gtk_entry_get_text (GTK_ENTRY (request.principal));
|
|
Packit |
79f644 |
principal = normalize_principal (principal_text, &realm;;
|
|
Packit |
79f644 |
gtk_entry_set_text (GTK_ENTRY (request.principal), principal);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* See if there's already an account of this type with the
|
|
Packit |
79f644 |
* given identity
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
provider_type = goa_provider_get_provider_type (provider);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!goa_utils_check_duplicate (client,
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
provider_type,
|
|
Packit |
79f644 |
(GoaPeekInterfaceFunc) goa_object_peek_account,
|
|
Packit |
79f644 |
&request.error))
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* If there isn't an account, then go ahead and create one
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "Realm", realm);
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "IsTemporary", "true");
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_manager_call_add_account (goa_client_get_manager (client),
|
|
Packit |
79f644 |
goa_provider_get_provider_type (provider),
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
g_variant_builder_end (&credentials),
|
|
Packit |
79f644 |
g_variant_builder_end (&details),
|
|
Packit |
79f644 |
NULL, /* GCancellable* */
|
|
Packit |
79f644 |
(GAsyncReadyCallback) add_account_cb,
|
|
Packit |
79f644 |
&request);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.connect_button, FALSE);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.principal, FALSE);
|
|
Packit |
79f644 |
show_progress_ui (GTK_CONTAINER (request.progress_grid), TRUE);
|
|
Packit |
79f644 |
g_main_loop_run (request.loop);
|
|
Packit |
79f644 |
if (request.error != NULL)
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
object = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
|
|
Packit |
79f644 |
request.account_object_path));
|
|
Packit |
79f644 |
account = goa_object_peek_account (object);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* After the account is created, try to sign it in
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
perform_initial_sign_in (self,
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
principal,
|
|
Packit |
79f644 |
request.cancellable,
|
|
Packit |
79f644 |
(GAsyncReadyCallback) on_account_signed_in,
|
|
Packit |
79f644 |
&request);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.connect_button, FALSE);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.principal, FALSE);
|
|
Packit |
79f644 |
show_progress_ui (GTK_CONTAINER (request.progress_grid), TRUE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_main_loop_run (request.loop);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.connect_button, TRUE);
|
|
Packit |
79f644 |
gtk_widget_set_sensitive (request.principal, TRUE);
|
|
Packit |
79f644 |
show_progress_ui (GTK_CONTAINER (request.progress_grid), FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (request.error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
gchar *markup;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
translate_error (&request.error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!g_error_matches (request.error,
|
|
Packit |
79f644 |
G_IO_ERROR,
|
|
Packit |
79f644 |
G_IO_ERROR_CANCELLED))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
markup = g_strdup_printf ("%s:\n%s",
|
|
Packit |
79f644 |
_("Error connecting to enterprise identity server"),
|
|
Packit |
79f644 |
request.error->message);
|
|
Packit |
79f644 |
gtk_label_set_markup (GTK_LABEL (request.cluebar_label), markup);
|
|
Packit |
79f644 |
g_free (markup);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_button_set_label (GTK_BUTTON (request.connect_button), _("_Try Again"));
|
|
Packit |
79f644 |
gtk_widget_set_no_show_all (request.cluebar, FALSE);
|
|
Packit |
79f644 |
gtk_widget_show_all (request.cluebar);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
g_clear_error (&request.error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* If it couldn't be signed in, then delete it and start over
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
goa_account_call_remove (account,
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
remove_account_cb,
|
|
Packit |
79f644 |
request.loop);
|
|
Packit |
79f644 |
g_main_loop_run (request.loop);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_clear_object (&object);
|
|
Packit |
79f644 |
g_clear_pointer (&principal, g_free);
|
|
Packit |
79f644 |
g_clear_pointer (&realm, g_free);
|
|
Packit |
79f644 |
g_clear_pointer (&request.account_object_path, g_free);
|
|
Packit |
79f644 |
goto start_over;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_account_set_is_temporary (account, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gtk_widget_hide (GTK_WIDGET (dialog));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
/* We might have an object even when request.error is set.
|
|
Packit |
79f644 |
* eg., if we failed to store the credentials in the keyring.
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
if (request.error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
translate_error (&request.error);
|
|
Packit |
79f644 |
g_propagate_error (error, request.error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
g_assert (object != NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_free (request.account_object_path);
|
|
Packit |
79f644 |
g_free (principal);
|
|
Packit |
79f644 |
g_free (realm);
|
|
Packit |
79f644 |
g_clear_pointer (&request.loop, (GDestroyNotify) g_main_loop_unref);
|
|
Packit |
79f644 |
g_clear_object (&request.cancellable);
|
|
Packit |
79f644 |
return object;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
dbus_proxy_reload_properties_sync (GDBusProxy *proxy,
|
|
Packit |
79f644 |
GCancellable *cancellable)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GVariant *result = NULL;
|
|
Packit |
79f644 |
char *name;
|
|
Packit |
79f644 |
char *name_owner = NULL;
|
|
Packit |
79f644 |
GVariant *value;
|
|
Packit |
79f644 |
GVariantIter *iter = NULL;
|
|
Packit |
79f644 |
gboolean ret = FALSE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
name_owner = g_dbus_proxy_get_name_owner (proxy);
|
|
Packit |
79f644 |
result = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (proxy),
|
|
Packit |
79f644 |
name_owner,
|
|
Packit |
79f644 |
g_dbus_proxy_get_object_path (proxy),
|
|
Packit |
79f644 |
"org.freedesktop.DBus.Properties",
|
|
Packit |
79f644 |
"GetAll",
|
|
Packit |
79f644 |
g_variant_new ("(s)", g_dbus_proxy_get_interface_name (proxy)),
|
|
Packit |
79f644 |
G_VARIANT_TYPE ("(a{sv})"),
|
|
Packit |
79f644 |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit |
79f644 |
-1,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
NULL);
|
|
Packit |
79f644 |
if (result == NULL)
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_variant_get (result, "(a{sv})", &iter);
|
|
Packit |
79f644 |
while (g_variant_iter_next (iter, "{sv}", &name, &value))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_dbus_proxy_set_cached_property (proxy, name, value);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_free (name);
|
|
Packit |
79f644 |
g_variant_unref (value);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ret = TRUE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_pointer (&iter, (GDestroyNotify) g_variant_iter_free);
|
|
Packit |
79f644 |
g_clear_pointer (&result, (GDestroyNotify) g_variant_unref);
|
|
Packit |
79f644 |
g_free (name_owner);
|
|
Packit |
79f644 |
return ret;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
ensure_credentials_sync (GoaProvider *provider,
|
|
Packit |
79f644 |
GoaObject *object,
|
|
Packit |
79f644 |
gint *out_expires_in,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaIdentityServiceIdentity *identity = NULL;
|
|
Packit |
79f644 |
GoaAccount *account = NULL;
|
|
Packit |
79f644 |
const char *identifier;
|
|
Packit |
79f644 |
gint64 timestamp;
|
|
Packit |
79f644 |
GDateTime *now, *expiration_time;
|
|
Packit |
79f644 |
GTimeSpan time_span;
|
|
Packit |
79f644 |
gboolean credentials_ensured = FALSE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
account = goa_object_get_account (object);
|
|
Packit |
79f644 |
identifier = goa_account_get_identity (account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ensure_identity_manager ();
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
identity = get_identity_from_object_manager (GOA_KERBEROS_PROVIDER (provider),
|
|
Packit |
79f644 |
identifier);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (identity != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (!dbus_proxy_reload_properties_sync (G_DBUS_PROXY (identity), cancellable))
|
|
Packit |
79f644 |
g_clear_object (&identity);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (identity == NULL || !goa_identity_service_identity_get_is_signed_in (identity))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError *lookup_error;
|
|
Packit |
79f644 |
gboolean ticket_synced;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
lookup_error = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
ticket_synced = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
|
|
Packit |
79f644 |
object,
|
|
Packit |
79f644 |
FALSE /* Don't allow interaction */,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
&lookup_error);
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!ticket_synced)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
translate_error (&lookup_error);
|
|
Packit |
79f644 |
g_set_error_literal (error,
|
|
Packit |
79f644 |
GOA_ERROR,
|
|
Packit |
79f644 |
GOA_ERROR_NOT_AUTHORIZED,
|
|
Packit |
79f644 |
lookup_error->message);
|
|
Packit |
79f644 |
g_error_free (lookup_error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (identity == NULL)
|
|
Packit |
79f644 |
identity = get_identity_from_object_manager (GOA_KERBEROS_PROVIDER (provider),
|
|
Packit |
79f644 |
identifier);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (identity == NULL)
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
dbus_proxy_reload_properties_sync (G_DBUS_PROXY (identity), cancellable);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
now = g_date_time_new_now_local ();
|
|
Packit |
79f644 |
timestamp = goa_identity_service_identity_get_expiration_timestamp (identity);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
expiration_time = g_date_time_new_from_unix_local (timestamp);
|
|
Packit |
79f644 |
time_span = g_date_time_difference (expiration_time, now);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
time_span /= G_TIME_SPAN_SECOND;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (time_span < 0 || time_span > G_MAXINT)
|
|
Packit |
79f644 |
time_span = 0;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (out_expires_in != NULL)
|
|
Packit |
79f644 |
*out_expires_in = (int) time_span;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
credentials_ensured = TRUE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_date_time_unref (now);
|
|
Packit |
79f644 |
g_date_time_unref (expiration_time);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&account);
|
|
Packit |
79f644 |
g_clear_object (&identity);
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
return credentials_ensured;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
remove_account_in_thread_func (GTask *task,
|
|
Packit |
79f644 |
gpointer source_object,
|
|
Packit |
79f644 |
gpointer task_data,
|
|
Packit |
79f644 |
GCancellable *cancellable)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
GoaAccount *account = NULL;
|
|
Packit |
79f644 |
GoaObject *object = GOA_OBJECT (task_data);
|
|
Packit |
79f644 |
const gchar *identifier;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ensure_identity_manager ();
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
account = goa_object_get_account (object);
|
|
Packit |
79f644 |
identifier = goa_account_get_identity (account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_debug ("Kerberos account %s removed and should now be signed out", identifier);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
if (!goa_identity_service_manager_call_sign_out_sync (identity_manager, identifier, cancellable, &error))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_task_return_boolean (task, TRUE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&account);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
remove_account (GoaProvider *provider,
|
|
Packit |
79f644 |
GoaObject *object,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GAsyncReadyCallback callback,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
task = g_task_new (self, cancellable, callback, user_data);
|
|
Packit |
79f644 |
g_task_set_source_tag (task, remove_account);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_task_set_task_data (task, g_object_ref (object), g_object_unref);
|
|
Packit |
79f644 |
g_task_run_in_thread (task, remove_account_in_thread_func);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (task);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
remove_account_finish (GoaProvider *provider,
|
|
Packit |
79f644 |
GAsyncResult *res,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
|
|
Packit |
79f644 |
task = G_TASK (res);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_get_source_tag (task) == remove_account, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_task_propagate_boolean (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static GoaIdentityServiceIdentity *
|
|
Packit |
79f644 |
get_identity_from_object_manager (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
const char *identifier)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaIdentityServiceIdentity *identity = NULL;
|
|
Packit |
79f644 |
GList *objects, *node;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
ensure_object_manager ();
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&object_manager_mutex);
|
|
Packit |
79f644 |
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
for (node = objects; node != NULL; node = node->next)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaIdentityServiceIdentity *candidate_identity;
|
|
Packit |
79f644 |
const char *candidate_identifier;
|
|
Packit |
79f644 |
GDBusObject *object;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
object = node->data;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (candidate_identity == NULL)
|
|
Packit |
79f644 |
continue;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (g_strcmp0 (candidate_identifier, identifier) == 0)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
identity = candidate_identity;
|
|
Packit |
79f644 |
break;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (candidate_identity);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_list_free_full (objects, (GDestroyNotify) g_object_unref);
|
|
Packit |
79f644 |
g_mutex_unlock (&object_manager_mutex);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return identity;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static char *
|
|
Packit |
79f644 |
sign_in_identity_sync (GoaKerberosProvider *self,
|
|
Packit |
79f644 |
const char *identifier,
|
|
Packit |
79f644 |
const char *password,
|
|
Packit |
79f644 |
const char *preauth_source,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GcrSecretExchange *secret_exchange;
|
|
Packit |
79f644 |
char *secret_key;
|
|
Packit |
79f644 |
char *return_key = NULL;
|
|
Packit |
79f644 |
char *concealed_secret;
|
|
Packit |
79f644 |
char *identity_object_path = NULL;
|
|
Packit |
79f644 |
gboolean keys_exchanged;
|
|
Packit |
79f644 |
GError *local_error;
|
|
Packit |
79f644 |
GVariantBuilder details;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
secret_exchange = gcr_secret_exchange_new (NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
secret_key = gcr_secret_exchange_begin (secret_exchange);
|
|
Packit |
79f644 |
ensure_identity_manager ();
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
keys_exchanged = goa_identity_service_manager_call_exchange_secret_keys_sync (identity_manager,
|
|
Packit |
79f644 |
identifier,
|
|
Packit |
79f644 |
secret_key,
|
|
Packit |
79f644 |
&return_key,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
error);
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
g_free (secret_key);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!keys_exchanged)
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (!gcr_secret_exchange_receive (secret_exchange, return_key))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_set_error (error,
|
|
Packit |
79f644 |
GCR_ERROR,
|
|
Packit |
79f644 |
GCR_ERROR_UNRECOGNIZED,
|
|
Packit |
79f644 |
_("Identity service returned invalid key"));
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
concealed_secret = gcr_secret_exchange_send (secret_exchange, password, -1);
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "initial-password", concealed_secret);
|
|
Packit |
79f644 |
g_free (concealed_secret);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (preauth_source != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauth_source);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
local_error = NULL;
|
|
Packit |
79f644 |
goa_identity_service_manager_call_sign_in_sync (identity_manager,
|
|
Packit |
79f644 |
identifier,
|
|
Packit |
79f644 |
g_variant_builder_end (&details),
|
|
Packit |
79f644 |
&identity_object_path,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
&local_error);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (local_error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (g_error_matches (local_error,
|
|
Packit |
79f644 |
GOA_IDENTITY_MANAGER_ERROR,
|
|
Packit |
79f644 |
GOA_IDENTITY_MANAGER_ERROR_ACCESSING_CREDENTIALS))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_assert_not_reached ();
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_propagate_error (error, local_error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_free (return_key);
|
|
Packit |
79f644 |
g_object_unref (secret_exchange);
|
|
Packit |
79f644 |
return identity_object_path;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
sign_in_thread (GTask *task,
|
|
Packit |
79f644 |
GoaKerberosProvider *self,
|
|
Packit |
79f644 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
79f644 |
GCancellable *cancellable)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
const char *identifier;
|
|
Packit |
79f644 |
const char *password;
|
|
Packit |
79f644 |
const char *preauth_source;
|
|
Packit |
79f644 |
char *object_path;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
identifier = g_task_get_source_tag (task);
|
|
Packit |
79f644 |
password = g_object_get_data (G_OBJECT (task), "password");
|
|
Packit |
79f644 |
preauth_source = g_object_get_data (G_OBJECT (task), "preauth-source");
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
object_path = sign_in_identity_sync (self, identifier, password, preauth_source, cancellable, &error);
|
|
Packit |
79f644 |
if (object_path == NULL)
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
g_task_return_pointer (task, object_path, NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_object_manager_created (gpointer object,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
gpointer unused G_GNUC_UNUSED)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GDBusObjectManager *manager;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
|
|
Packit |
79f644 |
if (manager == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("GoaKerberosProvider: Could not connect to identity service: %s", error->message);
|
|
Packit |
79f644 |
g_clear_error (&error);
|
|
Packit |
79f644 |
return;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&object_manager_mutex);
|
|
Packit |
79f644 |
object_manager = manager;
|
|
Packit |
79f644 |
g_cond_signal (&object_manager_condition);
|
|
Packit |
79f644 |
g_mutex_unlock (&object_manager_mutex);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
create_object_manager (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
|
|
Packit |
79f644 |
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
|
|
Packit |
79f644 |
"org.gnome.Identity",
|
|
Packit |
79f644 |
"/org/gnome/Identity",
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
on_object_manager_created,
|
|
Packit |
79f644 |
NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
ensure_object_manager (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_mutex_lock (&object_manager_mutex);
|
|
Packit |
79f644 |
while (object_manager == NULL)
|
|
Packit |
79f644 |
g_cond_wait (&object_manager_condition, &object_manager_mutex);
|
|
Packit |
79f644 |
g_mutex_unlock (&object_manager_mutex);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
on_identity_manager_created (gpointer identity,
|
|
Packit |
79f644 |
GAsyncResult *result,
|
|
Packit |
79f644 |
gpointer unused G_GNUC_UNUSED)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GoaIdentityServiceManager *manager;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
|
|
Packit |
79f644 |
if (manager == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("GoaKerberosProvider: Could not connect to identity service manager: %s", error->message);
|
|
Packit |
79f644 |
g_clear_error (&error);
|
|
Packit |
79f644 |
return;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
identity_manager = manager;
|
|
Packit |
79f644 |
g_cond_signal (&identity_manager_condition);
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
create_identity_manager (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
|
Packit |
79f644 |
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
|
|
Packit |
79f644 |
"org.gnome.Identity",
|
|
Packit |
79f644 |
"/org/gnome/Identity/Manager",
|
|
Packit |
79f644 |
NULL,
|
|
Packit |
79f644 |
(GAsyncReadyCallback)
|
|
Packit |
79f644 |
on_identity_manager_created,
|
|
Packit |
79f644 |
NULL);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
ensure_identity_manager (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_mutex_lock (&identity_manager_mutex);
|
|
Packit |
79f644 |
while (identity_manager == NULL)
|
|
Packit |
79f644 |
g_cond_wait (&identity_manager_condition, &identity_manager_mutex);
|
|
Packit |
79f644 |
g_mutex_unlock (&identity_manager_mutex);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
goa_kerberos_provider_init (GoaKerberosProvider *provider)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
goa_kerberos_provider_class_init (GoaKerberosProviderClass *kerberos_class)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
static volatile GQuark goa_identity_manager_error_domain = 0;
|
|
Packit |
79f644 |
GoaProviderClass *provider_class;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
provider_class = GOA_PROVIDER_CLASS (kerberos_class);
|
|
Packit |
79f644 |
provider_class->get_provider_type = get_provider_type;
|
|
Packit |
79f644 |
provider_class->get_provider_name = get_provider_name;
|
|
Packit |
79f644 |
provider_class->get_provider_group = get_provider_group;
|
|
Packit |
79f644 |
provider_class->get_provider_features = get_provider_features;
|
|
Packit |
79f644 |
provider_class->get_provider_icon = get_provider_icon;
|
|
Packit |
79f644 |
provider_class->build_object = build_object;
|
|
Packit |
79f644 |
provider_class->add_account = add_account;
|
|
Packit |
79f644 |
provider_class->refresh_account = refresh_account;
|
|
Packit |
79f644 |
provider_class->ensure_credentials_sync = ensure_credentials_sync;
|
|
Packit |
79f644 |
provider_class->remove_account = remove_account;
|
|
Packit |
79f644 |
provider_class->remove_account_finish = remove_account_finish;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* this will force associating errors in the
|
|
Packit |
79f644 |
* GOA_IDENTITY_MANAGER_ERROR error domain with
|
|
Packit |
79f644 |
* org.gnome.Identity.Manager.Error.* errors via
|
|
Packit |
79f644 |
* g_dbus_error_register_error_domain().
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
goa_identity_manager_error_domain = GOA_IDENTITY_MANAGER_ERROR;
|
|
Packit |
79f644 |
goa_identity_manager_error_domain; /* shut up -Wunused-but-set-variable */
|
|
Packit |
79f644 |
}
|