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:
cred_handle – The credential
handle returned by gss_acquire_cred(). Alternatively,
GSS_C_NO_CREDENTIAL can be used to indicate the default credential.
GSS_C_NO_CONTEXT indicates an initial null context. Because gss_init_sec_context() is usually called in a loop, subsequent calls should pass the
context handle that was returned by previous calls.
input_token – The context token received from the client.
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
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(3GSS) 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.