On 06/07/2013 09:42 AM, Weijun Wang wrote:
Hi All

The GSSContext::initSecContext() method could either return a token
(possibly null if no more token is needed) when the call succeeds or
throw a GSSException if there is a failure, but not *both*. The same
applies to acceptSecContext().

However, according to RFC 2743 2.2.1 [1], the C bindings of GSS-API:

    It is the caller's responsibility to establish a communications path
    to the target, and to transmit any returned output_token (independent
    of the accompanying returned major_status value) to the target over
    that path.

In fact, MIT krb5's gss-client.c sample does show:

         do {
             maj_stat = gss_init_sec_context(..., &send_tok, ...);
             ...
             if (send_tok.length != 0) {    # send the token anyway
                 if (send_token(..., &send_tok) < 0) {
                     ...
                     return -1;
                 }
             }                              # before return value check
             if (maj_stat != GSS_S_COMPLETE
                 && maj_stat != GSS_S_CONTINUE_NEEDED) {
                 ...
                 return -1;
             }

             if (maj_stat == GSS_S_CONTINUE_NEEDED) {
                 ...
             }
         } while (maj_stat == GSS_S_CONTINUE_NEEDED);

Without the ability to send a token when there is a failure, a Java
program has no chance to tell the other side what's happening. This is
very user-unfriendly. Also, in the case of SPNEGO, a "reject"
NegTokenResp token will never be able to sent.

I cannot find a good way to fix it without changing the semantic of
current APIs. Maybe we can add a new GSSException::getResidue() method
to return this last token. But that means the method call will be quite
complicated, something like

         try {
             send(initSecContext(inToken));
         } catch (GSSException e) {
             if (e.getResidue() != null) {
                 send(e.getResidue());
             }
             throw e;
         }

That doesn't seem too complicated to me, all things considered. I think this would be a reasonable solution. I would simply name the method getToken instead of getResidue.

As for the overloaded initSecContext(InputStream, OutputStream) style,
it looks easier to update this method to do the correct thing without
any new API. However, the change will be very confusing because there is
no more number of written bytes to return. More importantly, if it's
just a silent behavior change, we'll have to care about compatibility
(Maybe someone already added his/her own KRB-ERROR sending codes?),
which makes the situation much tougher.

Can you describe how the application code would use this method like you did above for the other initSecContext method?

--Sean


Thanks
Max

[1] http://tools.ietf.org/html/rfc2743#page-46

Reply via email to