1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
3
* Copyright (C) 2012 Red Hat, Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Author: Ray Strode <rstrode@redhat.com>
21
* Based on code from Debarshi Ray <debarshir@gnome.org>
22
* Stef Walter <stefw@gnome.org>
26
#include <glib/gi18n-lib.h>
28
#include "goalogging.h"
29
#include "goaprovider.h"
30
#include "goakerberosprovider.h"
31
#include "goaeditablelabel.h"
33
#include "goaidentity.h"
37
#include "org.gnome.Identity.h"
40
* GoaKerberosProvider:
42
* The #GoaKerberosProvider structure contains only private request and should
43
* only be accessed using the provided API.
45
struct _GoaKerberosProvider
48
GoaProvider parent_instance;
49
GoaIdentityServiceManager *identity_manager;
50
GDBusObjectManager *object_manager;
53
typedef struct _GoaKerberosProviderClass GoaKerberosProviderClass;
55
struct _GoaKerberosProviderClass
57
GoaProviderClass parent_class;
61
* SECTION:goakerberosprovider
62
* @title: GoaKerberosProvider
63
* @short_description: A provider for enterperise identity servers
65
* #GoaKerberosProvider is used to access enterperise identity servers.
68
G_DEFINE_TYPE_WITH_CODE (GoaKerberosProvider, goa_kerberos_provider, GOA_TYPE_PROVIDER,
69
g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
75
get_provider_type (GoaProvider *provider)
81
get_provider_name (GoaProvider *provider, GoaObject *object)
83
return g_strdup(_("Enterprise Login (Kerberos)"));
92
GtkWidget *cluebar_label;
96
GtkWidget *realm_entry;
97
GtkWidget *realm_combo_box;
98
GtkListStore *realm_store;
100
guint interface_added_id;
102
gboolean realm_chosen;
104
gchar *account_object_path;
110
translate_error (GError **error)
112
if (!g_dbus_error_is_remote_error (*error))
115
g_dbus_error_strip_remote_error (*error);
119
on_identity_signed_in (GoaIdentityServiceManager *manager,
120
GAsyncResult *result,
121
GSimpleAsyncResult *operation_result)
125
char *identity_object_path;
128
signed_in = goa_identity_service_manager_call_sign_in_finish (manager,
129
&identity_object_path,
135
translate_error (&error);
137
if (g_error_matches (error,
139
G_IO_ERROR_CANCELLED))
141
g_clear_error (&error);
142
g_set_error_literal (&error,
144
GOA_ERROR_DIALOG_DISMISSED,
148
g_simple_async_result_take_error (operation_result, error);
149
g_simple_async_result_complete_in_idle (operation_result);
150
g_object_unref (operation_result);
154
g_simple_async_result_set_op_res_gpointer (operation_result,
155
g_strdup (identity_object_path),
158
g_simple_async_result_complete_in_idle (operation_result);
159
g_object_unref (operation_result);
163
on_identity_manager_ensured (GoaKerberosProvider *self,
164
GAsyncResult *result,
165
GSimpleAsyncResult *operation_result)
167
GoaIdentityServiceManager *manager;
171
manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
174
translate_error (&error);
175
g_simple_async_result_take_error (operation_result, error);
176
g_simple_async_result_complete_in_idle (operation_result);
177
g_object_unref (operation_result);
181
g_simple_async_result_set_op_res_gpointer (operation_result,
182
g_object_ref (manager),
185
g_simple_async_result_complete_in_idle (operation_result);
186
g_object_unref (operation_result);
190
ensure_identity_manager (GoaKerberosProvider *self,
191
GCancellable *cancellable,
192
GAsyncReadyCallback callback,
195
GSimpleAsyncResult *operation_result;
197
operation_result = g_simple_async_result_new (G_OBJECT (self),
200
ensure_identity_manager);
201
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
203
g_object_set_data (G_OBJECT (operation_result),
207
if (self->identity_manager != NULL)
209
g_simple_async_result_set_op_res_gpointer (operation_result,
210
g_object_ref (self->identity_manager),
213
g_simple_async_result_complete_in_idle (operation_result);
214
g_object_unref (operation_result);
218
goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
219
G_DBUS_PROXY_FLAGS_NONE,
220
"org.gnome.Identity",
221
"/org/gnome/Identity/Manager",
223
(GAsyncReadyCallback)
224
on_identity_manager_ensured,
229
on_object_manager_ensured (GoaKerberosProvider *self,
230
GAsyncResult *result,
231
GSimpleAsyncResult *operation_result)
233
GDBusObjectManager *manager;
237
manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
240
translate_error (&error);
241
g_simple_async_result_take_error (operation_result, error);
242
g_simple_async_result_complete_in_idle (operation_result);
243
g_object_unref (operation_result);
247
g_simple_async_result_set_op_res_gpointer (operation_result,
248
g_object_ref (manager),
251
g_simple_async_result_complete_in_idle (operation_result);
252
g_object_unref (operation_result);
256
ensure_object_manager (GoaKerberosProvider *self,
257
GCancellable *cancellable,
258
GAsyncReadyCallback callback,
261
GSimpleAsyncResult *operation_result;
263
operation_result = g_simple_async_result_new (G_OBJECT (self),
266
ensure_object_manager);
267
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
269
g_object_set_data (G_OBJECT (operation_result),
273
if (self->object_manager != NULL)
275
g_simple_async_result_set_op_res_gpointer (operation_result,
276
g_object_ref (self->object_manager),
279
g_simple_async_result_complete_in_idle (operation_result);
280
g_object_unref (operation_result);
283
goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
284
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
285
"org.gnome.Identity",
286
"/org/gnome/Identity",
288
(GAsyncReadyCallback)
289
on_object_manager_ensured,
294
on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
295
GAsyncResult *result,
296
GSimpleAsyncResult *operation_result)
298
const char *identifier;
299
const char *password;
300
GCancellable *cancellable;
302
GVariantBuilder details;
306
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
309
g_simple_async_result_take_error (operation_result, error);
310
g_simple_async_result_complete_in_idle (operation_result);
311
g_object_unref (operation_result);
315
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
316
password = g_object_get_data (G_OBJECT (operation_result), "password");
317
identifier = g_simple_async_result_get_source_tag (operation_result);
319
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
321
if (password != NULL)
323
GcrSecretExchange *secret_exchange;
326
secret_exchange = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
328
secret = gcr_secret_exchange_send (secret_exchange, password, -1);
329
g_variant_builder_add (&details, "{ss}", "initial-password", secret);
333
goa_identity_service_manager_call_sign_in (self->identity_manager,
335
g_variant_builder_end (&details),
337
(GAsyncReadyCallback)
338
on_identity_signed_in,
343
on_secret_keys_exchanged (GoaIdentityServiceManager *manager,
344
GAsyncResult *result,
345
GSimpleAsyncResult *operation_result)
347
GcrSecretExchange *secret_exchange;
351
secret_exchange = g_simple_async_result_get_source_tag (operation_result);
354
if (!goa_identity_service_manager_call_exchange_secret_keys_finish (manager,
359
g_object_unref (secret_exchange);
361
g_simple_async_result_take_error (operation_result, error);
362
g_simple_async_result_complete_in_idle (operation_result);
363
g_object_unref (operation_result);
367
if (!gcr_secret_exchange_receive (secret_exchange, return_key))
369
g_object_unref (secret_exchange);
371
g_simple_async_result_set_error (operation_result,
373
GCR_ERROR_UNRECOGNIZED,
374
_("Identity service returned invalid key"));
375
g_simple_async_result_complete_in_idle (operation_result);
376
g_object_unref (operation_result);
380
g_simple_async_result_set_op_res_gpointer (operation_result,
384
g_simple_async_result_complete_in_idle (operation_result);
385
g_object_unref (operation_result);
389
exchange_secret_keys (GoaKerberosProvider *self,
390
const char *password,
391
GCancellable *cancellable,
392
GAsyncReadyCallback callback,
396
GSimpleAsyncResult *operation_result;
397
GcrSecretExchange *secret_exchange;
400
secret_exchange = gcr_secret_exchange_new (NULL);
402
operation_result = g_simple_async_result_new (G_OBJECT (self),
407
if (password == NULL)
409
g_simple_async_result_complete_in_idle (operation_result);
410
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
416
secret_key = gcr_secret_exchange_begin (secret_exchange);
418
goa_identity_service_manager_call_exchange_secret_keys (self->identity_manager,
421
(GAsyncReadyCallback)
422
on_secret_keys_exchanged,
428
on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
429
GAsyncResult *result,
430
GSimpleAsyncResult *operation_result)
432
GoaIdentityServiceManager *manager;
433
const char *password;
434
GCancellable *cancellable;
439
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
442
g_simple_async_result_take_error (operation_result, error);
443
g_simple_async_result_complete_in_idle (operation_result);
444
g_object_unref (operation_result);
448
manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
450
if (self->identity_manager == NULL)
451
self->identity_manager = g_object_ref (manager);
453
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
454
password = g_object_get_data (G_OBJECT (operation_result), "password");
456
exchange_secret_keys (self,
459
(GAsyncReadyCallback)
460
on_secret_keys_exchanged_for_sign_in,
465
sign_in_identity (GoaKerberosProvider *self,
466
const char *identifier,
467
const char *password,
468
GCancellable *cancellable,
469
GAsyncReadyCallback callback,
472
GSimpleAsyncResult *operation_result;
474
operation_result = g_simple_async_result_new (G_OBJECT (self),
480
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
482
g_object_set_data (G_OBJECT (operation_result),
485
g_object_set_data (G_OBJECT (operation_result),
490
ensure_identity_manager (self,
492
(GAsyncReadyCallback)
493
on_identity_manager_ensured_for_sign_in,
498
on_object_manager_ensured_for_look_up (GoaKerberosProvider *self,
499
GAsyncResult *result,
500
GSimpleAsyncResult *operation_result)
502
GDBusObjectManager *manager;
503
const char *identifier;
504
GList *objects, *node;
509
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
512
g_simple_async_result_take_error (operation_result, error);
513
g_simple_async_result_complete_in_idle (operation_result);
514
g_object_unref (operation_result);
518
manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
520
if (self->object_manager == NULL)
521
self->object_manager = g_object_ref (manager);
523
identifier = g_simple_async_result_get_source_tag (operation_result);
525
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
528
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->object_manager));
530
for (node = objects; node != NULL; node = node->next)
532
GoaIdentityServiceIdentity *candidate_identity;
533
const char *candidate_identifier;
538
candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
540
if (candidate_identity == NULL)
543
candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
545
if (g_strcmp0 (candidate_identifier, identifier) == 0)
547
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
554
g_object_unref (candidate_identity);
557
g_list_free_full (objects, (GDestroyNotify) g_object_unref);
558
g_simple_async_result_complete_in_idle (G_SIMPLE_ASYNC_RESULT (operation_result));
559
g_object_unref (operation_result);
563
look_up_identity (GoaKerberosProvider *self,
564
const char *identifier,
565
GCancellable *cancellable,
566
GAsyncReadyCallback callback,
569
GSimpleAsyncResult *operation_result;
571
operation_result = g_simple_async_result_new (G_OBJECT (self),
577
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
579
g_object_set_data (G_OBJECT (operation_result),
582
ensure_object_manager (self,
584
(GAsyncReadyCallback)
585
on_object_manager_ensured_for_look_up,
590
on_account_signed_in (GoaProvider *provider,
591
GAsyncResult *result,
592
SignInRequest *request)
594
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
597
g_main_loop_quit (request->loop);
601
g_main_loop_quit (request->loop);
605
get_ticket_sync (GoaKerberosProvider *self,
607
gboolean is_interactive,
608
GCancellable *cancellable,
611
GVariant *credentials;
612
GError *lookup_error;
614
const char *identifier;
615
const char *password;
616
gboolean has_password;
617
SignInRequest request;
622
account = goa_object_peek_account (object);
623
identifier = goa_account_get_identity (account);
627
credentials = goa_utils_lookup_credentials_sync (GOA_PROVIDER (self),
632
if (credentials == NULL && !is_interactive)
634
if (lookup_error != NULL)
635
g_propagate_error (error, lookup_error);
639
GOA_ERROR_NOT_AUTHORIZED,
640
_("Could not find saved credentials for principal `%s' in keyring"), identifier);
644
has_password = g_variant_lookup (credentials, "password", "&s", &password);
645
if (!has_password && !is_interactive)
649
GOA_ERROR_NOT_AUTHORIZED,
650
_("Did not find password for principal `%s' in credentials"),
655
memset (&request, 0, sizeof (SignInRequest));
656
request.loop = g_main_loop_new (NULL, FALSE);
657
request.error = NULL;
659
sign_in_identity (self,
663
(GAsyncReadyCallback)
664
on_account_signed_in,
667
g_main_loop_run (request.loop);
668
g_main_loop_unref (request.loop);
670
if (request.error != NULL)
672
g_propagate_error (error, request.error);
678
if (credentials != NULL)
679
g_variant_unref (credentials);
685
notify_is_temporary_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
688
gboolean is_temporary;
690
/* Toggle IsTemporary */
691
goa_util_account_notify_property_cb (object, pspec, "IsTemporary");
693
account = GOA_ACCOUNT (object);
694
g_object_get (account, "is-temporary", &is_temporary, NULL);
696
/* Set/unset SessionId */
699
GDBusConnection *connection;
702
connection = G_DBUS_CONNECTION (user_data);
703
guid = g_dbus_connection_get_guid (connection);
704
goa_utils_keyfile_set_string (account, "SessionId", guid);
707
goa_utils_keyfile_remove_key (account, "SessionId");
711
on_handle_get_ticket (GoaTicketing *interface,
712
GDBusMethodInvocation *invocation)
716
GoaProvider *provider;
720
object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface)));
721
account = goa_object_peek_account (object);
723
provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account));
725
got_ticket = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
727
TRUE /* Allow interaction */,
732
g_dbus_method_invocation_take_error (invocation, error);
734
goa_ticketing_complete_get_ticket (interface, invocation);
736
g_object_unref (provider);
741
build_object (GoaProvider *provider,
742
GoaObjectSkeleton *object,
745
GDBusConnection *connection,
750
GoaTicketing *ticketing;
751
gboolean ticketing_enabled;
757
if (!GOA_PROVIDER_CLASS (goa_kerberos_provider_parent_class)->build_object (provider,
766
account = goa_object_get_account (GOA_OBJECT (object));
768
ticketing = goa_object_get_ticketing (GOA_OBJECT (object));
769
ticketing_enabled = g_key_file_get_boolean (key_file, group, "TicketingEnabled", NULL);
771
if (ticketing_enabled)
773
if (ticketing == NULL)
775
ticketing = goa_ticketing_skeleton_new ();
777
g_signal_connect (ticketing,
779
G_CALLBACK (on_handle_get_ticket),
782
goa_object_skeleton_set_ticketing (object, ticketing);
786
else if (ticketing != NULL)
788
goa_object_skeleton_set_ticketing (object, NULL);
793
goa_account_set_ticketing_disabled (account, !ticketing_enabled);
795
g_signal_connect (account,
796
"notify::is-temporary",
797
G_CALLBACK (notify_is_temporary_cb),
800
g_signal_connect (account,
801
"notify::ticketing-disabled",
802
G_CALLBACK (goa_util_account_notify_property_cb),
809
g_clear_object (&ticketing);
815
add_entry (GtkWidget *grid1,
818
GtkWidget **out_entry)
820
GtkStyleContext *context;
824
label = gtk_label_new_with_mnemonic (text);
825
context = gtk_widget_get_style_context (label);
826
gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
827
gtk_widget_set_vexpand (label, TRUE);
828
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
829
gtk_container_add (GTK_CONTAINER (grid1), label);
831
entry = gtk_entry_new ();
832
gtk_widget_set_hexpand (entry, TRUE);
833
gtk_widget_set_vexpand (entry, TRUE);
834
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
835
gtk_entry_set_max_length (GTK_ENTRY (entry), 132);
836
gtk_container_add (GTK_CONTAINER (grid2), entry);
838
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
839
if (out_entry != NULL)
844
add_combo_box (GtkWidget *grid1,
847
const gchar *placeholder,
849
GtkWidget **out_combo_box,
850
GtkWidget **out_entry)
852
GtkStyleContext *context;
854
GtkWidget *combo_box;
857
label = gtk_label_new_with_mnemonic (text);
858
context = gtk_widget_get_style_context (label);
859
gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
860
gtk_widget_set_vexpand (label, TRUE);
861
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
862
gtk_container_add (GTK_CONTAINER (grid1), label);
864
combo_box = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL (model));
865
gtk_widget_set_hexpand (combo_box, TRUE);
866
gtk_widget_set_vexpand (combo_box, TRUE);
867
gtk_widget_show (combo_box);
869
entry = gtk_bin_get_child (GTK_BIN (combo_box));
870
gtk_entry_set_max_length (GTK_ENTRY (entry), 132);
871
gtk_entry_set_placeholder_text (GTK_ENTRY (entry), placeholder);
873
gtk_container_add (GTK_CONTAINER (grid2), combo_box);
875
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
876
if (out_combo_box != NULL)
877
*out_combo_box = combo_box;
879
if (out_entry != NULL)
884
on_realm_added (GDBusObjectManager *manager,
885
GoaIdentityServiceObject *object,
886
GDBusInterface *interface,
887
SignInRequest *request)
889
GoaIdentityServiceRealm *realm;
890
GDBusInterfaceInfo *info;
893
info = g_dbus_interface_get_info (interface);
895
if (g_strcmp0 (info->name, "org.gnome.Identity.Realm") != 0)
898
realm = goa_identity_service_object_peek_realm (object);
903
gtk_list_store_append (request->realm_store, &iter);
904
gtk_list_store_set (request->realm_store,
906
0, goa_identity_service_realm_get_domain (realm),
910
if (!request->realm_chosen && goa_identity_service_realm_get_is_enrolled (realm))
911
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (request->realm_combo_box), &iter);
915
on_object_manager_ensured_for_getting_realms (GoaKerberosProvider *self,
916
GAsyncResult *result,
917
SignInRequest *request)
919
GDBusObjectManager *manager;
920
GList *objects, *node;
925
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
929
manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
931
if (self->object_manager == NULL)
932
self->object_manager = g_object_ref (manager);
934
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->object_manager));
936
for (node = objects; node != NULL; node = node->next)
938
GoaIdentityServiceRealm *realm;
944
realm = GOA_IDENTITY_SERVICE_REALM (g_dbus_object_get_interface (object, "org.gnome.Identity.Realm"));
949
gtk_list_store_append (request->realm_store, &iter);
950
gtk_list_store_set (request->realm_store,
952
0, goa_identity_service_realm_get_domain (realm),
956
if (!request->realm_chosen && goa_identity_service_realm_get_is_enrolled (realm))
957
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (request->realm_combo_box), &iter);
960
request->interface_added_id = g_signal_connect (self->object_manager,
962
G_CALLBACK (on_realm_added),
965
g_list_free_full (objects, (GDestroyNotify) g_object_unref);
969
create_account_details_ui (GoaKerberosProvider *self,
971
gboolean new_account,
972
SignInRequest *request)
974
GtkWidget *header_grid;
982
header_grid = gtk_grid_new ();
983
gtk_orientable_set_orientation (GTK_ORIENTABLE (header_grid), GTK_ORIENTATION_HORIZONTAL);
984
gtk_box_pack_start (GTK_BOX (vbox), header_grid, FALSE, FALSE, 0);
986
label = gtk_label_new (NULL);
987
gtk_widget_set_hexpand (label, TRUE);
988
markup = g_strconcat ("<b>",
989
(new_account) ? _("New Enterprise Login (Kerberos)") : _("Enterpise Login (Kerberos)"),
992
gtk_label_set_markup (GTK_LABEL (label), markup);
994
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
995
gtk_misc_set_padding (GTK_MISC (label), 0.0, 12);
996
gtk_container_add (GTK_CONTAINER (header_grid), label);
998
request->spinner = gtk_spinner_new ();
999
gtk_widget_set_no_show_all (request->spinner, TRUE);
1000
gtk_container_add (GTK_CONTAINER (header_grid), request->spinner);
1002
request->cluebar = gtk_info_bar_new ();
1003
gtk_info_bar_set_message_type (GTK_INFO_BAR (request->cluebar), GTK_MESSAGE_ERROR);
1004
gtk_widget_set_no_show_all (request->cluebar, TRUE);
1005
gtk_box_pack_start (GTK_BOX (vbox), request->cluebar, FALSE, FALSE, 0);
1007
request->cluebar_label = gtk_label_new ("");
1008
gtk_label_set_line_wrap (GTK_LABEL (request->cluebar_label), TRUE);
1009
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (request->cluebar))),
1010
request->cluebar_label);
1012
grid1 = gtk_grid_new ();
1013
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid1), GTK_ORIENTATION_VERTICAL);
1014
gtk_grid_set_row_spacing (GTK_GRID (grid1), 12);
1016
grid2 = gtk_grid_new ();
1017
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid2), GTK_ORIENTATION_VERTICAL);
1018
gtk_grid_set_row_spacing (GTK_GRID (grid2), 12);
1020
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
1021
gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
1022
gtk_box_pack_start (GTK_BOX (hbox), grid1, FALSE, FALSE, 0);
1023
gtk_box_pack_start (GTK_BOX (hbox), grid2, TRUE, TRUE, 0);
1024
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1026
request->realm_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_OBJECT);
1027
add_combo_box (grid1,
1030
_("Enterprise domain or realm name"),
1031
request->realm_store,
1032
&request->realm_combo_box,
1033
&request->realm_entry);
1034
gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (request->realm_combo_box), 0);
1036
add_entry (grid1, grid2, _("User_name"), &request->username);
1038
ensure_object_manager (self,
1040
(GAsyncReadyCallback)
1041
on_object_manager_ensured_for_getting_realms,
1044
gtk_widget_grab_focus (request->realm_combo_box);
1046
gtk_dialog_add_button (request->dialog, GTK_STOCK_CONNECT, GTK_RESPONSE_OK);
1047
gtk_dialog_set_default_response (request->dialog, GTK_RESPONSE_OK);
1048
gtk_dialog_set_response_sensitive (request->dialog, GTK_RESPONSE_OK, TRUE);
1050
gtk_window_get_size (GTK_WINDOW (request->dialog), &width, NULL);
1051
gtk_widget_set_size_request (GTK_WIDGET (request->dialog), width, -1);
1055
add_account_cb (GoaManager *manager,
1056
GAsyncResult *result,
1059
SignInRequest *request = user_data;
1060
goa_manager_call_add_account_finish (manager,
1061
&request->account_object_path,
1064
if (request->error != NULL)
1065
translate_error (&request->error);
1066
g_main_loop_quit (request->loop);
1070
remove_account_cb (GoaAccount *account,
1071
GAsyncResult *result,
1074
goa_account_call_remove_finish (account, result, NULL);
1075
g_main_loop_quit (loop);
1079
refresh_account (GoaProvider *provider,
1085
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
1086
gboolean got_ticket;
1087
GError *ticket_error = NULL;
1089
g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (provider), FALSE);
1090
g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
1091
g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
1092
g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
1093
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1095
got_ticket = get_ticket_sync (self,
1097
TRUE /* Allow interaction */,
1101
if (ticket_error != NULL)
1103
translate_error (&ticket_error);
1104
g_propagate_error (error, ticket_error);
1111
on_initial_sign_in_done (GoaKerberosProvider *self,
1112
GAsyncResult *result,
1113
GSimpleAsyncResult *operation_result)
1116
gboolean remember_password;
1119
object = g_simple_async_result_get_source_tag (operation_result);
1121
remember_password = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (operation_result),
1122
"remember-password"));
1125
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
1127
g_simple_async_result_take_error (operation_result, error);
1129
else if (remember_password)
1131
GVariantBuilder builder;
1132
const char *object_path;
1134
object_path = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1136
if (object_path != NULL && object != NULL)
1138
GcrSecretExchange *secret_exchange;
1139
const char *password;
1141
secret_exchange = g_object_get_data (G_OBJECT (operation_result), "secret-exchange");
1142
password = gcr_secret_exchange_get_secret (secret_exchange, NULL);
1144
/* FIXME: we go to great lengths to keep the password in non-pageable memory,
1145
* and then just duplicate it into a gvariant here
1147
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
1148
g_variant_builder_add (&builder,
1151
g_variant_new_string (password));
1154
goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (self),
1156
g_variant_builder_end (&builder),
1162
g_simple_async_result_complete_in_idle (operation_result);
1163
g_object_unref (operation_result);
1167
on_system_prompt_answered_for_initial_sign_in (GcrPrompt *prompt,
1168
GAsyncResult *result,
1169
GSimpleAsyncResult *operation_result)
1171
GoaKerberosProvider *self;
1172
GCancellable *cancellable;
1174
const char *principal;
1175
const char *password;
1176
GcrSecretExchange *secret_exchange;
1178
self = GOA_KERBEROS_PROVIDER (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
1179
principal = g_object_get_data (G_OBJECT (operation_result), "principal");
1180
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1183
password = gcr_prompt_password_finish (prompt, result, &error);
1185
if (password == NULL)
1187
gcr_system_prompt_close (GCR_SYSTEM_PROMPT (prompt), NULL, NULL);
1190
g_simple_async_result_take_error (operation_result, error);
1192
g_cancellable_cancel (cancellable);
1194
g_simple_async_result_complete_in_idle (operation_result);
1195
g_object_unref (operation_result);
1199
secret_exchange = gcr_system_prompt_get_secret_exchange (GCR_SYSTEM_PROMPT (prompt));
1200
g_object_set_data_full (G_OBJECT (operation_result),
1202
g_object_ref (secret_exchange),
1206
g_object_set_data (G_OBJECT (operation_result),
1207
"remember-password",
1208
GINT_TO_POINTER (gcr_prompt_get_choice_chosen (prompt)));
1210
gcr_system_prompt_close (GCR_SYSTEM_PROMPT (prompt), NULL, NULL);
1212
sign_in_identity (self,
1216
(GAsyncReadyCallback)
1217
on_initial_sign_in_done,
1222
on_system_prompt_open_for_initial_sign_in (GcrSystemPrompt *system_prompt,
1223
GAsyncResult *result,
1224
GSimpleAsyncResult *operation_result)
1226
GCancellable *cancellable;
1230
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1232
prompt = gcr_system_prompt_open_finish (result, &error);
1236
g_simple_async_result_take_error (operation_result, error);
1238
g_simple_async_result_complete_in_idle (operation_result);
1239
g_object_unref (operation_result);
1244
gcr_prompt_set_title (prompt, _("Log In to Realm"));
1245
gcr_prompt_set_description (prompt, _("Please enter your password below."));
1246
gcr_prompt_set_choice_label (prompt, _("Remember this password"));
1248
gcr_prompt_password_async (prompt,
1250
(GAsyncReadyCallback)
1251
on_system_prompt_answered_for_initial_sign_in,
1256
perform_initial_sign_in (GoaKerberosProvider *self,
1258
const char *principal,
1259
SignInRequest *request)
1262
GSimpleAsyncResult *operation_result;
1263
GCancellable *cancellable;
1265
cancellable = g_cancellable_new ();
1267
operation_result = g_simple_async_result_new (G_OBJECT (self),
1268
(GAsyncReadyCallback)
1269
on_account_signed_in ,
1272
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1274
g_object_set_data (G_OBJECT (operation_result),
1277
g_object_set_data (G_OBJECT (operation_result),
1282
gcr_system_prompt_open_async (-1,
1284
(GAsyncReadyCallback)
1285
on_system_prompt_open_for_initial_sign_in,
1290
get_realm (SignInRequest *request)
1295
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (request->realm_combo_box), &iter))
1296
gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (request->realm_combo_box)),
1301
realm = g_strdup (gtk_entry_get_text (GTK_ENTRY (request->realm_entry)));
1307
add_account (GoaProvider *provider,
1313
GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
1314
SignInRequest request;
1315
GVariantBuilder credentials;
1316
GVariantBuilder details;
1318
GoaAccount *account;
1320
const char *username;
1321
const char *provider_type;
1323
gchar *principal_for_display;
1328
principal_for_display = NULL;
1330
memset (&request, 0, sizeof (SignInRequest));
1331
request.loop = g_main_loop_new (NULL, FALSE);
1332
request.dialog = dialog;
1333
request.error = NULL;
1335
create_account_details_ui (self, GTK_WIDGET (vbox), TRUE, &request);
1336
gtk_widget_show_all (GTK_WIDGET (vbox));
1339
response = gtk_dialog_run (dialog);
1341
if (response != GTK_RESPONSE_OK)
1343
g_set_error (&request.error,
1345
GOA_ERROR_DIALOG_DISMISSED,
1346
_("Dialog was dismissed"));
1350
realm = get_realm (&request);
1351
username = gtk_entry_get_text (GTK_ENTRY (request.username));
1354
principal = g_strdup_printf ("%s@%s", username, realm);
1356
/* See if there's already an account of this type with the
1359
provider_type = goa_provider_get_provider_type (provider);
1361
if (!goa_utils_check_duplicate (client,
1364
(GoaPeekInterfaceFunc) goa_object_peek_account,
1368
/* If there isn't an account, then go ahead and create one
1370
g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
1372
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
1373
g_variant_builder_add (&details, "{ss}", "Realm", realm);
1374
g_variant_builder_add (&details, "{ss}", "IsTemporary", "true");
1375
g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
1377
g_free (principal_for_display);
1378
principal_for_display = g_strdup_printf ("%s@%s", username, realm);
1382
goa_manager_call_add_account (goa_client_get_manager (client),
1383
goa_provider_get_provider_type (provider),
1385
principal_for_display,
1386
g_variant_builder_end (&credentials),
1387
g_variant_builder_end (&details),
1388
NULL, /* GCancellable* */
1389
(GAsyncReadyCallback) add_account_cb,
1391
g_main_loop_run (request.loop);
1392
if (request.error != NULL)
1395
object = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
1396
request.account_object_path));
1397
account = goa_object_peek_account (object);
1399
gtk_spinner_start (GTK_SPINNER (request.spinner));
1400
gtk_widget_show (request.spinner);
1402
/* After the account is created, try to sign it in
1404
perform_initial_sign_in (self, object, principal, &request);
1406
g_main_loop_run (request.loop);
1408
if (request.error != NULL)
1413
translate_error (&request.error);
1415
if (!g_error_matches (request.error,
1417
G_IO_ERROR_CANCELLED))
1419
markup = g_strdup_printf ("<b>%s:</b>\n%s",
1420
_("Error connecting to enterperise identity server"),
1421
request.error->message);
1422
gtk_label_set_markup (GTK_LABEL (request.cluebar_label), markup);
1425
button = gtk_dialog_get_widget_for_response (request.dialog, GTK_RESPONSE_OK);
1426
gtk_button_set_label (GTK_BUTTON (button), _("_Try Again"));
1427
gtk_widget_set_no_show_all (request.cluebar, FALSE);
1428
gtk_widget_show_all (request.cluebar);
1430
g_clear_error (&request.error);
1432
/* If it couldn't be signed in, then delete it and start over
1434
goa_account_call_remove (account,
1436
(GAsyncReadyCallback)
1439
g_main_loop_run (request.loop);
1440
g_clear_object (&object);
1444
gtk_widget_hide (GTK_WIDGET (dialog));
1447
/* We might have an object even when request.error is set.
1448
* eg., if we failed to store the credentials in the keyring.
1450
if (request.error != NULL)
1452
translate_error (&request.error);
1453
g_propagate_error (error, request.error);
1456
g_assert (object != NULL);
1458
if (request.interface_added_id != 0)
1459
g_signal_handler_disconnect (G_OBJECT (self->object_manager), request.interface_added_id);
1461
g_free (request.account_object_path);
1463
g_free (principal_for_display);
1464
if (request.loop != NULL)
1465
g_main_loop_unref (request.loop);
1470
show_account (GoaProvider *provider,
1477
GOA_PROVIDER_CLASS (goa_kerberos_provider_parent_class)->show_account (provider,
1483
goa_util_add_row_switch_from_keyfile_with_blurb (left, right, object,
1485
"ticketing-disabled",
1486
_("Network Resources"));
1490
on_identity_looked_up (GoaKerberosProvider *provider,
1491
GAsyncResult *result,
1492
GSimpleAsyncResult *operation_result)
1495
GoaIdentityServiceIdentity *identity;
1499
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
1501
g_simple_async_result_take_error (operation_result, error);
1502
g_simple_async_result_complete_in_idle (operation_result);
1503
g_object_unref (operation_result);
1507
identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1508
if (identity != NULL)
1509
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1510
g_object_ref (identity),
1514
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1518
g_simple_async_result_complete_in_idle (operation_result);
1519
g_object_unref (operation_result);
1523
on_identity_looked_up_to_ensure_credentials (GoaKerberosProvider *self,
1524
GAsyncResult *result,
1525
GSimpleAsyncResult *operation_result)
1528
GoaIdentityServiceIdentity *identity;
1531
GoaAccount *account;
1532
const char *identifier;
1533
GCancellable *cancellable;
1536
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
1538
g_simple_async_result_take_error (operation_result, error);
1539
g_simple_async_result_complete_in_idle (operation_result);
1540
g_object_unref (operation_result);
1544
identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1546
if (identity != NULL && goa_identity_service_identity_get_is_signed_in (identity))
1548
g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1549
g_object_ref (identity),
1552
g_simple_async_result_complete_in_idle (operation_result);
1553
g_object_unref (operation_result);
1557
object = GOA_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
1558
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1560
if (!get_ticket_sync (self,
1562
FALSE /* Don't allow interaction */,
1566
g_simple_async_result_take_error (operation_result, error);
1567
g_simple_async_result_complete_in_idle (operation_result);
1568
g_object_unref (operation_result);
1572
account = goa_object_peek_account (object);
1573
identifier = goa_account_get_identity (account);
1575
look_up_identity (self,
1578
(GAsyncReadyCallback)
1579
on_identity_looked_up,
1582
g_simple_async_result_complete_in_idle (operation_result);
1583
g_object_unref (operation_result);
1587
on_credentials_ensured (GoaObject *object,
1588
GAsyncResult *result,
1591
g_main_loop_quit (loop);
1595
ensure_credentials_sync (GoaProvider *provider,
1597
gint *out_expires_in,
1598
GCancellable *cancellable,
1601
GoaIdentityServiceIdentity *identity;
1602
GoaAccount *account;
1603
const char *identifier;
1604
GSimpleAsyncResult *operation_result;
1606
GMainContext *context;
1608
GDateTime *now, *expiration_time;
1609
GTimeSpan time_span;
1610
GError *lookup_error;
1612
account = goa_object_peek_account (object);
1613
identifier = goa_account_get_identity (account);
1615
context = g_main_context_new ();
1616
g_main_context_push_thread_default (context);
1617
loop = g_main_loop_new (context, FALSE);
1618
operation_result = g_simple_async_result_new (G_OBJECT (object),
1619
(GAsyncReadyCallback)
1620
on_credentials_ensured,
1622
ensure_credentials_sync);
1623
g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1625
g_object_set_data (G_OBJECT (operation_result),
1629
g_object_ref (operation_result);
1630
look_up_identity (GOA_KERBEROS_PROVIDER (provider),
1633
(GAsyncReadyCallback)
1634
on_identity_looked_up_to_ensure_credentials,
1637
g_main_loop_run (loop);
1638
g_main_loop_unref (loop);
1640
g_main_context_pop_thread_default (context);
1641
g_main_context_unref (context);
1643
lookup_error = NULL;
1644
if (g_simple_async_result_propagate_error (operation_result, &lookup_error))
1646
translate_error (&lookup_error);
1647
g_propagate_error (error, lookup_error);
1648
g_object_unref (operation_result);
1652
identity = g_simple_async_result_get_op_res_gpointer (operation_result);
1654
now = g_date_time_new_now_local ();
1655
timestamp = goa_identity_service_identity_get_expiration_timestamp (identity);
1656
expiration_time = g_date_time_new_from_unix_local (timestamp);
1657
time_span = g_date_time_difference (expiration_time, now);
1659
time_span /= G_TIME_SPAN_SECOND;
1661
if (time_span < 0 || time_span > G_MAXINT)
1664
*out_expires_in = (int) time_span;
1666
g_date_time_unref (now);
1667
g_date_time_unref (expiration_time);
1668
g_object_unref (operation_result);
1674
goa_kerberos_provider_init (GoaKerberosProvider *provider)
1679
goa_kerberos_provider_class_init (GoaKerberosProviderClass *kerberos_class)
1681
GoaProviderClass *provider_class;
1683
provider_class = GOA_PROVIDER_CLASS (kerberos_class);
1684
provider_class->get_provider_type = get_provider_type;
1685
provider_class->get_provider_name = get_provider_name;
1686
provider_class->build_object = build_object;
1687
provider_class->add_account = add_account;
1688
provider_class->refresh_account = refresh_account;
1689
provider_class->show_account = show_account;
1690
provider_class->ensure_credentials_sync = ensure_credentials_sync;