Subject: RPCSEC_GSS interop wrt minor status codes

From: Nicolas Williams <[email-masked]>
Date: Mon, 4 Nov 2002 17:48:54 -0600

While researching some GSS-API features/issues I ran into a problem
with RPCSEC_GSS interoperability.

Facts:

 - RFC2203 (RPCSEC_GSS), section 5.2.3.1 says that when the server's
   gss_accept_sec_context() returns an error then the server must
   (lower-case) send a NULL handle *and* token in the response to the
   client

 - The GSS-API RFCs imply, but do not explicitly state, that
   gss_accept_sec_context() CAN produce an output token even if its
   major status is an error

 - RFC1964 (the Kerberos GSS mechanism spec) explicitly allows for
   KRB-ERROR as Kerberos mech GSS token

 - RFC1964 defines symbolic names for Kerberos mech GSS minor status
   codes, but NOT integers (i.e., there no standard wire representation
   of Kerberos GSS mech minor status codes other than the error token
   defined in RFC1964, a KRB-ERROR wrapped with a GSS header).

   Note that the error code in the KRB-ERROR is NOT the same as the
   minor code produced by gss_accept_sec_context(), not in the case of
   MIT krb5 and implementations derived from it.

Problem:

 - There is no interoperable way to communicate minor status codes from
   the Kerberos GSS mechanism in RPCSEC_GSS.

   There is one specific error condition that effectively cannot be
   communicated interoperably: when the initiator refers to the acceptor
   by an incorrect name (e.g., host/foo instead of nfs/foo). There is no
   GSS major error for such a condition; there is a Kerberos error code
   for this (KRB_AP_ERR_NOT_US), but it can't be communicated
   interoperably in the context of RPCSEC_GSS (see above).

Solution 0: Do nothing. The client will know that there was an error and
            will know the major error code, but won't reliably know the
	    minor code, so the user will have less info to go on, but
	    hey, they can live with this, right?

Solution 1: Modify RPCSEC_GSS to allow non-null GSS tokens in error
            responses from the server's gss_accept_sec_context(). Does
	    not affect wire representation. Clients may or may not like
	    this but it doesn't matter as errors are final. It is
	    possible that some clients may leak memory (or even crash?)
	    if this is done.

Solution 2: Standardize integer values for the minor status code
            symbolic names listed in RFC1964.

Solution (2) is a poor alternative to solution (1), though it may be
independently desirable.

It may be worth testing client behaviour w/ solution (1) at the
Connectathon.

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 5 Nov 2002 11:36:45 -0600

There is one solution which may not require that the draft be updated at
all.

Solution 3: If the server has a gss error token then the server should
	    set the gss-major field of its rpc_gss_init_res reply to
	    GSS_S_CONTINUTE_NEEDED and the gss_token field to the token
	    produced by GSS_Accept_sec_context(). The client will then
	    call GSS_Init_sec_context() with the error token and
	    discover the actual error condition, thus abandoning the
	    context creation request.

NOTE: RFC2203 does not specify what happens when a client passes a token
      sent by the server to GSS_Init_sec_context() and then gets an
      error. In the case of the server sending GSS_S_CONTINUTE_NEEDED
      the RFC says that the client must send back a token, but this
      cannot be so if the client gets an error from GSS_Init_sec_context().
      In the solution (3) case the server knows that the client is going
      to get an error from GSS_Init_sec_context() anyways, so it will
      correctly not expect additional tokens from the client.

Cheers,

Nico

---

From: Mike Eisler <[email-masked]>
Date: Tue, 05 Nov 2002 11:49:43 -0800

>             context creation request.

Why not just return GSS_S_COMPLETE? But regardless, if we took this route,
it seems to me RFC2203 would have to be updated.

>       correctly not expect additional tokens from the client.

BTW, RFC2744, the C bindings for GSS-API has a nice code fragment for
the target's processing of tokens via gss_accept_sec_context() that shows
clearly that if there is an output token, then regardless of
the major status, the output token is sent to the initiator. (I wish I had
this loop when I wrote RFC2203 :-( .

So I think if we do any updating of RFC2203, we should do it
right, and follow the GSS-API standard.

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 5 Nov 2002 14:20:38 -0600

> it seems to me RFC2203 would have to be updated.

Because when the server sends GSS_S_COMPLETE, the client expects a
non-null handle. Right?

And yes, solution (3) takes advantage of an underspecified aspect of
RFC2203 which would have to be updated regardless, as you say. Clients
have to be able to cope with the particular situation which is
underspecified anyways, so solution (3) is in-spec, IMO, though
accidentally so, or, rather, I think implementations could use solution
(3) without breaking the spec.

> this loop when I wrote RFC2203 :-( .

Ah, yes.

> right, and follow the GSS-API standard.

Agreed.

Cheers,

Nico
--