Credential collections
Nico Williams
nico at cryptonector.com
Wed Mar 23 16:27:02 EDT 2011
On Wed, Mar 23, 2011 at 2:56 PM, <ghudson at mit.edu> wrote:
> We need to decide how, in the core Unix code, to handle credentials
> for multiple client principals. There are three facets to this
> problem: API, CLI, and representation.
>
> API
> ---
>
> Most prior work on this problem has assumed that each ccache is for
> one client principal. This is not actually required by the krb5_cc_*
> data model; I think the idea flows mostly from the traditional
> behavior of kinit and kdestroy.
>
> We have a krb5_cccol_* API for iterating over all known ccaches;
So, the problem with ccache collections is that they really bleed into
the UI. Why should the user have to be aware of per-principal ccaches
and then, on top, a collection of those, when the user only really
cares about the TGTs they have, not the cached non-initial/non-TGT
tickets?
One answer might be that the user might want to use subsets of
credentials for different applications. But this is a difficult
problem because of the need to group processes that should see
particular sets of credentials, and each OS has a different approach
to this, thus this is a problem best left to the integrators. But
even granting this answer, I think I'd rather deal in views into
credentials sets than in collections of ccaches (and if you ask what
the difference is, the answer to that is that "ccache" is not really
something that users should have to be aware of).
The same, incidentally, goes for the developer. As a developer I want
a single object handle to represent access to the credential store,
and I want to be able to list the client principals for which there
are credentials, and I want to be able to ask for specific tickets. A
ccache collection concept isn't terribly complex, but it will require
more code if the developer has to first grab a ccache from the
collection then call krb5_get_creds() or whatever.
I'd rather add a new ccache type, APIs and CLIs for those, that
provide a collection than add a new abstraction. Even better: I'd
rather extend the existing ccache file format (or not -- just cluster
all TGTs in the beginning when adding credentials for additional
principals). Even better: I'd like a SQLite3-based ccache type and,
for compatibility with non-JNI JGSS programs and programs linked
statically, have the code also append tickets to a v4 ccache (but not
search it).
> Heimdal supports that as well (as well as its own
> krb5_cc_cache_get_first and krb5_cc_cache_get_next APIs, which operate
> on a single type). The implementation works best with a daemon-backed
> ccache type like API or KCM.
Well, if the implementations exist, then it's too late, and you can
just ignore the above comments.
> The options I can see for ccache lookup from the GSSAPI krb5 code are:
>
> 1. Use the krb5_cccol_* API, possibly adding a search operation to
> that API.
>
> 2. Reject the idea of a cache collection iterator, and just look for
> credentials of the desired client principal within the default ccache.
>
> 3. Use the richer kim_ccache_* API. (Requires using KIM for the first
> cut implementation, which may require more resources than we have
> available for this.)
>
> I personally prefer option 2 except that it ignores previous work.
I prefer extending the existing API to a new abstraction that builds
on the old one. But if the Heimdal interfaces are gaining traction
then you won't have much choice.
> CLI
> ---
>
> kinit and kdestroy can be used to manage multiple ccaches using the -c
> flag, but it's not very convenient. The only previous work I'm aware
> of in this area is in KfM, which has the following extensions:
>
> * "kinit principal" scans the collection for a ccache for principal,
> and creates a new unique CCAPI ccache if one doesn't exist.
>
> * "klist -A" lists creds for all ccaches in the collection.
>
> * "kdestroy -A" destroys all ccaches in the collection. "kdestroy -p
> principal" scans the collection for a ccache for principal and
> destroys it.
>
> * "kswitch -c ccname" or "kswitch -p princname" sets the default
> ccache in the collection. (In the normal case this translates into
> a message to the CCAPI daemon. When KRB5CCNAME is set the semantics
> are confusing to me and possibly broken.)
I like this except for the kswitch -c ccname case.
> The kinit change is substantial; users accustomed to the old behavior
> could wind up leaving tickets around.
Indeed. I'd be happy with needing an option to not clobber the prior
credentials.
> Options I can see are:
>
> 1. Implement the KfM extensions.
>
> 2. Implement the KfM extensions, but require a kinit flag to use the
> collection.
2, and/or with a krb5.conf param in addition to a kinit option.
> If we reject the idea of iterating over a cache collection, then the
> KfM extensions would need to be adjusted somewhat to make sense.
Yes, but fortunately the ccache collection concept hasn't bled too
much into the CLI.
> Representation
> --------------
>
> Iteration over ccaches currently works best with a daemon-backed
> ccache type. The daemon acts like a non-persistent filesystem
> containing only ccaches, which makes it easy to search.
>
> Unfortunately, we don't have a daemon-backed ccache type in the core
> krb5 Unix code yet. One possible answer is that this whole project
> should gate on a CCAPI or KCM implementation for Unix in MIT krb5. If
> we take that as the path, I'm guessing we could get the daemon-backed
> ccache done for 1.10, but probably nothing beyond that in the client
> identity selection space.
>
> So, some other options:
>
> 1. If we reject the idea of iterating over a cache collection, the
> representation problem becomes easy; credential collections are just
> FILE-format ccache files containing tickets for multiple client
> principals.
The main problem with this is that if the ccache gets large then
searching for credentials gets painful. My proposal would be that
whenever TGTs are added the ccache is re-written from scratch, with
all TGTs coming first, then all other INITIAL tickets, then all
cached, still-live non-INITIAL, non-TGT tickets.
My solution to the perf problem in general would be to use SQLite3 and
a v4 ccache file, with all searches done via the SQLite3 DB and all
additions done to both.
> 3. We could create the notion of a per-uid directory of ccaches, and
> try to somehow migrate there from the current default ccache names
> (typically /tmp/krb5cc_*, often chosen by pam_krb5 or similar).
I do believe that PAM / login is the best place to create something
like /var/run/krb5/ccache/<UID>/. This would instantly defeat the
sorts of attacks available when using well-known file names in /tmp/.
Nico
--
More information about the krbdev
mailing list