Rather than reply point by point, I thought it might be helpful to clarify the 
security model that this draft is aiming for, and then we can address the best 
way of modifying the language in the draft to better communicate this.

In a single user cache manager, we don't really care about the existence of the 
cache manager. Any data which is requested by a user is for the use of that 
user only. Similarly, any data returned by extended callback breaks is also 
only for that user's attention. 

In a multi user cache manager, on the other hand, data requests are on behalf 
of both the user (who will consume that data immediately), and the cache 
manager (which will store the returned data, and possibly supply it to other 
users). In this case, both are party to the initial request, and both have an 
interest in the validity of both the initial data set, and any data contained 
in later callback breaks. This is where the AFSCombineTokens operation comes in 
to play. It allows both the user, and the cache manager to authenticate both 
the request, and the response. Because the call is secured using a combination 
of the user and CM keys, the user can't forge fileserver responses in order to 
feed bogus data to the cache manager.

For the purposes of this discussion, we are only interested in the security of 
extended callbacks. An attacker who can forge conventional callback breaks can 
only cause performance degradation to a client. An attacker who can forge 
extended callback breaks can insert arbitrary data into a clients cache. When 
talking about security, we are actually interested in two distinct properties. 
Firstly, it must be impossible for an attacker to forge callback breaks, and so 
corrupt the contents of the cache. Secondly, it must be impossible for an 
attacker to read callback breaks that are destined for another client. Extended 
callbacks may contain sensitive file, or directory information that shouldn't 
be disclosed to eavesdroppers.

At the moment, clients are identified by means of either a UUID or a host/port 
pair. There's no cryptographically strong binding between the UUID and 
per-client-key. In a world in which all clients were centrally registered, we 
could create this binding by means of an identity (for example, each client has 
an afs-client/<hostname>@REALM Kerberos principal). However, we want to be able 
to support anonymous clients, so there's no need for central client 
registration. In this world, the only way in which a UUID and key can be 
associated together is through an assertion. In order to support truly 
anonymous schemes (where there isn't even a unique ID provided with each key), 
we're also not relying on individual cache manager identities.

SetCallbackKey provides the mechanism for performing that assertion. However, 
because we have no trust in what has been asserted, we need to protect against 
two different scenarios. Firstly, an attacker that gets there before the 
current client, shouldn't be able to assert a key that then prevents a client 
from using extended callbacks. Secondly, an attacker who arrives after the 
current client shouldn't be able to assert a new key, and in doing so, gain the 
ability to read all of the client's outstanding callback breaks.

The language contained in the draft was an attempt to balance these security 
requirements against implementation complexity.

However, thinking about things further, I think there is an exploitable race 
between a client making a request, and an attacker performing a forged 
SetCallbackKey with the client's UUID. In order to prevent this race, we need 
to only permit anonymous identities with a unique (or hard to collide) 
identifier. 

In this model, each time we receive a SetCallbackKey, we would record the rxgk 
client identity which authenticated the RPC, and the key used. We could 
maintain a LRU style list of these, up to some (implementation defined) limit. 
When an identity is about to be removed for this list, any callbacks held by 
that identity have to be transitioned to "normal" callbacks.

Only RPCs which are authenticated with identities on this list would be 
eligible for extended callbacks. RPCs with different client identities, or 
which are issued over non-rxgk security classes, would not receive extended 
callbacks. Where we have callbacks for the same object requested by multiple 
different client identities, the key of the most recent identity used would be 
used to encrypt the callback.

Making all of this work complicates things significantly at the client, which 
must now maintain an rxgk token signing service, so that it can issue a proper 
token to the server for each key that it has in play, such that it can then 
pull the key out of that token.

Does that make sense?

Cheers,

Simon.

_______________________________________________
AFS3-standardization mailing list
[email protected]
http://lists.openafs.org/mailman/listinfo/afs3-standardization

Reply via email to