![]() |
![]() |
| |||||||||||||||||
|
Applications that use the GSS-API should include the file gssapi.h. A general schema of this process is presented in Figure 1-6, which shows one way that the GSS-API can be used; other scenarios are possible. Figure 1-6 Using the GSS-API: An Overview ![]() CredentialsA credential is a data structure that provides proof of an application's claim to a principal name. An application uses a credential to establish its global identity. You can think of a credential as a principal's "identity badge," a set of information that proves that a person, machine, or program is who it claims to be and, often, what privileges it has. The GSS-API does not provide credentials. Credentials are created by the security mechanisms that underly the GSS-API, before GSS-API functions are called. In many cases, for example, users receive credentials when they log in to a system. A given GSS-API credential is valid for a single principal. A single credential can contain several elements for that principal, each created by a different mechanism, as shown in Figure 1-7. This means that a credential acquired on a machine with several security mechanisms will be valid if transferred to a machine that has only a subset of those mechanisms. The GSS-API accesses credentials through the gss_cred_id_t structure; this structure is called a credential handle. Credentials are opaque to applications; you don't need to know the specifics of a given credential. Figure 1-7 Generalized GSS-API Credential ![]() Credentials come in three forms:
Acquiring CredentialsBefore a security context can be established, both the server and the client must acquire their respective credentials. Once acquired, credentials can be re-used until they expire, at which time they must be re-acquired. Credentials used by the client and those used by the server might have different lifetimes. GSS-API-based applications acquire credentials in one of two ways:
In most cases, gss_acquire_cred() is called only by a context acceptor (server), because the context initiator (client) is likely to have received its credentials at login. The initiator, therefore, can usually specify only the default credential. The context acceptor can also bypass using gss_acquire_cred() and use its default credential instead. The initiator's credential proves its identity to other processes, while the acceptor acquires a credential to enable it to accept a security context. Consider the case of a client making an ftp request to a server. The client already has a credential, from login, and the GSS-API is automatically retrieves that credential when the client attempts to initiate a context. The server program, however, explicitly acquires credentials for the requested service (ftp). gss_acquire_cred() takes the syntax shown below:
gss_acquire_cred() returns GSS_S_COMPLETE if it completes successfully. If it cannot return a valid credential, it returns GSS_S_NO_CRED; see the gss_acquire_cred(3GSS) man page for other error codes. An example of acquiring a credential can be found in Acquiring Credentials (program listing in server_acquire_creds()). gss_add_cred() is similar to gss_acquire_cred(), but allows an application to either create a new credential handle based on an existing credential or to add a new credential element to the existing one. If GSS_C_NO_CREDENTIAL is specified as the existing credential, then gss_add_cred() will create a new credential based on default behavior. See the gss_add_cred(3GSS) man page for more information. Context EstablishmentAs stated earlier, the two most significant things that the GSS-API does in providing security are to create security contexts and to protect data. After an application has the credential(s) it needs, it's time to establish a security context. To do this, one application (typically a client) initiates the context, and another (usually a server) accepts it. Multiple contexts between peers are allowed. The communicating applications establish a joint security context by exchanging authentication tokens. The security context is a pair of GSS-API data structures that contain information shared between the two applications. This information describes the state of each application (in terms of security). A security context is required for protection of data. Context Initiation (Client)Security context initiation between an application and a remote peer is done using the gss_init_sec_context() function. If successful, this function returns a context handle for the context being established and a context-level token to send to the acceptor. Before calling gss_init_sec_context(), however, the client should:
When calling gss_init_sec_context(), the client typically passes the following argument values:
Applications are not bound to use these default values. Additionally, the client will specify its requirements for other security parameters with the req_flags argument. The full set of gss_init_sec_context() arguments is described below. The context acceptor can require several "handshakes" in order to establish a context; that is, it can require the initiator to send more than one piece of context information before it considers the context fully established. Therefore, for portability, context initiation should always be done as part of a loop that checks whether the context has been fully established. If the context is not complete, gss_init_sec_context() returns a major-status code of GSS_C_CONTINUE_NEEDED. Thus a loop should use gss_init_sec_context()'s return value to test whether to continue the initiation loop. The client passes context information to the server in the form of the output token returned by gss_init_sec_context(). The client receives information back from the server as an input token, which can then be passed as an argument to subsequent calls of gss_init_sec_context(). If the received input token has a length of zero, however, then no more output tokens are required by the server. Therefore, in addition to checking for the return status of gss_init_sec_context(), the loop should check the input token's length to see if a further token needs to be sent to the server. (Before the loop begins, the input token's length should be initialized to zero, either by setting the input 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 can look like, highly generalized: context = GSS_C_NO_CONTEXT
input token = GSS_C_NO_BUFFER
do
call gss_init_sec_context(credential, context, name, input token,
output token, other args...)
if (there's an output token to send to the acceptor)
send the output token to the acceptor
release the output token
if (the context is not complete)
receive an input token from the acceptor
if (there's a GSS-API error)
delete the context
until the context is complete
Naturally, a real loop will be more complete, with, for example, much more extensive error-checking. See Establishing a Context (program listing in client_establish_context()) for a real example of such a context-initiation loop. Additionally, the gss_init_sec_context(3GSS) man page gives a less generic example than this. | |||||||||||||||||
| |||||||||||||||||