Patches for KRB cache issues.

Resolves: #2152695
This commit is contained in:
Ray Strode 2022-12-17 22:58:54 -05:00
parent eff82aff54
commit 7c69675add
3 changed files with 321 additions and 1 deletions

35
115.patch Normal file
View File

@ -0,0 +1,35 @@
From 8c5b63069dfbf36ac662369d9ba3fb4ab0d2efb2 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 15 Dec 2022 14:46:01 -0500
Subject: [PATCH 2/2] kerberos-identity: Fix buglet in update_identity
The update_identity function is supposed to transfer the identity
form one object to another.
In practice, this is currently always a noop because only objects
with the same identities get copied to each other.
Nevertheless, there is a bug in the function. It grabs the identity
from the target object instead of from the source object.
This commit fixes that.
---
src/goaidentity/goakerberosidentity.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index a20c0438..bc607966 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -1507,7 +1507,7 @@ update_identifier (GoaKerberosIdentity *self, GoaKerberosIdentity *new_identity)
{
char *new_identifier;
- new_identifier = get_identifier (self, NULL);
+ new_identifier = get_identifier (new_identity, NULL);
if (g_strcmp0 (self->identifier, new_identifier) != 0 && new_identifier != NULL)
{
g_free (self->identifier);
--
GitLab

278
116.patch Normal file
View File

@ -0,0 +1,278 @@
From c17527f4996614bd7fcefde6e1f8949c61d3c96c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 15 Dec 2022 16:27:27 -0500
Subject: [PATCH 1/2] goakerberosidentity: Fix crash when erasing credentials
Right now when erasing an identity we erase the
active credentials first and then the inactive
ones.
We neglect to take the active one out of the hash
table, though, so it gets destroyed twice.
This commit fixes that.
---
src/goaidentity/goakerberosidentity.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index 9e9b8a74..ac550f12 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -1686,60 +1686,62 @@ goa_kerberos_identity_renew (GoaKerberosIdentity *self, GError **error)
{
goto free_principal;
}
g_debug ("GoaKerberosIdentity: identity %s renewed", name);
renewed = TRUE;
free_principal:
krb5_free_principal (self->kerberos_context, principal);
out:
g_free (name);
return renewed;
}
gboolean
goa_kerberos_identity_erase (GoaKerberosIdentity *self, GError **error)
{
GHashTableIter iter;
const char *name;
krb5_ccache credentials_cache;
krb5_error_code error_code = 0;
if (self->active_credentials_cache_name != NULL)
{
credentials_cache = (krb5_ccache) g_hash_table_lookup (self->credentials_caches,
self->active_credentials_cache_name);
g_debug ("GoaKerberosIdentity: Destroying active credentials cache %s", self->active_credentials_cache_name);
error_code = krb5_cc_destroy (self->kerberos_context, credentials_cache);
+ g_hash_table_remove (self->credentials_caches, self->active_credentials_cache_name);
+
g_clear_pointer (&self->active_credentials_cache_name, g_free);
if (error_code != 0)
{
set_and_prefix_error_from_krb5_error_code (self,
error,
GOA_IDENTITY_ERROR_REMOVING_CREDENTIALS,
error_code, _("Could not erase identity: "));
}
}
g_hash_table_iter_init (&iter, self->credentials_caches);
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer*) &credentials_cache))
{
g_debug ("GoaKerberosIdentity: Destroying inactive credentials cache %s", name);
krb5_cc_destroy (self->kerberos_context, credentials_cache);
}
g_hash_table_remove_all (self->credentials_caches);
return error_code == 0;
}
GoaIdentity *
goa_kerberos_identity_new (krb5_context context, krb5_ccache cache, GError **error)
{
GoaKerberosIdentity *self;
krb5_ccache copied_cache;
self = GOA_KERBEROS_IDENTITY (g_object_new (GOA_TYPE_KERBEROS_IDENTITY, NULL));
self->kerberos_context = context;
--
2.37.0.rc1
From 2bb898f5137d09e998e2d5ad0127a65df8cf15e0 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 15 Dec 2022 15:35:49 -0500
Subject: [PATCH 2/2] goakerberosidentity: Explicitly switch to credentials
cache when needed
If we're updating a credentials cache and decide
it should be the new default for an identity, and
the old credentials cache was the default cache
for the cache collection then we should make the
new credential cache the default cache for the
collection, too.
This commit adds that. It also makes the new
credentials cache the default if there wasn't a
valid default set already. This brings consistency
to differences in behavior from different kerberos
ccache types.
---
src/goaidentity/goakerberosidentity.c | 65 +++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index ac550f12..71c1ff09 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -1524,98 +1524,157 @@ goa_kerberos_identity_compare (GoaKerberosIdentity *self,
if (self->cached_verification_level < new_identity->cached_verification_level)
return -100;
if (self->cached_verification_level > new_identity->cached_verification_level)
return 100;
if (self->cached_verification_level != VERIFICATION_LEVEL_SIGNED_IN)
return 50;
if (self->expiration_time < new_identity->expiration_time)
return -10;
if (self->expiration_time > new_identity->expiration_time)
return 10;
if (self->start_time > new_identity->start_time)
return -5;
if (self->start_time < new_identity->start_time)
return 5;
if (self->renewal_time < new_identity->renewal_time)
return -1;
if (self->renewal_time > new_identity->renewal_time)
return 1;
return 0;
}
+static char *
+get_default_cache_name (GoaKerberosIdentity *self)
+{
+ int error_code;
+ krb5_ccache default_cache;
+ krb5_principal principal;
+ char *default_cache_name;
+ char *principal_name;
+
+ error_code = krb5_cc_default (self->kerberos_context, &default_cache);
+
+ if (error_code != 0)
+ return NULL;
+
+ /* Return NULL if the default cache doesn't pass basic sanity checks
+ */
+ error_code = krb5_cc_get_principal (self->kerberos_context, default_cache, &principal);
+
+ if (error_code != 0)
+ return NULL;
+
+ error_code = krb5_unparse_name_flags (self->kerberos_context, principal, 0, &principal_name);
+ krb5_free_principal (self->kerberos_context, principal);
+
+ if (error_code != 0)
+ return NULL;
+
+ krb5_free_unparsed_name (self->kerberos_context, principal_name);
+
+ default_cache_name = g_strdup (krb5_cc_get_name (self->kerberos_context, default_cache));
+ krb5_cc_close (self->kerberos_context, default_cache);
+
+ return default_cache_name;
+}
+
void
goa_kerberos_identity_update (GoaKerberosIdentity *self,
GoaKerberosIdentity *new_identity)
{
VerificationLevel old_verification_level, new_verification_level;
gboolean time_changed = FALSE;
char *preauth_identity_source = NULL;
int comparison;
+ G_LOCK (identity_lock);
+
+ old_verification_level = self->cached_verification_level;
+ new_verification_level = new_identity->cached_verification_level;
+
comparison = goa_kerberos_identity_compare (self, new_identity);
if (new_identity->active_credentials_cache_name != NULL)
{
+ g_autofree char *default_cache_name = NULL;
krb5_ccache credentials_cache;
krb5_ccache copied_cache;
+ gboolean should_switch_to_new_credentials_cache = FALSE;
+
+ default_cache_name = get_default_cache_name (self);
+
+ if (default_cache_name == NULL)
+ should_switch_to_new_credentials_cache = TRUE;
credentials_cache = (krb5_ccache) g_hash_table_lookup (new_identity->credentials_caches,
new_identity->active_credentials_cache_name);
krb5_cc_dup (new_identity->kerberos_context, credentials_cache, &copied_cache);
+ if (g_strcmp0 (default_cache_name, self->active_credentials_cache_name) == 0)
+ {
+ if ((comparison < 0) ||
+ (comparison == 0 && old_verification_level != VERIFICATION_LEVEL_SIGNED_IN))
+ should_switch_to_new_credentials_cache = TRUE;
+ }
+
if (comparison < 0)
- g_clear_pointer (&self->active_credentials_cache_name, &g_free);
+ {
+ g_clear_pointer (&self->active_credentials_cache_name, g_free);
+ self->active_credentials_cache_name = g_strdup (new_identity->active_credentials_cache_name);
+ }
goa_kerberos_identity_add_credentials_cache (self, copied_cache);
+
+ if (should_switch_to_new_credentials_cache)
+ krb5_cc_switch (self->kerberos_context, copied_cache);
}
+ G_UNLOCK (identity_lock);
clear_alarms (new_identity);
if (comparison >= 0)
return;
G_LOCK (identity_lock);
update_identifier (self, new_identity);
time_changed |= set_start_time (self, new_identity->start_time);
time_changed |= set_renewal_time (self, new_identity->renewal_time);
time_changed |= set_expiration_time (self, new_identity->expiration_time);
- old_verification_level = self->cached_verification_level;
- new_verification_level = new_identity->cached_verification_level;
G_UNLOCK (identity_lock);
if (time_changed)
{
if (new_verification_level == VERIFICATION_LEVEL_SIGNED_IN)
reset_alarms (self);
else
clear_alarms (self);
}
G_LOCK (identity_lock);
g_free (self->preauth_identity_source);
self->preauth_identity_source = preauth_identity_source;
G_UNLOCK (identity_lock);
if (new_verification_level != old_verification_level)
{
if (old_verification_level == VERIFICATION_LEVEL_SIGNED_IN &&
new_verification_level == VERIFICATION_LEVEL_EXISTS)
{
G_LOCK (identity_lock);
self->cached_verification_level = new_verification_level;
G_UNLOCK (identity_lock);
g_signal_emit (G_OBJECT (self), signals[EXPIRED], 0);
}
else if (old_verification_level == VERIFICATION_LEVEL_EXISTS &&
new_verification_level == VERIFICATION_LEVEL_SIGNED_IN)
{
G_LOCK (identity_lock);
--
2.37.0.rc1

View File

@ -6,7 +6,7 @@
Name: gnome-online-accounts Name: gnome-online-accounts
Version: 3.46.0 Version: 3.46.0
Release: 2%{?dist} Release: 3%{?dist}
Summary: Single sign-on framework for GNOME Summary: Single sign-on framework for GNOME
License: LGPLv2+ License: LGPLv2+
@ -18,6 +18,8 @@ Source0: https://download.gnome.org/sources/gnome-online-accounts/3.46/%{name}-%
# https://bugzilla.redhat.com/show_bug.cgi?id=1913641 # https://bugzilla.redhat.com/show_bug.cgi?id=1913641
Patch0: 0001-google-Remove-Photos-support.patch Patch0: 0001-google-Remove-Photos-support.patch
Patch1: 112.patch Patch1: 112.patch
Patch2: 115.patch
Patch3: 116.patch
BuildRequires: pkgconfig(gcr-3) BuildRequires: pkgconfig(gcr-3)
@ -65,6 +67,8 @@ developing applications that use %{name}.
%endif %endif
%patch1 -p1 %patch1 -p1
%patch2 -p1
%patch3 -p1
%build %build
%meson \ %meson \
@ -119,6 +123,9 @@ developing applications that use %{name}.
%{_datadir}/vala/ %{_datadir}/vala/
%changelog %changelog
* Thu Dec 15 2022 Gwyn Ciesla <gwync@protonmail.com> - 3.46.0-3
- Patches for KRB cache issues.
* Wed Nov 30 2022 Gwyn Ciesla <gwync@protonmail.com> - 3.46.0-2 * Wed Nov 30 2022 Gwyn Ciesla <gwync@protonmail.com> - 3.46.0-2
- Patch for multiple credential cache issues. - Patch for multiple credential cache issues.