gssapi and an expired TGT in cache

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

gssapi and an expired TGT in cache

Sorin Manolache
Hello,

I use the GSSAPI in order to get a TGT and then I use the TGT in order
to get a service ticket.

The code is:

gss_cred_id_t cred;
gss_acquire_cred_with_password(&minor, name, &pwd, GSS_C_INDEFINITE,
GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred, &actual_mechs, &time_rec);

Then I pass the acquired cred to gss_init_sec_context(... cred ...).

If I have a cache file and the cache contains an expired TGT then

*) no request is made to the KDC
*) gss_acquire_cred_with_password succeeds
*) time_rec is zero after gss_acquire_cred_with_password
*) gss_init_sec_context fails with GSS_S_FAILURE and the minor code is
KRB5KRB_AP_ERR_TKT_EXPIRED. The call chain is
...->krb5_tkt_creds_get->krb5_tkt_creds_step->...->get_cached_local_tgt.

If I run kdestroy and I reexecute the code above then

*) a request is made to the KDC
*) gss_init_sec_context succeeds
*) the TGT and the service ticket are added to the cache.

Is this the intended behaviour? I thought that caches do not change the
functionality of a program but just improve its performance.

Is there a way to change this behaviour at GSSAPI level? To expose the
krb5_ccache of a gss_cred_id_t credential? In particular I would like to
remove the expired TGT from the cache and reexecute the
gss_acquire_cred_with_password.

If it is not possible at GSSAPI level, how should I do it at krb5 level?
I have a gss_cred_id_t and I need a krb5_context, a krb5_creds, and a
krb5_ccache in order to execute krb5_cc_remove_cred.

TIA,
Sorin
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: gssapi and an expired TGT in cache

Greg Hudson
On 03/03/2015 10:34 AM, Sorin Manolache wrote:
> If I have a cache file and the cache contains an expired TGT then
> *) no request is made to the KDC

This looks like a bug.  I will file a ticket.

> Is there a way to change this behaviour at GSSAPI level? To expose the
> krb5_ccache of a gss_cred_id_t credential? In particular I would like to
> remove the expired TGT from the cache and reexecute the
> gss_acquire_cred_with_password.

Not using generic GSSAPI functions, no.

> If it is not possible at GSSAPI level, how should I do it at krb5 level?
> I have a gss_cred_id_t and I need a krb5_context, a krb5_creds, and a
> krb5_ccache in order to execute krb5_cc_remove_cred.

krb5_cc_remove_cred() isn't implemented for the FILE ccache type.  Your
best options for working around this are (1) to destroy the cache
entirely, (2) to use a memory ccache, or (3) to use a client keytab.
The third option is the best if it meets your requirements, which it
might not.

For the first option, you want krb5_init_context(), krb5_cc_default(),
and krb5_cc_destroy().  To clean up you want krb5_free_context().

For the second option, you want krb5_init_context(),
krb5_cc_new_unique(context, "MEMORY", NULL, &id),
krb5_cc_get_full_name(), and gss_krb5_ccache_name().  To clean up you
want krb5_cc_close() and krb5_free_context().  gss_krb5_ccache_name()
sets a thread-specific global variable which affects future krb5 GSSAPI
operations in that thread; you can clear it by calling it again with a
NULL value.

For the third option, you'll need to change the application to use
gss_acquire_cred() instead of gss_acquire_cred_with_password().  Create
a keytab whose first key is the desired client key, set the
KRB5_CLIENT_KTNAME environment variable to the path to that file,
possibly set KRB5CCNAME to a file which won't be disturbed by other
uses, and let the krb5 GSSAPI code manage the ccache.

Some of the features mentioned above are relatively new and might not be
available in older versions.
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: gssapi and an expired TGT in cache

Sorin Manolache
On 2015-03-03 18:05, Greg Hudson wrote:

Thank you for your very informative reply.

>
>> If it is not possible at GSSAPI level, how should I do it at krb5 level?
>> I have a gss_cred_id_t and I need a krb5_context, a krb5_creds, and a
>> krb5_ccache in order to execute krb5_cc_remove_cred.
>
> krb5_cc_remove_cred() isn't implemented for the FILE ccache type.  Your
> best options for working around this are (1) to destroy the cache
> entirely, (2) to use a memory ccache, or (3) to use a client keytab.
> The third option is the best if it meets your requirements, which it
> might not.
>
> For the second option, you want krb5_init_context(),
> krb5_cc_new_unique(context, "MEMORY", NULL, &id),
> krb5_cc_get_full_name(), and gss_krb5_ccache_name().  To clean up you
> want krb5_cc_close() and krb5_free_context().  gss_krb5_ccache_name()
> sets a thread-specific global variable which affects future krb5 GSSAPI
> operations in that thread; you can clear it by calling it again with a
> NULL value.

Unfortunately it seems that krb5_cc_remove_cred is not implemented for
the memory cache type either.

Apparently the kcm cache type implements it. However kcm is not
available in my version of kerberos (1.12.1) and it's unlikely that the
sysadmins will backport it for the version of the linux distribution
that we have in production.

I guess I'll stick with the cache destruction method.

Thanks again.

Sorin

_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: gssapi and an expired TGT in cache

Greg Hudson
On 03/04/2015 10:42 AM, Sorin Manolache wrote:
> Unfortunately it seems that krb5_cc_remove_cred is not implemented for
> the memory cache type either.

Yes, but if you use a memory ccache, you won't be sharing with other
processes, so there will never be pre-existing creds there.

_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: gssapi and an expired TGT in cache

Sorin Manolache
On 2015-03-04 17:21, Greg Hudson wrote:
> On 03/04/2015 10:42 AM, Sorin Manolache wrote:
>> Unfortunately it seems that krb5_cc_remove_cred is not implemented for
>> the memory cache type either.
>
> Yes, but if you use a memory ccache, you won't be sharing with other
> processes, so there will never be pre-existing creds there.
>

That is true. However my application is a http server module with an
indefinite running time (similar to
http://css.csail.mit.edu/6.858/2014/projects/kanter-bcyphers-bfaviero-jpeebles.pdf)
so the credentials will eventually expire.

As the server is multi-threaded the krb5_cc_destroy alternative doesn't
work either: all gss_acquire_cred/krb5 calls should be then protected by
a mutex in order to avoid a race condition with krb5_cc_destroy. As my
module does almost exclusively gssapi/krb5 calls the whole application
becomes almost mono-threaded.

So I see the following alternatives:

1) patch gss_acquire_cred_with_password such that it detects that the
TGT stored in the cache is expired, makes a KDC request, and replaces
the expired TGT in the cache with the newly created TGT.

2) implement krb5_mcc_remove_cred. Is there any particular reason why it
was left unimplemented?

3) switch to the heimdal implementation. However heimdal uses the cache
only if the desired name passed to gss_acquire_cred is the default
principal of the cache so it's not really what I want either.

I would try the 2nd. If I succeed I'll submit the patch. If I fail, I'll
go with the 3rd one.

Best regards,
Sorin

_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev