Skip Navigation Links | |
Exit Print View | |
![]() |
Developer's Guide to Oracle Solaris 10 Security Oracle Solaris 10 1/13 Information Library |
1. Oracle Solaris Security for Developers (Overview)
2. Developing Privileged Applications
3. Writing PAM Applications and Services
4. Writing Applications That Use GSS-API
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
D. Source Code for SASL Example
To make the client and server programs work as shown, a number of other functions are required. These functions are used to display values. The functions are not otherwise needed. The functions in this category are as follows:
send_token() – Transfers tokens and messages to a recipient
recv_token() – Accepts tokens and messages from a sender
display_status() – Shows the status returned by the last GSS-API function called
write_all() – Writes a buffer to a file
read_all() – Reads a file into a buffer
display_ctx_flags() – Shows in a readable form information about the current context, such as whether confidentiality or mutual authentication is allowed
print_token() – Prints out a token's value
The code for these functions is shown in the following example.
Example A-3 Code Listings for Miscellaneous GSS-API Functions
/* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #if !defined(lint) && !defined(__CODECENTER__) static char *rcsid = "$Header: /cvs/krbdev/krb5/src/appl/gss-sample/\ gss-misc.c, v 1.15 1996/07/22 20:21:20 marc Exp $"; #endif #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <gssapi/gssapi.h> #include <gssapi/gssapi_ext.h> #include <gss-misc.h> #include <stdlib.h> FILE *display_file; static void display_status_1 (char *m, OM_uint32 code, int type); static int write_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = write(fildes, ptr, nbyte); if (ret < 0) { if (errno == EINTR) continue; return(ret); } else if (ret == 0) { return(ptr-buf); } } return(ptr-buf); } static int read_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = read(fildes, ptr, nbyte); if (ret < 0) { if (errno == EINTR) continue; return(ret); } else if (ret == 0) { return(ptr-buf); } } return(ptr-buf); } /* * Function: send_token * * Purpose: Writes a token to a file descriptor. * * Arguments: * * s (r) an open file descriptor * tok (r) the token to write * * Returns: 0 on success, -1 on failure * * Effects: * * send_token writes the token length (as a network long) and then the * token data to the file descriptor s. It returns 0 on success, and * -1 if an error occurs or if it could not write all the data. */ int send_token(s, tok) int s; gss_buffer_t tok; { int len, ret; len = htonl(tok->length); ret = write_all(s, (char *) &len, 4); if (ret < 0) { perror("sending token length"); return -1; } else if (ret != 4) { if (display_file) fprintf(display_file, "sending token length: %d of %d bytes written\n", ret, 4); return -1; } ret = write_all(s, tok->value, tok->length); if (ret < 0) { perror("sending token data"); return -1; } else if (ret != tok->length) { if (display_file) fprintf(display_file, "sending token data: %d of %d bytes written\n", ret, tok->length); return -1; } return 0; } /* * Function: recv_token * * Purpose: Reads a token from a file descriptor. * * Arguments: * * s (r) an open file descriptor * tok (w) the read token * * Returns: 0 on success, -1 on failure * * Effects: * * recv_token reads the token length (as a network long), allocates * memory to hold the data, and then reads the token data from the * file descriptor s. It blocks to read the length and data, if * necessary. On a successful return, the token should be freed with * gss_release_buffer. It returns 0 on success, and -1 if an error * occurs or if it could not read all the data. */ int recv_token(s, tok) int s; gss_buffer_t tok; { int ret; ret = read_all(s, (char *) &tok->length, 4); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 4) { if (display_file) fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 4); return -1; } tok->length = ntohl(tok->length); tok->value = (char *) malloc(tok->length); if (tok->value == NULL) { if (display_file) fprintf(display_file, "Out of memory allocating token data\n"); return -1; } ret = read_all(s, (char *) tok->value, tok->length); if (ret < 0) { perror("reading token data"); free(tok->value); return -1; } else if (ret != tok->length) { fprintf(stderr, "sending token data: %d of %d bytes written\n", ret, tok->length); free(tok->value); return -1; } return 0; } static void display_status_1(m, code, type) char *m; OM_uint32 code; int type; { OM_uint32 maj_stat, min_stat; gss_buffer_desc msg; OM_uint32 msg_ctx; msg_ctx = 0; while (1) { maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (display_file) fprintf(display_file, "GSS-API error %s: %s\n", m, (char *)msg.value); (void) gss_release_buffer(&min_stat, &msg); if (!msg_ctx) break; } } /* * Function: display_status * * Purpose: displays GSS-API messages * * Arguments: * * msg a string to be displayed with the message * maj_stat the GSS-API major status code * min_stat the GSS-API minor status code * * Effects: * * The GSS-API messages associated with maj_stat and min_stat are * displayed on stderr, each preceded by "GSS-API error <msg>: " and * followed by a newline. */ void display_status(msg, maj_stat, min_stat) char *msg; OM_uint32 maj_stat; OM_uint32 min_stat; { display_status_1(msg, maj_stat, GSS_C_GSS_CODE); display_status_1(msg, min_stat, GSS_C_MECH_CODE); } /* * Function: display_ctx_flags * * Purpose: displays the flags returned by context initiation in * a human-readable form * * Arguments: * * int ret_flags * * Effects: * * Strings corresponding to the context flags are printed on * stdout, preceded by "context flag: " and followed by a newline */ void display_ctx_flags(flags) OM_uint32 flags; { if (flags & GSS_C_DELEG_FLAG) fprintf(display_file, "context flag: GSS_C_DELEG_FLAG\n"); if (flags & GSS_C_MUTUAL_FLAG) fprintf(display_file, "context flag: GSS_C_MUTUAL_FLAG\n"); if (flags & GSS_C_REPLAY_FLAG) fprintf(display_file, "context flag: GSS_C_REPLAY_FLAG\n"); if (flags & GSS_C_SEQUENCE_FLAG) fprintf(display_file, "context flag: GSS_C_SEQUENCE_FLAG\n"); if (flags & GSS_C_CONF_FLAG ) fprintf(display_file, "context flag: GSS_C_CONF_FLAG \n"); if (flags & GSS_C_INTEG_FLAG ) fprintf(display_file, "context flag: GSS_C_INTEG_FLAG \n"); } void print_token(tok) gss_buffer_t tok; { int i; unsigned char *p = tok->value; if (!display_file) return; for (i=0; i < tok->length; i++, p++) { fprintf(display_file, "%02x ", *p); if ((i % 16) == 15) { fprintf(display_file, "\n"); } } fprintf(display_file, "\n"); fflush(display_file); }