[OpenAFS-devel] [LKML] Re: In-kernel Authentication Tokens (PAGs)

Jeffrey Hutzelman jhutz@cmu.edu
Thu, 15 Jul 2004 11:27:39 -0400


On Wednesday, July 14, 2004 20:59:57 -0400 Kyle Moffett 
<mrmacman_g4@mac.com> wrote:

> On Jul 14, 2004, at 18:20, Jeffrey Hutzelman wrote:
>
>> OK, but what's a "key" ?
>> What value do I get to use to associate authentication context
>> with things like credentials, cached connections, rights
>> metadata, and so on?  Bear in mind that these structures are
>> not only fairly complex, but may belong to a user-mode
>> process.  So, it won't work to just make them be part of the "key".
>
> A "key" is a generic object with a name (Think Kerberos principal),
> a type (Kerberos service ticket, AES key, etc), and a binary blob of
> data.  The infrastructure itself doesn't much care what's _in_ the
> key, it only sets up some complex associations from a process to
> a set of "keys" that can be searched in a predefined order.
>
> I am not completely familiar with all of the metadata that AFS
> needs to maintain, but with the key system it is possible to have
> many different sets of keys accessible.  Perhaps AFS could just
> add an extra connection "key" blob that expires when whatever
> connection used ceases to exist.  If I have only received the
> initial Kerberos AFS ticket and have not actually tried to access
> the /afs tree, I won't have a "connection" key, but once I have, I
> get one.
>
> The key subsystem will have provisions for kernel modules that
> implement "key" types (Types that begin with a "+"), so that they
> can receive notifications when keys are created, deleted, expire
> are renewed, etc.

Wait..  So types that don't begin with a + are just random data that can be 
manipulated by things in user space?

I assume there will be some mechanism to limit how much storage a user can 
allocate in this fashion.

>> Basically, I need some sort of label I can use in these structures.
>> It must be the case that the meaning of a particular value of that
>> label cannot change without my receiving a notification, so I don't
>> end up with a cached connection established with one user's
>> credentials that is labelled with a label that now belongs to another
>> user.
>
> Here are the structure's that I'm using right now:
>
> struct key {
> 	struct key_type *type;
> 	
> 	spinlock_t lock;
> 	atomic_t refs;
> 	
> 	void *user_lock_owner;
> 	unsigned long user_lock_level;
> 	
> 	/* Undecided stuff here for key expiration */
> 	
> 	char *desc;
> 	void *blob;
> 	size_t blob_len;
> 	
> 	/* More permissions stuff here, not decided yet */
> };
>
> struct key_type {
> 	char *name;
> 	
> 	int (*will_create)(char **desc, void **blob, size_t *blob_len);
> 	void (*did_create)(struct key *key, const char *desc, const void *blob,
> size_t blob_len); 	
> 	int (*will_change_desc)(struct key *key, const char *old, char **new);
> 	void (*did_change_desc)(struct key *key, const char *old, const char
> *new); 	
> 	int (*will_change_blob)(struct key *key, const char *old, size_t
> old_len, char **new, size_t *new_len); 	void (*did_change_blob)(struct
> key *key, const char *old, size_t old_len, const char *new, size_t
> new_len); 	
> 	void (*will_destroy)(struct key *key);
> };
>
> There is also a key_handle type, but I haven't quite finalized
> all the aspects of how it should work yet.
>
>> Similarly, it is important to have notification when the credentials
>> themselves change -- if you set a new token, I need to throw away
>> cached connections established with the old token.
>
> Let's assume 2 objects, a generic "Kerberos service ticket" with
> no in-kernel handling, and an "AFS connection token" that has
> all the AFS metadata and a cached copy of the ticket used in
> that connection.  When a user runs the new and improved
> "aklog", their "afs/realm@REALM" Kerberos service ticket (type
> "+kerberos_v5_service" is searched for.  If found, its contents
> are copied along with any necessary metadata into the
> "afs/realm@REALM" token of type "+openafs_connection".
> AFS can store whatever it needs to have for the duration of the
> session, and run on the assumption that when their token is
> not needed it will lose all references and be deleted.

OK, except I can't necessarily just "store all the data in the key".
There has to be notification, since these data structures don't exist in 
isolation (a connection, for example, belongs to a hash table that allows 
the rx listener to determine which connection an incoming packet belongs 
to; cached filesystem metadata is stored in the vnode status cache), and 
since they might actually belong to a user-mode process that can't access 
kernel memory directly (arlad).

So again, there needs to be some sort of identifier which either
(a) is unique across an entire run of the system, or
(b) has a notification mechanism for when it goes away.

We currently assume (a) on most platforms, but I actually prefer (b) 
because it makes things cleaner -- you don't end up with a bunch of garbage 
lying around.

It looks like you've already dealt with notification when a key loses all 
its references, so now we just need to identify (or invent) a suitable 
identifier.


>> It also must be the case that a user cannot "forge" a label.
>> So, it pretty much has to be a kernel-defined property of the
>> key, rather than a user-supplied value.
>
> I don't know exactly what you mean by "forging" a label, but
> as far as the implementation goes, user-space can _ask_
> for whatever description (like kerberos principal name) that
> it wants, with whatever blob it wants.  It's up to the kernel
> module to actually implement data checking on any blobs.

So, a naive use of this mechanism would be to just store a PAG ID in a key 
rather than in the groups list, and leave everything else the way it is. 
That won't work, because the kernel would let a user specify any value he 
wants for that key, and thus join any PAG.

So, the "label" we use to mark connections, cached rights data, etc cannot 
simply be the value of the key blob.  It needs to be something the user 
cannot simply set to whatever he wants.



-- Jeff