GSS-API and libkrb5 behavior for Anonymous tickets
Nicolas Williams
Nicolas.Williams at sun.com
Tue Nov 3 12:41:55 EST 2009
In my interpretation, the principles of the GSS-API w.r.t. anonymity are
as follows:
- If you use a non-default credential handle when calling
gss_init_sec_context(), then the mechanism is constrained to
authenticating only that handle's desired_name as the initiator
principal, UNLESS the anon req_flag is set (more on that below).
- If you use a credential handle for a desired_name with anonymous
or anonymous-like name type, then you can only get anonymity (or
pseudonymity; see below) when you call gss_init_sec_context() with
that credential handle.
The GSS-API doesn't have a notion of credential store or of
"initial credentials", so it's possible that one could get
pseudonymity instead of anonymity unless the caller sets the
anonymous req_flag (they have to then check that it's set in the
ret_flags). That is, the implementation might fetch an anonymous
TGT and then fetch service tickets using that TGT, which might
allow all the various services to track the initiators' actions
back to that one anon TGT. gss_acquire_cred() could store
credentials for anonymous desired_names in the current ccache, but
I'd rather that it always return fresh credentials when
desired_name is an anonymous name.
- To use a default credential handle is the same as to use a credential
handle whose desired_name matches the default principal of the
current credential store (ccache). See above.
- req_flags are all optional; a mechanism is free to grant more or
fewer than requested, and the caller of gss_init_sec_context() must
check ret_flags. However, ret_flags must be set appropriately as
soon as possible! RFC2743 says:
"
Callers wishing to perform context establishment only if anonymity
support is provided should transfer a returned token from
GSS_Init_sec_context() to the peer only if it is accompanied by a
TRUE anon_state indicator.
"
This leaves the mechanism designer/implementor a lot of freedom. Too
much freedom, I think. But not so much freedom that a careful
application would ever authenticate a non-anon initiator
accidentally.
(Aside: it would be very odd to set the anonymous ret_flag when the
caller did not request it and the initiator credential handle was not
an anonymous one. This should just not happen. Note that mechanisms
that can only do anon initiator name authentication can only have
anon cred handles. If you use SPNEGO, a default credential handle,
and such a mechanism, then you could see the anon ret_flag set even
though the caller did not set the anon req_flag.)
Thus to call gss_init_sec_context() with the default credential when
there's a non-anonymous crendential available, and the anonymous
req_flag means that the mechanism is free to authenticate the
initiator non-anonymously (and not set the anonymous ret_flag).
Just because the mechanism can do that doesn't mean it should. I'd
rather treat the anon req_flag as critical in the mechanism
implementations, even though from the application's p.o.v. it's
optional.
We can derive these rules for the krb5 mech from the above:
1) If the app calls gss_import_name() with GSS_C_NT_ANONYMOUS to get an
anon name, then calls gss_acquire_cred(), then for the krb5 mech that
implements anonymous PKINIT this should work.
We may need to define a krb5-specific anon name-type whose syntax
allows the specification of a realm name. But use of that should be
optional.
2) If the app calls gss_acquire_cred() with desired_name == some
anonymous or anonymous-like name, then the krb5 mech should acquire
anon tickets, or defer this to the point where gss_init_sec_context()
is called.
3) If the app calls gss_init_sec_context() with an anonymous credential
handle then:
a) the krb5 mech should authenticate that credential's anonymous
desired_name and NEVER authenticate the caller's default credential's
desired_name, if there are any non-anon default creds;
b) the anon ret_flag should be set regardless of whether the anon
req_flag was set.
4) If the app calls gss_init_sec_context() with a default credential, or
with a non-anonymous credential handle *and* sets the anon req_flag,
then technically the krb5 mech should attempt anonymous
authentication and may fail without authenticating the non-anon
initiator name if it could not do anonymous authentication. Ideally
the mechanism should attempt anon auth and must fail without
authenticating the non-anon initiator. (If anon auth succeeds, then
the anon ret_flag must be set, of course.)
Nico
--
More information about the krbdev
mailing list