Movatterモバイル変換


[0]ホーム

URL:


Go to main content
oracle home

Developer's Guide to Oracle® Solaris 11.4 Security

Exit Print View

 
Search Scope:
  »  ...Documentation Home  »  Oracle Solaris 11.4 Information Library  »  Developer's Guide to Oracle® ...  »  GSS-API Client Example  »  Establishing a Security Context With the Server
Updated: November 2020
 
 

Establishing a Security Context With the Server

After the connection is made,call_server() uses the functionclient_establish_context() to create the security context, as follows:

if (client_establish_context(s, service-name, deleg-flag, oid, &context,                                  &ret-flags) < 0) {          (void) close(s);          return -1;     }
  • s is a file descriptor that representsthe connection that is established byconnect_to_server().

  • service-name is the requested networkservice.

  • deleg-flag specifies whether theserver can act as a proxy for the client.

  • oid is the mechanism.

  • context is the context to be created.

  • ret-flags is anint thatspecifies any flags to be returned by the GSS-API functiongss_init_sec_context().

    Theclient_establish_context() performs the followingtasks:

  • Translates the service name into internal GSSAPI format

  • Performs a loop of token exchanges between the client andthe server until the security context is complete

Translating a Service Name into GSS-API Format

The first task thatclient_establish_context() performs is to translate the service name string to internal GSS-API format by usinggss_import_name().

Example 14  GSSAPI Clientclient_establish_context() Name Translation
     /*     * Import the name into target_name.  Use send_tok to save     * local variable space.     */     send_tok.value = service_name;     send_tok.length = strlen(service_name) + 1;     maj_stat = gss_import_name(&min_stat, &send_tok,                        (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &target_name);     if (maj_stat != GSS_S_COMPLETE) {          display_status("parsing name", maj_stat, min_stat);          return -1;     }

gss_import_name() takes the name of the service, which is stored in an opaque GSS_API buffer send_tok, and converts the string to the GSS_API internal name target_name. send_tok is used to save space instead of declaring a new gss_buffer_desc. The third argument is a gss_OID type that indicates the send_tok name format. This example usesGSS_C_NT_HOSTBASED_SERVICE, which means a service of the formatservice@host. SeeGSS-API Name Types for other possible values for this argument.

Establishing a Security Context for GSS-API

Once the service has been translated to GSS-API internal format, the context can be established. To maximize portability, establishing context should always be performed as a loop.

Before entering the loop,client_establish_context() initializes the context and thetoken_ptr parameter. There is a choice in the use oftoken_ptr.token_ptr can point either tosend_tok, the token to be sent to the server, or torecv_tok, the token that is sent back by the server.

    Inside the loop, two items are checked:

  • The status that is returned bygss_init_sec_context()

    The return status catches any errors that might require the loop to be aborted.gss_init_sec_context() returns GSS_S_CONTINUE_NEEDED if and only if the server has another token to send.

  • The size of token to be sent to the server, which is generated bygss_init_sec_context().

    A token size of zero indicates that no more information exists that can be sent to the server and that the loop can be exited. The token size is determined fromtoken_ptr.

The following pseudocode describes the loop:

dogss_init_sec_context() if no context was created exit with error; if the status is neither "complete" nor "in process" release the service namespace and exit with error; if there is a token to send to the server, that is, the size is nonzero send the token; if sending the token fails, release the token and service namespaces. Exit with error; release the namespace for the token that was just sent; if the context is not completely set up receive a token from the server;while the context is not complete

    The loop starts with a call togss_init_sec_context(), which takes the following arguments:

  • The status code to be set by the underlying mechanism.

  • The credential handle. The example usesGSS_C_NO_CREDENTIAL to act as a default principal.

  • gss-context, which represents the context handle to be created.

  • target-name of the service, as a GSS_API internal name.

  • oid, the ID for the mechanism.

  • Request flags. In this case, the client requests that the server authenticate itself, that message-duplication be turned on, and that the server act as a proxy if requested.

  • No time limit for the context.

  • No request for channel bindings.

  • token_ptr, which points to the token to be received from the server.

  • The mechanism actually used by the server. The mechanism is set toNULL here because the application does not use this value.

  • &send_tok, which is the token thatgss_init_sec_context() creates to send to the server.

  • Return flags. Set toNULL because they are ignored in this example.


Note -  The client does not need to acquire credentials before initiating a context. On the client side, credential management is handled transparently by the GSS-API. That is, the GSS-APIknows how to get credentials that are created by this mechanism for this principal. As a result, the application can passgss_init_sec_context() a default credential. On the server side, however, a server application must explicitly acquire credentials for a service before accepting a context. SeeAcquiring Credentials.

After checking that a context or part of one exists and thatgss_init_sec_context() is returning valid status,connect_to_server() checks thatgss_init_sec_context() has provided a token to send to the server. If no token is present, the server has signalled that no other tokens are needed. If a token has been provided, then that token must be sent to the server. If sending the token fails, the namespaces for the token and service cannot be determined, andconnect_to_server() exits. The following algorithm checks for the presence of a token by looking at the length:

if (send_tok_length != 0) {     if (send_token(s, &send_tok) < 0) {          (void) gss_release_buffer(&min_stat, &send_tok);          (void) gss_release_name(&min_stat, &target_name);          return -1;     }}

send_token() is not a GSS-API function and needs to be written by the user. Thesend_token() function writes a token to the file descriptor.send_token() returns 0 on success and –1 on failure. GSS-API does not send or receive tokens itself. The calling applications are responsible for sending and receiving any tokens that have been created by GSS-API.

The source code for the context establishment loop is provided below.

Example 15  GSSAPI Client Loop for Establishing Contexts
/* * Perform the context establishment loop. * * On each pass through the loop, token_ptr points to the token * to send to the server (or GSS_C_NO_BUFFER on the first pass). * Every generated token is stored in send_tok which is then * transmitted to the server; every received token is stored in * recv_tok, which token_ptr is then set to, to be processed by * the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero * if and only if the server is expecting another token from us, * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if * and only if the server has another token to send us. */token_ptr = GSS_C_NO_BUFFER;*gss_context = GSS_C_NO_CONTEXT;1234567890123456789012345678901234567890123456789012345678901234567890123456do {    maj_stat =        gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL,         gss_context, target_name, oid,         GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | deleg_flag,        0, NULL,                      /* no channel bindings */        token_ptr, NULL,              /* ignore mech type */        &send_tok, ret_flags, NULL);  /* ignore time_rec */    if (gss_context == NULL){        printf("Cannot create context\n");        return GSS_S_NO_CONTEXT;    }    if (token_ptr != GSS_C_NO_BUFFER)        (void) gss_release_buffer(&min_stat, &recv_tok);    if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {        display_status("initializing context", maj_stat, min_stat);        (void) gss_release_name(&min_stat, &target_name);        return -1;    }    if (send_tok.length != 0){        fprintf(stdout, "Sending init_sec_context token (size=%ld)...",            send_tok.length);        if (send_token(s, &send_tok) < 0) {            (void) gss_release_buffer(&min_stat, &send_tok);            (void) gss_release_name(&min_stat, &target_name);            return -1;        }    }    (void) gss_release_buffer(&min_stat, &send_tok);    if (maj_stat == GSS_S_CONTINUE_NEEDED) {        fprintf(stdout, "continue needed...");        if (recv_token(s, &recv_tok) < 0) {            (void) gss_release_name(&min_stat, &target_name);            return -1;        }        token_ptr = &recv_tok;    }    printf("\n");} while (maj_stat == GSS_S_CONTINUE_NEEDED);

For more information about howsend_token() andrecv_token() work, seeMiscellaneous GSS-API Sample Functions.

Copyright © 2000, 2020, Oracle and/or its affiliates. 
Previous
Next

[8]ページ先頭

©2009-2025 Movatter.jp