GSS-API Programming Guide

Context Acceptance (Server)

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 initiated (with gss_init_sec_context()) by a client.

gss_accept_sec_context() takes as its main input an input token sent by the initiator. It 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 requested by the client. The server acquires these credentials with the gss_acquire_cred() function. Alternatively, the server can bypass acquiring credentials explicitly and instead specify the default credential (indicated by GSS_C_NO_CREDENTIAL) when calling gss_accept_sec_context().

When calling gss_accept_sec_context(), the server passes the following argument values:

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

Security context establishment may require several “handshakes”; that is, the initiator and acceptor may have 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 it hasn't, gss_accept_sec_context() returns a major-status code of GSS_C_CONTINUE_NEEDED. Thus a loop should use the value returned by gss_accept_sec_context() to test whether to continue the acceptance loop.

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

This is what such a loop might look like, highly generalized:

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

Naturally, a real loop will be more complete, doing much more extensive error-checking. See Accepting a Context (listing in server_establish_context()) for a real example of such a context-acceptance loop. Additionally, the gss_accept_sec_context() man page gives a somewhat less generic example than this.

Again, the GSS-API does not send or receive tokens; these must be handled by the application. Examples of token-transferring functions are found in send_token() and recv_token().

Here is a synopsis of gss_accept_sec_context(). For more information, see the gss_accept_sec_context(3GSS) man page.


Example 1–6 gss_accept_sec_context()

     OM_uint32 gss_accept_sec_context (
       OM_uint32                    *minor_status,
       gss_ctx_id_t                 *context_handle,
       const gss_cred_id_t          acceptor_cred_handle,
       const gss_buffer_t           input_token_buffer,
       const gss_channel_bindings_t input_chan_bindings,
       const gss_name_t             *src_name,
       gss_OID                      *mech_type,
       gss_buffer_t                 output_token,
       OM_uint32                    *ret_flags,
       OM_uint32                    *time_req,
       gss_cred_id_t                *delegated_cred_handle)

minor_status

The status code returned by the underlying mechanism.

context_handle

The context handle to return to the initiator. This argument should be set to GSS_C_NO_CONTEXT before the loop begins.

acceptor_cred_handle

The handle for the credentials acquired by the acceptor, typically through gss_acquire_cred()). Can be initialized to GSS_C_NO_CREDENTIAL to indicate a default credential to use. If no default credential is defined, the function returns GSS_C_NO_CRED.

(Note: if gss_acquire_cred() was passed GSS_C_NO_NAME as a principal name, it produces a credential that will cause gss_accept_sec_context() to treat it as a default credential.)

input_token_buffer

Token received from the context initiator.

input_chan_bindings

Specific peer-to-peer channel identification information connected with the security context. See Channel Bindings for more information about channel bindings. Set to GSS_C_NO_CHANNEL_BINDINGS if you don't want to use channel bindings.

src_name

The name of the initiating principal; for example, nfs@machinename. If you don't care, set to NULL.

mech_type

The security mechanism used. Set to NULL if you don't care which mechanism is used.

output_token

The token to send to the initiator. Should be initialized to GSS_C_NO_BUFFER before the function is called (or its length field set to zero). If the length is zero, no token needs to be sent.

ret_flags

Flags indicating additional services or parameters requested for this context. ret_flags flags should be logically AND'd to test the returned bit-mask value, as in:


if (ret_flags & GSS_C_CONF_FLAG)
     confidentiality = TRUE;

GSS_C_DELEG_FLAG

Indicates the initiator's credentials may be delegated via the delegated_cred_handle argument. See Delegation.

GSS_C_MUTUAL_FLAG

Indicates that mutual authentication is available. See Mutual Authentication.

GSS_C_REPLAY_FLAG

Indicates that detection of repeated messages is available. See Out-of-Sequence Detection and Replay Detection.

GSS_C_SEQUENCE_FLAG

Indicates that detection of out-of-sequence messages is available. See Out-of-Sequence Detection and Replay Detection.

GSS_C_CONF_FLAG

If true, confidentiality service is allowed for transferred messages; that is, that messages can be encrypted. If confidentiality is not allowed, then only data-origin authentication and integrity services can be applied (this last only if GSS_C_INTEG_FLAG is not returned as false).

GSS_C_INTEG_FLAG

If true, the integrity service can be applied to messages; that is, that messages can be stamped with a MIC to ensure their validity.

GSS_C_ANON_FLAG

Indicates that the context initiator will be anonymous. See Anonymous Authentication.

GSS_C_PROT_READY_FLAG

Sometimes context establishment can take several passes, and sometimes the client can send enough information on the initial passes to allow the acceptor to process context-related data, even though the context is incomplete. In those circumstances the acceptor needs to know in which way, if any, the information has been protected.

If true, GSS_C_PROT_READY_FLAG indicates that the protection services indicated by the GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG flags are available. The acceptor can therefore call the appropriate data–reception functions, gss_unwrap() or gss_verify_mic(), with these services in mind.

(Additionally, as with the context initiator, the acceptor can use these flags in buffering any data it might want to send to the initiator, transmitting it when the context is fully established.)

If GSS_C_PROT_READY_FLAG is false, then the acceptor cannot make any assumptions about data protection, and must wait until the context is complete (that is, when gss_accept_sec_context() returns GSS_S_COMPLETE).


Note –

Earlier versions of the GSS-API did not support the GSS_C_PROT_READY_FLAG argument, so developers wanting to maximize portability should determine which per-message services are available by looking at the GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG flags after a context has been successfully established.


GSS_C_TRANS_FLAG

If true, this context can be exported. For more information on importing and exporting contexts, see Context Export and Import.

time_rec

Number of seconds for which the context will remain valid. Specify NULL if you're not interested in this value.

delegated_cred_handle

The credential handle for credentials received from the context initiator, that is, the client's credentials. Valid only if the initiator has requested that the acceptor act as a proxy: that is, if the ret_flags argument resolves to GSS_C_DELEG_FLAG. See Delegation for more about delegation.

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