Developer's Guide to Oracle Solaris Security

Accepting a Context in GSS-API

The other half of context establishment is context acceptance, which is done through the gss_accept_sec_context() function. In a typical scenario, a server accepts a context that has been initiated by a client with gss_init_sec_context().

The main input to gss_accept_sec_context() is an input token from the initiator. The initiator returns a context handle as well as an output token to be returned to the initiator. Before gss_accept_sec_context() can be called, however, the server should acquire credentials for the service that was requested by the client. The server acquires these credentials with the gss_acquire_cred() function. Alternatively, the server can bypass explicit acquisition of credentials by specifying the default credential, that is, GSS_C_NO_CREDENTIAL, when the server calls gss_accept_sec_context().

When calling gss_accept_sec_context(), the server can set the following arguments as shown:

The full set of gss_accept_sec_context() arguments is described in the following paragraphs.

Security context establishment might require several handshakes. The initiator and acceptor often need to send more than one piece of context information before the context is fully established. Therefore, for portability, context acceptance should always be done as part of a loop that checks whether the context has been fully established. If the context is not yet established, gss_accept_sec_context() returns a major status code of GSS_C_CONTINUE_NEEDED. Therefore, a loop should use the value that was returned by gss_accept_sec_context() to test whether to continue the acceptance loop.

The context acceptor returns context information to the initiator in the form of the output token that was returned by gss_accept_sec_context(). Subsequently, the acceptor can receive additional information from the initiator as an input token. The input token is then passed as an argument to subsequent gss_accept_sec_context() calls. When gss_accept_sec_context() has no more tokens to send to the initiator, an output token with a length of zero is returned. Besides checking for the return status gss_accept_sec_context(), the loop should check the output token's length to see whether another token must be sent. Before the loop begins, the output token's length should be initialized to zero. Either set the output token to GSS_C_NO_BUFFER, or set the structure's length field to a value of zero.

The following pseudocode demonstrates an example of context establishment from the server side.

context = GSS_C_NO_CONTEXT
output token = GSS_C_NO_BUFFER

do

     receive an input token from the initiator

     call gss_accept_sec_context(context, cred handle, input token,
                                                output token, other args...)

     if (there's an output token to send to the initiator)
          send the output token to the initiator
          release the output token

     if (there's a GSS-API error)
          delete the context

until the context is complete

A real loop would be more complete with more extensive error-checking. See Establishing a Security Context With the Server for a real example of such a context-acceptance loop. Additionally, the gss_accept_sec_context() man page provides an example.

Again, GSS-API does not send or receive tokens. Tokens must be handled by the application. Examples of token-transferring functions are found in Miscellaneous GSS-API Sample Functions.

gss_accept_sec_context() returns GSS_S_COMPLETE if it completes successfully. If the context is not complete, the function returns GSS_S_CONTINUE_NEEDED. If errors occur, the function returns error codes. For more information, see the gss_accept_sec_context(3GSS) man page.