Developer's Guide to Oracle® Solaris 11 Security

Exit Print View

Updated: July 2014
 
 

Receiving Data From a Client

After checking for inetd, the gss-server program then calls sign_server(), which does the main work of the program. sign_server() first establishes the context by calling server_establish_context().

    sign_server() performs the following tasks:

  • Accepts the context

  • Unwraps the data

  • Signs the data

  • Returns the data

These tasks are described in the subsequent sections. The following source code illustrates the sign_server() function.


Note - The source code for this example is also available through the Oracle download center. See http://www.oracle.com/technetwork/indexes/downloads/sdlc-decommission-333274.html.
Example 6-3  sign_server() Function
int sign_server(s, server_creds)
     int s;
     gss_cred_id_t server_creds;
{
     gss_buffer_desc client_name, xmit_buf, msg_buf;
     gss_ctx_id_t context;
     OM_uint32 maj_stat, min_stat;
     int i, conf_state, ret_flags;
     char	*cp;
     
     /* Establish a context with the client */
     if (server_establish_context(s, server_creds, &context,
				  &client_name, &ret_flags) < 0)
	return(-1);
	  
     printf("Accepted connection: \"%.*s\"\n",
	    (int) client_name.length, (char *) client_name.value);
     (void) gss_release_buffer(&min_stat, &client_name);

     for (i=0; i < 3; i++)
	     if (test_import_export_context(&context))
		     return -1;

     /* Receive the sealed message token */
     if (recv_token(s, &xmit_buf) < 0)
	return(-1);
	  
     if (verbose && log) {
	fprintf(log, "Sealed message token:\n");
	print_token(&xmit_buf);
     }

     maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf,
			   &conf_state, (gss_qop_t *) NULL);
     if (maj_stat != GSS_S_COMPLETE) {
	display_status("unsealing message", maj_stat, min_stat);
	return(-1);
     } else if (! conf_state) {
	fprintf(stderr, "Warning!  Message not encrypted.\n");
     }

     (void) gss_release_buffer(&min_stat, &xmit_buf);

     fprintf(log, "Received message: ");
     cp = msg_buf.value;
     if ((isprint(cp[0]) || isspace(cp[0])) &&
	 (isprint(cp[1]) || isspace(cp[1]))) {
	fprintf(log, "\"%.*s\"\n", msg_buf.length, msg_buf.value);
     } else {
	printf("\n");
	print_token(&msg_buf);
     }
	  
     /* Produce a signature block for the message */
     maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT,
			    &msg_buf, &xmit_buf);
     if (maj_stat != GSS_S_COMPLETE) {
	display_status("signing message", maj_stat, min_stat);
	return(-1);
     }

     (void) gss_release_buffer(&min_stat, &msg_buf);

     /* Send the signature block to the client */
     if (send_token(s, &xmit_buf) < 0)
	return(-1);

     (void) gss_release_buffer(&min_stat, &xmit_buf);

     /* Delete context */
     maj_stat = gss_delete_sec_context(&min_stat, &context, NULL);
     if (maj_stat != GSS_S_COMPLETE) {
	display_status("deleting context", maj_stat, min_stat);
	return(-1);
     }

     fflush(log);

     return(0);
}