aboutsummaryrefslogtreecommitdiff
path: root/src/windows/gss/gss-misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows/gss/gss-misc.c')
-rw-r--r--src/windows/gss/gss-misc.c345
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