[gnome-online-accounts/wip/kerberos: 5/5] stuff that needs to be squashed
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/wip/kerberos: 5/5] stuff that needs to be squashed
- Date: Fri, 17 Aug 2012 04:44:17 +0000 (UTC)
commit 2d6edc4140c4e7fa753b338657faaa49e298b86f
Author: Ray Strode <rstrode redhat com>
Date: Wed Aug 15 19:48:26 2012 -0400
stuff that needs to be squashed
data/dbus-interfaces.xml | 7 +
src/Makefile.am | 2 +-
src/goabackend/Makefile.am | 19 +-
src/goabackend/goakerberosprovider.c | 1226 ++++++++++++++++++++------
src/goabackend/org.gnome.Identity.xml | 73 --
src/goaidentity/Makefile.am | 2 +
src/goaidentity/goaalarm.c | 25 +-
src/goaidentity/goaidentity.c | 6 -
src/goaidentity/goaidentity.h | 3 +-
src/goaidentity/goaidentityservice.c | 1002 ++++++++++++---------
src/goaidentity/goaidentityutils.c | 4 +-
src/goaidentity/goaidentityutils.h | 4 +-
src/goaidentity/goakerberosidentity.c | 190 ++---
src/goaidentity/goakerberosidentitymanager.c | 11 +-
src/goaidentity/org.gnome.Identity.xml | 17 +
15 files changed, 1643 insertions(+), 948 deletions(-)
---
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
index 07aac04..c58aed0 100644
--- a/data/dbus-interfaces.xml
+++ b/data/dbus-interfaces.xml
@@ -486,6 +486,13 @@
ticketing capabilities.
-->
<interface name="org.gnome.OnlineAccounts.Ticketing">
+ <!--
+ GetTicket:
+
+ Use this method to obtain an ticket that can be used to
+ access resources for the account.
+ -->
+ <method name="GetTicket"/>
</interface>
</node>
diff --git a/src/Makefile.am b/src/Makefile.am
index 21cf4e5..63a20e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
NULL =
-SUBDIRS = goa goabackend goaidentity daemon examples
+SUBDIRS = goa goaidentity goabackend daemon examples
-include $(top_srcdir)/git.mk
diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am
index b9d607f..ad608bd 100644
--- a/src/goabackend/Makefile.am
+++ b/src/goabackend/Makefile.am
@@ -6,6 +6,7 @@ EXTRA_DIST =
INCLUDES = \
-I$(top_builddir)/src -I$(top_srcdir)/src \
-I$(top_builddir)/src -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/goaidentity \
-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
@@ -35,19 +36,6 @@ enum_built_sources = \
EXTRA_DIST += goabackendenumtypes.h.template goabackendenumtypes.c.template
-dbus_built_sources = org.gnome.Identity.c org.gnome.Identity.h
-
-$(dbus_built_sources) : Makefile.am org.gnome.Identity.xml
- gdbus-codegen \
- --interface-prefix org.gnome.Identity. \
- --c-namespace GoaIdentity \
- --c-generate-object-manager \
- --generate-c-code org.gnome.Identity \
- org.gnome.Identity.xml \
- $(NULL)
-
-EXTRA_DIST += $(dbus_built_sources)
-
# ----------------------------------------------------------------------------------------------------
lib_LTLIBRARIES = libgoa-backend-1.0.la
@@ -71,7 +59,6 @@ libgoa_backend_1_0_la_HEADERS = \
goayahooprovider.h \
goatwitterprovider.h \
goawindowsliveprovider.h \
- org.gnome.Identity.h \
$(NULL)
libgoa_backend_1_0_la_SOURCES = \
@@ -95,7 +82,7 @@ libgoa_backend_1_0_la_SOURCES = \
goautils.h goautils.c \
goawebview.h goawebview.c \
nautilus-floating-bar.h nautilus-floating-bar.c \
- org.gnome.Identity.c org.gnome.Identity.h \
+ $(top_srcdir)/src/goaidentity/org.gnome.Identity.c \
$(NULL)
libgoa_backend_1_0_la_CPPFLAGS = \
@@ -107,6 +94,7 @@ libgoa_backend_1_0_la_CFLAGS = \
-DGOA_API_IS_SUBJECT_TO_CHANGE \
$(WEBKIT_GTK_CFLAGS) \
$(JSON_GLIB_CFLAGS) \
+ $(GCR_CFLAGS) \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS) \
$(REST_CFLAGS) \
@@ -119,6 +107,7 @@ libgoa_backend_1_0_la_LIBADD = \
$(top_builddir)/src/goa/libgoa-1.0.la \
$(WEBKIT_GTK_LIBS) \
$(JSON_GLIB_LIBS) \
+ $(GCR_LIBS) \
$(GLIB_LIBS) \
$(GTK_LIBS) \
$(REST_LIBS) \
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
index 1b8b75b..edf3088 100644
--- a/src/goabackend/goakerberosprovider.c
+++ b/src/goabackend/goakerberosprovider.c
@@ -29,6 +29,9 @@
#include "goakerberosprovider.h"
#include "goaeditablelabel.h"
#include "goautils.h"
+#include "goaidentity.h"
+
+#include <gcr/gcr.h>
#include "org.gnome.Identity.h"
@@ -42,7 +45,8 @@ struct _GoaKerberosProvider
{
/*< private >*/
GoaProvider parent_instance;
- GoaIdentityManager *identity_manager;
+ GoaIdentityServiceManager *identity_manager;
+ GDBusObjectManager *object_manager;
};
typedef struct _GoaKerberosProviderClass GoaKerberosProviderClass;
@@ -78,6 +82,620 @@ get_provider_name (GoaProvider *provider, GoaObject *object)
return g_strdup(_("Enterprise Identity"));
}
+typedef struct
+{
+ GtkDialog *dialog;
+ GMainLoop *loop;
+
+ GtkWidget *cluebar;
+ GtkWidget *cluebar_label;
+ GtkWidget *spinner;
+
+ GtkWidget *realm;
+
+ GtkWidget *expander;
+ GtkWidget *username;
+ GtkWidget *server;
+
+ gchar *account_object_path;
+
+ GError *error;
+} SignInRequest;
+
+static void
+on_identity_signed_in (GoaIdentityServiceManager *manager,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ gboolean signed_in;
+ GError *error;
+ char *identity_object_path;
+
+ error = NULL;
+ signed_in = goa_identity_service_manager_call_sign_in_finish (manager,
+ &identity_object_path,
+ result,
+ &error);
+
+ if (!signed_in)
+ {
+ /* FIXME: should do proper error matching here */
+ if (strstr (error->message, "ancel") != NULL)
+ {
+ g_clear_error (&error);
+ g_set_error_literal (&error,
+ GOA_ERROR,
+ GOA_ERROR_DIALOG_DISMISSED,
+ "");
+ }
+ else
+ g_dbus_error_strip_remote_error (error);
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_strdup (identity_object_path),
+ (GDestroyNotify)
+ g_free);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+on_identity_manager_ensured (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GoaIdentityServiceManager *manager;
+ GError *error;
+
+ error = NULL;
+ manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
+ if (manager == NULL)
+ {
+ g_dbus_error_strip_remote_error (error);
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_object_ref (manager),
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+ensure_identity_manager (GoaKerberosProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *operation_result;
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ ensure_identity_manager);
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+
+ if (self->identity_manager != NULL)
+ {
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_object_ref (self->identity_manager),
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.gnome.Identity",
+ "/org/gnome/Identity/Manager",
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_manager_ensured,
+ operation_result);
+}
+
+static void
+on_object_manager_ensured (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GDBusObjectManager *manager;
+ GError *error;
+
+ error = NULL;
+ manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
+ if (manager == NULL)
+ {
+ g_dbus_error_strip_remote_error (error);
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_object_ref (manager),
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+ensure_object_manager (GoaKerberosProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *operation_result;
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ ensure_object_manager);
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+
+ if (self->object_manager != NULL)
+ {
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_object_ref (self->object_manager),
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+ goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+ "org.gnome.Identity",
+ "/org/gnome/Identity",
+ cancellable,
+ (GAsyncReadyCallback)
+ on_object_manager_ensured,
+ operation_result);
+}
+
+static void
+on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ const char *identifier;
+ const char *password;
+ GCancellable *cancellable;
+ GError *error;
+ GVariantBuilder details;
+
+ error = NULL;
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+ password = g_object_get_data (G_OBJECT (operation_result), "password");
+ identifier = g_simple_async_result_get_source_tag (operation_result);
+
+ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+
+ if (password != NULL)
+ {
+ GcrSecretExchange *secret_exchange;
+ char *secret;
+
+ secret_exchange = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ secret = gcr_secret_exchange_send (secret_exchange, password, -1);
+ g_variant_builder_add (&details, "{ss}", "initial-password", secret);
+ g_free (secret);
+ }
+
+ goa_identity_service_manager_call_sign_in (self->identity_manager,
+ identifier,
+ g_variant_builder_end (&details),
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_signed_in,
+ operation_result);
+}
+
+static void
+on_secret_keys_exchanged (GoaIdentityServiceManager *manager,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GcrSecretExchange *secret_exchange;
+ char *return_key;
+ GError *error;
+
+ secret_exchange = g_simple_async_result_get_source_tag (operation_result);
+
+ error = NULL;
+ if (!goa_identity_service_manager_call_exchange_secret_keys_finish (manager,
+ &return_key,
+ result,
+ &error))
+ {
+ g_object_unref (secret_exchange);
+
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ if (!gcr_secret_exchange_receive (secret_exchange, return_key))
+ {
+ g_object_unref (secret_exchange);
+
+ g_simple_async_result_set_error (operation_result,
+ GCR_ERROR,
+ GCR_ERROR_UNRECOGNIZED,
+ _("Identity service returned invalid key"));
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ secret_exchange,
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+exchange_secret_keys (GoaKerberosProvider *self,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+
+ GSimpleAsyncResult *operation_result;
+ GcrSecretExchange *secret_exchange;
+ char *secret_key;
+
+ secret_exchange = gcr_secret_exchange_new (NULL);
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ secret_exchange);
+
+ if (password == NULL)
+ {
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ NULL,
+ NULL);
+ return;
+ }
+
+ secret_key = gcr_secret_exchange_begin (secret_exchange);
+
+ goa_identity_service_manager_call_exchange_secret_keys (self->identity_manager,
+ secret_key,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_secret_keys_exchanged,
+ operation_result);
+ g_free (secret_key);
+}
+
+static void
+on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GoaIdentityServiceManager *manager;
+ const char *password;
+ GCancellable *cancellable;
+ GError *error;
+
+ error = NULL;
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ if (self->identity_manager == NULL)
+ self->identity_manager = g_object_ref (manager);
+
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+ password = g_object_get_data (G_OBJECT (operation_result), "password");
+
+ exchange_secret_keys (self,
+ password,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_secret_keys_exchanged_for_sign_in,
+ operation_result);
+}
+
+static void
+sign_in_identity (GoaKerberosProvider *self,
+ const char *identifier,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *operation_result;
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ (gpointer)
+ identifier);
+
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+ g_object_set_data (G_OBJECT (operation_result),
+ "password",
+ (gpointer)
+ password);
+
+ ensure_identity_manager (self,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_manager_ensured_for_sign_in,
+ operation_result);
+}
+
+static void
+on_object_manager_ensured_for_look_up (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GDBusObjectManager *manager;
+ const char *identifier;
+ GList *objects, *node;
+ GError *error;
+
+ error = NULL;
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ if (self->object_manager == NULL)
+ self->object_manager = g_object_ref (manager);
+
+ identifier = g_simple_async_result_get_source_tag (operation_result);
+
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ NULL,
+ NULL);
+ objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->object_manager));
+
+ for (node = objects; node != NULL; node = node->next)
+ {
+ GoaIdentityServiceIdentity *candidate_identity;
+ const char *candidate_identifier;
+ GDBusObject *object;
+
+ object = node->data;
+
+ candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
+
+ if (candidate_identity == NULL)
+ continue;
+
+ candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
+
+ if (g_strcmp0 (candidate_identifier, identifier) == 0)
+ {
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ candidate_identity,
+ (GDestroyNotify)
+ g_object_unref);
+ break;
+ }
+
+ g_object_unref (candidate_identity);
+ }
+
+ g_list_free_full (objects, (GDestroyNotify) g_object_unref);
+ g_simple_async_result_complete_in_idle (G_SIMPLE_ASYNC_RESULT (operation_result));
+ g_object_unref (operation_result);
+}
+
+static void
+look_up_identity (GoaKerberosProvider *self,
+ const char *identifier,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *operation_result;
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ (gpointer)
+ identifier);
+
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+ ensure_object_manager (self,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_object_manager_ensured_for_look_up,
+ operation_result);
+}
+
+static void
+on_account_signed_in (GoaProvider *provider,
+ GAsyncResult *result,
+ SignInRequest *request)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ &request->error))
+ {
+ g_main_loop_quit (request->loop);
+ return;
+ }
+
+ g_main_loop_quit (request->loop);
+}
+
+static gboolean
+get_ticket_sync (GoaKerberosProvider *self,
+ GoaObject *object,
+ gboolean is_interactive,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVariant *credentials;
+ GError *lookup_error;
+ GoaAccount *account;
+ const char *identifier;
+ const char *password;
+ SignInRequest request;
+ gboolean ret;
+
+ ret = FALSE;
+
+ account = goa_object_peek_account (object);
+ identifier = goa_account_get_identity (account);
+ password = NULL;
+
+ lookup_error = NULL;
+ credentials = goa_utils_lookup_credentials_sync (GOA_PROVIDER (self),
+ object,
+ cancellable,
+ &lookup_error);
+ if (!is_interactive)
+ {
+ if (credentials == NULL)
+ {
+ if (lookup_error != NULL)
+ g_propagate_error (error, lookup_error);
+ else
+ g_set_error (error,
+ GOA_ERROR,
+ GOA_ERROR_NOT_AUTHORIZED,
+ _("Could not find saved credentials for principal `%s' in keyring"), identifier);
+ goto out;
+ }
+
+ if (!g_variant_lookup (credentials, "password", "&s", &password))
+ {
+ g_set_error (error,
+ GOA_ERROR,
+ GOA_ERROR_NOT_AUTHORIZED,
+ _("Did not find password for principal `%s' in credentials"),
+ identifier);
+ goto out;
+ }
+ }
+
+ memset (&request, 0, sizeof (SignInRequest));
+ request.loop = g_main_loop_new (NULL, FALSE);
+ request.error = NULL;
+
+ sign_in_identity (self,
+ identifier,
+ password,
+ NULL,
+ (GAsyncReadyCallback)
+ on_account_signed_in,
+ &request);
+
+ g_main_loop_run (request.loop);
+ g_main_loop_unref (request.loop);
+
+ if (request.error != NULL)
+ {
+ g_propagate_error (error, request.error);
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+ if (credentials != NULL)
+ g_variant_unref (credentials);
+
+ return ret;
+}
+
+static gboolean
+on_handle_get_ticket (GoaTicketing *interface,
+ GDBusMethodInvocation *invocation)
+{
+ GoaObject *object;
+ GoaAccount *account;
+ GoaProvider *provider;
+ GError *error;
+ gboolean got_ticket;
+
+ object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface)));
+ account = goa_object_peek_account (object);
+
+ provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account));
+ error = NULL;
+ got_ticket = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
+ object,
+ TRUE /* Allow interaction */,
+ NULL,
+ &error);
+
+ if (!got_ticket)
+ g_dbus_method_invocation_take_error (invocation, error);
+ else
+ goa_ticketing_complete_get_ticket (interface, invocation);
+
+ g_object_unref (provider);
+ return TRUE;
+}
+
static gboolean
build_object (GoaProvider *provider,
GoaObjectSkeleton *object,
@@ -111,13 +729,19 @@ build_object (GoaProvider *provider,
if (ticketing == NULL)
{
ticketing = goa_ticketing_skeleton_new ();
+
+ g_signal_connect (ticketing,
+ "handle-get-ticket",
+ G_CALLBACK (on_handle_get_ticket),
+ NULL);
+
goa_object_skeleton_set_ticketing (object, ticketing);
+
}
}
- else
+ else if (ticketing != NULL)
{
- if (ticketing != NULL)
- goa_object_skeleton_set_ticketing (object, NULL);
+ goa_object_skeleton_set_ticketing (object, NULL);
}
if (just_added)
@@ -168,28 +792,10 @@ add_entry (GtkWidget *grid1,
*out_entry = entry;
}
-typedef struct
-{
- GtkDialog *dialog;
- GMainLoop *loop;
-
- GtkWidget *cluebar;
- GtkWidget *cluebar_label;
- GtkWidget *spinner;
-
- GtkWidget *realm;
-
- GtkWidget *expander;
- GtkWidget *username;
- GtkWidget *server;
-
- gchar *account_object_path;
-
- GError *error;
-} SignInRequest;
-
static void
-create_account_details_ui (GtkBox *vbox, gboolean new_account, SignInRequest *request)
+create_account_details_ui (GtkBox *vbox,
+ gboolean new_account,
+ SignInRequest *request)
{
GtkWidget *header_grid;
GtkWidget *grid1;
@@ -263,238 +869,209 @@ add_account_cb (GoaManager *manager, GAsyncResult *res, gpointer user_request)
&request->account_object_path,
res,
&request->error);
+ if (request->error != NULL)
+ g_dbus_error_strip_remote_error (request->error);
g_main_loop_quit (request->loop);
}
-static void
-on_identity_signed_in (GoaIdentityManager *manager,
- GAsyncResult *result,
- GSimpleAsyncResult *operation_result)
+static gboolean
+refresh_account (GoaProvider *provider,
+ GoaClient *client,
+ GoaObject *object,
+ GtkWindow *parent,
+ GError **error)
{
- gboolean signed_in;
- GError *error;
- char *identity_object_path;
-
- error = NULL;
- signed_in = goa_identity_manager_call_sign_in_finish (manager,
- &identity_object_path,
- result,
- &error);
+ GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
+ gboolean got_ticket;
- if (!signed_in)
- {
- g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete_in_idle (operation_result);
- return;
- }
+ g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (provider), FALSE);
+ g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
+ g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- g_simple_async_result_set_op_res_gpointer (operation_result,
- g_strdup (identity_object_path),
- (GDestroyNotify)
- g_free);
- g_simple_async_result_complete_in_idle (operation_result);
+ got_ticket = get_ticket_sync (self,
+ object,
+ TRUE /* Allow interaction */,
+ NULL,
+ error);
+ return got_ticket;
}
static void
-on_identity_manager_ensured (GoaKerberosProvider *self,
- GAsyncResult *result,
- GSimpleAsyncResult *operation_result)
+on_initial_sign_in_done (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
{
- GoaIdentityManager *manager;
- GError *error;
+ GError *error;
+ gboolean remember_password;
+ GoaObject *object;
+
+ object = g_simple_async_result_get_source_tag (operation_result);
+
+ remember_password = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (operation_result),
+ "remember-password"));
error = NULL;
- manager = goa_identity_manager_proxy_new_for_bus_finish (result, &error);
- if (manager == NULL)
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
{
g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete_in_idle (operation_result);
- return;
+ }
+ else if (remember_password)
+ {
+ GVariantBuilder builder;
+ const char *object_path;
+
+ object_path = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ if (object_path != NULL && object != NULL)
+ {
+ GcrSecretExchange *secret_exchange;
+ const char *password;
+
+ secret_exchange = g_object_get_data (G_OBJECT (operation_result), "secret-exchange");
+ password = gcr_secret_exchange_get_secret (secret_exchange, NULL);
+
+ /* FIXME: we go to great lengths to keep the password in non-pageable memory,
+ * and then just duplicate it into a gvariant here
+ */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "password",
+ g_variant_new_string (password));
+
+ error = NULL;
+ goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (self),
+ object,
+ g_variant_builder_end (&builder),
+ NULL,
+ NULL);
+ }
}
- g_simple_async_result_set_op_res_gpointer (operation_result,
- g_object_ref (manager),
- (GDestroyNotify)
- g_object_unref);
g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
}
static void
-ensure_identity_manager (GoaKerberosProvider *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+on_system_prompt_answered_for_initial_sign_in (GcrPrompt *prompt,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
{
- GSimpleAsyncResult *operation_result;
+ GoaKerberosProvider *self;
+ GCancellable *cancellable;
+ GError *error;
+ const char *principal;
+ const char *password;
+ GcrSecretExchange *secret_exchange;
- operation_result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- ensure_identity_manager);
- g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+ self = GOA_KERBEROS_PROVIDER (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ principal = g_object_get_data (G_OBJECT (operation_result), "principal");
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
- g_object_set_data (G_OBJECT (operation_result),
- "cancellable",
- cancellable);
+ error = NULL;
+ password = gcr_prompt_password_finish (prompt, result, &error);
- if (self->identity_manager != NULL)
+ if (password == NULL)
{
- g_simple_async_result_set_op_res_gpointer (operation_result,
- g_object_ref (self->identity_manager),
- (GDestroyNotify)
- g_object_unref);
+ if (error != NULL)
+ g_simple_async_result_take_error (operation_result, error);
+ else
+ g_cancellable_cancel (cancellable);
+
g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
return;
}
- goa_identity_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- "org.gnome.Identity",
- "/org/gnome/Identity/Manager",
- cancellable,
- (GAsyncReadyCallback)
- on_identity_manager_ensured,
- operation_result);
+ secret_exchange = gcr_system_prompt_get_secret_exchange (GCR_SYSTEM_PROMPT (prompt));
+ g_object_set_data_full (G_OBJECT (operation_result),
+ "secret-exchange",
+ g_object_ref (secret_exchange),
+ (GDestroyNotify)
+ g_object_unref);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "remember-password",
+ GINT_TO_POINTER (gcr_prompt_get_choice_chosen (prompt)));
+
+ gcr_system_prompt_close (GCR_SYSTEM_PROMPT (prompt), NULL, NULL);
+
+ sign_in_identity (self,
+ principal,
+ password,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_initial_sign_in_done,
+ operation_result);
}
static void
-on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
- GAsyncResult *result,
- GSimpleAsyncResult *operation_result)
+on_system_prompt_open_for_initial_sign_in (GcrSystemPrompt *system_prompt,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
{
- GoaIdentityManager *manager;
- const char *identity;
- const char *password;
- GCancellable *cancellable;
- GError *error;
- GVariantBuilder details;
+ GCancellable *cancellable;
+ GcrPrompt *prompt;
+ GError *error;
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
error = NULL;
+ prompt = gcr_system_prompt_open_finish (result, &error);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- &error))
+ if (prompt == NULL)
{
g_simple_async_result_take_error (operation_result, error);
+
g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+
return;
}
- manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
-
- if (self->identity_manager == NULL) {
- self->identity_manager = g_object_ref (manager);
- }
-
- cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
- password = g_object_get_data (G_OBJECT (operation_result), "password");
- identity = g_simple_async_result_get_source_tag (operation_result);
-
- g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
-
- if (password != NULL)
- g_variant_builder_add (&details, "{ss}", "initial-password", password);
+ gcr_prompt_set_description (prompt, _("Please enter your password below."));
+ gcr_prompt_set_choice_label (prompt, _("Remember this password"));
- goa_identity_manager_call_sign_in (self->identity_manager,
- identity,
- g_variant_builder_end (&details),
- cancellable,
- (GAsyncReadyCallback)
- on_identity_signed_in,
- operation_result);
+ gcr_prompt_password_async (prompt,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_system_prompt_answered_for_initial_sign_in,
+ operation_result);
}
static void
-sign_in_identity (GoaKerberosProvider *self,
- const char *identity,
- const char *password,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+perform_initial_sign_in (GoaKerberosProvider *self,
+ GoaObject *object,
+ const char *principal,
+ SignInRequest *request)
{
+
GSimpleAsyncResult *operation_result;
+ GCancellable *cancellable;
- operation_result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- (gpointer)
- identity);
+ cancellable = g_cancellable_new ();
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ (GAsyncReadyCallback)
+ on_account_signed_in ,
+ request,
+ object);
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
g_object_set_data (G_OBJECT (operation_result),
"cancellable",
cancellable);
g_object_set_data (G_OBJECT (operation_result),
- "password",
+ "principal",
(gpointer)
- password);
-
- ensure_identity_manager (self,
- cancellable,
- (GAsyncReadyCallback)
- on_identity_manager_ensured_for_sign_in,
- operation_result);
-}
-
-static void
-on_account_signed_in (GoaProvider *provider,
- GAsyncResult *result,
- SignInRequest *request)
-{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- &request->error))
- {
- g_main_loop_quit (request->loop);
- return;
- }
-
- g_main_loop_quit (request->loop);
-}
-
-static gboolean
-refresh_account (GoaProvider *provider,
- GoaClient *client,
- GoaObject *object,
- GtkWindow *parent,
- GError **error)
-{
- GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
- SignInRequest request;
- GoaAccount *account;
- const char *identity;
-
- g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (provider), FALSE);
- g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
- g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- account = goa_object_peek_account (object);
- identity = goa_account_get_identity (account);
-
- memset (&request, 0, sizeof (SignInRequest));
- request.loop = g_main_loop_new (NULL, FALSE);
- request.error = NULL;
-
- error = NULL;
- sign_in_identity (self,
- identity,
- NULL,
- NULL,
- (GAsyncReadyCallback)
- on_account_signed_in,
- &request);
-
- g_main_loop_run (request.loop);
- g_main_loop_unref (request.loop);
-
- if (request.error != NULL)
- {
- g_propagate_error (error, request.error);
- return FALSE;
- }
+ principal);
- return TRUE;
+ gcr_system_prompt_open_async (-1,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_system_prompt_open_for_initial_sign_in,
+ operation_result);
}
static GoaObject *
@@ -550,9 +1127,7 @@ start_over:
* given identity
*/
provider_type = goa_provider_get_provider_type (provider);
- /* FIXME: consider adding a new credentials interface for
- * kerberos
- */
+
if (!goa_utils_check_duplicate (client,
principal,
provider_type,
@@ -566,6 +1141,7 @@ start_over:
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
g_variant_builder_add (&details, "{ss}", "Realm", realm);
+ g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
g_free (principal_for_display);
principal_for_display = g_strdup_printf ("%s %s", username, realm);
@@ -592,13 +1168,7 @@ start_over:
/* After the account is created, try to sign it in
*/
- sign_in_identity (self,
- principal,
- NULL,
- NULL,
- (GAsyncReadyCallback)
- on_account_signed_in,
- &request);
+ perform_initial_sign_in (self, object, principal, &request);
g_main_loop_run (request.loop);
@@ -608,19 +1178,23 @@ start_over:
gchar *markup;
g_dbus_error_strip_remote_error (request.error);
- markup = g_strdup_printf ("<b>%s:</b> %s",
- _("Error connecting to enterperise identity server"),
- request.error->message);
- g_clear_error (&request.error);
-
- gtk_label_set_markup (GTK_LABEL (request.cluebar_label), markup);
- g_free (markup);
- button = gtk_dialog_get_widget_for_response (request.dialog, GTK_RESPONSE_OK);
- gtk_button_set_label (GTK_BUTTON (button), _("_Try Again"));
- gtk_expander_set_expanded (GTK_EXPANDER (request.expander), TRUE);
- gtk_widget_set_no_show_all (request.cluebar, FALSE);
- gtk_widget_show_all (request.cluebar);
+ if (strstr (request.error->message, "ancel") == NULL)
+ {
+ markup = g_strdup_printf ("<b>%s:</b> %s",
+ _("Error connecting to enterperise identity server"),
+ request.error->message);
+ g_clear_error (&request.error);
+
+ gtk_label_set_markup (GTK_LABEL (request.cluebar_label), markup);
+ g_free (markup);
+
+ button = gtk_dialog_get_widget_for_response (request.dialog, GTK_RESPONSE_OK);
+ gtk_button_set_label (GTK_BUTTON (button), _("_Try Again"));
+ gtk_expander_set_expanded (GTK_EXPANDER (request.expander), TRUE);
+ gtk_widget_set_no_show_all (request.cluebar, FALSE);
+ gtk_widget_show_all (request.cluebar);
+ }
/* If it couldn't be signed in, then delete it and start over
*/
@@ -668,6 +1242,111 @@ show_account (GoaProvider *provider,
_("Network Resources"));
}
+static void
+on_identity_looked_up (GoaKerberosProvider *provider,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+
+ GoaIdentityServiceIdentity *identity;
+ GError *error;
+
+ error = NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ if (identity != NULL)
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ g_object_ref (identity),
+ (GDestroyNotify)
+ g_object_unref);
+ else
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ NULL,
+ NULL);
+
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+on_identity_looked_up_to_ensure_credentials (GoaKerberosProvider *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+
+ GoaIdentityServiceIdentity *identity;
+ GError *error;
+ GoaObject *object;
+ GoaAccount *account;
+ const char *identifier;
+ GCancellable *cancellable;
+
+ error = NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ if (identity != NULL && goa_identity_service_identity_get_is_signed_in (identity))
+ {
+ g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+ g_object_ref (identity),
+ (GDestroyNotify)
+ g_object_unref);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ object = GOA_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+
+ if (!get_ticket_sync (self,
+ object,
+ FALSE /* Don't allow interaction */,
+ cancellable,
+ &error))
+ {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ account = goa_object_peek_account (object);
+ identifier = goa_account_get_identity (account);
+
+ look_up_identity (self,
+ identifier,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_looked_up,
+ operation_result);
+
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+on_credentials_ensured (GoaObject *object,
+ GAsyncResult *result,
+ GMainLoop *loop)
+{
+ g_main_loop_quit (loop);
+}
+
static gboolean
ensure_credentials_sync (GoaProvider *provider,
GoaObject *object,
@@ -675,73 +1354,66 @@ ensure_credentials_sync (GoaProvider *provider,
GCancellable *cancellable,
GError **error)
{
- GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
- GVariant *credentials;
- GoaAccount *account;
- const char *identity;
- const char *password;
- SignInRequest request;
- gboolean ret;
-
- ret = FALSE;
+ GoaIdentityServiceIdentity *identity;
+ GoaAccount *account;
+ const char *identifier;
+ GSimpleAsyncResult *operation_result;
+ GMainLoop *loop;
+ gint64 timestamp;
+ GDateTime *now, *expiration_time;
+ GTimeSpan time_span;
account = goa_object_peek_account (object);
- identity = goa_account_get_identity (account);
+ identifier = goa_account_get_identity (account);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ operation_result = g_simple_async_result_new (G_OBJECT (object),
+ (GAsyncReadyCallback)
+ on_credentials_ensured,
+ loop,
+ ensure_credentials_sync);
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
- credentials = goa_utils_lookup_credentials_sync (provider,
- object,
- cancellable,
- error);
- if (credentials == NULL)
- {
- if (error != NULL && *error == NULL)
- g_set_error (error,
- GOA_ERROR,
- GOA_ERROR_NOT_AUTHORIZED,
- _("Could not find saved credentials for principal `%s' in keyring"), identity);
- goto out;
- }
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+
+ g_object_ref (operation_result);
+ look_up_identity (GOA_KERBEROS_PROVIDER (provider),
+ identifier,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_looked_up_to_ensure_credentials,
+ operation_result);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
- if (!g_variant_lookup (credentials, "password", "&s", &password))
+ if (g_simple_async_result_propagate_error (operation_result, error))
{
- g_set_error (error,
- GOA_ERROR,
- GOA_ERROR_NOT_AUTHORIZED,
- _("Did not find password for principal `%s' in credentials"),
- identity);
- goto out;
+ g_object_unref (operation_result);
+ return FALSE;
}
- memset (&request, 0, sizeof (SignInRequest));
- request.loop = g_main_loop_new (NULL, FALSE);
- request.error = NULL;
+ identity = g_simple_async_result_get_op_res_gpointer (operation_result);
- error = NULL;
- sign_in_identity (self,
- identity,
- password,
+ now = g_date_time_new_now_local ();
+ timestamp = goa_identity_service_identity_get_expiration_timestamp (identity);
+ expiration_time = g_date_time_new_from_unix_local (timestamp);
+ time_span = g_date_time_difference (expiration_time, now);
- NULL,
- (GAsyncReadyCallback)
- on_account_signed_in,
- &request);
+ time_span /= G_TIME_SPAN_SECOND;
- g_main_loop_run (request.loop);
- g_main_loop_unref (request.loop);
+ if (time_span < 0 || time_span > G_MAXINT)
+ time_span = 0;
- if (request.error != NULL)
- {
- g_propagate_error (error, request.error);
- goto out;
- }
+ *out_expires_in = (int) time_span;
- *out_expires_in = -1;
- ret = TRUE;
-out:
- if (credentials != NULL)
- g_variant_unref (credentials);
+ g_date_time_unref (now);
+ g_date_time_unref (expiration_time);
+ g_object_unref (operation_result);
- return ret;
+ return TRUE;
}
static void
@@ -750,11 +1422,11 @@ goa_kerberos_provider_init (GoaKerberosProvider *provider)
}
static void
-goa_kerberos_provider_class_init (GoaKerberosProviderClass *klass)
+goa_kerberos_provider_class_init (GoaKerberosProviderClass *kerberos_class)
{
GoaProviderClass *provider_class;
- provider_class = GOA_PROVIDER_CLASS (klass);
+ provider_class = GOA_PROVIDER_CLASS (kerberos_class);
provider_class->get_provider_type = get_provider_type;
provider_class->get_provider_name = get_provider_name;
provider_class->build_object = build_object;
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
index 8fa4ad3..46f1c92 100644
--- a/src/goaidentity/Makefile.am
+++ b/src/goaidentity/Makefile.am
@@ -56,6 +56,8 @@ $(identity_dbus_built_sources) : Makefile.am org.gnome.Identity.xml
--c-generate-object-manager \
--generate-c-code org.gnome.Identity \
org.gnome.Identity.xml \
+ --annotate "org.gnome.Identity" \
+ "org.gtk.GDBus.C.Name" Identity \
$(NULL)
BUILT_SOURCES += $(identity_dbus_built_sources)
EXTRA_DIST += org.gnome.Identity.xml
diff --git a/src/goaidentity/goaalarm.c b/src/goaidentity/goaalarm.c
index 545a5ec..e28dd86 100644
--- a/src/goaidentity/goaalarm.c
+++ b/src/goaidentity/goaalarm.c
@@ -392,6 +392,7 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
struct itimerspec timer_spec;
int fd;
int result;
+ GSource *source;
static gboolean seen_before = FALSE;
if (!seen_before)
@@ -424,15 +425,16 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
self->priv->type = GOA_ALARM_TYPE_TIMER;
self->priv->timer.stream = g_unix_input_stream_new (fd, TRUE);
- self->priv->timer.source =
+ source =
g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM
(self->priv->timer.stream),
self->priv->cancellable);
+ self->priv->timer.source = source;
g_source_set_callback (self->priv->timer.source,
(GSourceFunc) on_timer_source_ready, self,
(GDestroyNotify) clear_timer_source_pointer);
g_source_attach (self->priv->timer.source, self->priv->context);
- g_source_unref (self->priv->timer.source);
+ g_source_unref (source);
return TRUE;
@@ -474,8 +476,9 @@ static void
schedule_wakeups_with_timeout_source (GoaAlarm *self)
{
GDateTime *now;
- GTimeSpan time_span;
- guint interval;
+ GSource *source;
+ GTimeSpan time_span;
+ guint interval;
self->priv->type = GOA_ALARM_TYPE_TIMEOUT;
@@ -492,14 +495,16 @@ schedule_wakeups_with_timeout_source (GoaAlarm *self)
*/
interval = MIN (interval, MAX_TIMEOUT_INTERVAL);
- self->priv->timeout.source = g_timeout_source_new (interval);
+ source = g_timeout_source_new (interval);
+
+ self->priv->timeout.source = source;
g_source_set_callback (self->priv->timeout.source,
(GSourceFunc)
on_timeout_source_ready,
self, (GDestroyNotify) clear_timeout_source_pointer);
g_source_attach (self->priv->timeout.source, self->priv->context);
- g_source_unref (self->priv->timeout.source);
+ g_source_unref (source);
}
static void
@@ -531,15 +536,19 @@ clear_immediate_wakeup_source_pointer (GoaAlarm *self)
static void
schedule_immediate_wakeup (GoaAlarm *self)
{
- self->priv->immediate_wakeup_source = g_idle_source_new ();
+ GSource *source;
+ source = g_idle_source_new ();
+
+ self->priv->immediate_wakeup_source = source;
g_source_set_callback (self->priv->immediate_wakeup_source,
(GSourceFunc)
on_immediate_wakeup_source_ready,
self,
(GDestroyNotify) clear_immediate_wakeup_source_pointer);
+
g_source_attach (self->priv->immediate_wakeup_source, self->priv->context);
- g_source_unref (self->priv->immediate_wakeup_source);
+ g_source_unref (source);
}
void
diff --git a/src/goaidentity/goaidentity.c b/src/goaidentity/goaidentity.c
index 03894e9..cf2f146 100644
--- a/src/goaidentity/goaidentity.c
+++ b/src/goaidentity/goaidentity.c
@@ -64,12 +64,6 @@ goa_identity_error_quark (void)
return error_quark;
}
-char **
-goa_identity_get_identifier_components (GoaIdentity *self)
-{
- return GOA_IDENTITY_GET_IFACE (self)->get_identifier_components (self);
-}
-
const char *
goa_identity_get_identifier (GoaIdentity *self)
{
diff --git a/src/goaidentity/goaidentity.h b/src/goaidentity/goaidentity.h
index 14fed36..acb4af1 100644
--- a/src/goaidentity/goaidentity.h
+++ b/src/goaidentity/goaidentity.h
@@ -41,7 +41,6 @@ struct _GoaIdentityInterface
GTypeInterface base_interface;
const char * (* get_identifier) (GoaIdentity *identity);
- char ** (* get_identifier_components) (GoaIdentity *identity);
gboolean (* is_signed_in) (GoaIdentity *identity);
};
@@ -57,6 +56,7 @@ typedef enum
GOA_IDENTITY_ERROR_SAVING_CREDENTIALS,
GOA_IDENTITY_ERROR_REMOVING_CREDENTIALS,
GOA_IDENTITY_ERROR_PARSING_IDENTIFIER,
+ GOA_IDENTITY_ERROR_USER_CANCELLED,
} GoaIdentityError;
typedef enum
@@ -71,7 +71,6 @@ GType goa_identity_get_type (void);
GQuark goa_identity_error_quark (void);
const char *goa_identity_get_identifier (GoaIdentity *identity);
-char **goa_identity_get_identifier_components (GoaIdentity *identity);
gboolean goa_identity_is_signed_in (GoaIdentity *identity);
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
index 0c66f24..f9034da 100644
--- a/src/goaidentity/goaidentityservice.c
+++ b/src/goaidentity/goaidentityservice.c
@@ -28,10 +28,10 @@
#include <glib-object.h>
#include <gio/gio.h>
-#include <libnotify/notify.h>
#include <gcr/gcr.h>
#include "goakerberosprovider.h"
+#include "goaidentityenumtypes.h"
#include "goaidentityutils.h"
#include "goakerberosidentitymanager.h"
@@ -46,16 +46,21 @@ struct _GoaIdentityServicePrivate
GoaClient *client;
GoaManager *accounts_manager;
+
+ GHashTable *watched_connections;
+ GHashTable *key_holders;
};
static void identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface);
-static void ask_to_sign_in (GoaIdentityService *self,
- GoaIdentity *identity,
- gconstpointer initial_password,
- GoaIdentitySignInFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+
+static void
+sign_in (GoaIdentityService *self,
+ const char *identifier,
+ gconstpointer initial_password,
+ GoaIdentitySignInFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
G_DEFINE_TYPE_WITH_CODE (GoaIdentityService,
goa_identity_service,
@@ -67,29 +72,17 @@ static char *
get_object_path_for_identity (GoaIdentityService *self,
GoaIdentity *identity)
{
- char **components;
- GString *object_path;
- int i;
-
- components = goa_identity_get_identifier_components (identity);
- object_path = g_string_new ("/org/gnome/Identity/Manager");
-
- for (i = 0; components[i] != NULL; i++)
- {
- char *escaped_component;
-
- g_string_append_c (object_path, '/');
- escaped_component = goa_identity_utils_escape_object_path_component (components[i],
- (gsize)
- strlen (components[i]));
-
- g_string_append (object_path, escaped_component);
+ const char *identifier;
+ char *escaped_identifier;
+ char *object_path;
- g_free (escaped_component);
- }
- g_strfreev (components);
+ identifier = goa_identity_get_identifier (identity);
+ escaped_identifier = goa_identity_utils_escape_object_path (identifier,
+ strlen (identifier));
+ object_path = g_strdup_printf ("/org/gnome/Identity/Identities/%s", escaped_identifier);
- return g_string_free (object_path, FALSE);
+ g_free (escaped_identifier);
+ return object_path;
}
static char *
@@ -101,20 +94,27 @@ export_identity (GoaIdentityService *self,
GDBusInterfaceSkeleton *interface;
object_path = get_object_path_for_identity (self, identity);
+
object = G_DBUS_OBJECT_SKELETON (goa_identity_service_object_skeleton_new (object_path));
- interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_org_gnome_identity_skeleton_new ());
+ interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_identity_skeleton_new ());
g_object_bind_property (G_OBJECT (identity),
"identifier",
G_OBJECT (interface),
"identifier",
- G_BINDING_DEFAULT);
+ G_BINDING_SYNC_CREATE);
g_object_bind_property (G_OBJECT (identity),
"expiration-timestamp",
G_OBJECT (interface),
"expiration-timestamp",
- G_BINDING_DEFAULT);
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (G_OBJECT (identity),
+ "is-signed-in",
+ G_OBJECT (interface),
+ "is-signed-in",
+ G_BINDING_SYNC_CREATE);
g_dbus_object_skeleton_add_interface (object, interface);
g_object_unref (interface);
@@ -132,6 +132,7 @@ unexport_identity (GoaIdentityService *self,
char *object_path;
object_path = get_object_path_for_identity (self, identity);
+
g_dbus_object_manager_server_unexport (self->priv->identity_object_manager_server,
object_path);
g_free (object_path);
@@ -164,45 +165,120 @@ on_sign_in_done (GoaIdentityService *self,
}
g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static GoaObject *
+find_object_with_principal (GoaIdentityService *self,
+ const char *principal,
+ gboolean must_be_enabled)
+{
+ GList *objects;
+ GList *node;
+ GoaObject *found_object;
+
+ objects = goa_client_get_accounts (self->priv->client);
+ found_object = NULL;
+ for (node = objects; node != NULL; node = node->next)
+ {
+ GoaObject *object = GOA_OBJECT (node->data);
+ GoaAccount *account;
+ const char *provider_type;
+ const char *account_identity;
+
+ account = goa_object_peek_account (object);
+
+ if (account == NULL)
+ continue;
+
+ provider_type = goa_account_get_provider_type (account);
+
+ if (g_strcmp0 (provider_type, "kerberos") != 0)
+ continue;
+
+ if (must_be_enabled)
+ {
+ GoaTicketing *ticketing;
+
+ ticketing = goa_object_peek_ticketing (object);
+
+ if (ticketing == NULL)
+ continue;
+ }
+
+ account_identity = goa_account_get_identity (account);
+
+ if (g_strcmp0 (account_identity, principal) == 0)
+ {
+ found_object = g_object_ref (object);
+ break;
+ }
+ }
+ g_list_free_full (objects, (GDestroyNotify) g_object_unref);
+
+ return found_object;
}
static void
-on_got_identity_for_sign_in (GoaIdentityManager *manager,
- GAsyncResult *result,
- GSimpleAsyncResult *operation_result)
+on_credentials_ensured (GoaAccount *account,
+ GAsyncResult *result,
+ GoaIdentityService *self)
{
- GoaIdentityService *self;
- GError *error;
- GoaIdentity *identity;
- char *password;
- GoaIdentitySignInFlags flags;
+ GError *error;
+ const char *account_identity;
+ int expires_in;
- error = NULL;
- identity = goa_identity_manager_get_identity_finish (manager, result, &error);
+ account_identity = goa_account_get_identity (account);
- if (error != NULL)
+ error = NULL;
+ if (!goa_account_call_ensure_credentials_finish (account,
+ &expires_in,
+ result,
+ &error))
{
- goa_debug ("GoaIdentityService: Identity could not be signed in: %s",
+ goa_debug ("GoaIdentityService: could not ensure credentials for account %s: %s",
+ account_identity,
error->message);
+ g_error_free (error);
return;
}
- self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ goa_debug ("GoaIdentityService: credentials for account %s ensured for %d seconds",
+ account_identity,
+ expires_in);
+}
+
+static gboolean
+should_ignore_object (GoaIdentityService *self,
+ GoaObject *object)
+{
+ GoaAccount *account;
+
+ account = goa_object_peek_account (object);
+
+ if (goa_account_get_ticketing_disabled (account))
+ return TRUE;
- password = g_object_get_data (G_OBJECT (result),
- "initial-password");
- flags = (GoaIdentitySignInFlags) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (result),
- "sign-in-flags"));
-
- ask_to_sign_in (self,
- identity,
- password,
- flags,
- NULL,
- (GAsyncReadyCallback)
- on_sign_in_done,
- operation_result);
+ return FALSE;
+}
+
+static void
+ensure_account_credentials (GoaIdentityService *self,
+ GoaObject *object)
+{
+
+ GoaAccount *account;
+
+ if (should_ignore_object (self, object))
+ return;
+
+ account = goa_object_peek_account (object);
+ goa_account_call_ensure_credentials (account,
+ NULL,
+ (GAsyncReadyCallback)
+ on_credentials_ensured,
+ self);
}
static void
@@ -211,6 +287,10 @@ on_sign_in_handled (GoaIdentityService *self,
GDBusMethodInvocation *invocation)
{
GError *error = NULL;
+ GoaObject *object;
+ char *principal;
+
+ principal = g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result));
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
{
@@ -225,6 +305,14 @@ on_sign_in_handled (GoaIdentityService *self,
invocation,
object_path);
}
+
+ object = find_object_with_principal (self, principal, TRUE);
+ g_free (principal);
+
+ if (object == NULL)
+ return;
+
+ ensure_account_credentials (self, object);
}
static void
@@ -241,13 +329,16 @@ read_sign_in_details (GoaIdentityServiceManager *manager,
g_variant_iter_init (&iter, details);
while (g_variant_iter_loop (&iter, "{ss}", &key, &value))
{
- if (g_strcmp0 (key, "initial-secret") == 0)
+ if (g_strcmp0 (key, "initial-password") == 0)
*secret_key = g_strdup (value);
- else if (g_strcmp0 (key, "disallow-renewal") == 0)
+ else if (g_strcmp0 (key, "disallow-renewal") == 0
+ && g_strcmp0 (value, "true") == 0)
*flags |= GOA_IDENTITY_SIGN_IN_FLAGS_DISALLOW_RENEWAL;
- else if (g_strcmp0 (key, "disallow-forwarding") == 0)
+ else if (g_strcmp0 (key, "disallow-forwarding") == 0
+ && g_strcmp0 (value, "true") == 0)
*flags |= GOA_IDENTITY_SIGN_IN_FLAGS_DISALLOW_FORWARDING;
- else if (g_strcmp0 (key, "disallow-proxying") == 0)
+ else if (g_strcmp0 (key, "disallow-proxying") == 0
+ && g_strcmp0 (value, "true") == 0)
*flags |= GOA_IDENTITY_SIGN_IN_FLAGS_DISALLOW_PROXYING;
}
}
@@ -259,51 +350,55 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
GVariant *details)
{
GoaIdentityService *self = GOA_IDENTITY_SERVICE (manager);
- GSimpleAsyncResult *result;
+ GSimpleAsyncResult *operation_result;
GoaIdentitySignInFlags flags;
char *secret_key;
+ gconstpointer initial_password;
+ GCancellable *cancellable;
secret_key = NULL;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- (GAsyncReadyCallback)
- on_sign_in_handled,
- g_object_ref (invocation),
- goa_identity_service_handle_sign_in);
+ initial_password = NULL;
read_sign_in_details (manager, details, &flags, &secret_key);
- g_object_set_data (G_OBJECT (result),
- "sign-in-flags",
- GUINT_TO_POINTER ((guint) flags));
-
if (secret_key != NULL)
{
- GcrSecretExchange *secret_exchange;
- gconstpointer initial_password;
+ GcrSecretExchange *secret_exchange;
- secret_exchange = gcr_secret_exchange_new (NULL);
+ secret_exchange = g_hash_table_lookup (self->priv->key_holders,
+ g_dbus_method_invocation_get_sender (invocation));
- g_object_weak_ref (G_OBJECT (result),
- (GWeakNotify)
- g_object_unref,
- secret_exchange);
+ if (secret_exchange == NULL)
+ {
+ g_free (secret_key);
+ g_dbus_method_invocation_return_error (invocation,
+ GOA_IDENTITY_MANAGER_ERROR,
+ GOA_IDENTITY_MANAGER_ERROR_ACCESSING_CREDENTIALS,
+ _("initial secret passed before secret key exchange"));
+ return TRUE;
+ }
gcr_secret_exchange_receive (secret_exchange, secret_key);
initial_password = gcr_secret_exchange_get_secret (secret_exchange, NULL);
-
- g_object_set_data (G_OBJECT (result),
- "initial-password",
- (gpointer)
- initial_password);
}
- goa_identity_manager_get_identity (self->priv->identity_manager,
- identifier,
- NULL,
- (GAsyncReadyCallback)
- on_got_identity_for_sign_in,
- result);
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ (GAsyncReadyCallback)
+ on_sign_in_handled,
+ g_object_ref (invocation),
+ g_strdup (identifier));
+
+ cancellable = g_cancellable_new ();
+ sign_in (self,
+ identifier,
+ initial_password,
+ flags,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_sign_in_done,
+ operation_result);
+ g_object_unref (cancellable);
+
return TRUE;
}
@@ -393,10 +488,138 @@ goa_identity_service_handle_sign_out (GoaIdentityServiceManager *manager,
}
static void
+on_secret_keys_exchanged (GoaIdentityService *self,
+ GAsyncResult *result)
+{
+ GDBusMethodInvocation *invocation;
+ GError *error;
+
+ invocation = g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result));
+
+ error = NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+ {
+ g_dbus_method_invocation_take_error (invocation, error);
+ }
+ else
+ {
+ const char *output_key;
+
+ output_key = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ goa_identity_service_manager_complete_exchange_secret_keys (GOA_IDENTITY_SERVICE_MANAGER (self),
+ invocation,
+ output_key);
+ }
+}
+
+static void
+on_caller_watched (GDBusConnection *connection,
+ const char *name,
+ const char *name_owner,
+ GSimpleAsyncResult *operation_result)
+{
+ GoaIdentityService *self;
+ GcrSecretExchange *secret_exchange;
+ const char *input_key;
+ char *output_key;
+
+ self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ input_key = g_object_get_data (G_OBJECT (operation_result), "input-key");
+
+ secret_exchange = gcr_secret_exchange_new (NULL);
+
+ if (!gcr_secret_exchange_receive (secret_exchange,
+ input_key))
+ {
+ g_simple_async_result_set_error (operation_result,
+ GCR_ERROR,
+ GCR_ERROR_UNRECOGNIZED,
+ _("Initial secret key is invalid"));
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_hash_table_insert (self->priv->key_holders,
+ g_strdup (name_owner),
+ secret_exchange);
+
+ output_key = gcr_secret_exchange_send (secret_exchange, NULL, 0);
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ output_key,
+ (GDestroyNotify)
+ g_free);
+ g_simple_async_result_complete_in_idle (operation_result);
+}
+
+static void
+on_caller_vanished (GDBusConnection *connection,
+ const char *name,
+ GSimpleAsyncResult *operation_result)
+{
+ GoaIdentityService *self;
+ GCancellable *cancellable;
+
+ self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+ g_cancellable_cancel (cancellable);
+
+ g_hash_table_remove (self->priv->watched_connections, name);
+ g_hash_table_remove (self->priv->key_holders, name);
+
+}
+
+static gboolean
+goa_identity_service_handle_exchange_secret_keys (GoaIdentityServiceManager *manager,
+ GDBusMethodInvocation *invocation,
+ const char *input_key)
+{
+ GoaIdentityService *self = GOA_IDENTITY_SERVICE (manager);
+ GSimpleAsyncResult *operation_result;
+ GCancellable *cancellable;
+ guint watch_id;
+ const char *sender;
+
+ cancellable = g_cancellable_new ();
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ (GAsyncReadyCallback)
+ on_secret_keys_exchanged,
+ NULL,
+ g_object_ref (invocation));
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+ g_object_set_data (G_OBJECT (operation_result), "cancellable", cancellable);
+
+ g_object_set_data_full (G_OBJECT (operation_result),
+ "input-key",
+ g_strdup (input_key),
+ (GDestroyNotify)
+ g_free);
+ sender = g_dbus_method_invocation_get_sender (invocation);
+ watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ sender,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback)
+ on_caller_watched,
+ (GBusNameVanishedCallback)
+ on_caller_vanished,
+ g_object_ref (operation_result),
+ (GDestroyNotify)
+ g_object_unref);
+ g_hash_table_insert (self->priv->watched_connections,
+ g_strdup (sender),
+ GUINT_TO_POINTER (watch_id));
+
+ return TRUE;
+}
+
+static void
identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface)
{
interface->handle_sign_in = goa_identity_service_handle_sign_in;
interface->handle_sign_out = goa_identity_service_handle_sign_out;
+ interface->handle_exchange_secret_keys = goa_identity_service_handle_exchange_secret_keys;
}
static void
@@ -407,6 +630,19 @@ goa_identity_service_init (GoaIdentityService *self)
GoaIdentityServicePrivate);
goa_debug ("GoaIdentityService: initializing");
+ self->priv->watched_connections = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)
+ g_free,
+ (GDestroyNotify)
+ g_bus_unwatch_name);
+
+ self->priv->key_holders = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)
+ g_free,
+ (GDestroyNotify)
+ g_object_unref);
}
static void
@@ -425,6 +661,8 @@ goa_identity_service_finalize (GObject *object)
g_clear_object (&self->priv->identity_manager);
g_clear_object (&self->priv->identity_object_manager_server);
+ g_clear_object (&self->priv->watched_connections);
+ g_clear_object (&self->priv->key_holders);
G_OBJECT_CLASS (goa_identity_service_parent_class)->finalize (object);
}
@@ -450,68 +688,6 @@ on_identity_renewed (GoaIdentityManager *manager,
goa_debug ("GoaIdentityService: identity renewed");
}
-static gboolean
-should_ignore_object (GoaIdentityService *self,
- GoaObject *object)
-{
- GoaAccount *account;
-
- account = goa_object_peek_account (object);
-
- if (goa_account_get_ticketing_disabled (account))
- return TRUE;
-
- return FALSE;
-}
-
-static GoaObject *
-find_object_with_principal (GoaIdentityService *self,
- const char *principal)
-{
- GList *objects;
- GList *node;
- GoaObject *found_object;
-
- objects = goa_client_get_accounts (self->priv->client);
-
- found_object = NULL;
- for (node = objects; node != NULL; node = node->next)
- {
- GoaObject *object = GOA_OBJECT (node->data);
- GoaAccount *account;
- GoaTicketing *ticketing;
- const char *provider_type;
- const char *account_identity;
-
- account = goa_object_peek_account (object);
-
- if (account == NULL)
- continue;
-
- provider_type = goa_account_get_provider_type (account);
-
- if (g_strcmp0 (provider_type, "kerberos") != 0)
- continue;
-
- ticketing = goa_object_peek_ticketing (object);
-
- if (ticketing == NULL)
- continue;
-
- account_identity = goa_account_get_identity (account);
-
- if (g_strcmp0 (account_identity, principal) == 0)
- {
- found_object = g_object_ref (object);
- break;
- }
- }
- g_list_free_full (objects, (GDestroyNotify) g_object_unref);
-
- return found_object;
-}
-
-
static void
on_identity_needs_renewal (GoaIdentityManager *identity_manager,
GoaIdentity *identity,
@@ -524,7 +700,7 @@ on_identity_needs_renewal (GoaIdentityManager *identity_manager,
goa_debug ("GoaIdentityService: identity %s needs renewal", principal);
- object = find_object_with_principal (self, principal);
+ object = find_object_with_principal (self, principal, TRUE);
if (object != NULL)
{
@@ -541,64 +717,10 @@ on_identity_needs_renewal (GoaIdentityManager *identity_manager,
self);
}
-typedef struct
-{
- GoaIdentityService *service;
- GoaIdentity *identity;
- gconstpointer initial_password;
- NotifyNotification *notification;
- GSimpleAsyncResult *result;
- GCancellable *cancellable;
- gulong refreshed_signal_id;
-
- GoaIdentitySignInFlags flags;
-} SignInRequest;
-
-static SignInRequest *
-sign_in_request_new (GoaIdentityService *service,
- GoaIdentity *identity,
- gconstpointer initial_password,
- GoaIdentitySignInFlags flags,
- NotifyNotification *notification,
- GSimpleAsyncResult *result,
- GCancellable *cancellable)
-{
- SignInRequest *request;
-
- request = g_slice_new0 (SignInRequest);
-
- request->service = service;
- request->identity = g_object_ref (identity);
- /* intentionally not dup'd, it's sitting in mlocked memory */
- request->initial_password = initial_password;
- request->flags = flags;
- request->notification = notification;
- request->result = result;
- request->cancellable = g_object_ref (cancellable);
-
- return request;
-}
-
-static void
-sign_in_request_free (SignInRequest *data)
-{
- GoaIdentityService *service = data->service;
-
- g_signal_handler_disconnect (service->priv->identity_manager,
- data->refreshed_signal_id);
- g_object_set_data (G_OBJECT (data->identity),
- "sign-in-request",
- NULL);
- g_clear_object (&data->identity);
- g_clear_object (&data->cancellable);
- g_clear_object (&data->result);
- g_slice_free (SignInRequest, data);
-}
-
static void
on_identity_signed_in (GoaIdentityManager *manager,
GAsyncResult *result,
- SignInRequest *request)
+ GSimpleAsyncResult *operation_result)
{
GError *error;
GoaIdentity *identity;
@@ -609,34 +731,63 @@ on_identity_signed_in (GoaIdentityManager *manager,
if (error != NULL)
{
goa_debug ("GoaIdentityService: could not sign in identity: %s",
- error->message);
- g_simple_async_result_take_error (request->result, error);
- g_simple_async_result_complete_in_idle (request->result);
- g_clear_object (&request->result);
- g_clear_object (&request->cancellable);
+ error->message);
+ g_simple_async_result_take_error (operation_result, error);
+ }
+ else
+ {
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ g_object_ref (identity),
+ (GDestroyNotify)
+ g_object_unref);
+ }
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+
+ goa_debug ("GoaIdentityService: identity signed in");
+}
+
+static void
+on_temporary_account_created_for_identity (GoaIdentityService *self,
+ GAsyncResult *result,
+ GoaIdentity *identity)
+{
+ GoaObject *object;
+ GError *error;
+
+ error = NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+ {
+ const char *identifier;
+
+ identifier = goa_identity_get_identifier (identity);
+ goa_debug ("Could not add temporary account for identity %s: %s",
+ identifier,
+ error->message);
+ g_error_free (error);
return;
}
- g_simple_async_result_set_op_res_gpointer (request->result,
- g_object_ref (identity),
- (GDestroyNotify)
- g_object_unref);
- g_simple_async_result_complete_in_idle (request->result);
- g_clear_object (&request->result);
- g_clear_object (&request->cancellable);
+ object = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- goa_debug ("GoaIdentityService: identity signed in");
+ if (object != NULL)
+ ensure_account_credentials (self, object);
}
static void
-on_account_created_for_identity (GoaManager *manager,
- GAsyncResult *result,
- GoaIdentityService *self)
+on_account_added (GoaManager *manager,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
{
+ GoaIdentityService *self;
+ GDBusObjectManager *object_manager;
char *object_path;
+ GoaObject *object;
GError *error;
+ self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
object_path = NULL;
+ object = NULL;
error = NULL;
if (!goa_manager_call_add_account_finish (manager,
@@ -644,37 +795,46 @@ on_account_created_for_identity (GoaManager *manager,
result,
&error))
{
- goa_debug ("Could not create account for identity: %s", error->message);
- g_error_free (error);
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
return;
}
- if (object_path != NULL)
+ if (object_path != NULL && object_path[0] != '\0')
{
goa_debug ("Created account for identity with object path %s", object_path);
+
+ object_manager = goa_client_get_object_manager (self->priv->client);
+ object = GOA_OBJECT (g_dbus_object_manager_get_object (object_manager,
+ object_path));
g_free (object_path);
}
+
+ if (object == NULL)
+ g_simple_async_result_set_op_res_gpointer (operation_result, NULL, NULL);
+ else
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ object,
+ (GDestroyNotify)
+ g_object_unref);
+
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
}
static void
-add_temporary_account_if_necessary (GoaIdentityService *self,
- GoaIdentity *identity)
+add_temporary_account (GoaIdentityService *self,
+ GoaIdentity *identity)
{
- char *realm;
- const char *principal;
- const char *principal_for_display;
- GoaObject *object;
- GVariantBuilder credentials;
- GVariantBuilder details;
+ char *realm;
+ const char *principal;
+ const char *principal_for_display;
+ GSimpleAsyncResult *operation_result;
+ GVariantBuilder credentials;
+ GVariantBuilder details;
principal = goa_identity_get_identifier (identity);
- object = find_object_with_principal (self, principal);
-
- if (object != NULL)
- {
- g_object_unref (object);
- return;
- }
goa_debug ("GoaIdentityService: adding temporary identity %s", principal);
@@ -690,6 +850,16 @@ add_temporary_account_if_necessary (GoaIdentityService *self,
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
g_variant_builder_add (&details, "{ss}", "Realm", realm);
g_variant_builder_add (&details, "{ss}", "IsPermanent", "false");
+ g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
+
+
+ goa_debug ("GoaIdentityService: asking to sign back in");
+
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ (GAsyncReadyCallback)
+ on_temporary_account_created_for_identity,
+ identity,
+ add_temporary_account);
goa_manager_call_add_account (self->priv->accounts_manager,
"kerberos",
@@ -699,8 +869,8 @@ add_temporary_account_if_necessary (GoaIdentityService *self,
g_variant_builder_end (&details),
NULL,
(GAsyncReadyCallback)
- on_account_created_for_identity,
- self);
+ on_account_added,
+ operation_result);
g_free (realm);
}
@@ -709,8 +879,16 @@ on_identity_added (GoaIdentityManager *identity_manager,
GoaIdentity *identity,
GoaIdentityService *self)
{
+ GoaObject *object;
+ const char *identifier;
+
export_identity (self, identity);
- add_temporary_account_if_necessary (self, identity);
+
+ identifier = goa_identity_get_identifier (identity);
+ object = find_object_with_principal (self, identifier, FALSE);
+
+ if (object == NULL)
+ add_temporary_account (self, identity);
}
static void
@@ -726,7 +904,16 @@ on_identity_refreshed (GoaIdentityManager *identity_manager,
GoaIdentity *identity,
GoaIdentityService *self)
{
- add_temporary_account_if_necessary (self, identity);
+ GoaObject *object;
+ const char *identifier;
+
+ identifier = goa_identity_get_identifier (identity);
+ object = find_object_with_principal (self, identifier, FALSE);
+
+ if (object == NULL)
+ add_temporary_account (self, identity);
+ else
+ ensure_account_credentials (self, object);
}
typedef struct
@@ -980,161 +1167,67 @@ on_identity_inquiry (GoaIdentityInquiry *inquiry,
gcr_system_prompt_open_async (-1,
cancellable,
(GAsyncReadyCallback)
- on_system_prompt_open, request);
-}
-
-static void
-on_sign_in_clicked (NotifyNotification *notification,
- const char *action_id,
- SignInRequest *request)
-{
- GoaIdentityService *self = request->service;
- GoaIdentity *identity = request->identity;
- const char *identifier;
-
- identifier = goa_identity_get_identifier (identity);
- goa_identity_manager_sign_identity_in (self->priv->identity_manager,
- identifier,
- request->initial_password,
- request->flags,
- (GoaIdentityInquiryFunc)
- on_identity_inquiry,
- self,
- request->cancellable,
- (GAsyncReadyCallback)
- on_identity_signed_in,
- request);
-}
-
-static void
-close_notification (GCancellable *cancellable,
- NotifyNotification *notification)
-{
- notify_notification_close (notification, NULL);
+ on_system_prompt_open,
+ request);
}
static void
cancel_sign_in (GoaIdentityManager *identity_manager,
GoaIdentity *identity,
- SignInRequest *data)
-{
- g_cancellable_cancel (data->cancellable);
- g_clear_object (&data->cancellable);
-}
-
-static void
-ask_to_sign_in (GoaIdentityService *self,
- GoaIdentity *identity,
- gconstpointer initial_password,
- GoaIdentitySignInFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ GSimpleAsyncResult *operation_result)
{
- NotifyNotification *notification;
- char *name;
- char *description;
- GSimpleAsyncResult *result;
- SignInRequest *request;
-
- if (cancellable == NULL)
- cancellable = g_cancellable_new ();
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- ask_to_sign_in);
- g_simple_async_result_set_check_cancellable (result, cancellable);
-
- request = g_object_get_data (G_OBJECT (identity), "sign-in-request");
-
- if (request != NULL)
- g_cancellable_cancel (request->cancellable);
+ GoaIdentity *operation_identity;
- goa_debug ("GoaIdentityService: asking to sign back in");
-
- name = goa_identity_manager_name_identity (self->priv->identity_manager, identity);
- if (goa_identity_is_signed_in (identity))
- {
- description =
- g_strdup_printf (_("The network realm %s will soon be inaccessible."),
- name);
- }
- else
+ operation_identity = g_simple_async_result_get_source_tag (operation_result);
+ if (operation_identity == identity)
{
- description = g_strdup_printf (_("The network realm %s is now inaccessible."),
- name);
- }
- g_free (name);
+ GCancellable *cancellable;
- notification = notify_notification_new (_("Realm Access"),
- description,
- "dialog-password-symbolic");
- g_free (description);
- notify_notification_set_app_name (notification, _("Network Realm"));
-
- request = sign_in_request_new (self,
- identity,
- initial_password,
- flags,
- notification,
- result,
- cancellable);
-
- g_object_set_data (G_OBJECT (identity),
- "sign-in-request",
- request);
-
- g_cancellable_connect (cancellable,
- G_CALLBACK (close_notification),
- notification,
- NULL);
-
- request->refreshed_signal_id =
- g_signal_connect (G_OBJECT (self->priv->identity_manager),
- "identity-refreshed",
- G_CALLBACK (cancel_sign_in),
- request);
-
- notify_notification_add_action (notification,
- "sign-in",
- _("Sign In"),
- (NotifyActionCallback)
- on_sign_in_clicked,
- request,
- (GFreeFunc)
- sign_in_request_free);
-
- notify_notification_show (notification, NULL);
+ cancellable = g_object_get_data (G_OBJECT (operation_result),
+ "cancellable");
+ g_cancellable_cancel (cancellable);
+ }
}
static void
-on_credentials_ensured (GoaAccount *account,
- GAsyncResult *result,
- GoaIdentityService *self)
+sign_in (GoaIdentityService *self,
+ const char *identifier,
+ gconstpointer initial_password,
+ GoaIdentitySignInFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- GError *error;
- const char *account_identity;
- int expires_in;
+ GSimpleAsyncResult *operation_result;
- account_identity = goa_account_get_identity (account);
+ goa_debug ("GoaIdentityService: asking to sign back in");
- error = NULL;
- if (!goa_account_call_ensure_credentials_finish (account,
- &expires_in,
- result,
- &error))
- {
- goa_debug ("GoaIdentityService: could not ensure credentials for account %s: %s",
- account_identity,
- error->message);
- g_error_free (error);
- return;
- }
+ operation_result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ sign_in);
+ g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+ g_object_set_data (G_OBJECT (operation_result),
+ "cancellable",
+ cancellable);
+ g_signal_connect_object (G_OBJECT (self->priv->identity_manager),
+ "identity-refreshed",
+ G_CALLBACK (cancel_sign_in),
+ operation_result,
+ 0);
- goa_debug ("GoaIdentityService: credentials for account %s ensured for %d seconds",
- account_identity,
- expires_in);
+ goa_identity_manager_sign_identity_in (self->priv->identity_manager,
+ identifier,
+ initial_password,
+ flags,
+ (GoaIdentityInquiryFunc)
+ on_identity_inquiry,
+ self,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_identity_signed_in,
+ operation_result);
}
static void
@@ -1144,26 +1237,17 @@ on_identity_expiring (GoaIdentityManager *identity_manager,
{
const char *principal;
GoaObject *object;
- GoaAccount *account;
principal = goa_identity_get_identifier (identity);
goa_debug ("GoaIdentityService: identity %s expiring", principal);
- object = find_object_with_principal (self, principal);
+ object = find_object_with_principal (self, principal, TRUE);
if (object == NULL)
return;
- if (should_ignore_object (self, object))
- return;
-
- account = goa_object_peek_account (object);
- goa_account_call_ensure_credentials (account,
- NULL,
- (GAsyncReadyCallback)
- on_credentials_ensured,
- self);
+ ensure_account_credentials (self, object);
}
static void
@@ -1173,27 +1257,17 @@ on_identity_expired (GoaIdentityManager *identity_manager,
{
const char *principal;
GoaObject *object;
- GoaAccount *account;
principal = goa_identity_get_identifier (identity);
goa_debug ("GoaIdentityService: identity %s expired", principal);
- object = find_object_with_principal (self, principal);
+ object = find_object_with_principal (self, principal, TRUE);
if (object == NULL)
return;
- if (should_ignore_object (self, object))
- return;
-
- account = goa_object_peek_account (object);
-
- goa_account_call_ensure_credentials (account,
- NULL,
- (GAsyncReadyCallback)
- on_credentials_ensured,
- self);
+ ensure_account_credentials (self, object);
}
static void
@@ -1214,6 +1288,32 @@ on_sign_out_for_account_change_done (GoaIdentityService *self,
}
static void
+on_get_ticket (GoaTicketing *ticketing,
+ GAsyncResult *result,
+ GoaAccount *account)
+{
+ GError *error;
+ const char *account_identity;
+
+ account_identity = goa_account_get_identity (account);
+
+ error = NULL;
+ if (!goa_ticketing_call_get_ticket_finish (ticketing,
+ result,
+ &error))
+ {
+ goa_debug ("GoaIdentityService: could not get ticket for account %s: %s",
+ account_identity,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ goa_debug ("GoaIdentityService: got ticket for account %s",
+ account_identity);
+}
+
+static void
on_account_interface_added (GDBusObjectManager *manager,
GoaObject *object,
GDBusInterface *interface,
@@ -1246,11 +1346,11 @@ on_account_interface_added (GDBusObjectManager *manager,
/* Ticketing interface is present, sign in if not already
* signed in.
*/
- goa_account_call_ensure_credentials (account,
- NULL,
- (GAsyncReadyCallback)
- on_credentials_ensured,
- self);
+ goa_ticketing_call_get_ticket (ticketing,
+ NULL,
+ (GAsyncReadyCallback)
+ on_get_ticket,
+ account);
return;
}
}
@@ -1355,7 +1455,6 @@ on_identities_listed (GoaIdentityManager *manager,
{
GError *error = NULL;
GList *identities, *node;
- GDBusObjectManager *object_manager;
g_signal_connect (G_OBJECT (self->priv->identity_manager),
"identity-added",
@@ -1387,17 +1486,6 @@ on_identities_listed (GoaIdentityManager *manager,
G_CALLBACK (on_account_removed),
self);
- object_manager = goa_client_get_object_manager (self->priv->client);
-
- g_signal_connect (G_OBJECT (object_manager),
- "interface-added",
- G_CALLBACK (on_account_interface_added),
- self);
- g_signal_connect (G_OBJECT (object_manager),
- "interface-removed",
- G_CALLBACK (on_account_interface_removed),
- self);
-
identities = goa_identity_manager_list_identities_finish (manager, result, &error);
if (identities == NULL)
@@ -1413,10 +1501,65 @@ on_identities_listed (GoaIdentityManager *manager,
for (node = identities; node != NULL; node = node->next)
{
GoaIdentity *identity = node->data;
+ const char *principal;
+ GoaObject *object;
+
+ export_identity (self, identity);
- add_temporary_account_if_necessary (self, identity);
+ principal = goa_identity_get_identifier (identity);
+ object = find_object_with_principal (self, principal, TRUE);
+
+ if (object == NULL)
+ add_temporary_account (self, identity);
+ else
+ g_object_unref (object);
}
+}
+
+static void
+ensure_credentials_for_accounts (GoaIdentityService *self)
+{
+ GDBusObjectManager *object_manager;
+ GList *accounts;
+ GList *node;
+
+ object_manager = goa_client_get_object_manager (self->priv->client);
+
+ g_signal_connect (G_OBJECT (object_manager),
+ "interface-added",
+ G_CALLBACK (on_account_interface_added),
+ self);
+ g_signal_connect (G_OBJECT (object_manager),
+ "interface-removed",
+ G_CALLBACK (on_account_interface_removed),
+ self);
+
+ accounts = goa_client_get_accounts (self->priv->client);
+
+ for (node = accounts; node != NULL; node = node->next)
+ {
+ GoaObject *object = GOA_OBJECT (node->data);
+ GoaAccount *account;
+ GoaTicketing *ticketing;
+ const char *provider_type;
+
+ account = goa_object_peek_account (object);
+ if (account == NULL)
+ continue;
+
+ provider_type = goa_account_get_provider_type (account);
+
+ if (g_strcmp0 (provider_type, "kerberos") != 0)
+ continue;
+
+ ticketing = goa_object_peek_ticketing (object);
+
+ if (ticketing == NULL)
+ continue;
+
+ ensure_account_credentials (self, object);
+ }
}
static void
@@ -1451,6 +1594,8 @@ on_got_client (GoaClient *client,
(GAsyncReadyCallback)
on_identities_listed,
self);
+
+ ensure_credentials_for_accounts (self);
}
static void
@@ -1551,6 +1696,9 @@ goa_identity_service_class_init (GoaIdentityServiceClass *service_class)
object_class->finalize = goa_identity_service_finalize;
+ goa_identity_utils_register_error_domain (GOA_IDENTITY_ERROR, GOA_TYPE_IDENTITY_ERROR);
+ goa_identity_utils_register_error_domain (GOA_IDENTITY_MANAGER_ERROR, GOA_TYPE_IDENTITY_MANAGER_ERROR);
+
g_type_class_add_private (service_class, sizeof (GoaIdentityServicePrivate));
}
diff --git a/src/goaidentity/goaidentityutils.c b/src/goaidentity/goaidentityutils.c
index 9cb8838..fb72916 100644
--- a/src/goaidentity/goaidentityutils.c
+++ b/src/goaidentity/goaidentityutils.c
@@ -32,8 +32,8 @@
#include <gio/gio.h>
char *
-goa_identity_utils_escape_object_path_component (const char *data,
- gsize length)
+goa_identity_utils_escape_object_path (const char *data,
+ gsize length)
{
const char *p;
char *object_path;
diff --git a/src/goaidentity/goaidentityutils.h b/src/goaidentity/goaidentityutils.h
index 9c4cd25..6840431 100644
--- a/src/goaidentity/goaidentityutils.h
+++ b/src/goaidentity/goaidentityutils.h
@@ -29,8 +29,8 @@
G_BEGIN_DECLS
-char *goa_identity_utils_escape_object_path_component (const char *data,
- gsize length);
+char *goa_identity_utils_escape_object_path (const char *data,
+ gsize length);
void goa_identity_utils_register_error_domain (GQuark error_domain,
GType error_enum);
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index a66ff63..dc3e9aa 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -47,8 +47,6 @@ struct _GoaKerberosIdentityPrivate
char *identifier;
guint identifier_idle_id;
- char **identifier_components;
-
krb5_timestamp expiration_time;
guint expiration_time_idle_id;
@@ -297,57 +295,6 @@ get_identifier (GoaKerberosIdentity *self,
return identifier;
}
-static char **
-get_identifier_components (GoaKerberosIdentity *self)
-{
- krb5_principal principal;
- krb5_error_code error_code;
- int size, i;
- GPtrArray *array;
-
- if (self->priv->identifier == NULL)
- return g_new0 (char *, 1);
-
- error_code = krb5_parse_name (self->priv->kerberos_context,
- self->priv->identifier,
- &principal);
-
- if (error_code != 0)
- {
- const char *error_message;
- error_message =
- krb5_get_error_message (self->priv->kerberos_context, error_code);
-
- goa_debug ("GoaKerberosIdentity: Error looking up principal "
- "identity in credential cache: %s",
- error_message);
- krb5_free_error_message (self->priv->kerberos_context, error_message);
- return g_new0 (char *, 1);
- }
-
- array = g_ptr_array_new ();
-
- g_ptr_array_add (array,
- g_strndup (principal->realm.data, principal->realm.length));
-
- size = krb5_princ_size (self->priv->kerberos_context, principal);
-
- for (i = 0; i < size; i++)
- {
- krb5_data *component;
- char *component_string;
-
- component = krb5_princ_component (self->priv->kerberos_context, principal, i);
-
- component_string = g_strndup (component->data, component->length);
- g_ptr_array_add (array, component_string);
-
- }
- g_ptr_array_add (array, NULL);
-
- return (char **) g_ptr_array_free (array, FALSE);
-}
-
static void
goa_kerberos_identity_init (GoaKerberosIdentity *self)
{
@@ -478,14 +425,6 @@ goa_kerberos_identity_get_identifier (GoaIdentity *identity)
return self->priv->identifier;
}
-static char **
-goa_kerberos_identity_get_identifier_components (GoaIdentity *identity)
-{
- GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (identity);
-
- return g_strdupv (self->priv->identifier_components);
-}
-
static gboolean
credentials_validate_existence (GoaKerberosIdentity *self,
krb5_principal principal, krb5_creds * credentials)
@@ -750,7 +689,6 @@ static void
identity_interface_init (GoaIdentityInterface *interface)
{
interface->get_identifier = goa_kerberos_identity_get_identifier;
- interface->get_identifier_components = goa_kerberos_identity_get_identifier_components;
interface->is_signed_in = goa_kerberos_identity_is_signed_in;
}
@@ -982,9 +920,6 @@ goa_kerberos_identity_initable_init (GInitable *initable,
queue_notify (self, &self->priv->identifier_idle_id, "identifier");
}
- if (self->priv->identifier_components == NULL)
- self->priv->identifier_components = get_identifier_components (self);
-
verification_error = NULL;
self->priv->cached_verification_level =
verify_identity (self, &verification_error);
@@ -1053,10 +988,11 @@ on_kerberos_inquiry (krb5_context kerberos_context,
operation->cancellable,
operation->inquiry_data);
+ if (!goa_identity_inquiry_is_complete (inquiry))
+ g_cancellable_cancel (operation->cancellable);
+
if (g_cancellable_is_cancelled (operation->cancellable))
error_code = KRB5_LIBOS_PWDINTR;
- else if (!goa_identity_inquiry_is_complete (inquiry))
- error_code = KRB5_LIBOS_PWDINTR;
else
error_code = 0;
@@ -1113,10 +1049,11 @@ out:
}
static SignInOperation *
-sign_in_operation_new (GoaKerberosIdentity *identity,
- GoaIdentityInquiryFunc inquiry_func,
- gpointer inquiry_data,
- GDestroyNotify destroy_notify, GCancellable *cancellable)
+sign_in_operation_new (GoaKerberosIdentity *identity,
+ GoaIdentityInquiryFunc inquiry_func,
+ gpointer inquiry_data,
+ GDestroyNotify destroy_notify,
+ GCancellable *cancellable)
{
SignInOperation *operation;
@@ -1144,14 +1081,15 @@ sign_in_operation_free (SignInOperation *operation)
}
gboolean
-goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
- const char *principal_name,
- gconstpointer initial_password,
- GoaIdentitySignInFlags flags,
- GoaIdentityInquiryFunc inquiry_func,
- gpointer inquiry_data,
- GDestroyNotify destroy_notify,
- GCancellable *cancellable, GError **error)
+goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
+ const char *principal_name,
+ gconstpointer initial_password,
+ GoaIdentitySignInFlags flags,
+ GoaIdentityInquiryFunc inquiry_func,
+ gpointer inquiry_data,
+ GDestroyNotify destroy_notify,
+ GCancellable *cancellable,
+ GError **error)
{
SignInOperation *operation;
krb5_principal principal;
@@ -1163,9 +1101,7 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
gboolean signed_in;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
- {
- return FALSE;
- }
+ return FALSE;
error_code = krb5_get_init_creds_opt_alloc (self->priv->kerberos_context,
&options);
@@ -1176,9 +1112,7 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
GOA_IDENTITY_ERROR_ALLOCATING_CREDENTIALS,
error_code, "%k");
if (destroy_notify)
- {
- destroy_notify (inquiry_data);
- }
+ destroy_notify (inquiry_data);
return FALSE;
}
@@ -1197,14 +1131,16 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
}
error_code = krb5_parse_name (self->priv->kerberos_context,
- principal_name, &principal);
+ principal_name,
+ &principal);
if (error_code != 0)
{
set_error_from_krb5_error_code (self,
error,
GOA_IDENTITY_ERROR_PARSING_IDENTIFIER,
- error_code, "%k");
+ error_code,
+ "%k");
if (destroy_notify)
destroy_notify (inquiry_data);
return FALSE;
@@ -1232,12 +1168,27 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
start_time,
service_name,
options);
+
+ if (error_code == KRB5_LIBOS_PWDINTR)
+ g_cancellable_cancel (operation->cancellable);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ {
+ if (destroy_notify)
+ destroy_notify (inquiry_data);
+ sign_in_operation_free (operation);
+
+ krb5_free_principal (self->priv->kerberos_context, principal);
+ goto done;
+ }
+
if (error_code != 0)
{
set_error_from_krb5_error_code (self,
error,
GOA_IDENTITY_ERROR_AUTHENTICATION_FAILED,
- error_code, "%k");
+ error_code,
+ "%k");
if (destroy_notify)
destroy_notify (inquiry_data);
sign_in_operation_free (operation);
@@ -1251,7 +1202,9 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
sign_in_operation_free (operation);
if (!goa_kerberos_identity_update_credentials (self,
- principal, &new_credentials, error))
+ principal,
+ &new_credentials,
+ error))
{
krb5_free_principal (self->priv->kerberos_context, principal);
goto done;
@@ -1283,38 +1236,6 @@ update_identifier (GoaKerberosIdentity *self, GoaKerberosIdentity *new_identity)
}
}
-static void
-update_identifier_components (GoaKerberosIdentity *self,
- GoaKerberosIdentity *new_identity)
-{
- char **new_components;
-
- new_components = get_identifier_components (self);
-
- if (g_strv_length (self->priv->identifier_components) ==
- g_strv_length (new_components))
- {
- int i;
-
- for (i = 0; new_components[i] != NULL; i++)
- {
- if (g_strcmp0 (self->priv->identifier_components[i],
- new_components[i]) != 0)
- {
- break;
- }
- else
- {
- g_strfreev (new_components);
- return;
- }
- }
- }
-
- g_strfreev (self->priv->identifier_components);
- self->priv->identifier_components = new_components;
-}
-
void
goa_kerberos_identity_update (GoaKerberosIdentity *self,
GoaKerberosIdentity *new_identity)
@@ -1322,9 +1243,7 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
VerificationLevel verification_level;
if (self->priv->credentials_cache != NULL)
- {
- krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache);
- }
+ krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache);
krb5_cc_dup (new_identity->priv->kerberos_context,
new_identity->priv->credentials_cache,
@@ -1332,19 +1251,14 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
G_LOCK (identity_lock);
update_identifier (self, new_identity);
- update_identifier_components (self, new_identity);
G_UNLOCK (identity_lock);
verification_level = verify_identity (self, NULL);
if (verification_level == VERIFICATION_LEVEL_SIGNED_IN)
- {
- reset_alarms (self);
- }
+ reset_alarms (self);
else
- {
- clear_alarms (self);
- }
+ clear_alarms (self);
if (verification_level != self->priv->cached_verification_level)
{
@@ -1358,8 +1272,8 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
g_signal_emit (G_OBJECT (self), signals[EXPIRED], 0);
}
- if (self->priv->cached_verification_level == VERIFICATION_LEVEL_EXISTS &&
- verification_level == VERIFICATION_LEVEL_SIGNED_IN)
+ else if (self->priv->cached_verification_level == VERIFICATION_LEVEL_EXISTS &&
+ verification_level == VERIFICATION_LEVEL_SIGNED_IN)
{
G_LOCK (identity_lock);
@@ -1368,6 +1282,12 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
g_signal_emit (G_OBJECT (self), signals[UNEXPIRED], 0);
}
+ else
+ {
+ G_LOCK (identity_lock);
+ self->priv->cached_verification_level = verification_level;
+ G_UNLOCK (identity_lock);
+ }
queue_notify (self, &self->priv->is_signed_in_idle_id, "is-signed-in");
}
}
@@ -1422,7 +1342,9 @@ goa_kerberos_identity_renew (GoaKerberosIdentity *self, GError **error)
}
if (!goa_kerberos_identity_update_credentials (self,
- principal, &new_credentials, error))
+ principal,
+ &new_credentials,
+ error))
{
krb5_free_principal (self->priv->kerberos_context, principal);
goto out;
diff --git a/src/goaidentity/goakerberosidentitymanager.c b/src/goaidentity/goakerberosidentitymanager.c
index b9eeac9..ed27a9a 100644
--- a/src/goaidentity/goakerberosidentitymanager.c
+++ b/src/goaidentity/goakerberosidentitymanager.c
@@ -823,6 +823,15 @@ sign_in_identity (GoaKerberosIdentityManager *self,
operation->cancellable,
&error))
{
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_clear_error (&error);
+ g_set_error_literal (&error,
+ GOA_IDENTITY_ERROR,
+ GOA_IDENTITY_ERROR_USER_CANCELLED,
+ _("User cancelled"));
+ }
+
g_simple_async_result_set_from_error (operation->result, error);
g_simple_async_result_set_op_res_gpointer (operation->result,
NULL,
@@ -1127,7 +1136,7 @@ goa_kerberos_identity_manager_renew_identity_finish (GoaIdentityManager *self,
static void
goa_kerberos_identity_manager_sign_identity_in (GoaIdentityManager *manager,
const char *identifier,
- gconstpointer *initial_password,
+ gconstpointer initial_password,
GoaIdentitySignInFlags flags,
GoaIdentityInquiryFunc inquiry_func,
gpointer inquiry_data,
diff --git a/src/goaidentity/org.gnome.Identity.xml b/src/goaidentity/org.gnome.Identity.xml
index 0bf6394..ac6b66e 100644
--- a/src/goaidentity/org.gnome.Identity.xml
+++ b/src/goaidentity/org.gnome.Identity.xml
@@ -31,6 +31,11 @@
-->
<interface name="org.gnome.Identity.Manager">
+ <method name="ExchangeSecretKeys">
+ <arg name="input_key" type="s" direction="in"/>
+ <arg name="output_key" type="s" direction="out"/>
+ </method>
+
<!--
SignIn:
@identity: The identifier of the identity (i.e., a kerberos principal name)
@@ -45,6 +50,12 @@
<arg name="identity_object_path" type="o" direction="out"/>
</method>
+ <!--
+ SignOut:
+ @identity: The identifier of the identity (i.e., a kerberos principal name)
+
+ Signs out an identity.
+ -->
<method name="SignOut">
<arg name="identity" type="s" direction="in"/>
</method>
@@ -68,6 +79,12 @@
-->
<property name="ExpirationTimestamp" type="x" access="read"/>
+ <!--
+ IsSignedIn:
+ Whether or not the identity is currently signed in
+ -->
+ <property name="IsSignedIn" type="b" access="read"/>
+
</interface>
</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]