|
|
1e691d |
From 3753904f1de123a724438bf7f0c58aac00ce4ef4 Mon Sep 17 00:00:00 2001
|
|
|
1e691d |
From: Ray Strode <rstrode@redhat.com>
|
|
|
1e691d |
Date: Tue, 21 Oct 2014 10:38:17 -0400
|
|
|
1e691d |
Subject: [PATCH 1/2] ticketing: add new details property
|
|
|
1e691d |
|
|
|
1e691d |
This commit adds a new "details" variant for attaching metadata
|
|
|
1e691d |
about tickets getting requested via the ticketing interface.
|
|
|
1e691d |
|
|
|
1e691d |
This will give the kerberos account provider a place to tuck away
|
|
|
1e691d |
kerberos-specific preauthentication configuration for the tickets
|
|
|
1e691d |
associated with smartcard backed kerberos accounts.
|
|
|
1e691d |
---
|
|
|
1e691d |
data/dbus-interfaces.xml | 2 ++
|
|
|
1e691d |
1 file changed, 2 insertions(+)
|
|
|
1e691d |
|
|
|
1e691d |
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
|
|
|
1e691d |
index 5bf26e9..fa8b18c 100644
|
|
|
1e691d |
--- a/data/dbus-interfaces.xml
|
|
|
1e691d |
+++ b/data/dbus-interfaces.xml
|
|
|
1e691d |
@@ -726,6 +726,8 @@
|
|
|
1e691d |
ticketing capabilities.
|
|
|
1e691d |
-->
|
|
|
1e691d |
<interface name="org.gnome.OnlineAccounts.Ticketing">
|
|
|
1e691d |
+ <property name="details" type="a{ss}" access="read"/>
|
|
|
1e691d |
+
|
|
|
1e691d |
|
|
|
1e691d |
GetTicket:
|
|
|
1e691d |
|
|
|
1e691d |
--
|
|
|
1e691d |
2.1.0
|
|
|
1e691d |
|
|
|
1e691d |
|
|
|
1e691d |
From 1544883b52453ba8e69e78b5bdacf7a57053326c Mon Sep 17 00:00:00 2001
|
|
|
1e691d |
From: Ray Strode <rstrode@redhat.com>
|
|
|
1e691d |
Date: Tue, 21 Oct 2014 10:46:50 -0400
|
|
|
1e691d |
Subject: [PATCH 2/2] kerberos: Support refreshing smartcard authenticated
|
|
|
1e691d |
kerberos tickets
|
|
|
1e691d |
|
|
|
1e691d |
Right now gnome-online-accounts doesn't manage smartcard based
|
|
|
1e691d |
kerberos credentials very well. The sign-in button just fails.
|
|
|
1e691d |
|
|
|
1e691d |
This commit adds support for tickets granted through smartcards.
|
|
|
1e691d |
|
|
|
1e691d |
Note, at the moment we don't provide a way to add new smartcard based
|
|
|
1e691d |
accounts, merely, manage existing ones that are added implicitly by
|
|
|
1e691d |
logging in with a smartcard, or by explicit kinit.
|
|
|
1e691d |
|
|
|
1e691d |
https://bugzilla.gnome.org/show_bug.cgi?id=739594
|
|
|
1e691d |
---
|
|
|
1e691d |
src/goabackend/goakerberosprovider.c | 43 +++++++++++++++++
|
|
|
1e691d |
src/goaidentity/goaidentitymanager.c | 2 +
|
|
|
1e691d |
src/goaidentity/goaidentitymanager.h | 2 +
|
|
|
1e691d |
src/goaidentity/goaidentityservice.c | 19 +++++++-
|
|
|
1e691d |
src/goaidentity/goakerberosidentity.c | 71 +++++++++++++++++++++++++++-
|
|
|
1e691d |
src/goaidentity/goakerberosidentity.h | 2 +
|
|
|
1e691d |
src/goaidentity/goakerberosidentitymanager.c | 14 ++++--
|
|
|
1e691d |
7 files changed, 146 insertions(+), 7 deletions(-)
|
|
|
1e691d |
|
|
|
1e691d |
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
|
|
|
1e691d |
index b2958b2..f9c54cd 100644
|
|
|
1e691d |
--- a/src/goabackend/goakerberosprovider.c
|
|
|
1e691d |
+++ b/src/goabackend/goakerberosprovider.c
|
|
|
1e691d |
@@ -370,6 +370,7 @@ on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
|
|
|
1e691d |
{
|
|
|
1e691d |
const char *identifier;
|
|
|
1e691d |
const char *password;
|
|
|
1e691d |
+ const char *preauth_source;
|
|
|
1e691d |
GCancellable *cancellable;
|
|
|
1e691d |
GError *error;
|
|
|
1e691d |
GVariantBuilder details;
|
|
|
1e691d |
@@ -387,6 +388,7 @@ on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
|
|
|
1e691d |
|
|
|
1e691d |
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
|
|
|
1e691d |
password = g_object_get_data (G_OBJECT (operation_result), "password");
|
|
|
1e691d |
+ preauth_source = g_object_get_data (G_OBJECT (operation_result), "preauthentication-source");
|
|
|
1e691d |
identifier = g_simple_async_result_get_source_tag (operation_result);
|
|
|
1e691d |
|
|
|
1e691d |
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
|
1e691d |
@@ -403,6 +405,11 @@ on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
|
|
|
1e691d |
g_free (secret);
|
|
|
1e691d |
}
|
|
|
1e691d |
|
|
|
1e691d |
+ if (preauth_source != NULL)
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauth_source);
|
|
|
1e691d |
+ }
|
|
|
1e691d |
+
|
|
|
1e691d |
goa_identity_service_manager_call_sign_in (self->identity_manager,
|
|
|
1e691d |
identifier,
|
|
|
1e691d |
g_variant_builder_end (&details),
|
|
|
1e691d |
@@ -538,6 +545,7 @@ static void
|
|
|
1e691d |
sign_in_identity (GoaKerberosProvider *self,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
const char *password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GCancellable *cancellable,
|
|
|
1e691d |
GAsyncReadyCallback callback,
|
|
|
1e691d |
gpointer user_data)
|
|
|
1e691d |
@@ -560,6 +568,11 @@ sign_in_identity (GoaKerberosProvider *self,
|
|
|
1e691d |
(gpointer)
|
|
|
1e691d |
password);
|
|
|
1e691d |
|
|
|
1e691d |
+ g_object_set_data_full (G_OBJECT (operation_result),
|
|
|
1e691d |
+ "preauthentication-source",
|
|
|
1e691d |
+ g_strdup (preauth_source),
|
|
|
1e691d |
+ g_free);
|
|
|
1e691d |
+
|
|
|
1e691d |
ensure_identity_manager (self,
|
|
|
1e691d |
cancellable,
|
|
|
1e691d |
(GAsyncReadyCallback)
|
|
|
1e691d |
@@ -691,8 +704,11 @@ get_ticket_sync (GoaKerberosProvider *self,
|
|
|
1e691d |
GVariant *credentials;
|
|
|
1e691d |
GError *lookup_error;
|
|
|
1e691d |
GoaAccount *account;
|
|
|
1e691d |
+ GoaTicketing *ticketing;
|
|
|
1e691d |
+ GVariant *details;
|
|
|
1e691d |
const char *identifier;
|
|
|
1e691d |
const char *password;
|
|
|
1e691d |
+ const char *preauth_source;
|
|
|
1e691d |
SignInRequest request;
|
|
|
1e691d |
gboolean ret;
|
|
|
1e691d |
|
|
|
1e691d |
@@ -700,6 +716,13 @@ get_ticket_sync (GoaKerberosProvider *self,
|
|
|
1e691d |
|
|
|
1e691d |
account = goa_object_peek_account (object);
|
|
|
1e691d |
identifier = goa_account_get_identity (account);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ ticketing = goa_object_get_ticketing (GOA_OBJECT (object));
|
|
|
1e691d |
+ details = goa_ticketing_get_details (ticketing);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ preauth_source = NULL;
|
|
|
1e691d |
+ g_variant_lookup (details, "preauthentication-source", "&s", &preauth_source);
|
|
|
1e691d |
+
|
|
|
1e691d |
password = NULL;
|
|
|
1e691d |
|
|
|
1e691d |
lookup_error = NULL;
|
|
|
1e691d |
@@ -742,6 +765,7 @@ get_ticket_sync (GoaKerberosProvider *self,
|
|
|
1e691d |
sign_in_identity (self,
|
|
|
1e691d |
identifier,
|
|
|
1e691d |
password,
|
|
|
1e691d |
+ preauth_source,
|
|
|
1e691d |
cancellable,
|
|
|
1e691d |
(GAsyncReadyCallback)
|
|
|
1e691d |
on_account_signed_in,
|
|
|
1e691d |
@@ -758,6 +782,8 @@ get_ticket_sync (GoaKerberosProvider *self,
|
|
|
1e691d |
|
|
|
1e691d |
ret = TRUE;
|
|
|
1e691d |
out:
|
|
|
1e691d |
+ g_clear_object (&ticketing);
|
|
|
1e691d |
+
|
|
|
1e691d |
if (credentials != NULL)
|
|
|
1e691d |
g_variant_unref (credentials);
|
|
|
1e691d |
|
|
|
1e691d |
@@ -855,6 +881,9 @@ build_object (GoaProvider *provider,
|
|
|
1e691d |
{
|
|
|
1e691d |
if (ticketing == NULL)
|
|
|
1e691d |
{
|
|
|
1e691d |
+ char *preauthentication_source;
|
|
|
1e691d |
+ GVariantBuilder details;
|
|
|
1e691d |
+
|
|
|
1e691d |
ticketing = goa_ticketing_skeleton_new ();
|
|
|
1e691d |
|
|
|
1e691d |
g_signal_connect (ticketing,
|
|
|
1e691d |
@@ -864,6 +893,13 @@ build_object (GoaProvider *provider,
|
|
|
1e691d |
|
|
|
1e691d |
goa_object_skeleton_set_ticketing (object, ticketing);
|
|
|
1e691d |
|
|
|
1e691d |
+ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
|
1e691d |
+
|
|
|
1e691d |
+ preauthentication_source = g_key_file_get_string (key_file, group, "PreauthenticationSource", NULL);
|
|
|
1e691d |
+ if (preauthentication_source)
|
|
|
1e691d |
+ g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauthentication_source);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ g_object_set (G_OBJECT (ticketing), "details", g_variant_builder_end (&details), NULL);
|
|
|
1e691d |
}
|
|
|
1e691d |
}
|
|
|
1e691d |
else if (ticketing != NULL)
|
|
|
1e691d |
@@ -1274,12 +1310,18 @@ on_system_prompt_answered_for_initial_sign_in (GcrPrompt *prompt,
|
|
|
1e691d |
GError *error;
|
|
|
1e691d |
const char *principal;
|
|
|
1e691d |
const char *password;
|
|
|
1e691d |
+ const char *preauth_source;
|
|
|
1e691d |
GcrSecretExchange *secret_exchange;
|
|
|
1e691d |
|
|
|
1e691d |
self = GOA_KERBEROS_PROVIDER (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
|
|
|
1e691d |
principal = g_object_get_data (G_OBJECT (operation_result), "principal");
|
|
|
1e691d |
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
|
|
|
1e691d |
|
|
|
1e691d |
+ /* We currently don't prompt the user to choose a preauthentication source during initial sign in
|
|
|
1e691d |
+ * so we assume there's no preauthentication source
|
|
|
1e691d |
+ */
|
|
|
1e691d |
+ preauth_source = NULL;
|
|
|
1e691d |
+
|
|
|
1e691d |
error = NULL;
|
|
|
1e691d |
password = gcr_prompt_password_finish (prompt, result, &error);
|
|
|
1e691d |
|
|
|
1e691d |
@@ -1313,6 +1355,7 @@ on_system_prompt_answered_for_initial_sign_in (GcrPrompt *prompt,
|
|
|
1e691d |
sign_in_identity (self,
|
|
|
1e691d |
principal,
|
|
|
1e691d |
password,
|
|
|
1e691d |
+ preauth_source,
|
|
|
1e691d |
cancellable,
|
|
|
1e691d |
(GAsyncReadyCallback)
|
|
|
1e691d |
on_initial_sign_in_done,
|
|
|
1e691d |
diff --git a/src/goaidentity/goaidentitymanager.c b/src/goaidentity/goaidentitymanager.c
|
|
|
1e691d |
index 40d2225..22dcd97 100644
|
|
|
1e691d |
--- a/src/goaidentity/goaidentitymanager.c
|
|
|
1e691d |
+++ b/src/goaidentity/goaidentitymanager.c
|
|
|
1e691d |
@@ -202,6 +202,7 @@ void
|
|
|
1e691d |
goa_identity_manager_sign_identity_in (GoaIdentityManager *self,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
@@ -212,6 +213,7 @@ goa_identity_manager_sign_identity_in (GoaIdentityManager *self,
|
|
|
1e691d |
GOA_IDENTITY_MANAGER_GET_IFACE (self)->sign_identity_in (self,
|
|
|
1e691d |
identifier,
|
|
|
1e691d |
initial_password,
|
|
|
1e691d |
+ preauth_source,
|
|
|
1e691d |
flags,
|
|
|
1e691d |
inquiry_func,
|
|
|
1e691d |
inquiry_data,
|
|
|
1e691d |
diff --git a/src/goaidentity/goaidentitymanager.h b/src/goaidentity/goaidentitymanager.h
|
|
|
1e691d |
index 89e6b6e..755053a 100644
|
|
|
1e691d |
--- a/src/goaidentity/goaidentitymanager.h
|
|
|
1e691d |
+++ b/src/goaidentity/goaidentitymanager.h
|
|
|
1e691d |
@@ -77,6 +77,7 @@ struct _GoaIdentityManagerInterface
|
|
|
1e691d |
void (* sign_identity_in) (GoaIdentityManager *identity_manager,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
@@ -140,6 +141,7 @@ GList *goa_identity_manager_list_identities_finish (GoaIdentityManager *identit
|
|
|
1e691d |
void goa_identity_manager_sign_identity_in (GoaIdentityManager *identity_manager,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
|
|
|
1e691d |
index 06fb946..38bbde6 100644
|
|
|
1e691d |
--- a/src/goaidentity/goaidentityservice.c
|
|
|
1e691d |
+++ b/src/goaidentity/goaidentityservice.c
|
|
|
1e691d |
@@ -60,6 +60,7 @@ static void
|
|
|
1e691d |
sign_in (GoaIdentityService *self,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GCancellable *cancellable,
|
|
|
1e691d |
GAsyncReadyCallback callback,
|
|
|
1e691d |
@@ -312,7 +313,8 @@ static void
|
|
|
1e691d |
read_sign_in_details (GoaIdentityServiceManager *manager,
|
|
|
1e691d |
GVariant *details,
|
|
|
1e691d |
GoaIdentitySignInFlags *flags,
|
|
|
1e691d |
- char **secret_key)
|
|
|
1e691d |
+ char **secret_key,
|
|
|
1e691d |
+ char **preauth_source)
|
|
|
1e691d |
{
|
|
|
1e691d |
GVariantIter iter;
|
|
|
1e691d |
char *key;
|
|
|
1e691d |
@@ -324,6 +326,8 @@ read_sign_in_details (GoaIdentityServiceManager *manager,
|
|
|
1e691d |
{
|
|
|
1e691d |
if (g_strcmp0 (key, "initial-password") == 0)
|
|
|
1e691d |
*secret_key = g_strdup (value);
|
|
|
1e691d |
+ else if (g_strcmp0 (key, "preauthentication-source") == 0)
|
|
|
1e691d |
+ *preauth_source = g_strdup (value);
|
|
|
1e691d |
else if (g_strcmp0 (key, "disallow-renewal") == 0
|
|
|
1e691d |
&& g_strcmp0 (value, "true") == 0)
|
|
|
1e691d |
*flags |= GOA_IDENTITY_SIGN_IN_FLAGS_DISALLOW_RENEWAL;
|
|
|
1e691d |
@@ -346,13 +350,15 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
|
|
|
1e691d |
GSimpleAsyncResult *operation_result;
|
|
|
1e691d |
GoaIdentitySignInFlags flags;
|
|
|
1e691d |
char *secret_key;
|
|
|
1e691d |
+ char *preauth_source;
|
|
|
1e691d |
gconstpointer initial_password;
|
|
|
1e691d |
GCancellable *cancellable;
|
|
|
1e691d |
|
|
|
1e691d |
secret_key = NULL;
|
|
|
1e691d |
+ preauth_source = NULL;
|
|
|
1e691d |
initial_password = NULL;
|
|
|
1e691d |
|
|
|
1e691d |
- read_sign_in_details (manager, details, &flags, &secret_key);
|
|
|
1e691d |
+ read_sign_in_details (manager, details, &flags, &secret_key, &preauth_source);
|
|
|
1e691d |
|
|
|
1e691d |
if (secret_key != NULL)
|
|
|
1e691d |
{
|
|
|
1e691d |
@@ -397,12 +403,14 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
|
|
|
1e691d |
sign_in (self,
|
|
|
1e691d |
identifier,
|
|
|
1e691d |
initial_password,
|
|
|
1e691d |
+ preauth_source,
|
|
|
1e691d |
flags,
|
|
|
1e691d |
cancellable,
|
|
|
1e691d |
(GAsyncReadyCallback)
|
|
|
1e691d |
on_sign_in_done,
|
|
|
1e691d |
operation_result);
|
|
|
1e691d |
|
|
|
1e691d |
+ g_free (preauth_source);
|
|
|
1e691d |
g_object_unref (cancellable);
|
|
|
1e691d |
|
|
|
1e691d |
return TRUE;
|
|
|
1e691d |
@@ -868,6 +876,7 @@ add_temporary_account (GoaIdentityService *self,
|
|
|
1e691d |
GoaIdentity *identity)
|
|
|
1e691d |
{
|
|
|
1e691d |
char *realm;
|
|
|
1e691d |
+ char *preauth_source;
|
|
|
1e691d |
const char *principal;
|
|
|
1e691d |
char *principal_for_display;
|
|
|
1e691d |
GSimpleAsyncResult *operation_result;
|
|
|
1e691d |
@@ -894,12 +903,15 @@ add_temporary_account (GoaIdentityService *self,
|
|
|
1e691d |
identity);
|
|
|
1e691d |
|
|
|
1e691d |
realm = goa_kerberos_identity_get_realm_name (GOA_KERBEROS_IDENTITY (identity));
|
|
|
1e691d |
+ preauth_source = goa_kerberos_identity_get_preauthentication_source (GOA_KERBEROS_IDENTITY (identity));
|
|
|
1e691d |
|
|
|
1e691d |
g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
|
|
|
1e691d |
|
|
|
1e691d |
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
|
|
|
1e691d |
g_variant_builder_add (&details, "{ss}", "Realm", realm);
|
|
|
1e691d |
g_variant_builder_add (&details, "{ss}", "IsTemporary", "true");
|
|
|
1e691d |
+ if (preauth_source != NULL)
|
|
|
1e691d |
+ g_variant_builder_add (&details, "{ss}", "PreauthenticationSource", preauth_source);
|
|
|
1e691d |
g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
|
|
|
1e691d |
|
|
|
1e691d |
|
|
|
1e691d |
@@ -925,6 +937,7 @@ add_temporary_account (GoaIdentityService *self,
|
|
|
1e691d |
on_account_added,
|
|
|
1e691d |
operation_result);
|
|
|
1e691d |
g_free (realm);
|
|
|
1e691d |
+ g_free (preauth_source);
|
|
|
1e691d |
g_free (principal_for_display);
|
|
|
1e691d |
}
|
|
|
1e691d |
|
|
|
1e691d |
@@ -1261,6 +1274,7 @@ static void
|
|
|
1e691d |
sign_in (GoaIdentityService *self,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GCancellable *cancellable,
|
|
|
1e691d |
GAsyncReadyCallback callback,
|
|
|
1e691d |
@@ -1288,6 +1302,7 @@ sign_in (GoaIdentityService *self,
|
|
|
1e691d |
goa_identity_manager_sign_identity_in (self->priv->identity_manager,
|
|
|
1e691d |
identifier,
|
|
|
1e691d |
initial_password,
|
|
|
1e691d |
+ preauth_source,
|
|
|
1e691d |
flags,
|
|
|
1e691d |
(GoaIdentityInquiryFunc)
|
|
|
1e691d |
on_identity_inquiry,
|
|
|
1e691d |
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
|
|
|
1e691d |
index d501a59..4370a09 100644
|
|
|
1e691d |
--- a/src/goaidentity/goakerberosidentity.c
|
|
|
1e691d |
+++ b/src/goaidentity/goakerberosidentity.c
|
|
|
1e691d |
@@ -47,6 +47,8 @@ struct _GoaKerberosIdentityPrivate
|
|
|
1e691d |
char *identifier;
|
|
|
1e691d |
guint identifier_idle_id;
|
|
|
1e691d |
|
|
|
1e691d |
+ char *preauth_identity_source;
|
|
|
1e691d |
+
|
|
|
1e691d |
krb5_timestamp expiration_time;
|
|
|
1e691d |
guint expiration_time_idle_id;
|
|
|
1e691d |
|
|
|
1e691d |
@@ -106,6 +108,8 @@ goa_kerberos_identity_dispose (GObject *object)
|
|
|
1e691d |
|
|
|
1e691d |
G_LOCK (identity_lock);
|
|
|
1e691d |
clear_alarms (self);
|
|
|
1e691d |
+ g_clear_pointer (&self->priv->preauth_identity_source,
|
|
|
1e691d |
+ g_free);
|
|
|
1e691d |
G_UNLOCK (identity_lock);
|
|
|
1e691d |
|
|
|
1e691d |
G_OBJECT_CLASS (goa_kerberos_identity_parent_class)->dispose (object);
|
|
|
1e691d |
@@ -406,6 +410,12 @@ goa_kerberos_identity_get_realm_name (GoaKerberosIdentity *self)
|
|
|
1e691d |
return realm_name;
|
|
|
1e691d |
}
|
|
|
1e691d |
|
|
|
1e691d |
+char *
|
|
|
1e691d |
+goa_kerberos_identity_get_preauthentication_source (GoaKerberosIdentity *self)
|
|
|
1e691d |
+{
|
|
|
1e691d |
+ return g_strdup (self->priv->preauth_identity_source);
|
|
|
1e691d |
+}
|
|
|
1e691d |
+
|
|
|
1e691d |
static const char *
|
|
|
1e691d |
goa_kerberos_identity_get_identifier (GoaIdentity *identity)
|
|
|
1e691d |
{
|
|
|
1e691d |
@@ -454,6 +464,44 @@ credentials_validate_existence (GoaKerberosIdentity *self,
|
|
|
1e691d |
return TRUE;
|
|
|
1e691d |
}
|
|
|
1e691d |
|
|
|
1e691d |
+static gboolean
|
|
|
1e691d |
+snoop_preauth_identity_from_credentials (GoaKerberosIdentity *self,
|
|
|
1e691d |
+ krb5_creds *credentials,
|
|
|
1e691d |
+ char **identity_source)
|
|
|
1e691d |
+{
|
|
|
1e691d |
+ GRegex *regex;
|
|
|
1e691d |
+ GMatchInfo *match_info = NULL;
|
|
|
1e691d |
+ gboolean identity_source_exposed = FALSE;
|
|
|
1e691d |
+
|
|
|
1e691d |
+ if (!krb5_is_config_principal (self->priv->kerberos_context, credentials->server))
|
|
|
1e691d |
+ return FALSE;
|
|
|
1e691d |
+
|
|
|
1e691d |
+ regex = g_regex_new ("\"X509_user_identity\":\"(?P<identity_source>[^\"]*)\"",
|
|
|
1e691d |
+ G_REGEX_MULTILINE | G_REGEX_CASELESS | G_REGEX_RAW,
|
|
|
1e691d |
+ 0,
|
|
|
1e691d |
+ NULL);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ if (regex == NULL)
|
|
|
1e691d |
+ return FALSE;
|
|
|
1e691d |
+
|
|
|
1e691d |
+ g_regex_match_full (regex, credentials->ticket.data, credentials->ticket.length, 0, 0, &match_info, NULL);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ if (match_info != NULL && g_match_info_matches (match_info))
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ if (identity_source)
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ g_free (*identity_source);
|
|
|
1e691d |
+ *identity_source = g_match_info_fetch_named (match_info, "identity_source");
|
|
|
1e691d |
+ }
|
|
|
1e691d |
+ identity_source_exposed = TRUE;
|
|
|
1e691d |
+ }
|
|
|
1e691d |
+
|
|
|
1e691d |
+ g_match_info_free (match_info);
|
|
|
1e691d |
+ g_regex_unref (regex);
|
|
|
1e691d |
+
|
|
|
1e691d |
+ return identity_source_exposed;
|
|
|
1e691d |
+}
|
|
|
1e691d |
+
|
|
|
1e691d |
static krb5_timestamp
|
|
|
1e691d |
get_current_time (GoaKerberosIdentity *self)
|
|
|
1e691d |
{
|
|
|
1e691d |
@@ -565,6 +613,7 @@ credentials_are_expired (GoaKerberosIdentity *self,
|
|
|
1e691d |
|
|
|
1e691d |
static VerificationLevel
|
|
|
1e691d |
verify_identity (GoaKerberosIdentity *self,
|
|
|
1e691d |
+ char **preauth_identity_source,
|
|
|
1e691d |
GError **error)
|
|
|
1e691d |
{
|
|
|
1e691d |
krb5_principal principal = NULL;
|
|
|
1e691d |
@@ -627,6 +676,10 @@ verify_identity (GoaKerberosIdentity *self,
|
|
|
1e691d |
else
|
|
|
1e691d |
verification_level = VERIFICATION_LEVEL_EXISTS;
|
|
|
1e691d |
}
|
|
|
1e691d |
+ else
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ snoop_preauth_identity_from_credentials (self, &credentials, preauth_identity_source);
|
|
|
1e691d |
+ }
|
|
|
1e691d |
|
|
|
1e691d |
krb5_free_cred_contents (self->priv->kerberos_context, &credentials);
|
|
|
1e691d |
|
|
|
1e691d |
@@ -933,7 +986,7 @@ goa_kerberos_identity_initable_init (GInitable *initable,
|
|
|
1e691d |
|
|
|
1e691d |
verification_error = NULL;
|
|
|
1e691d |
self->priv->cached_verification_level =
|
|
|
1e691d |
- verify_identity (self, &verification_error);
|
|
|
1e691d |
+ verify_identity (self, &self->priv->preauth_identity_source, &verification_error);
|
|
|
1e691d |
|
|
|
1e691d |
switch (self->priv->cached_verification_level)
|
|
|
1e691d |
{
|
|
|
1e691d |
@@ -1140,6 +1193,7 @@ gboolean
|
|
|
1e691d |
goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
|
|
|
1e691d |
const char *principal_name,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
@@ -1211,6 +1265,13 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
|
|
|
1e691d |
if ((flags & GOA_IDENTITY_SIGN_IN_FLAGS_DISALLOW_RENEWAL) == 0)
|
|
|
1e691d |
krb5_get_init_creds_opt_set_renew_life (options, G_MAXINT);
|
|
|
1e691d |
|
|
|
1e691d |
+ if (preauth_source != NULL)
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ krb5_get_init_creds_opt_set_pa (self->priv->kerberos_context,
|
|
|
1e691d |
+ options,
|
|
|
1e691d |
+ "X509_user_identity", preauth_source);
|
|
|
1e691d |
+ }
|
|
|
1e691d |
+
|
|
|
1e691d |
/* Poke glibc in case the network changed
|
|
|
1e691d |
*/
|
|
|
1e691d |
res_init ();
|
|
|
1e691d |
@@ -1301,6 +1362,7 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
|
|
|
1e691d |
GoaKerberosIdentity *new_identity)
|
|
|
1e691d |
{
|
|
|
1e691d |
VerificationLevel verification_level;
|
|
|
1e691d |
+ char *preauth_identity_source = NULL;
|
|
|
1e691d |
|
|
|
1e691d |
if (self->priv->credentials_cache != NULL)
|
|
|
1e691d |
krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache);
|
|
|
1e691d |
@@ -1313,13 +1375,18 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
|
|
|
1e691d |
update_identifier (self, new_identity);
|
|
|
1e691d |
G_UNLOCK (identity_lock);
|
|
|
1e691d |
|
|
|
1e691d |
- verification_level = verify_identity (self, NULL);
|
|
|
1e691d |
+ verification_level = verify_identity (self, &preauth_identity_source, NULL);
|
|
|
1e691d |
|
|
|
1e691d |
if (verification_level == VERIFICATION_LEVEL_SIGNED_IN)
|
|
|
1e691d |
reset_alarms (self);
|
|
|
1e691d |
else
|
|
|
1e691d |
clear_alarms (self);
|
|
|
1e691d |
|
|
|
1e691d |
+ G_LOCK (identity_lock);
|
|
|
1e691d |
+ g_free (self->priv->preauth_identity_source);
|
|
|
1e691d |
+ self->priv->preauth_identity_source = preauth_identity_source;
|
|
|
1e691d |
+ G_UNLOCK (identity_lock);
|
|
|
1e691d |
+
|
|
|
1e691d |
if (verification_level != self->priv->cached_verification_level)
|
|
|
1e691d |
{
|
|
|
1e691d |
if (self->priv->cached_verification_level == VERIFICATION_LEVEL_SIGNED_IN &&
|
|
|
1e691d |
diff --git a/src/goaidentity/goakerberosidentity.h b/src/goaidentity/goakerberosidentity.h
|
|
|
1e691d |
index 1e24796..8d2860a 100644
|
|
|
1e691d |
--- a/src/goaidentity/goakerberosidentity.h
|
|
|
1e691d |
+++ b/src/goaidentity/goakerberosidentity.h
|
|
|
1e691d |
@@ -66,6 +66,7 @@ GoaIdentity *goa_kerberos_identity_new (krb5_context kerberos_context,
|
|
|
1e691d |
gboolean goa_kerberos_identity_sign_in (GoaKerberosIdentity *self,
|
|
|
1e691d |
const char *principal_name,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
@@ -81,5 +82,6 @@ gboolean goa_kerberos_identity_erase (GoaKerberosIdentity *self,
|
|
|
1e691d |
|
|
|
1e691d |
char *goa_kerberos_identity_get_principal_name (GoaKerberosIdentity *self);
|
|
|
1e691d |
char *goa_kerberos_identity_get_realm_name (GoaKerberosIdentity *self);
|
|
|
1e691d |
+char *goa_kerberos_identity_get_preauthentication_source (GoaKerberosIdentity *self);
|
|
|
1e691d |
G_END_DECLS
|
|
|
1e691d |
#endif /* __GOA_KERBEROS_IDENTITY_H__ */
|
|
|
1e691d |
diff --git a/src/goaidentity/goakerberosidentitymanager.c b/src/goaidentity/goakerberosidentitymanager.c
|
|
|
1e691d |
index c9796ad..a1898c9 100644
|
|
|
1e691d |
--- a/src/goaidentity/goakerberosidentitymanager.c
|
|
|
1e691d |
+++ b/src/goaidentity/goakerberosidentitymanager.c
|
|
|
1e691d |
@@ -81,6 +81,7 @@ typedef struct
|
|
|
1e691d |
{
|
|
|
1e691d |
const char *identifier;
|
|
|
1e691d |
gconstpointer initial_password;
|
|
|
1e691d |
+ char *preauth_source;
|
|
|
1e691d |
GoaIdentitySignInFlags sign_in_flags;
|
|
|
1e691d |
GoaIdentityInquiry *inquiry;
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func;
|
|
|
1e691d |
@@ -151,10 +152,14 @@ operation_free (Operation *operation)
|
|
|
1e691d |
|
|
|
1e691d |
if (operation->type != OPERATION_TYPE_SIGN_IN &&
|
|
|
1e691d |
operation->type != OPERATION_TYPE_GET_IDENTITY)
|
|
|
1e691d |
- g_clear_object (&operation->identity);
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ g_clear_object (&operation->identity);
|
|
|
1e691d |
+ }
|
|
|
1e691d |
else
|
|
|
1e691d |
- g_clear_pointer (&operation->identifier, g_free);
|
|
|
1e691d |
-
|
|
|
1e691d |
+ {
|
|
|
1e691d |
+ g_clear_pointer (&operation->identifier, g_free);
|
|
|
1e691d |
+ g_clear_pointer (&operation->preauth_source, g_free);
|
|
|
1e691d |
+ }
|
|
|
1e691d |
g_clear_object (&operation->result);
|
|
|
1e691d |
|
|
|
1e691d |
g_slice_free (Operation, operation);
|
|
|
1e691d |
@@ -863,6 +868,7 @@ sign_in_identity (GoaKerberosIdentityManager *self,
|
|
|
1e691d |
if (!goa_kerberos_identity_sign_in (GOA_KERBEROS_IDENTITY (identity),
|
|
|
1e691d |
operation->identifier,
|
|
|
1e691d |
operation->initial_password,
|
|
|
1e691d |
+ operation->preauth_source,
|
|
|
1e691d |
operation->sign_in_flags,
|
|
|
1e691d |
(GoaIdentityInquiryFunc)
|
|
|
1e691d |
on_kerberos_identity_inquiry,
|
|
|
1e691d |
@@ -1178,6 +1184,7 @@ static void
|
|
|
1e691d |
goa_kerberos_identity_manager_sign_identity_in (GoaIdentityManager *manager,
|
|
|
1e691d |
const char *identifier,
|
|
|
1e691d |
gconstpointer initial_password,
|
|
|
1e691d |
+ const char *preauth_source,
|
|
|
1e691d |
GoaIdentitySignInFlags flags,
|
|
|
1e691d |
GoaIdentityInquiryFunc inquiry_func,
|
|
|
1e691d |
gpointer inquiry_data,
|
|
|
1e691d |
@@ -1201,6 +1208,7 @@ goa_kerberos_identity_manager_sign_identity_in (GoaIdentityManager *manager,
|
|
|
1e691d |
* for duration of operation
|
|
|
1e691d |
*/
|
|
|
1e691d |
operation->initial_password = initial_password;
|
|
|
1e691d |
+ operation->preauth_source = g_strdup (preauth_source);
|
|
|
1e691d |
operation->sign_in_flags = flags;
|
|
|
1e691d |
operation->inquiry_func = inquiry_func;
|
|
|
1e691d |
operation->inquiry_data = inquiry_data;
|
|
|
1e691d |
--
|
|
|
1e691d |
2.1.0
|
|
|
1e691d |
|