JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris Security for Developers Guide
search filter icon
search icon

Document Information

Preface

1.  Oracle Solaris Security for Developers (Overview)

2.  Developing Privileged Applications

3.  Writing PAM Applications and Services

4.  Writing Applications That Use GSS-API

5.  GSS-API Client Example

6.  GSS-API Server Example

GSSAPI Server Example Overview

GSSAPI Server Example Structure

Running the GSSAPI Server Example

GSSAPI Server Example: main() Function

Acquiring Credentials

Checking for inetd

Receiving Data From a Client

Accepting a Context

Unwrapping the Message

Signing and Returning the Message

Using the test_import_export_context() Function

Cleanup in the GSSAPI Server Example

7.  Writing Applications That Use SASL

8.  Introduction to the Oracle Solaris Cryptographic Framework

9.  Writing User-Level Cryptographic Applications and Providers

10.  Using the Smart Card Framework

A.  Sample C-Based GSS-API Programs

B.  GSS-API Reference

C.  Specifying an OID

D.  Source Code for SASL Example

E.  SASL Reference Tables

F.  Packaging and Signing Cryptographic Providers

Glossary

Index

Acquiring Credentials

Credentials are created by the underlying mechanisms rather than by the client application, server application, or GSS-API. A client program often has credentials that are obtained at login. A server always needs to acquire credentials explicitly.

The gss-server program has a function, server_acquire_creds(), to get the credentials for the service to be provided. server_acquire_creds() takes as input the name of the service and the security mechanism to be used. server_acquire_creds() then returns the credentials for the service.

server_acquire_creds() uses the GSS-API function gss_acquire_cred() to get the credentials for the service that the server provides. Before server_acquire_creds() accesses gss_acquire_cred(), server_acquire_creds() must take care of two tasks:

  1. Checking for a list of mechanisms and reducing the list to a single mechanism for the purpose of getting a credential.

    If a single credential can be shared by multiple mechanisms, the gss_acquire_cred() function returns credentials for all those mechanisms. Therefore, gss_acquire_cred() takes as input a set of mechanisms. (See Working With Credentials in GSS-API.) In most cases, however, including this one, a single credential might not work for multiple mechanisms. In the gss-server program, either a single mechanism is specified on the command line or else the default mechanism is used. Therefore, the first task is to make sure that the set of mechanisms that was passed to gss_acquire_cred() contains a single mechanism, default or otherwise, as follows:

    if (mechOid != GSS_C_NULL_OID) {
         desiredMechs = &mechOidSet;
         mechOidSet.count = 1;
         mechOidSet.elements = mechOid;
    } else
         desiredMechs = GSS_C_NULL_OID_SET;

    GSS_C_NULL_OID_SET indicates that the default mechanism should be used.

  2. Translating the service name into GSS-API format.

    Because gss_acquire_cred() takes the service name in the form of a gss_name_t structure, the name of the service must be imported into that format. The gss_import_name() function performs this translation. Because this function, like all GSS-API functions, requires arguments to be GSS-API types, the service name has to be copied to a GSS-API buffer first, as follows:

         name_buf.value = service_name;
         name_buf.length = strlen(name_buf.value) + 1;
         maj_stat = gss_import_name(&min_stat, &name_buf,
                    (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
         if (maj_stat != GSS_S_COMPLETE) {
              display_status("importing name", maj_stat, min_stat);
              if (mechOid != GSS_C_NO_OID)
                    gss_release_oid(&min_stat, &mechOid);
              return -1;
         }

    Note again the use of the nonstandard function gss_release_oid().

    The input is the service name as a string in name_buf. The output is the pointer to a gss_name_t structure, server_name. The third argument, GSS_C_NT_HOSTBASED_SERVICE, is the name type for the string in name_buf. In this case, the name type indicates that the string should be interpreted as a service of the format service@host.

After these tasks have been performed, the server program can call gss_acquire_cred():

maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
                                 desiredMechs, GSS_C_ACCEPT,
                                 server_creds, NULL, NULL);

The following source code illustrates the server_acquire_creds() function.


Note - The source code for this example is also available through the Sun download center. See http://www.sun.com/download/products.xml?id=41912db5.


Example 6-2 Sample Code for server_acquire_creds() Function

/*
 * Function: server_acquire_creds
 *
 * Purpose: imports a service name and acquires credentials for it
 *
 * Arguments:
 *
 *      service_name    (r) the ASCII service name
        mechType        (r) the mechanism type to use
 *      server_creds    (w) the GSS-API service credentials
 *
 * Returns: 0 on success, -1 on failure
 *
 * Effects:
 *
 * The service name is imported with gss_import_name, and service
 * credentials are acquired with gss_acquire_cred.  If either operation
 * fails, an error message is displayed and -1 is returned; otherwise,
 * 0 is returned.
 */
int server_acquire_creds(service_name, mechOid, server_creds)
     char *service_name;
     gss_OID mechOid;
     gss_cred_id_t *server_creds;
{
     gss_buffer_desc name_buf;
     gss_name_t server_name;
     OM_uint32 maj_stat, min_stat;
     gss_OID_set_desc mechOidSet;
     gss_OID_set desiredMechs = GSS_C_NULL_OID_SET;

     if (mechOid != GSS_C_NULL_OID) {
                desiredMechs = &mechOidSet;
                mechOidSet.count = 1;
                mechOidSet.elements = mechOid;
     } else
                desiredMechs = GSS_C_NULL_OID_SET;

     name_buf.value = service_name;
     name_buf.length = strlen(name_buf.value) + 1;
     maj_stat = gss_import_name(&min_stat, &name_buf,
                (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
     if (maj_stat != GSS_S_COMPLETE) {
          display_status("importing name", maj_stat, min_stat);
          if (mechOid != GSS_C_NO_OID)
                gss_release_oid(&min_stat, &mechOid);
          return -1;
     }

     maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
                                 desiredMechs, GSS_C_ACCEPT,
                                 server_creds, NULL, NULL);

     if (maj_stat != GSS_S_COMPLETE) {
          display_status("acquiring credentials", maj_stat, min_stat);
          return -1;
     }

     (void) gss_release_name(&min_stat, &server_name);

     return 0;
}