diff options
Diffstat (limited to 'src/windows/gss/gss-misc.c')
-rw-r--r-- | src/windows/gss/gss-misc.c | 345 |
1 files changed, 273 insertions, 72 deletions
diff --git a/src/windows/gss/gss-misc.c b/src/windows/gss/gss-misc.c index cb84e93..28227e2 100644 --- a/src/windows/gss/gss-misc.c +++ b/src/windows/gss/gss-misc.c @@ -19,136 +19,270 @@ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 2004 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ #include "gss.h" #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> +#include <sys\timeb.h> +#include <time.h> -/*+ +FILE *display_file; +DWORD ws_err; + +gss_buffer_desc empty_token_buf = { 0, (void *) "" }; +gss_buffer_t empty_token = &empty_token_buf; + +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 = send(fildes, ptr, nbyte, 0); + if (ret < 0) { + ws_err = WSAGetLastError(); + errno = ws_err; + return(ret); + } else if (ret == 0) { + return(ptr-buf); + } + } + + return(ptr-buf); +} + +static int read_all(int s, char *buf, unsigned int nbyte) +{ + int ret; + char *ptr; + fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(s, &rfds); + tv.tv_sec = 10; + tv.tv_usec = 0; + + for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { + if ( select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(s, &rfds) ) + return(ptr-buf); + ret = recv(s, ptr, nbyte, 0); + if (ret < 0) { + ws_err = WSAGetLastError(); + errno = ws_err; + 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 + * s (r) an open file descriptor + * flags (r) the flags to write + * 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. + * If the flags are non-null, send_token writes the token flags (a + * single byte, even though they're passed in in an integer). Next, + * the token length (as a network long) and then the token data are + * written 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(int s, gss_buffer_t tok) { - long len; - size_t ret; - size_t ws_err; +int send_token(int s, int flags, gss_buffer_t tok) +{ + int len, ret; + unsigned char char_flags = (unsigned char) flags; + unsigned char lenbuf[4]; - len = htonl(tok->length); + if (char_flags) { + ret = write_all(s, (char *)&char_flags, 1); + if (ret != 1) { + my_perror("sending token flags"); + OkMsgBox ("Winsock error %d \n", ws_err); + return -1; + } + } + if (tok->length > 0xffffffffUL) + abort(); + lenbuf[0] = (tok->length >> 24) & 0xff; + lenbuf[1] = (tok->length >> 16) & 0xff; + lenbuf[2] = (tok->length >> 8) & 0xff; + lenbuf[3] = tok->length & 0xff; - ret = send (s, (char *) &len, 4, 0); // Send length over the socket + ret = write_all(s, lenbuf, 4); if (ret < 0) { - ws_err = WSAGetLastError(); - errno = ws_err; - my_perror("sending token length"); + my_perror("sending token length"); OkMsgBox ("Winsock error %d \n", ws_err); - return -1; + return -1; } else if (ret != 4) { - ws_err = WSAGetLastError(); - OkMsgBox("sending token length: %d of %d bytes written\nWinsock error = %d\n", - ret, 4, ws_err); - return -1; + if (verbose) + printf("sending token length: %d of %d bytes written\r\n", + ret, 4); + return -1; } - ret = send (s, tok->value, tok->length, 0); // Send the data + ret = write_all(s, tok->value, tok->length); if (ret < 0) { - ws_err = WSAGetLastError(); - errno = ws_err; - my_perror("sending token data"); - OkMsgBox ("Winsock error %d \n", ws_err); - return -1; + my_perror("sending token data"); + OkMsgBox ("Winsock error %d \n", ws_err); + return -1; } else if (ret != tok->length) { - ws_err = WSAGetLastError(); - OkMsgBox ("sending token data: %d of %d bytes written\nWinsock error = %d\n", - ret, tok->length, ws_err); - return -1; + if (verbose) + printf("sending token data: %d of %d bytes written\r\n", + ret, (int) 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 + * s (r) an open file descriptor + * flags (w) the read flags + * 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. + * recv_token reads the token flags (a single byte, even though + * they're stored into an integer, then 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 (int s, gss_buffer_t tok) { +int recv_token(int s, int * flags, gss_buffer_t tok) +{ int ret; - unsigned long len; - size_t ws_err; + unsigned char char_flags; + unsigned char lenbuf[4]; - ret = recv (s, (char *) &len, 4, 0); + ret = read_all(s, (char *) &char_flags, 1); if (ret < 0) { - ws_err = WSAGetLastError(); - errno = ws_err; - my_perror("reading token length"); - OkMsgBox ("Winsock error %d \n", ws_err); + my_perror("reading token flags"); + OkMsgBox ("Winsock error %d \n", ws_err); return -1; - } else if (ret != 4) { - ws_err = WSAGetLastError(); - OkMsgBox ("reading token length: %d of %d bytes written\nWinsock error = %d\n", - ret, 4, ws_err); - return -1; + } else if (! ret) { + if (display_file) + printf("reading token flags: 0 bytes read\r\n", display_file); + return -1; + } else { + *flags = (int) char_flags; } - - len = ntohl(len); - tok->length = (size_t) len; - tok->value = (char *) malloc(tok->length); - if (tok->value == NULL) { - OkMsgBox ("Out of memory allocating token data\n"); + + if (char_flags == 0 ) { + lenbuf[0] = 0; + ret = read_all(s, &lenbuf[1], 3); + if (ret < 0) { + my_perror("reading token length"); + OkMsgBox ("Winsock error %d \n", ws_err); + return -1; + } else if (ret != 3) { + if (verbose) + printf("reading token length: %d of %d bytes read\r\n", + ret, 3); + return -1; + } + } + else { + ret = read_all(s, lenbuf, 4); + if (ret < 0) { + my_perror("reading token length"); + OkMsgBox ("Winsock error %d \n", ws_err); + return -1; + } else if (ret != 4) { + if (verbose) + printf("reading token length: %d of %d bytes read\r\n", + ret, 4); + return -1; + } + } + + tok->length = ((lenbuf[0] << 24) + | (lenbuf[1] << 16) + | (lenbuf[2] << 8) + | lenbuf[3]); + tok->value = (char *) malloc(tok->length ? tok->length : 1); + if (tok->length && tok->value == NULL) { + if (verbose) + printf("Out of memory allocating token data\r\n"); return -1; } - ret = recv (s, (char *) tok->value, tok->length, 0); + ret = read_all(s, (char *) tok->value, tok->length); if (ret < 0) { - ws_err = WSAGetLastError(); - errno = ws_err; - my_perror("reading token data"); - OkMsgBox ("Winsock error %d \n", ws_err); - free(tok->value); - return -1; - } else if ((size_t) ret != tok->length) { - ws_err = WSAGetLastError(); - OkMsgBox ("reading token data: %d of %d bytes written\nWinsock error = %d\n", - ret, tok->length, ws_err); - free(tok->value); - return -1; + my_perror("reading token data"); + OkMsgBox ("Winsock error %d \n", ws_err); + free(tok->value); + return -1; + } else if (ret != tok->length) { + printf("sending token data: %d of %d bytes written\r\n", + ret, (int) tok->length); + free(tok->value); + return -1; } return 0; } +void +free_token(gss_buffer_t tok) +{ + if (tok->length <= 0 || tok->value == NULL) + return; + + free(tok->value); + tok->value = NULL; + tok->length = 0; +} + /*+ * Function: display_status * @@ -183,6 +317,9 @@ display_status_1(char *m, OM_uint32 code, int type) { maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); + if (verbose) + printf("GSS-API error %s: %s\r\n", m, + (char *)msg.value); OkMsgBox ("GSS-API error %s: %s\n", m, (char *)msg.value); (void) gss_release_buffer(&min_stat, &msg); @@ -191,6 +328,70 @@ display_status_1(char *m, OM_uint32 code, int type) { break; } } + +/* + * Function: display_ctx_flags + * + * Purpose: displays the flags returned by context initation 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) + printf("context flag: GSS_C_DELEG_FLAG\r\n"); + if (flags & GSS_C_MUTUAL_FLAG) + printf("context flag: GSS_C_MUTUAL_FLAG\r\n"); + if (flags & GSS_C_REPLAY_FLAG) + printf("context flag: GSS_C_REPLAY_FLAG\r\n"); + if (flags & GSS_C_SEQUENCE_FLAG) + printf("context flag: GSS_C_SEQUENCE_FLAG\r\n"); + if (flags & GSS_C_CONF_FLAG ) + printf("context flag: GSS_C_CONF_FLAG \r\n"); + if (flags & GSS_C_INTEG_FLAG ) + printf("context flag: GSS_C_INTEG_FLAG \r\n"); +} + +void print_token(tok) + gss_buffer_t tok; +{ + int i; + unsigned char *p = tok->value; + + if (!verbose) + return; + for (i=0; i < tok->length; i++, p++) { + printf("%02x ", *p); + if ((i % 16) == 15) { + printf("\r\n"); + } + } + printf("\r\n"); +} + + +int gettimeofday (struct timeval *tv, void *ignore_tz) +{ + struct _timeb tb; + _tzset(); + _ftime(&tb); + if (tv) { + tv->tv_sec = tb.time; + tv->tv_usec = tb.millitm * 1000; + } + return 0; +} + /*+************************************************************************* ** ** OkMsgBox |