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:

cred_handle – The credential
handle returned by gss_acquire_cred(). Alternatively, GSS_C_NO_CREDENTIAL can be used to indicate the default credential.

context_handle – 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 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

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.