As submitted by Openvision Technologies:
authorTheodore Tso <tytso@mit.edu>
Sat, 18 Dec 1993 03:14:21 +0000 (03:14 +0000)
committerTheodore Tso <tytso@mit.edu>
Sat, 18 Dec 1993 03:14:21 +0000 (03:14 +0000)
To: tytso@MIT.EDU
Subject: gssapi
Date: Fri, 17 Dec 1993 17:55:06 -0500
From: Marc Horowitz <marc@security.ov.com>

This is named in my RCS tree as MIT931217.  The copyright notice
included is (hopefully) final.  Good luck!

Marc

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@3205 dc483132-0cff-0310-8789-dd5450dbe970

49 files changed:
src/lib/gssapi/Makefile [new file with mode: 0644]
src/lib/gssapi/generic/Makefile [new file with mode: 0644]
src/lib/gssapi/generic/display_com_err_status.c [new file with mode: 0644]
src/lib/gssapi/generic/display_major_status.c [new file with mode: 0644]
src/lib/gssapi/generic/gssapi.h [new file with mode: 0644]
src/lib/gssapi/generic/gssapiP_generic.h [new file with mode: 0644]
src/lib/gssapi/generic/gssapi_generic.c [new file with mode: 0644]
src/lib/gssapi/generic/gssapi_generic.h [new file with mode: 0644]
src/lib/gssapi/generic/gssapi_generic_err.et [new file with mode: 0644]
src/lib/gssapi/generic/release_buffer.c [new file with mode: 0644]
src/lib/gssapi/generic/release_oid_set.c [new file with mode: 0644]
src/lib/gssapi/generic/util_buffer.c [new file with mode: 0644]
src/lib/gssapi/generic/util_canonhost.c [new file with mode: 0644]
src/lib/gssapi/generic/util_dup.c [new file with mode: 0644]
src/lib/gssapi/generic/util_oid.c [new file with mode: 0644]
src/lib/gssapi/generic/util_token.c [new file with mode: 0644]
src/lib/gssapi/generic/util_validate.c [new file with mode: 0644]
src/lib/gssapi/krb5/Makefile [new file with mode: 0644]
src/lib/gssapi/krb5/accept_sec_context.c [new file with mode: 0644]
src/lib/gssapi/krb5/acquire_cred.c [new file with mode: 0644]
src/lib/gssapi/krb5/compare_name.c [new file with mode: 0644]
src/lib/gssapi/krb5/context_time.c [new file with mode: 0644]
src/lib/gssapi/krb5/delete_sec_context.c [new file with mode: 0644]
src/lib/gssapi/krb5/display_name.c [new file with mode: 0644]
src/lib/gssapi/krb5/display_status.c [new file with mode: 0644]
src/lib/gssapi/krb5/get_tkt_flags.c [new file with mode: 0644]
src/lib/gssapi/krb5/gssapiP_krb5.h [new file with mode: 0644]
src/lib/gssapi/krb5/gssapi_krb5.c [new file with mode: 0644]
src/lib/gssapi/krb5/gssapi_krb5.h [new file with mode: 0644]
src/lib/gssapi/krb5/gssapi_krb5_err.et [new file with mode: 0644]
src/lib/gssapi/krb5/import_name.c [new file with mode: 0644]
src/lib/gssapi/krb5/indicate_mechs.c [new file with mode: 0644]
src/lib/gssapi/krb5/init_sec_context.c [new file with mode: 0644]
src/lib/gssapi/krb5/inquire_context.c [new file with mode: 0644]
src/lib/gssapi/krb5/inquire_cred.c [new file with mode: 0644]
src/lib/gssapi/krb5/k5seal.c [new file with mode: 0644]
src/lib/gssapi/krb5/k5unseal.c [new file with mode: 0644]
src/lib/gssapi/krb5/krb5_gss_glue.c [new file with mode: 0644]
src/lib/gssapi/krb5/process_context_token.c [new file with mode: 0644]
src/lib/gssapi/krb5/release_cred.c [new file with mode: 0644]
src/lib/gssapi/krb5/release_name.c [new file with mode: 0644]
src/lib/gssapi/krb5/seal.c [new file with mode: 0644]
src/lib/gssapi/krb5/sign.c [new file with mode: 0644]
src/lib/gssapi/krb5/unseal.c [new file with mode: 0644]
src/lib/gssapi/krb5/util_cksum.c [new file with mode: 0644]
src/lib/gssapi/krb5/util_crypt.c [new file with mode: 0644]
src/lib/gssapi/krb5/util_seed.c [new file with mode: 0644]
src/lib/gssapi/krb5/util_seqnum.c [new file with mode: 0644]
src/lib/gssapi/krb5/verify.c [new file with mode: 0644]

diff --git a/src/lib/gssapi/Makefile b/src/lib/gssapi/Makefile
new file mode 100644 (file)
index 0000000..0ace19c
--- /dev/null
@@ -0,0 +1,31 @@
+# 
+# Copyright 1993 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.
+# 
+
+# $Id$
+
+TOP = ../..
+include $(TOP)/config.mk/template
+
+all::
+
+SUBDIRS = generic krb5 trust unit-test
+expand SubdirTarget
diff --git a/src/lib/gssapi/generic/Makefile b/src/lib/gssapi/generic/Makefile
new file mode 100644 (file)
index 0000000..6fa6194
--- /dev/null
@@ -0,0 +1,74 @@
+# 
+# Copyright 1993 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.
+# 
+
+# $Id$
+
+TOP = ../../..
+include $(TOP)/config.mk/template
+
+CCSRCS = \
+       display_major_status.c \
+       display_com_err_status.c \
+       gssapi_generic.c \
+       release_buffer.c \
+       release_oid_set.c \
+       util_buffer.c \
+       util_canonhost.c \
+       util_dup.c \
+       util_oid.c \
+       util_token.c \
+       util_validate.c
+CCOBJS = $(addsuffix .o,$(basename $(CCSRCS)))
+
+ETSRCS = gssapi_generic_err.et
+ETCS = $(addsuffix .c,$(basename $(ETSRCS)))
+ETHS = $(addsuffix .h,$(basename $(ETSRCS)))
+ETOBJS = $(addsuffix .o,$(basename $(ETSRCS)))
+
+OBJS = $(CCOBJS)
+
+CFLAGS := -I. $(CFLAGS)
+
+all::
+
+all:: $(ETCS) $(ETHS)
+
+listobjs:
+       @echo $(CCOBJS) $(ETOBJS)
+
+SRCS = $(CCSRCS)
+DEPENDS = $(ETHS)
+expand Depend
+
+ETABLES = $(ETSRCS)
+expand ErrorTables
+
+stage:: $(CCOBJS) $(ETOBJS)
+
+all:: $(CCOBJS) $(ETOBJS)
+
+SRCS = $(CCSRCS)
+expand Saber
+
+HDRS = gssapi.h gssapi_generic.h
+HDRS_DIR = gssapi
+expand InstallIncludes
diff --git a/src/lib/gssapi/generic/display_com_err_status.c b/src/lib/gssapi/generic/display_com_err_status.c
new file mode 100644 (file)
index 0000000..0a36f91
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_generic.h"
+#include <com_err.h>
+
+/* XXXX internationalization!! */
+
+/**/
+
+static int init_et = 0;
+static const char * const no_error = "No error";
+
+/**/
+
+/* if status_type == GSS_C_GSS_CODE, return up to three error messages,
+     for routine errors, call error, and status, in that order.
+     message_context == 0 : print the routine error
+     message_context == 1 : print the calling error
+     message_context > 2  : print supplementary info bit (message_context-2)
+   if status_type == GSS_C_MECH_CODE, return the output from error_message()
+   */
+
+OM_uint32
+g_display_com_err_status(OM_uint32 *minor_status,
+                        OM_uint32 status_value,
+                        gss_buffer_t status_string)
+{
+   status_string->length = 0;
+   status_string->value = NULL;
+
+   if (!init_et) {
+      initialize_ggss_error_table();
+      init_et = 1;
+   }
+
+   if (! g_make_string_buffer(((status_value == 0)?no_error:
+                              error_message(status_value)),
+                             status_string)) {
+      *minor_status = ENOMEM;
+      return(GSS_S_FAILURE);
+   }
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/generic/display_major_status.c b/src/lib/gssapi/generic/display_major_status.c
new file mode 100644 (file)
index 0000000..0216cf1
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_generic.h"
+
+/*
+ * $Id$
+ */
+
+/* This code has knowledge of the min and max errors of each type
+   within the gssapi major status */
+
+#define GSS_ERROR_STR(value, array, select, min, max, num) \
+   (((select(value) < (min)) || (select(value) > (max))) ? NULL : \
+    (array)[num(value)])
+
+/**/
+
+static const char * const calling_error_string[] = {
+   NULL,
+   "A required input parameter could not be read",
+   "A required input parameter could not be written",
+   "A parameter was malformed",
+};
+static const char * const calling_error = "calling error";
+
+#define GSS_CALLING_ERROR_STR(x) \
+   GSS_ERROR_STR((x), calling_error_string, GSS_CALLING_ERROR, \
+                GSS_S_CALL_INACCESSIBLE_READ, GSS_S_CALL_BAD_STRUCTURE, \
+                GSS_CALLING_ERROR_FIELD)
+
+/**/
+
+static const char * const routine_error_string[] = {
+   NULL,
+   "An unsupported mechanism was requested",
+   "An invalid name was supplied",
+   "A supplied name was of an unsupported type",
+   "Incorrect channel bindings were supplied",
+   "An invalid status code was supplied",
+   "A token had an invalid signature",
+   "No credentials were supplied",
+   "No context has been established",
+   "A token was invalid",
+   "A credential was invalid",
+   "The referenced credentials have expired",
+   "The context has expired",
+   "Miscellaneous failure",   
+};   
+
+static const char * const routine_error = "routine error";
+
+#define GSS_ROUTINE_ERROR_STR(x) \
+   GSS_ERROR_STR((x), routine_error_string, GSS_ROUTINE_ERROR, \
+                GSS_S_BAD_MECH, GSS_S_FAILURE, \
+                GSS_ROUTINE_ERROR_FIELD)
+
+/**/
+
+/* this becomes overly gross after about 4 strings */
+
+static const char * const sinfo_string[] = {
+   "The routine must be called again to complete its function",
+   "The token was a duplicate of an earlier token",
+   "The token's validity period has expired",
+   "A later token has already been processed",
+};
+
+static const char * const sinfo_code = "supplementary info code";
+
+#define LSBGET(x) ((((x)^((x)-1))+1)>>1)
+#define LSBMASK(n) ((1<<(n))^((1<<(n))-1))
+
+#define GSS_SINFO_STR(x) \
+   ((((1<<(x)) < GSS_S_CONTINUE_NEEDED) || ((1<<(x)) > GSS_S_UNSEQ_TOKEN)) ? \
+    /**/NULL:sinfo_string[(x)])
+
+/**/
+
+static const char * const no_error = "No error";
+static const char * const unknown_error = "Unknown %s (field = %d)";
+
+/**/
+
+int display_unknown(const char *kind, OM_uint32 value,
+               gss_buffer_t buffer)
+{
+   int len;
+   char *str;
+
+   if ((str =
+       (char *) xmalloc(len = strlen(unknown_error)+strlen(kind)+7)) == NULL)
+      return(0);
+
+   sprintf(str, unknown_error, kind, value);
+
+   buffer->length = len;
+   buffer->value = str;
+
+   return(1);
+}
+
+/* code should be set to the calling error field */
+
+static OM_uint32
+   display_calling(OM_uint32 *minor_status,
+                  OM_uint32 code,
+                  gss_buffer_t status_string)
+{
+   const char *str;
+
+   if (str = GSS_CALLING_ERROR_STR(code)) {
+      if (! g_make_string_buffer(str, status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      if (! display_unknown(calling_error, GSS_CALLING_ERROR_FIELD(code),
+                           status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   }
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
+
+/* code should be set to the routine error field */
+
+static OM_uint32
+   display_routine(OM_uint32 *minor_status,
+                  OM_uint32 code,
+                  gss_buffer_t status_string)
+{
+   const char *str;
+
+   if (str = GSS_ROUTINE_ERROR_STR(code)) {
+      if (! g_make_string_buffer(str, status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      if (! display_unknown(routine_error, GSS_ROUTINE_ERROR_FIELD(code),
+                           status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   }
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
+
+/* code should be set to the bit offset (log_2) of a supplementary info bit */
+
+static OM_uint32
+   display_bit(OM_uint32 *minor_status,
+              OM_uint32 code,
+              gss_buffer_t status_string)
+{
+   const char *str;
+
+   if (str = GSS_SINFO_STR(code)) {
+      if (! g_make_string_buffer(str, status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      if (! display_unknown(sinfo_code, 1<<code, status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   }
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
+
+/**/
+
+/* return error messages, for routine errors, call error, and status,
+   in that order.
+     message_context == 0 : print the routine error
+     message_context == 1 : print the calling error
+     message_context > 2  : print supplementary info bit (message_context-2)
+     */
+
+OM_uint32
+g_display_major_status(OM_uint32 *minor_status,
+                      OM_uint32 status_value,
+                      int *message_context,
+                      gss_buffer_t status_string)
+{
+   OM_uint32 ret, tmp;
+   int bit;
+
+   /*** deal with no error at all specially */
+
+   if (status_value == 0) {
+      if (! g_make_string_buffer(no_error, status_string)) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+      *message_context = 0;
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
+
+   /*** do routine error */
+
+   if (*message_context == 0) {
+      if (tmp = GSS_ROUTINE_ERROR(status_value)) {
+        status_value -= tmp;
+        if (ret = display_routine(minor_status, tmp, status_string))
+           return(ret);
+        *minor_status = 0;
+        if (status_value) {
+           (*message_context)++;
+           return(GSS_S_CONTINUE_NEEDED);
+        } else {
+           *message_context = 0;
+           return(GSS_S_COMPLETE);
+        }
+      } else {
+        (*message_context)++;
+      }
+   } else {
+      status_value -= GSS_ROUTINE_ERROR(status_value);
+   }
+
+   /*** do calling error */
+
+   if (*message_context == 1) {
+      if (tmp = GSS_CALLING_ERROR(status_value)) {
+        status_value -= tmp;
+        if (ret = display_calling(minor_status, tmp, status_string))
+           return(ret);
+        *minor_status = 0;
+        if (status_value) {
+           (*message_context)++;
+           return(GSS_S_CONTINUE_NEEDED);
+        } else {
+           *message_context = 0;
+           return(GSS_S_COMPLETE);
+        }
+      } else {
+        (*message_context)++;
+      }
+   } else {
+      status_value -= GSS_CALLING_ERROR(status_value);
+   }
+
+   /*** do sinfo bits (*message_context == 2 + number of bits done) */
+
+   tmp = GSS_SUPPLEMENTARY_INFO_FIELD(status_value);
+   /* mask off the bits which have been done */
+   if (*message_context > 2) {
+      tmp &= ~LSBMASK(*message_context-3);
+      status_value &= ~LSBMASK(*message_context-3);
+   }
+
+   if (!tmp) {
+      /* bogon input - there should be something left */
+      *minor_status = G_BAD_MSG_CTX;
+      return(GSS_S_FAILURE);
+   }
+
+   /* compute the bit offset */
+   /*SUPPRESS 570*/
+   for (bit=0; (1<<bit) != LSBGET(tmp); bit++) ;
+
+   /* print it */
+   if (ret = display_bit(minor_status, bit, status_string))
+      return(ret);
+
+   /* compute the new status_value/message_context */
+   status_value -= 1<<bit;
+
+   if (status_value) {
+      *message_context = bit+3;
+      return(GSS_S_CONTINUE_NEEDED);
+   } else {
+      *message_context = 0;
+      return(GSS_S_COMPLETE);
+   }
+}
diff --git a/src/lib/gssapi/generic/gssapi.h b/src/lib/gssapi/generic/gssapi.h
new file mode 100644 (file)
index 0000000..c2a9af0
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#ifndef _GSSAPI_H_
+#define _GSSAPI_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * $Id$
+ */
+
+/*
+ * First, define the platform-dependent types.
+ */
+typedef unsigned int OM_uint32;
+typedef void * gss_name_t;
+typedef void * gss_cred_id_t;
+typedef void * gss_ctx_id_t;
+
+/*
+ * Note that a platform supporting the xom.h X/Open header file
+ * may make use of that header for the definitions of OM_uint32
+ * and the structure to which gss_OID_desc equates.
+ */
+
+typedef struct gss_OID_desc_struct {
+      OM_uint32 length;
+      void      *elements;
+} gss_OID_desc, *gss_OID;
+
+typedef const gss_OID_desc * const const_gss_OID;
+
+typedef struct gss_OID_set_desc_struct  {
+      int     count;
+      gss_OID elements;
+} gss_OID_set_desc, *gss_OID_set;
+
+typedef struct gss_buffer_desc_struct {
+      size_t length;
+      void *value;
+} gss_buffer_desc, *gss_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+      OM_uint32 initiator_addrtype;
+      gss_buffer_desc initiator_address;
+      OM_uint32 acceptor_addrtype;
+      gss_buffer_desc acceptor_address;
+      gss_buffer_desc application_data;
+} *gss_channel_bindings_t;
+
+
+/*
+ * Six independent flags each of which indicates that a context
+ * supports a specific service option.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC     0
+#define GSS_C_AF_LOCAL      1
+#define GSS_C_AF_INET       2
+#define GSS_C_AF_IMPLINK    3
+#define GSS_C_AF_PUP        4
+#define GSS_C_AF_CHAOS      5
+#define GSS_C_AF_NS         6
+#define GSS_C_AF_NBS        7
+#define GSS_C_AF_ECMA       8
+#define GSS_C_AF_DATAKIT    9
+#define GSS_C_AF_CCITT      10
+#define GSS_C_AF_SNA        11
+#define GSS_C_AF_DECnet     12
+#define GSS_C_AF_DLI        13
+#define GSS_C_AF_LAT        14
+#define GSS_C_AF_HYLINK     15
+#define GSS_C_AF_APPLETALK  16
+#define GSS_C_AF_BSC        17
+#define GSS_C_AF_DSS        18
+#define GSS_C_AF_OSI        19
+#define GSS_C_AF_X25        21
+
+#define GSS_C_AF_NULLADDR   255
+
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NULL_OID ((gss_OID) 0)
+#define GSS_C_NULL_OID_SET ((gss_OID_set) 0)
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+
+/*
+ * Define the default Quality of Protection for per-message
+ * services.  Note that an implementation that offers multiple
+ * levels of QOP may either reserve a value (for example zero,
+ * as assumed here) to mean "default protection", or alternatively
+ * may simply equate GSS_C_QOP_DEFAULT to a specific explicit QOP
+ * value.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xffffffffu
+
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK 0377
+#define GSS_C_ROUTINE_ERROR_MASK 0377
+#define GSS_C_SUPPLEMENTARY_MASK 0177777
+
+/*
+ * The macros that test status codes for error conditions
+ */
+#define GSS_CALLING_ERROR(x) \
+  ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+  ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+  ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+  ((GSS_CALLING_ERROR(x) != 0) || (GSS_ROUTINE_ERROR(x) != 0))
+
+/* XXXX these are not part of the GSSAPI C bindings!  (but should be) */
+
+#define GSS_CALLING_ERROR_FIELD(x) \
+   (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+#define GSS_ROUTINE_ERROR_FIELD(x) \
+   (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
+   (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+                             (1 << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+                             (2 << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+                             (3 << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (1 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (2 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (3 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (4 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (5 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (6 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CRED (7 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (8 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (9 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL (10 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED (11 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED (12 << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (13 << GSS_C_ROUTINE_ERROR_OFFSET)
+/* XXXX This is a necessary evil until the spec is fixed */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+
+
+/*
+ * Finally, function prototypes for the GSSAPI routines.
+ */
+
+OM_uint32 gss_acquire_cred
+           (OM_uint32*,       /* minor_status */
+            gss_name_t,       /* desired_name */
+            OM_uint32,        /* time_req */
+            gss_OID_set,      /* desired_mechs */
+            int,              /* cred_usage */
+            gss_cred_id_t*,   /* output_cred_handle */
+            gss_OID_set*,     /* actual_mechs */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 gss_release_cred
+           (OM_uint32*,       /* minor_status */
+            gss_cred_id_t*    /* cred_handle */
+           );
+
+OM_uint32 gss_init_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_cred_id_t,    /* claimant_cred_handle */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_name_t,       /* target_name */
+            const_gss_OID,    /* mech_type */
+            int,              /* req_flags */
+            OM_uint32,        /* time_req */
+            gss_channel_bindings_t,
+                              /* input_chan_bindings */
+            gss_buffer_t,     /* input_token */
+            gss_OID*,         /* actual_mech_type */
+            gss_buffer_t,     /* output_token */
+            int*,             /* ret_flags */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 gss_accept_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_cred_id_t,    /* verifier_cred_handle */
+            gss_buffer_t,     /* input_token_buffer */
+            gss_channel_bindings_t,
+                              /* input_chan_bindings */
+            gss_name_t*,      /* src_name */
+            gss_OID*,         /* mech_type */
+            gss_buffer_t,     /* output_token */
+            int*,             /* ret_flags */
+            OM_uint32*,       /* time_rec */
+            gss_cred_id_t*    /* delegated_cred_handle */
+           );
+
+OM_uint32 gss_process_context_token
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t      /* token_buffer */
+           );
+
+OM_uint32 gss_delete_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_buffer_t      /* output_token */
+           );
+
+OM_uint32 gss_context_time
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 gss_sign
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            int,              /* qop_req */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t      /* message_token */
+           );
+
+OM_uint32 gss_verify
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t,     /* token_buffer */
+            int*              /* qop_state */
+           );
+
+OM_uint32 gss_seal
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            int,              /* conf_req_flag */
+            int,              /* qop_req */
+            gss_buffer_t,     /* input_message_buffer */
+            int*,             /* conf_state */
+            gss_buffer_t      /* output_message_buffer */
+           );
+
+OM_uint32 gss_unseal
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t,     /* input_message_buffer */
+            gss_buffer_t,     /* output_message_buffer */
+            int*,             /* conf_state */
+            int*              /* qop_state */
+           );
+
+OM_uint32 gss_display_status
+           (OM_uint32*,       /* minor_status */
+            OM_uint32,        /* status_value */
+            int,              /* status_type */
+            const_gss_OID,    /* mech_type */
+            int*,             /* message_context */
+            gss_buffer_t      /* status_string */
+           );
+
+OM_uint32 gss_indicate_mechs
+           (OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* mech_set */
+           );
+
+OM_uint32 gss_compare_name
+           (OM_uint32*,       /* minor_status */
+            gss_name_t,       /* name1 */
+            gss_name_t,       /* name2 */
+            int*              /* name_equal */
+           );
+
+OM_uint32 gss_display_name
+           (OM_uint32*,      /* minor_status */
+            gss_name_t,      /* input_name */
+            gss_buffer_t,     /* output_name_buffer */
+            gss_OID*         /* output_name_type */
+           );
+
+OM_uint32 gss_import_name
+           (OM_uint32*,       /* minor_status */
+            gss_buffer_t,     /* input_name_buffer */
+            const_gss_OID,    /* input_name_type */
+            gss_name_t*       /* output_name */
+           );
+
+OM_uint32 gss_release_name
+           (OM_uint32*,       /* minor_status */
+            gss_name_t*       /* input_name */
+           );
+
+OM_uint32 gss_release_buffer
+           (OM_uint32*,       /* minor_status */
+            gss_buffer_t      /* buffer */
+           );
+
+OM_uint32 gss_release_oid_set
+           (OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* set */
+           );
+
+OM_uint32 gss_inquire_cred
+           (OM_uint32 *,      /* minor_status */
+            gss_cred_id_t,    /* cred_handle */
+            gss_name_t *,     /* name */
+            OM_uint32 *,      /* lifetime */
+            int *,            /* cred_usage */
+            gss_OID_set *     /* mechanisms */
+           );
+
+OM_uint32 gss_inquire_context
+          (OM_uint32*,       /* minor_status */
+           gss_ctx_id_t,     /* context_handle */
+           gss_name_t*,      /* initiator_name */
+           gss_name_t*,      /* acceptor_name */
+           OM_uint32*,       /* lifetime_rec */
+           gss_OID*,         /* mech_type */
+           int*,             /* ret_flags */
+           int*              /* locally_initiated */
+          );
+
+
+#endif /* _GSSAPI_H_ */
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
new file mode 100644 (file)
index 0000000..5d82755
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#ifndef _GSSAPIP_GENERIC_H_
+#define _GSSAPIP_GENERIC_H_
+
+/*
+ * $Id$
+ */
+
+#include "gssapi.h"
+
+#include "gssapi_generic_err.h"
+#include <errno.h>
+
+/** helper macros **/
+
+#define g_OID_equal(o1,o2) \
+   (((o1)->length == (o2)->length) && \
+    (memcmp((o1)->elements,(o2)->elements,(o1)->length) == 0))
+
+#define TWRITE_INT(ptr, tmp, num) \
+   (tmp) = htonl(num); \
+   memcpy(ptr, (char *) &(tmp), sizeof(tmp)); \
+   (ptr) += sizeof(tmp);
+            
+#define TREAD_INT(ptr, num) \
+   memcpy((char *) &(num), (char *) (ptr), sizeof(num)); \
+   (num) = ntohl(num); \
+   (ptr) += sizeof(num);
+
+#define TWRITE_STR(ptr, str, len) \
+   memcpy((ptr), (char *) (str), (len)); \
+   (ptr) += (len);
+
+#define TREAD_STR(ptr, str, len) \
+   (str) = (ptr); \
+   (ptr) += (len);
+
+#define TWRITE_BUF(ptr, tmp, buf) \
+   TWRITE_INT((ptr), (tmp), (buf).length); \
+   TWRITE_STR((ptr), (buf).value, (buf).length);
+
+/** malloc wrappers; these may actually do something later */
+
+#define xmalloc(n) malloc(n)
+#define xrealloc(p,n) realloc(p,n)
+#ifdef xfree
+#undef xfree
+#endif
+#define xfree(p) free(p)
+
+/** helper functions **/
+
+int g_save_name(void **vdb, gss_name_t *name);
+int g_save_cred_id(void **vdb, gss_cred_id_t *cred);
+int g_save_ctx_id(void **vdb, gss_ctx_id_t *ctx);
+
+int g_validate_name(void **vdb, gss_name_t *name);
+int g_validate_cred_id(void **vdb, gss_cred_id_t *cred);
+int g_validate_ctx_id(void **vdb, gss_ctx_id_t *ctx);
+
+int g_delete_name(void **vdb, gss_name_t *name);
+int g_delete_cred_id(void **vdb, gss_cred_id_t *cred);
+int g_delete_ctx_id(void **vdb, gss_ctx_id_t *ctx);
+
+int g_make_string_buffer(const char *str, gss_buffer_t buffer);
+
+int g_copy_OID_set(const gss_OID_set_desc * const in, gss_OID_set *out);
+
+int g_token_size(const_gss_OID mech, unsigned int body_size);
+
+void g_make_token_header(const_gss_OID mech, int body_size,
+                         unsigned char **buf, int tok_type);
+
+int g_verify_token_header(const_gss_OID mech, int *body_size,
+                         unsigned char **buf, int tok_type, int toksize);
+
+OM_uint32 g_display_major_status(OM_uint32 *minor_status,
+                                OM_uint32 status_value,
+                                int *message_context,
+                                gss_buffer_t status_string);
+
+OM_uint32 g_display_com_err_status(OM_uint32 *minor_status,
+                                  OM_uint32 status_value,
+                                  gss_buffer_t status_string);
+
+char *g_canonicalize_host(char *hostname);
+
+char *g_strdup(char *str);
+
+/** declarations of internal name mechanism functions **/
+
+OM_uint32 generic_gss_release_buffer
+           (OM_uint32*,       /* minor_status */
+            gss_buffer_t      /* buffer */
+           );
+
+OM_uint32 generic_gss_release_oid_set
+           (OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* set */
+           );
+
+#endif /* _GSSAPIP_GENERIC_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
new file mode 100644 (file)
index 0000000..26d7eeb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_generic.h"
+
+static const gss_OID_desc oids[] = {
+   {2, "\001\001"},
+   {2, "\001\002"},
+   {2, "\001\003"},
+   {2, "\001\004"},
+};
+
+const_gss_OID gss_nt_user_name = oids+0;
+const_gss_OID gss_nt_machine_uid_name = oids+1;
+const_gss_OID gss_nt_string_uid_name = oids+2;
+const_gss_OID gss_nt_service_name = oids+3;
diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h
new file mode 100644 (file)
index 0000000..8d934dd
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#ifndef _GSSAPI_GENERIC_H_
+#define _GSSAPI_GENERIC_H_
+
+/*
+ * $Id$
+ */
+
+#include <gssapi/gssapi.h>
+
+extern const gss_OID_desc * const gss_nt_user_name;
+extern const gss_OID_desc * const gss_nt_machine_uid_name;
+extern const gss_OID_desc * const gss_nt_string_uid_name;
+extern const gss_OID_desc * const gss_nt_service_name;
+
+#endif /* _GSSAPI_GENERIC_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_generic_err.et b/src/lib/gssapi/generic/gssapi_generic_err.et
new file mode 100644 (file)
index 0000000..fed788c
--- /dev/null
@@ -0,0 +1,38 @@
+# 
+# Copyright 1993 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.
+# 
+
+#
+# $Id$
+#
+
+error_table ggss
+
+error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string"
+error_code G_BAD_STRING_UID, "STRING-UID-NAME contains nondigits"
+error_code G_NOUSER, "UID does not resolve to username"
+error_code G_VALIDATE_FAILED, "Validation error"
+error_code G_BUFFER_ALLOC, "Couldn't allocate gss_buffer_t data"
+error_code G_BAD_MSG_CTX, "Message context invalid"
+error_code G_WRONG_SIZE, "Buffer is the wrong size"
+error_code G_BAD_USAGE, "Credential usage type is unknown"
+error_code G_UNKNOWN_QOP, "Unknown quality of protection specified"
+end
diff --git a/src/lib/gssapi/generic/release_buffer.c b/src/lib/gssapi/generic/release_buffer.c
new file mode 100644 (file)
index 0000000..ecb8eab
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_generic.h"
+
+OM_uint32
+generic_gss_release_buffer(OM_uint32 *minor_status,
+                          gss_buffer_t buffer)
+{
+   if ((buffer->length) &&
+       (buffer->value)) {
+      xfree(buffer->value);
+      buffer->length = 0;
+      buffer->value = NULL;
+   }
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/generic/release_oid_set.c b/src/lib/gssapi/generic/release_oid_set.c
new file mode 100644 (file)
index 0000000..e821e6e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_generic.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+generic_gss_release_oid_set(OM_uint32 *minor_status,
+                           gss_OID_set *set)
+{
+   *minor_status = 0;
+
+   if (*set == GSS_C_NULL_OID_SET)
+      return(GSS_S_COMPLETE);
+
+   xfree((*set)->elements);
+   xfree(*set);
+
+   *set = GSS_C_NULL_OID_SET;
+
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/generic/util_buffer.c b/src/lib/gssapi/generic/util_buffer.c
new file mode 100644 (file)
index 0000000..63c1052
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_generic.h"
+#include <string.h>
+
+/* return nonzero on success, 0 on failure
+   make sure that buffer is consistent (release'able) when this
+   function exits, no matter what the exit value */
+
+int g_make_string_buffer(const char *str, gss_buffer_t buffer)
+{
+   buffer->length = strlen(str)+1;
+
+   if ((buffer->value = (void *) xmalloc(buffer->length)) == NULL) {
+      buffer->length = 0;
+      return(0);
+   }
+
+   strcpy(buffer->value, str);
+
+   return(1);
+}
diff --git a/src/lib/gssapi/generic/util_canonhost.c b/src/lib/gssapi/generic/util_canonhost.c
new file mode 100644 (file)
index 0000000..8fb7a03
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+/* This file could be OS specific */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+
+#include "gssapiP_generic.h"
+
+char *g_canonicalize_host(char *hostname)
+{
+   struct hostent *hent;
+   char *canon, *str;
+
+   if ((hent = gethostbyname(hostname)) == NULL)
+      return(NULL);
+
+   if ((canon = xmalloc(strlen(hent->h_name)+1)) == NULL)
+      return(NULL);
+
+   strcpy(canon, hent->h_name);
+
+   for (str = canon; *str; str++)
+      if (isupper(*str)) *str = tolower(*str);
+
+   return(canon);
+}
diff --git a/src/lib/gssapi/generic/util_dup.c b/src/lib/gssapi/generic/util_dup.c
new file mode 100644 (file)
index 0000000..4da6547
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_generic.h"
+#include <string.h>
+
+char *g_strdup(char *str)
+{
+   char *ret;
+
+   if ((ret = (char *) xmalloc(strlen(str)+1)) == NULL)
+      return(NULL);
+
+   strcpy(ret, str);
+
+   return(ret);
+}
diff --git a/src/lib/gssapi/generic/util_oid.c b/src/lib/gssapi/generic/util_oid.c
new file mode 100644 (file)
index 0000000..40f730a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_generic.h"
+
+/*
+ * $Id$
+ */
+
+int
+g_copy_OID_set(const gss_OID_set_desc * const in, gss_OID_set *out)
+{
+   gss_OID_set copy;
+   int i;
+
+   *out = NULL;
+
+   if ((copy =
+       (gss_OID_set_desc *) xmalloc(sizeof(gss_OID_set_desc))) == NULL)
+      return(0);
+
+   copy->count = in->count;
+
+   if ((copy->elements = 
+       (gss_OID_desc *) xmalloc(sizeof(gss_OID_desc)*copy->count)) == NULL) {
+      xfree(copy);
+      return(0);
+   }
+
+   for (i=0; i<in->count; i++)
+      copy->elements[i] = in->elements[i];
+
+   *out = copy;
+   return(1);
+}
diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c
new file mode 100644 (file)
index 0000000..3fad4b9
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_generic.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+/* XXXX this code currently makes the assumption that a mech oid will
+   never be longer than 127 bytes.  This assumption is not inherent in
+   the interfaces, so the code can be fixed if the OSI namespace
+   balloons unexpectedly. */
+
+/* Each token looks like this:
+
+0x60                           tag for APPLICATION 0, SEQUENCE
+                                       (constructed, definite-length)
+       <length>                possible multiple bytes, need to parse/generate
+       0x06                    tag for OBJECT IDENTIFIER
+               <moid_length>   compile-time constant string (assume 1 byte)
+               <moid_bytes>    compile-time constant string
+       <inner_bytes>           the ANY containing the application token
+                                       bytes 0,1 are the token type
+                                       bytes 2,n are the token data
+
+For the purposes of this abstraction, the token "header" consists of
+the sequence tag and length octets, the mech OID DER encoding, and the
+first two inner bytes, which indicate the token type.  The token
+"body" consists of everything else.
+
+*/
+
+static int der_length_size(int length)
+{
+   if (length < (1<<7))
+      return(1);
+   else if (length < (1<<8))
+      return(2);
+   else if (length < (1<<16))
+      return(3);
+   else if (length < (1<<24))
+      return(4);
+   else
+      return(5);
+}
+
+static void der_write_length(unsigned char **buf, int length)
+{
+   if (length < (1<<7)) {
+      *(*buf)++ = (unsigned char) length;
+   } else {
+      *(*buf)++ = (unsigned char) (der_length_size(length)+127);
+      if (length >= (1<<24))
+        *(*buf)++ = (unsigned char) (length>>24);
+      if (length >= (1<<16))
+        *(*buf)++ = (unsigned char) ((length>>16)&0xff);
+      if (length >= (1<<8))
+        *(*buf)++ = (unsigned char) ((length>>8)&0xff);
+      *(*buf)++ = (unsigned char) (length&0xff);
+   }
+}
+
+/* returns decoded length, or < 0 on failure.  Advances buf and
+   decrements bufsize */
+
+static int der_read_length(unsigned char **buf, int *bufsize)
+{
+   unsigned char sf;
+   int ret;
+
+   if (*bufsize < 1)
+      return(-1);
+   sf = *(*buf)++;
+   (*bufsize)--;
+   if (sf & 0x80) {
+      if ((sf &= 0x7f) > ((*bufsize)-1))
+        return(-1);
+      ret = 0;
+      for (; sf; sf--) {
+        ret = (ret<<8) + (*(*buf)++);
+        (*bufsize)--;
+      }
+   } else {
+      ret = sf;
+   }
+
+   return(ret);
+}
+
+/* returns the length of a token, given the mech oid and the body size */
+
+int g_token_size(const_gss_OID mech, unsigned int body_size)
+{
+   /* set body_size to sequence contents size */
+   body_size += 4 + mech->length;
+   return(1 + der_length_size(body_size) + body_size);
+}
+
+/* fills in a buffer with the token header.  The buffer is assumed to
+   be the right size.  buf is advanced past the token header */
+
+void g_make_token_header(const_gss_OID mech, int body_size,
+                         unsigned char **buf, int tok_type)
+{
+   *(*buf)++ = 0x60;
+   der_write_length(buf, 4 + mech->length + body_size);
+   *(*buf)++ = 0x06;
+   *(*buf)++ = (unsigned char) mech->length;
+   TWRITE_STR(*buf, mech->elements, mech->length);
+   *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
+   *(*buf)++ = (unsigned char) (tok_type&0xff);
+}
+
+/* given a buffer containing a token, reads and verifies the token,
+   leaving buf advanced past the token header, and setting body_size
+   to the number of remaining bytes */
+
+int g_verify_token_header(const_gss_OID mech, int *body_size,
+                         unsigned char **buf, int tok_type, int toksize)
+{
+   int seqsize;
+   gss_OID_desc toid;
+
+   if ((toksize-=1) < 0)
+      return(0);
+   if (*(*buf)++ != 0x60)
+      return(0);
+
+   if ((seqsize = der_read_length(buf, &toksize)) < 0)
+      return(0);
+
+   if (seqsize != toksize)
+      return(0);
+
+   if ((toksize-=1) < 0)
+      return(0);
+   if (*(*buf)++ != 0x06)
+      return(0);
+   if ((toksize-=1) < 0)
+      return(0);
+   toid.length = *(*buf)++;
+
+   if ((toksize-=toid.length) < 0)
+      return(0);
+   toid.elements = *buf;
+   (*buf)+=toid.length;
+
+   if (! g_OID_equal(&toid, mech))
+      return(0);
+   if ((toksize-=2) < 0)
+      return(0);
+
+   if ((*(*buf)++ != ((tok_type>>8)&0xff)) ||
+       (*(*buf)++ != (tok_type&0xff)))
+      return(0);
+
+   *body_size = toksize;
+
+   return(1);
+}
diff --git a/src/lib/gssapi/generic/util_validate.c b/src/lib/gssapi/generic/util_validate.c
new file mode 100644 (file)
index 0000000..0c25c26
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+/*
+ * functions to validate name, credential, and context handles
+ */
+
+#include "gssapiP_generic.h"
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <limits.h>
+#include <db.h>
+
+#define V_NAME         1
+#define V_CRED_ID      2
+#define V_CTX_ID       3
+
+typedef struct _vkey {
+   int type;
+   void *ptr;
+} vkey;
+
+static const int one = 1;
+static const DBT dbtone = { (void *) &one, sizeof(one) };
+
+/* All these functions return 0 on failure, and non-zero on success */
+
+static int g_save(DB **vdb, int type, void *ptr)
+{
+   vkey vk;
+   DBT key;
+
+   if (!*vdb)
+      *vdb = dbopen(NULL, O_CREAT|O_RDWR, O_CREAT|O_RDWR, DB_HASH, NULL);
+
+   vk.type = type;
+   vk.ptr = ptr;
+
+   key.data = &vk;
+   key.size = sizeof(vk);
+
+   return((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0);
+}
+
+static int g_validate(DB **vdb, int type, void *ptr)
+{
+   vkey vk;
+   DBT key, value;
+
+   if (!*vdb)
+      return(0);
+
+   vk.type = type;
+   vk.ptr = ptr;
+
+   key.data = &vk;
+   key.size = sizeof(vk);
+
+   if ((*((*vdb)->get))(*vdb, &key, &value, 0))
+      return(0);
+
+   return((value.size == sizeof(one)) &&
+         (*((int *) value.data) == one));
+}
+
+static int g_delete(DB **vdb, int type, void *ptr)
+{
+   vkey vk;
+   DBT key;
+
+   if (!*vdb)
+      return(0);
+
+   vk.type = type;
+   vk.ptr = ptr;
+
+   key.data = &vk;
+   key.size = sizeof(vk);
+
+   return((*((*vdb)->del))(*vdb, &key, 0) == 0);
+}
+
+/* functions for each type */
+
+/* save */
+
+int g_save_name(void **vdb, gss_name_t *name)
+{
+   return(g_save((DB **) vdb, V_NAME, (void *) name));
+}
+int g_save_cred_id(void **vdb, gss_cred_id_t *cred)
+{
+   return(g_save((DB **) vdb, V_CRED_ID, (void *) cred));
+}
+int g_save_ctx_id(void **vdb, gss_ctx_id_t *ctx)
+{
+   return(g_save((DB **) vdb, V_CTX_ID, (void *) ctx));
+}
+
+/* validate */
+
+int g_validate_name(void **vdb, gss_name_t *name)
+{
+   return(g_validate((DB **) vdb, V_NAME, (void *) name));
+}
+int g_validate_cred_id(void **vdb, gss_cred_id_t *cred)
+{
+   return(g_validate((DB **) vdb, V_CRED_ID, (void *) cred));
+}
+int g_validate_ctx_id(void **vdb, gss_ctx_id_t *ctx)
+{
+   return(g_validate((DB **) vdb, V_CTX_ID, (void *) ctx));
+}
+
+/* delete */
+
+int g_delete_name(void **vdb, gss_name_t *name)
+{
+   return(g_delete((DB **) vdb, V_NAME, (void *) name));
+}
+int g_delete_cred_id(void **vdb, gss_cred_id_t *cred)
+{
+   return(g_delete((DB **) vdb, V_CRED_ID, (void *) cred));
+}
+int g_delete_ctx_id(void **vdb, gss_ctx_id_t *ctx)
+{
+   return(g_delete((DB **) vdb, V_CTX_ID, (void *) ctx));
+}
+
diff --git a/src/lib/gssapi/krb5/Makefile b/src/lib/gssapi/krb5/Makefile
new file mode 100644 (file)
index 0000000..0235b4d
--- /dev/null
@@ -0,0 +1,98 @@
+# 
+# Copyright 1993 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.
+# 
+
+# $Id$
+
+TOP = ../../..
+include $(TOP)/config.mk/template
+
+CCSRCS = \
+       accept_sec_context.c \
+       acquire_cred.c \
+       compare_name.c \
+       context_time.c \
+       delete_sec_context.c \
+       display_name.c \
+       display_status.c \
+       get_tkt_flags.c \
+       gssapi_krb5.c \
+       import_name.c \
+       indicate_mechs.c \
+       init_sec_context.c \
+       inquire_context.c \
+       inquire_cred.c \
+       k5seal.c \
+       k5unseal.c \
+       krb5_gss_glue.c \
+       process_context_token.c \
+       release_cred.c \
+       release_name.c \
+       seal.c \
+       sign.c \
+       unseal.c \
+       util_cksum.c \
+       util_crypt.c \
+       util_seed.c \
+       util_seqnum.c \
+       verify.c
+CCOBJS = $(addsuffix .o,$(basename $(CCSRCS)))
+
+ETSRCS = gssapi_krb5_err.et
+ETCS = $(addsuffix .c,$(basename $(ETSRCS)))
+ETHS = $(addsuffix .h,$(basename $(ETSRCS)))
+ETOBJS = $(addsuffix .o,$(basename $(ETSRCS)))
+
+GENERICOBJS := $(addprefix ../generic/,$(shell $(MAKE) -f ../generic/Makefile listobjs))
+GENERICSRCS := $(addsuffix .c,$(basename $(GENERICOBJS)))
+
+CFLAGS := -I. -I../generic $(CFLAGS)
+
+KRB5LIB = libgssapi_krb5.a
+
+all:: $(KRB5LIB)
+
+all:: $(ETHS) $(ETCS)
+
+$(GENERICOBJS):
+       @echo Not all generic objects exist.
+       false
+
+SRCS = $(CCSRCS)
+DEPENDS = $(ETHS)
+expand Depend
+
+ETABLES = $(ETSRCS)
+expand ErrorTables
+
+LIB = $(KRB5LIB)
+OBJS = $(CCOBJS) $(ETOBJS) $(GENERICOBJS)
+expand InstallLibrary
+
+SRCS = $(CCSRCS)
+expand Saber
+
+clean::
+       $(CLEAN) $(CCOBJS) $(ETOBJS)
+
+HDRS = gssapi_krb5.h
+HDRS_DIR = gssapi
+expand InstallIncludes
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
new file mode 100644 (file)
index 0000000..ae51bdf
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+/* XXXX This widen/narrow stuff is bletcherous, but it seems to be
+   necessary.  Perhaps there is a "better" way, but I don't know what it
+   is */
+
+#include <krb5/widen.h>
+static krb5_error_code
+rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server,
+              krb5_kvno kvno, krb5_keyblock **keyblock)
+#include <krb5/narrow.h>
+{
+   krb5_error_code code;
+   krb5_keytab_entry ktentry;
+
+   if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno,
+                               &ktentry))
+      return(code);
+
+   code = krb5_copy_keyblock(&ktentry.key, keyblock);
+
+   (void) krb5_kt_free_entry(&ktentry);
+
+   return(code);
+}
+
+static krb5_error_code
+make_ap_rep(krb5_tkt_authent *authdat,
+           krb5_keyblock *subkey,
+           krb5_int32 *seq_send,
+           gss_buffer_t token)
+{
+   krb5_error_code code;
+   krb5_ap_rep_enc_part ap_rep_data;
+   krb5_data ap_rep;
+   int tlen;
+   unsigned char *t, *ptr;
+
+   /* make the ap_rep */
+
+   ap_rep_data.ctime = authdat->authenticator->ctime;
+   ap_rep_data.cusec = authdat->authenticator->cusec;
+   ap_rep_data.subkey = authdat->authenticator->subkey;
+
+   if (code = krb5_generate_seq_number(authdat->ticket->enc_part2->session,
+                                      &ap_rep_data.seq_number))
+      return(code);
+
+   if (code = krb5_mk_rep(&ap_rep_data, subkey, &ap_rep))
+      return(code);
+
+   /* build up the token */
+
+   /* allocate space for the token */
+   tlen = g_token_size(gss_mech_krb5, ap_rep.length);
+
+   if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
+      xfree(ap_rep.data);
+      return(ENOMEM);
+   }
+
+   /* fill in the buffer */
+
+   ptr = t;
+
+   g_make_token_header(gss_mech_krb5, ap_rep.length,
+                      &ptr, KG_TOK_CTX_AP_REP);
+
+   TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
+
+   /* free the ap_rep */
+
+   xfree(ap_rep.data);
+
+   /* pass everything back */
+
+   *seq_send = ap_rep_data.seq_number;
+
+   token->length = tlen;
+   token->value = (void *) t;
+
+   return(0);
+}
+
+OM_uint32
+krb5_gss_accept_sec_context(OM_uint32 *minor_status,
+                           gss_ctx_id_t *context_handle,
+                           gss_cred_id_t verifier_cred_handle,
+                           gss_buffer_t input_token,
+                           gss_channel_bindings_t input_chan_bindings,
+                           gss_name_t *src_name,
+                           gss_OID *mech_type,
+                           gss_buffer_t output_token,
+                           int *ret_flags,
+                           OM_uint32 *time_rec,
+                           gss_cred_id_t *delegated_cred_handle)
+{
+   unsigned char *ptr, *ptr2;
+   long tmp;
+   krb5_gss_cred_id_t cred;
+   krb5_data ap_req;
+   int i;
+   krb5_error_code code;
+   krb5_address addr, *paddr;
+   krb5_tkt_authent *authdat;
+   krb5_checksum md5;
+   krb5_rcache rcache;
+   krb5_principal name;
+   int gss_flags;
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_timestamp now;
+   gss_buffer_desc token;
+
+   /* set up returns to be freeable */
+
+   if (src_name)
+      *src_name = GSS_C_NO_NAME;
+   output_token->length = 0;
+   output_token->value = NULL;
+   if (mech_type)
+      *mech_type = GSS_C_NULL_OID;
+   /* return a bogus cred handle */
+   if (delegated_cred_handle)
+      *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+
+   /* context handle must be unspecified */
+
+   /*SUPPRESS 29*/
+   if (*context_handle != GSS_C_NO_CONTEXT) {
+      *minor_status = 0;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   /* validate the cred handle - no default */
+
+   /*SUPPRESS 29*/
+   if (verifier_cred_handle == GSS_C_NO_CREDENTIAL) {
+      *minor_status = 0;
+      return(GSS_S_NO_CRED);
+   } else {
+      if (! kg_validate_cred_id(verifier_cred_handle)) {
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL);
+      }
+   }
+
+   cred = (krb5_gss_cred_id_t) verifier_cred_handle;
+
+   /* make sure the supplied credentials are valid for accept */
+
+   if ((cred->usage != GSS_C_ACCEPT) &&
+       (cred->usage != GSS_C_BOTH)) {
+      *minor_status = 0;
+      return(GSS_S_NO_CRED);
+   }
+
+   /* verify the token's integrity, and leave the token in ap_req */
+
+   ptr = (unsigned char *) input_token->value;
+
+   if (! g_verify_token_header(gss_mech_krb5, &(ap_req.length),
+                              &ptr, KG_TOK_CTX_AP_REQ, input_token->length)) {
+      *minor_status = 0;
+      return(GSS_S_DEFECTIVE_TOKEN);
+   }
+
+   TREAD_STR(ptr, (unsigned char *) ap_req.data, ap_req.length);
+
+   /* construct the sender_addr */
+
+   if ((input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) &&
+       (input_chan_bindings->initiator_addrtype == GSS_C_AF_INET)) {
+      /* XXX is this right? */
+      addr.addrtype = ADDRTYPE_INET;
+      addr.length = input_chan_bindings->initiator_address.length;
+      addr.contents = input_chan_bindings->initiator_address.value;
+
+      paddr = &addr;
+   } else {
+      paddr = NULL;
+   }
+
+   /* decode the AP_REQ message */
+
+   /* get the rcache pointer */
+
+   if (krb5_princ_size(cred->princ) > 1) {
+      if (code = krb5_get_server_rcache(krb5_princ_component(cred->princ, 1),
+                                       &rcache)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      rcache = NULL;
+   }
+
+   /* decode the message */
+
+   if (code = krb5_rd_req(&ap_req, cred->princ, paddr, NULL, &rd_req_keyproc,
+                         (krb5_pointer) cred->keytab, rcache, &authdat)) {
+      (void) krb5_rc_close(rcache);
+      xfree(rcache);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   /* close and free the rcache */
+
+   krb5_rc_close(rcache);
+   xfree(rcache);
+
+   /* make sure the necessary parts of the authdat are present */
+
+   if ((authdat->authenticator->subkey == NULL) ||
+       (authdat->ticket->enc_part2 == NULL)) {
+      krb5_free_tkt_authent(authdat);
+      *minor_status = KG_NO_SUBKEY;
+      return(GSS_S_FAILURE);
+   }
+
+   /* verify that the checksum is correct */
+
+   /* 24 == checksum length: see token formats document */
+   if ((authdat->authenticator->checksum->checksum_type != CKSUMTYPE_KG_CB) ||
+       (authdat->authenticator->checksum->length != 24)) {
+      krb5_free_tkt_authent(authdat);
+      *minor_status = 0;
+      return(GSS_S_BAD_BINDINGS);
+   }
+
+   ptr = (unsigned char *) authdat->authenticator->checksum->contents;
+
+   if (code = kg_checksum_channel_bindings(input_chan_bindings, &md5)) {
+      krb5_free_tkt_authent(authdat);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   TREAD_INT(ptr, tmp);
+   if (tmp != md5.length) {
+      xfree(md5.contents);
+      krb5_free_tkt_authent(authdat);
+      *minor_status = KG_BAD_LENGTH;
+      return(GSS_S_FAILURE);
+   }
+
+   TREAD_STR(ptr, ptr2, md5.length);
+   if (memcmp(ptr2, md5.contents, md5.length) != 0) {
+      xfree(md5.contents);
+      krb5_free_tkt_authent(authdat);
+      *minor_status = 0;
+      return(GSS_S_BAD_BINDINGS);
+   }
+
+   xfree(md5.contents);
+
+   TREAD_INT(ptr, gss_flags);
+
+   /* create the ctx struct and start filling it in */
+
+   if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+       == NULL) {
+      *minor_status = ENOMEM;
+      return(GSS_S_FAILURE);
+   }
+
+   ctx->initiate = 0;
+   ctx->mutual = gss_flags & GSS_C_MUTUAL_FLAG;
+   ctx->seed_init = 0;
+   ctx->cred = cred;
+
+   if (code = krb5_copy_principal(cred->princ, &ctx->here)) {
+      xfree(ctx);
+      krb5_free_tkt_authent(authdat);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (code = krb5_copy_principal(authdat->authenticator->client,
+                                 &ctx->there)) {
+      krb5_free_principal(ctx->here);
+      xfree(ctx);
+      krb5_free_tkt_authent(authdat);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (code = krb5_copy_keyblock(authdat->authenticator->subkey,
+                                &ctx->subkey)) {
+      krb5_free_principal(ctx->there);
+      krb5_free_principal(ctx->here);
+      xfree(ctx);
+      krb5_free_tkt_authent(authdat);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   /* fill in the encryption descriptors */
+
+   krb5_use_cstype(&ctx->enc.eblock, ETYPE_RAW_DES_CBC);
+   ctx->enc.processed = 0;
+   if (code = krb5_copy_keyblock(ctx->subkey, &ctx->enc.key))
+      return(code); 
+   for (i=0; i<ctx->enc.key->length; i++)
+      /*SUPPRESS 113*/
+      ctx->enc.key->contents[i] ^= 0xf0;
+
+   krb5_use_cstype(&ctx->seq.eblock, ETYPE_RAW_DES_CBC);
+   ctx->seq.processed = 0;
+   ctx->seq.key = ctx->subkey;
+
+   ctx->endtime = authdat->ticket->enc_part2->times.endtime;
+
+   ctx->flags = authdat->ticket->enc_part2->flags;
+
+   ctx->seq_recv = authdat->authenticator->seq_number;
+
+   /* at this point, the entire context structure is filled in, 
+      so it can be released.  */
+
+   /* generate an AP_REP if necessary */
+
+   if (ctx->mutual) {
+      if (code = make_ap_rep(authdat, ctx->subkey, &ctx->seq_send, &token)) {
+        (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx,
+                                     NULL);
+        krb5_free_tkt_authent(authdat);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      token.length = 0;
+      token.value = NULL;
+      ctx->seq_send = ctx->seq_recv;
+   }
+
+   /* done with authdat! */
+   krb5_free_tkt_authent(authdat);
+
+   /* set the return arguments */
+
+   if (src_name) {
+      if (code = krb5_copy_principal(ctx->there, &name)) {
+        if (token.value)
+           xfree(token.value);
+        (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx,
+                                     NULL);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   if (mech_type)
+      *mech_type = (gss_OID) gss_mech_krb5;
+
+   if (time_rec) {
+      if (code = krb5_timeofday(&now)) {
+        if (src_name)
+           krb5_free_principal(name);
+        xfree(token.value);
+        (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx,
+                                     NULL);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      *time_rec = ctx->endtime - now;
+   }
+
+   if (ret_flags)
+      *ret_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | ctx->mutual;
+
+   ctx->established = 1;
+
+
+   /* intern the src_name */
+
+   if (src_name)
+      if (! kg_save_name((gss_name_t) name)) {
+        krb5_free_principal(name);
+        if (token.value)
+           xfree(token.value);
+        (void)krb5_gss_delete_sec_context(minor_status,
+                                          (gss_ctx_id_t *) &ctx, NULL);
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_FAILURE);
+      }
+
+   /* intern the context handle */
+
+   if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+      if (src_name) {
+        (void) kg_delete_name((gss_name_t) name);
+        krb5_free_principal(name);
+      }
+      if (token.value)
+        xfree(token.value);
+      (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx,
+                                       NULL);
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_FAILURE);
+   }
+
+   *context_handle = ctx;
+
+   *output_token = token;
+
+   if (src_name)
+      *src_name = (gss_name_t) name;
+
+   /* finally! */
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
new file mode 100644 (file)
index 0000000..d09c708
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+/* get credentials corresponding to a key in the krb5 keytab.
+   If the default name is requested, return the name in output_princ.
+     If output_princ is non-NULL, the caller will use or free it, regardless
+     of the return value.
+   If successful, set the keytab-specific fields in cred
+   */
+
+static OM_uint32
+acquire_accept_cred(OM_uint32 *minor_status,
+                   gss_name_t desired_name,
+                   krb5_principal *output_princ,
+                   krb5_gss_cred_id_rec *cred)
+{
+   krb5_error_code code;
+   krb5_principal princ;
+   krb5_keytab kt;
+   krb5_keytab_entry entry;
+   krb5_kt_cursor cur;
+
+   *output_princ = NULL;
+   cred->keytab = NULL;
+
+   /* open the default keytab */
+
+   if (code = krb5_kt_default(&kt)) {
+      *minor_status = code;
+      return(GSS_S_CRED_UNAVAIL);
+   }
+
+   /* figure out what principal to use.  If the default name is
+      requested, use the default sn2princ output */
+
+   if (desired_name == GSS_C_NO_NAME) {
+      if (code = krb5_sname_to_principal(NULL, NULL, KRB5_NT_SRV_HST,
+                                        &princ)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      *output_princ = princ;
+   } else {
+      princ = (krb5_principal) desired_name;
+   }
+
+   /* iterate over the keytab searching for the principal */
+
+   if (code = krb5_kt_start_seq_get(kt, &cur)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   while (!(code = krb5_kt_next_entry(kt, &entry, &cur))) {
+      if (krb5_principal_compare(entry.principal, princ)) {
+        code = 0;
+        krb5_kt_free_entry(&entry);
+        break;
+      } 
+      krb5_kt_free_entry(&entry);
+   }
+
+   if (code == KRB5_KT_END) {
+      /* this means that the principal wasn't in the keytab */
+      (void)krb5_kt_end_seq_get(kt, &cur);
+      *minor_status = KG_KEYTAB_NOMATCH;
+      return(GSS_S_CRED_UNAVAIL);
+   } else if (code) {
+      /* this means some error occurred reading the keytab */
+      (void)krb5_kt_end_seq_get(kt, &cur);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   } else {
+      /* this means that we found a matching entry */
+      if (code = krb5_kt_end_seq_get(kt, &cur)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   /* hooray.  we made it */
+
+   cred->keytab = kt;
+   return(GSS_S_COMPLETE);
+}
+
+/* get credentials corresponding to the default credential cache.
+   If the default name is requested, return the name in output_princ.
+     If output_princ is non-NULL, the caller will use or free it, regardless
+     of the return value.
+   If successful, set the ccache-specific fields in cred.
+   */
+
+static OM_uint32
+acquire_init_cred(OM_uint32 *minor_status,
+                 gss_name_t desired_name,
+                 krb5_principal *output_princ,
+                 krb5_gss_cred_id_rec *cred)
+{
+   krb5_error_code code;
+   krb5_ccache ccache;
+   krb5_principal princ;
+   krb5_flags flags;
+   krb5_cc_cursor cur;
+   krb5_creds creds;
+   int got_endtime;
+
+   cred->ccache = NULL;
+
+   /* open the default credential cache */
+
+   if (code = krb5_cc_default(&ccache)) {
+      *minor_status = code;
+      return(GSS_S_CRED_UNAVAIL);
+   }
+
+   /* turn off OPENCLOSE mode while extensive frobbing is going on */
+
+   flags = 0;          /* turns off OPENCLOSE mode */
+   if (code = krb5_cc_set_flags(ccache, flags)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   /* get out the principal name and see if it matches */
+
+   if (code = krb5_cc_get_principal(ccache, &princ)) {
+      (void)krb5_cc_close(ccache);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (desired_name != GSS_C_NO_NAME) {
+      if (! krb5_principal_compare(princ, (krb5_principal) desired_name)) {
+        (void)krb5_free_principal(princ);
+        (void)krb5_cc_close(ccache);
+        *minor_status = KG_CCACHE_NOMATCH;
+        return(GSS_S_CRED_UNAVAIL);
+      }
+      (void)krb5_free_principal(princ);
+      princ = (krb5_principal) desired_name;
+   } else {
+      *output_princ = princ;
+   }
+
+   /* iterate over the ccache, find the tgt */
+
+   if (code = krb5_cc_start_seq_get(ccache, &cur)) {
+      (void)krb5_cc_close(ccache);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   /* this is hairy.  If there's a tgt for the principal's local realm
+      in here, that's what we want for the expire time.  But if
+      there's not, then we want to use the first key.  */
+
+   got_endtime = 0;
+
+   while (!(code = krb5_cc_next_cred(ccache, &cur, &creds))) {
+      if ((creds.server->length == 2) &&
+         (strcmp(creds.server->realm.data, princ->realm.data) == 0) &&
+         (strcmp((char *) creds.server->data[0].data, "krbtgt") == 0) &&
+         (strcmp((char *) creds.server->data[1].data,
+                 princ->realm.data) == 0)) {
+        cred->tgt_expire = creds.times.endtime;
+        got_endtime = 1;
+        *minor_status = 0;
+        code = 0;
+        krb5_free_cred_contents(&creds);
+        break;
+      }
+      if (got_endtime == 0) {
+        cred->tgt_expire = creds.times.endtime;
+        got_endtime = 1;
+        *minor_status = KG_TGT_MISSING;
+      }
+      krb5_free_cred_contents(&creds);
+   }
+
+   if (code && code != KRB5_CC_END) {
+      /* this means some error occurred reading the ccache */
+      (void)krb5_cc_end_seq_get(ccache, &cur);
+      (void)krb5_cc_close(ccache);
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   } else {
+      /* this means that we found an endtime to use. */
+      if (code = krb5_cc_end_seq_get(ccache, &cur)) {
+        (void)krb5_cc_close(ccache);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      flags = KRB5_TC_OPENCLOSE;       /* turns on OPENCLOSE mode */
+      if (code = krb5_cc_set_flags(ccache, flags)) {
+        (void)krb5_cc_close(ccache);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   /* the credentials match and are valid */
+
+   cred->ccache = ccache;
+   /* minor_status is set while we are iterating over the ccache */
+   return(GSS_S_COMPLETE);
+}
+   
+/*ARGSUSED*/
+OM_uint32
+krb5_gss_acquire_cred(OM_uint32 *minor_status,
+                     gss_name_t desired_name,
+                     OM_uint32 time_req,
+                     gss_OID_set desired_mechs,
+                     int cred_usage,
+                     gss_cred_id_t *output_cred_handle,
+                     gss_OID_set *actual_mechs,
+                     OM_uint32 *time_rec)
+{
+   int i;
+   krb5_gss_cred_id_t cred;
+   gss_OID_set mechs;
+   OM_uint32 ret;
+   krb5_error_code code;
+
+   /* make sure all outputs are valid */
+
+   *output_cred_handle = NULL;
+   if (actual_mechs)
+      *actual_mechs = NULL;
+   if (time_rec)
+      *time_rec = 0;
+
+   /* validate the name */
+
+   /*SUPPRESS 29*/
+   if ((desired_name != GSS_C_NO_NAME) &&
+       (! kg_validate_name(desired_name))) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   /* verify that the requested mechanism set is the default, or
+      contains krb5 */
+
+   if (desired_mechs != GSS_C_NULL_OID_SET) {
+      for (i=0; i<desired_mechs->count; i++)
+        if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i])))
+           break;
+      if (i == desired_mechs->count) {
+        *minor_status = 0;
+        return(GSS_S_BAD_MECH);
+      }
+   }
+
+   /* create the gss cred structure */
+
+   if ((cred =
+       (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) {
+      *minor_status = ENOMEM;
+      return(GSS_S_FAILURE);
+   }
+
+   cred->usage = cred_usage;
+   cred->princ = NULL;
+
+   cred->keytab = NULL;
+   cred->ccache = NULL;
+
+   if ((cred_usage != GSS_C_INITIATE) &&
+       (cred_usage != GSS_C_ACCEPT) &&
+       (cred_usage != GSS_C_BOTH)) {
+      xfree(cred);
+      *minor_status = G_BAD_USAGE;
+      return(GSS_S_FAILURE);
+   }
+
+   /* if requested, acquire credentials for accepting */
+   /* this will fill in cred->princ if the desired_name is not specified */
+
+   if ((cred_usage == GSS_C_ACCEPT) ||
+       (cred_usage == GSS_C_BOTH))
+      if ((ret = acquire_accept_cred(minor_status, desired_name,
+                                    &(cred->princ), cred))
+         != GSS_S_COMPLETE) {
+        if (cred->princ)
+           krb5_free_principal(cred->princ);
+        xfree(cred);
+        /* minor_status set by acquire_accept_cred() */
+        return(ret);
+      }
+
+   /* if requested, acquire credentials for initiation */
+   /* this will fill in cred->princ if it wasn't set above, and
+      the desired_name is not specified */
+
+   if ((cred_usage == GSS_C_INITIATE) ||
+       (cred_usage == GSS_C_BOTH))
+      if ((ret =
+          acquire_init_cred(minor_status,
+                            cred->princ?cred->princ:desired_name,
+                            &(cred->princ), cred))
+         != GSS_S_COMPLETE) {
+        if (cred->keytab)
+           krb5_kt_close(cred->keytab);
+        if (cred->princ)
+           krb5_free_principal(cred->princ);
+        xfree(cred);
+        /* minor_status set by acquire_init_cred() */
+        return(ret);
+      }
+
+   /* if the princ wasn't filled in already, fill it in now */
+
+   if (!cred->princ)
+      if (code = krb5_copy_principal((krb5_principal) desired_name,
+                                    &(cred->princ))) {
+        if (cred->ccache)
+           (void)krb5_cc_close(cred->ccache);
+        if (cred->keytab)
+           (void)krb5_kt_close(cred->keytab);
+        xfree(cred);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+   /*** at this point, the cred structure has been completely created */
+
+   /* compute time_rec */
+
+   if (cred_usage == GSS_C_ACCEPT) {
+      if (time_rec)
+        *time_rec = GSS_C_INDEFINITE;
+   } else {
+      krb5_timestamp now;
+
+      if (code = krb5_timeofday(&now)) {
+        if (cred->ccache)
+           (void)krb5_cc_close(cred->ccache);
+        if (cred->keytab)
+           (void)krb5_kt_close(cred->keytab);
+        if (cred->princ)
+           krb5_free_principal(cred->princ);
+        xfree(cred);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+      if (time_rec)
+        *time_rec = cred->tgt_expire - now;
+   }
+
+   /* create mechs */
+
+   if (actual_mechs) {
+      if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) {
+        if (cred->ccache)
+           (void)krb5_cc_close(cred->ccache);
+        if (cred->keytab)
+           (void)krb5_kt_close(cred->keytab);
+        if (cred->princ)
+           krb5_free_principal(cred->princ);
+        xfree(cred);
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   /* intern the credential handle */
+
+   if (! kg_save_cred_id((gss_cred_id_t) cred)) {
+      free(mechs->elements);
+      free(mechs);
+      if (cred->ccache)
+        (void)krb5_cc_close(cred->ccache);
+      if (cred->keytab)
+        (void)krb5_kt_close(cred->keytab);
+      if (cred->princ)
+        krb5_free_principal(cred->princ);
+      xfree(cred);
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_FAILURE);
+   }
+
+   /* return success */
+
+   *minor_status = 0;
+   *output_cred_handle = (gss_cred_id_t) cred;
+   if (actual_mechs)
+      *actual_mechs = mechs;
+
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/compare_name.c b/src/lib/gssapi/krb5/compare_name.c
new file mode 100644 (file)
index 0000000..455bd6d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+OM_uint32
+krb5_gss_compare_name(OM_uint32 *minor_status,
+                     gss_name_t name1,
+                     gss_name_t name2,
+                     int *name_equal)
+{ 
+   if (! kg_validate_name(name1)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   if (! kg_validate_name(name2)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   *minor_status = 0;
+   *name_equal = krb5_principal_compare((krb5_principal) name1,
+                                       (krb5_principal) name2);
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
new file mode 100644 (file)
index 0000000..00b8ae3
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_context_time(OM_uint32 *minor_status,
+                     gss_ctx_id_t context_handle,
+                     OM_uint32 *time_rec)
+{
+   krb5_error_code code;
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_timestamp now;
+   krb5_deltat lifetime;
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   if (code = krb5_timeofday(&now)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if ((lifetime = ctx->endtime - now) <= 0) {
+      *time_rec = 0;
+      *minor_status = 0;
+      return(GSS_S_CONTEXT_EXPIRED);
+   } else {
+      *time_rec = lifetime;
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
+}
diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c
new file mode 100644 (file)
index 0000000..0419607
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_delete_sec_context(OM_uint32 *minor_status,
+                           gss_ctx_id_t *context_handle,
+                           gss_buffer_t output_token)
+{
+   krb5_gss_ctx_id_rec *ctx;
+
+   if (output_token) {
+      output_token->length = 0;
+      output_token->value = NULL;
+   }
+
+   /*SUPPRESS 29*/
+   if (*context_handle == GSS_C_NO_CONTEXT) {
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
+
+   /*SUPPRESS 29*/
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(*context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   /* construct a delete context token if necessary */
+
+   if (output_token) {
+      OM_uint32 major;
+      gss_buffer_desc empty = {0, NULL};
+
+      if (major = kg_seal(minor_status, *context_handle, 0, GSS_C_QOP_DEFAULT,
+                         &empty, NULL, output_token, KG_TOK_DEL_CTX))
+        return(major);
+   }
+
+   /* invalidate the context handle */
+
+   (void)kg_delete_ctx_id(*context_handle);
+
+   /* free all the context state */
+
+   ctx = (gss_ctx_id_t) *context_handle;
+
+   if (ctx->enc.processed)
+      krb5_finish_key(&ctx->enc.eblock);
+   krb5_free_keyblock(ctx->enc.key);
+
+   if (ctx->seq.processed)
+      krb5_finish_key(&ctx->seq.eblock);
+
+   krb5_free_principal(ctx->here);
+   krb5_free_principal(ctx->there);
+   krb5_free_keyblock(ctx->subkey);
+
+   xfree(ctx);
+
+   /* zero the handle itself */
+
+   *context_handle = GSS_C_NO_CONTEXT;
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/display_name.c b/src/lib/gssapi/krb5/display_name.c
new file mode 100644 (file)
index 0000000..d5a8312
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+OM_uint32
+krb5_gss_display_name(OM_uint32 *minor_status,
+                     gss_name_t input_name,
+                     gss_buffer_t output_name_buffer,
+                     gss_OID *output_name_type)
+{
+   krb5_error_code code;
+   char *str;
+
+   output_name_buffer->length = 0;
+   output_name_buffer->value = NULL;
+
+   if (! kg_validate_name(input_name)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   if (code = krb5_unparse_name((krb5_principal) input_name, &str)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (! g_make_string_buffer(str, output_name_buffer)) {
+      xfree(str);
+
+      *minor_status = G_BUFFER_ALLOC;
+      return(GSS_S_FAILURE);
+   }
+
+   xfree(str);
+
+   *minor_status = 0;
+   if (output_name_type)
+      *output_name_type = (gss_OID) gss_mech_krb5;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/display_status.c b/src/lib/gssapi/krb5/display_status.c
new file mode 100644 (file)
index 0000000..974698d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <com_err.h>
+
+/*
+ * $Id$
+ */
+
+/* XXXX internationalization!! */
+
+/**/
+
+static int init_et = 0;
+
+/**/
+
+OM_uint32
+krb5_gss_display_status(OM_uint32 *minor_status,
+                       OM_uint32 status_value,
+                       int status_type,
+                       const_gss_OID mech_type,
+                       int *message_context,
+                       gss_buffer_t status_string)
+{
+   status_string->length = 0;
+   status_string->value = NULL;
+
+   if ((mech_type != GSS_C_NULL_OID) &&
+       (! g_OID_equal(gss_mech_krb5, mech_type))) {
+      *minor_status = 0;
+      return(GSS_S_BAD_MECH);
+   }
+
+   if (status_type == GSS_C_GSS_CODE) {
+      return(g_display_major_status(minor_status, status_value,
+                                   message_context, status_string));
+   } else if (status_type == GSS_C_MECH_CODE) {
+      if (!init_et) {
+        krb5_init_ets();
+        initialize_k5g_error_table();
+        init_et = 1;
+      }
+
+      if (*message_context) {
+        *minor_status = G_BAD_MSG_CTX;
+        return(GSS_S_FAILURE);
+      }
+
+      return(g_display_com_err_status(minor_status, status_value,
+                                     status_string));
+   } else {
+      *minor_status = 0;
+      return(GSS_S_BAD_STATUS);
+   }
+}
diff --git a/src/lib/gssapi/krb5/get_tkt_flags.c b/src/lib/gssapi/krb5/get_tkt_flags.c
new file mode 100644 (file)
index 0000000..a35259c
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
+                      gss_ctx_id_t context_handle,
+                      krb5_flags *ticket_flags)
+{
+   krb5_gss_ctx_id_rec *ctx;
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   if (ticket_flags)
+      *ticket_flags = ctx->flags;
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
new file mode 100644 (file)
index 0000000..e61dae7
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#ifndef _GSSAPIP_KRB5_H_
+#define _GSSAPIP_KRB5_H_
+
+/*
+ * $Id$
+ */
+
+#include <krb5/krb5.h>
+#include <memory.h>
+#include <netinet/in.h>
+
+/* work around sunos braindamage */
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+
+/* this must be after <krb5/krb5.h>, since krb5 #defines xfree(), too */
+#include "../generic/gssapiP_generic.h"
+#include "gssapi_krb5.h"
+#include "gssapi_krb5_err.h"
+
+/** constants **/
+
+#define CKSUMTYPE_KG_CB                0x8003
+
+#define KG_TOK_CTX_AP_REQ      0x0100
+#define KG_TOK_CTX_AP_REP      0x0200
+#define KG_TOK_CTX_ERROR       0x0300
+#define KG_TOK_SIGN_MSG                0x0101
+#define KG_TOK_SEAL_MSG                0x0201
+#define KG_TOK_DEL_CTX         0x0102
+
+/** internal types **/
+
+typedef krb5_principal krb5_gss_name_t;
+
+typedef struct _krb5_gss_cred_id_rec {
+   /* name/type of credential */
+   int usage;
+   krb5_principal princ;       /* this is not interned as a gss_name_t */
+
+   /* keytab (accept) data */
+   krb5_keytab keytab;
+
+   /* ccache (init) data */
+   krb5_ccache ccache;
+   krb5_timestamp tgt_expire;
+} krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; 
+
+typedef struct _krb5_gss_enc_desc {
+   int processed;
+   krb5_keyblock *key;
+   krb5_encrypt_block eblock;
+} krb5_gss_enc_desc;
+
+typedef struct _krb5_gss_ctx_id_rec {
+   int initiate;       /* nonzero if initiating, zero if accepting */
+   int mutual;
+   int seed_init;
+   unsigned char seed[16];
+   krb5_gss_cred_id_t cred;
+   krb5_principal here;
+   krb5_principal there;
+   krb5_keyblock *subkey;
+   krb5_gss_enc_desc enc;
+   krb5_gss_enc_desc seq;
+   krb5_timestamp endtime;
+   krb5_flags flags;
+   krb5_int32 seq_send;
+   krb5_int32 seq_recv;
+   int established;
+} krb5_gss_ctx_id_rec, krb5_gss_ctx_id_t;
+
+extern void *kg_vdb;
+
+/* helper macros */
+
+#define kg_save_name(name)             g_save_name(&kg_vdb,name)
+#define kg_save_cred_id(cred)          g_save_cred_id(&kg_vdb,cred)
+#define kg_save_ctx_id(ctx)            g_save_ctx_id(&kg_vdb,ctx)
+
+#define kg_validate_name(name)         g_validate_name(&kg_vdb,name)
+#define kg_validate_cred_id(cred)      g_validate_cred_id(&kg_vdb,cred)
+#define kg_validate_ctx_id(ctx)                g_validate_ctx_id(&kg_vdb,ctx)
+
+#define kg_delete_name(name)           g_delete_name(&kg_vdb,name)
+#define kg_delete_cred_id(cred)                g_delete_cred_id(&kg_vdb,cred)
+#define kg_delete_ctx_id(ctx)          g_delete_ctx_id(&kg_vdb,ctx)
+
+/** helper functions **/
+
+OM_uint32 kg_get_defcred(OM_uint32 *minor_status, gss_cred_id_t *cred);
+
+OM_uint32 kg_release_defcred(OM_uint32 *minor_status);
+
+krb5_error_code kg_checksum_channel_bindings(gss_channel_bindings_t cb,
+                                            krb5_checksum *cksum);
+
+krb5_error_code kg_make_seq_num(krb5_gss_enc_desc *ed, int direction,
+                               int seqnum, unsigned char *cksum,
+                               unsigned char *buf);
+
+krb5_error_code kg_make_seed(krb5_keyblock *key, unsigned char *seed);
+
+int kg_confounder_size(krb5_gss_enc_desc *ed);
+
+krb5_error_code kg_make_confounder(krb5_gss_enc_desc *ed, unsigned char *buf);
+
+int kg_encrypt_size(krb5_gss_enc_desc *ed, int n);
+
+krb5_error_code kg_encrypt(krb5_gss_enc_desc *ed, krb5_pointer iv,
+                          krb5_pointer in, krb5_pointer out, int length);
+
+krb5_error_code kg_decrypt(krb5_gss_enc_desc *ed, krb5_pointer iv,
+                          krb5_pointer in, krb5_pointer out, int length);
+
+OM_uint32 kg_seal(OM_uint32 *minor_status,
+                 gss_ctx_id_t context_handle,
+                 int conf_req_flag,
+                 int qop_req,
+                 gss_buffer_t input_message_buffer,
+                 int *conf_state,
+                 gss_buffer_t output_message_buffer,
+                 int toktype);
+
+OM_uint32 kg_unseal(OM_uint32 *minor_status,
+                   gss_ctx_id_t context_handle,
+                   gss_buffer_t input_token_buffer,
+                   gss_buffer_t message_buffer,
+                   int *conf_state,
+                   int *qop_state,
+                   int toktype);
+
+/** declarations of internal name mechanism functions **/
+
+OM_uint32 krb5_gss_acquire_cred
+           (OM_uint32*,       /* minor_status */
+            gss_name_t,       /* desired_name */
+            OM_uint32,        /* time_req */
+            gss_OID_set,      /* desired_mechs */
+            int,              /* cred_usage */
+            gss_cred_id_t*,   /* output_cred_handle */
+            gss_OID_set*,     /* actual_mechs */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 krb5_gss_release_cred
+           (OM_uint32*,       /* minor_status */
+            gss_cred_id_t*    /* cred_handle */
+           );
+
+OM_uint32 krb5_gss_init_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_cred_id_t,    /* claimant_cred_handle */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_name_t,       /* target_name */
+            const_gss_OID,    /* mech_type */
+            int,              /* req_flags */
+            OM_uint32,        /* time_req */
+            gss_channel_bindings_t,
+                              /* input_chan_bindings */
+            gss_buffer_t,     /* input_token */
+            gss_OID*,         /* actual_mech_type */
+            gss_buffer_t,     /* output_token */
+            int*,             /* ret_flags */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 krb5_gss_accept_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_cred_id_t,    /* verifier_cred_handle */
+            gss_buffer_t,     /* input_token_buffer */
+            gss_channel_bindings_t,
+                              /* input_chan_bindings */
+            gss_name_t*,      /* src_name */
+            gss_OID*,         /* mech_type */
+            gss_buffer_t,     /* output_token */
+            int*,             /* ret_flags */
+            OM_uint32*,       /* time_rec */
+            gss_cred_id_t*    /* delegated_cred_handle */
+           );
+
+OM_uint32 krb5_gss_process_context_token
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t      /* token_buffer */
+           );
+
+OM_uint32 krb5_gss_delete_sec_context
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_buffer_t      /* output_token */
+           );
+
+OM_uint32 krb5_gss_context_time
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            OM_uint32*        /* time_rec */
+           );
+
+OM_uint32 krb5_gss_sign
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            int,              /* qop_req */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t      /* message_token */
+           );
+
+OM_uint32 krb5_gss_verify
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t,     /* token_buffer */
+            int*              /* qop_state */
+           );
+
+OM_uint32 krb5_gss_seal
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            int,              /* conf_req_flag */
+            int,              /* qop_req */
+            gss_buffer_t,     /* input_message_buffer */
+            int*,             /* conf_state */
+            gss_buffer_t      /* output_message_buffer */
+           );
+
+OM_uint32 krb5_gss_unseal
+           (OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t,     /* input_message_buffer */
+            gss_buffer_t,     /* output_message_buffer */
+            int*,             /* conf_state */
+            int*              /* qop_state */
+           );
+
+OM_uint32 krb5_gss_display_status
+           (OM_uint32*,       /* minor_status */
+            OM_uint32,        /* status_value */
+            int,              /* status_type */
+            const_gss_OID,    /* mech_type */
+            int*,             /* message_context */
+            gss_buffer_t      /* status_string */
+           );
+
+OM_uint32 krb5_gss_indicate_mechs
+           (OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* mech_set */
+           );
+
+OM_uint32 krb5_gss_compare_name
+           (OM_uint32*,       /* minor_status */
+            gss_name_t,       /* name1 */
+            gss_name_t,       /* name2 */
+            int*              /* name_equal */
+           );
+
+OM_uint32 krb5_gss_display_name
+           (OM_uint32*,      /* minor_status */
+            gss_name_t,      /* input_name */
+            gss_buffer_t,     /* output_name_buffer */
+            gss_OID*         /* output_name_type */
+           );
+
+OM_uint32 krb5_gss_import_name
+           (OM_uint32*,       /* minor_status */
+            gss_buffer_t,     /* input_name_buffer */
+            const_gss_OID,    /* input_name_type */
+            gss_name_t*       /* output_name */
+           );
+
+OM_uint32 krb5_gss_release_name
+           (OM_uint32*,       /* minor_status */
+            gss_name_t*       /* input_name */
+           );
+
+OM_uint32 krb5_gss_inquire_cred
+           (OM_uint32 *,      /* minor_status */
+            gss_cred_id_t,    /* cred_handle */
+            gss_name_t *,     /* name */
+            OM_uint32 *,      /* lifetime */
+            int *,            /* cred_usage */
+            gss_OID_set *     /* mechanisms */
+           );
+
+OM_uint32 krb5_gss_inquire_context
+          (OM_uint32*,       /* minor_status */
+           gss_ctx_id_t,     /* context_handle */
+           gss_name_t*,      /* initiator_name */
+           gss_name_t*,      /* acceptor_name */
+           OM_uint32*,       /* lifetime_rec */
+           gss_OID*,         /* mech_type */
+           int*,             /* ret_flags */
+           int*              /* locally_initiated */
+          );
+
+#endif /* _GSSAPIP_KRB5_H_ */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
new file mode 100644 (file)
index 0000000..ada5f6f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+/** exported constants defined in gssapi_krb5.h **/
+
+/* these are bogus, but will compile */
+
+static const gss_OID_desc oids[] = {
+   /* this OID is from Ted.  It's not official yet, but it's close. */
+   {5, "\053\005\001\005\002"},
+   {2, "\002\002"},
+   {2, "\002\003"},
+};
+
+const_gss_OID gss_mech_krb5 = oids+0;
+const_gss_OID gss_nt_krb5_name = oids+1;
+const_gss_OID gss_nt_krb5_principal = oids+2;
+
+static const gss_OID_set_desc oidsets[] = {
+   {1, (gss_OID) oids},
+};
+
+const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0;
+
+void *kg_vdb = NULL;
+
+/** default credential support */
+
+/* default credentials */
+
+static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
+
+/* XXX what happens when the default credentials expire or are invalidated? */
+
+OM_uint32
+kg_get_defcred(OM_uint32 *minor_status, gss_cred_id_t *cred)
+{
+   if (defcred == GSS_C_NO_CREDENTIAL) {
+      OM_uint32 major;
+
+      if ((major = krb5_gss_acquire_cred(minor_status, GSS_C_NO_NAME,
+                                        GSS_C_INDEFINITE, GSS_C_NULL_OID_SET,
+                                        GSS_C_INITIATE, &defcred, NULL,
+                                        NULL)) &&
+         GSS_ERROR(major)) {
+        defcred = GSS_C_NO_CREDENTIAL;
+        return(major);
+      }
+   }
+
+   *cred = defcred;
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
+
+OM_uint32
+kg_release_defcred(OM_uint32 *minor_status)
+{
+   if (defcred == GSS_C_NO_CREDENTIAL) {
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
+
+   return(krb5_gss_release_cred(minor_status, &defcred));
+}
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
new file mode 100644 (file)
index 0000000..937609d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#ifndef _GSSAPI_KRB5_H_
+#define _GSSAPI_KRB5_H_
+
+/*
+ * $Id$
+ */
+
+#include <gssapi/gssapi_generic.h>
+#include <krb5/krb5.h>
+
+extern const gss_OID_desc * const gss_mech_krb5;
+extern const gss_OID_set_desc * const gss_mech_set_krb5;
+
+extern const gss_OID_desc * const gss_nt_krb5_name;
+extern const gss_OID_desc * const gss_nt_krb5_principal;
+
+OM_uint32 gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
+                                gss_ctx_id_t context_handle,
+                                krb5_flags *ticket_flags);
+
+
+#endif /* _GSSAPI_KRB5_H_ */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5_err.et b/src/lib/gssapi/krb5/gssapi_krb5_err.et
new file mode 100644 (file)
index 0000000..ca7a543
--- /dev/null
@@ -0,0 +1,38 @@
+# 
+# Copyright 1993 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.
+# 
+
+#
+# $Id$
+#
+
+error_table k5g
+
+error_code KG_CCACHE_NOMATCH, "Principal in credential cache does not match desired name"
+error_code KG_KEYTAB_NOMATCH, "No principal in keytab matches desired name"
+error_code KG_TGT_MISSING, "Credential cache has no TGT"
+error_code KG_NO_SUBKEY, "Authenticator has no subkey"
+error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established"
+error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token"
+error_code KG_BAD_LENGTH, "Invalid field length in token"
+error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context"
+
+end
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
new file mode 100644 (file)
index 0000000..51fbd9f
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include <string.h>
+#include <pwd.h>
+
+#include "gssapiP_krb5.h"
+
+/*
+ * errors:
+ * GSS_S_BAD_NAMETYPE  if the type is bogus
+ * GSS_S_BAD_NAME      if the type is good but the name is bogus
+ * GSS_S_FAILURE       if memory allocation fails
+ */
+
+OM_uint32
+krb5_gss_import_name(OM_uint32 *minor_status,
+                    gss_buffer_t input_name_buffer,
+                    const_gss_OID input_name_type,
+                    gss_name_t *output_name)
+{
+   krb5_principal princ;
+   krb5_error_code code;
+   char *stringrep;
+   struct passwd *pw;
+
+   /* set up default returns */
+
+   *output_name = NULL;
+   *minor_status = 0;
+
+   /* Go find the appropriate string rep to pass into parse_name */
+
+   if ((input_name_type != GSS_C_NULL_OID) &&
+       g_OID_equal(input_name_type, gss_nt_service_name)) {
+      char *tmp, *service, *host;
+
+      if ((tmp =
+          (char *) xmalloc(strlen(input_name_buffer->value)+1)) == NULL) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+
+      strcpy(tmp, input_name_buffer->value);
+
+      service = tmp;
+      if ((host = strchr(tmp, '@')) == NULL) {
+        xfree(tmp);
+        *minor_status = G_BAD_SERVICE_NAME;
+        return(GSS_S_BAD_NAME);
+      }
+      *host = '\0';
+      host++;
+
+      code = krb5_sname_to_principal(host, service, KRB5_NT_SRV_HST,
+                                    &princ);
+
+      xfree(tmp);
+   } else if ((input_name_type != GSS_C_NULL_OID) &&
+             (g_OID_equal(input_name_type, gss_nt_krb5_principal))) {
+      krb5_principal input;
+
+      if (input_name_buffer->length != sizeof(krb5_principal)) {
+        *minor_status = G_WRONG_SIZE;
+        return(GSS_S_BAD_NAME);
+      }
+
+      input = *((krb5_principal *) input_name_buffer->value);
+
+      if (code = krb5_copy_principal(input, &princ)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   } else {
+      stringrep = NULL;
+
+      if ((input_name_type == GSS_C_NULL_OID) ||
+         g_OID_equal(input_name_type, gss_nt_krb5_name) ||
+         g_OID_equal(input_name_type, gss_nt_user_name)) {
+        stringrep = (char *) input_name_buffer->value;
+      } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) {
+        if (pw = getpwuid(*((uid_t *) input_name_buffer->value)))
+           stringrep = pw->pw_name;
+        else
+           *minor_status = G_NOUSER;
+      } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) {
+        if (pw = getpwuid((uid_t) atoi(input_name_buffer->value)))
+           stringrep = pw->pw_name;
+        else
+           *minor_status = G_NOUSER;
+      } else {
+        return(GSS_S_BAD_NAMETYPE);
+      }
+
+      /* at this point, stringrep is set, or if not, *minor_status is. */
+
+      if (stringrep)
+        code = krb5_parse_name((char *) stringrep, &princ);
+      else
+        return(GSS_S_BAD_NAME);
+   }
+
+   /* at this point, a krb5 function has been called to set princ.  code
+      contains the return status */
+
+   if (code) {
+      *minor_status = (OM_uint32) code;
+      return(GSS_S_BAD_NAME);
+   }
+
+   /* save the name in the validation database */
+
+   if (! kg_save_name((gss_name_t) princ)) {
+      krb5_free_principal(princ);
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_FAILURE);
+   }
+
+   /* return it */
+
+   *output_name = (gss_name_t) princ;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/indicate_mechs.c b/src/lib/gssapi/krb5/indicate_mechs.c
new file mode 100644 (file)
index 0000000..c20679f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+OM_uint32
+krb5_gss_indicate_mechs(OM_uint32 *minor_status,
+                       gss_OID_set *mech_set)
+{
+   *minor_status = 0;
+   *mech_set = (gss_OID_set) gss_mech_set_krb5;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
new file mode 100644 (file)
index 0000000..a62a286
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+static krb5_error_code
+make_ap_req(krb5_gss_cred_id_t cred,
+           krb5_principal server,
+           krb5_timestamp *endtime,
+           gss_channel_bindings_t chan_bindings,
+           int do_mutual,
+           krb5_keyblock **subkey,
+           krb5_flags *flags,
+           krb5_int32 *seqnum,
+           gss_buffer_t token)
+{
+   krb5_error_code code;
+   krb5_checksum md5, checksum;
+   krb5_creds creds;
+   krb5_authenticator authent;
+   krb5_data ap_req;
+   long tmp;
+   unsigned char *ptr;
+   unsigned char ckbuf[24];            /* see the token formats doc */
+   unsigned char *t;
+   int tlen;
+
+   /* build the checksum buffer */
+
+   /* compute the hash of the channel bindings */
+
+   if (code = kg_checksum_channel_bindings(chan_bindings, &md5))
+      return(code);
+
+   ptr = ckbuf;
+
+   TWRITE_INT(ptr, tmp, md5.length);
+   TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length);
+   TWRITE_INT(ptr, tmp, do_mutual?GSS_C_MUTUAL_FLAG:0);
+
+   /* done with this, free it */
+   xfree(md5.contents);
+
+   checksum.checksum_type = CKSUMTYPE_KG_CB;
+   checksum.length = sizeof(ckbuf);
+   checksum.contents = (krb5_octet *) ckbuf;
+
+   /* fill in the necessary fields in creds */
+
+   memset((char *) &creds, 0, sizeof(creds));
+   creds.client = cred->princ;
+   creds.server = server;
+
+   creds.times.endtime = *endtime;
+
+   /* call mk_req.  subkey and ap_req need to be used or destroyed */
+
+   if (code = krb5_mk_req_extended(do_mutual?AP_OPTS_MUTUAL_REQUIRED:0,
+                                  &checksum, 0, 0, subkey, cred->ccache,
+                                  &creds, &authent, &ap_req))
+      return(code);
+
+   /* store the interesting stuff from creds and authent */
+   *endtime = creds.times.endtime;
+   *flags = creds.ticket_flags;
+   *seqnum = authent.seq_number;
+
+   /* free stuff which was created */
+
+   /* XXXX There's a bug in krb5 here, but I have no clue what it is.
+      This is a workaround. */
+   if (creds.client == cred->princ)
+      creds.client = NULL;
+
+   krb5_free_cred_contents(&creds);
+
+   /* build up the token */
+
+   /* allocate space for the token */
+   tlen = g_token_size(gss_mech_krb5, ap_req.length);
+
+   if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
+      xfree(ap_req.data);
+      krb5_free_keyblock(*subkey);
+      return(ENOMEM);
+   }
+
+   /* fill in the buffer */
+
+   ptr = t;
+
+   g_make_token_header(gss_mech_krb5, ap_req.length,
+                      &ptr, KG_TOK_CTX_AP_REQ);
+
+   TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length);
+
+   /* free the ap_req */
+
+   xfree(ap_req.data);
+
+   /* pass it back */
+
+   token->length = tlen;
+   token->value = (void *) t;
+
+   return(0);
+}
+
+OM_uint32
+krb5_gss_init_sec_context(OM_uint32 *minor_status,
+                         gss_cred_id_t claimant_cred_handle,
+                         gss_ctx_id_t *context_handle,
+                         gss_name_t target_name,
+                         const_gss_OID mech_type,
+                         int req_flags,
+                         OM_uint32 time_req,
+                         gss_channel_bindings_t input_chan_bindings,
+                         gss_buffer_t input_token,
+                         gss_OID *actual_mech_type,
+                         gss_buffer_t output_token,
+                         int *ret_flags,
+                         OM_uint32 *time_rec)
+{
+   krb5_gss_cred_id_t cred;
+   krb5_error_code code; 
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_timestamp now;
+   gss_buffer_desc token;
+   int i;
+
+   /* set up return values so they can be "freed" successfully */
+
+   output_token->length = 0;
+   output_token->value = NULL;
+   if (actual_mech_type)
+      *actual_mech_type = (gss_OID) gss_mech_krb5;
+
+   /* verify the mech_type */
+
+   if ((mech_type != GSS_C_NULL_OID) &&
+       (! g_OID_equal(mech_type, gss_mech_krb5))) {
+      *minor_status = 0;
+      return(GSS_S_BAD_MECH);
+   }
+
+   /* verify the credential, or use the default */
+   /*SUPPRESS 29*/
+   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+      OM_uint32 major;
+
+      if ((major = kg_get_defcred(minor_status, &claimant_cred_handle)) &&
+         GSS_ERROR(major)) {
+        return(major);
+      }
+   } else {
+      if (! kg_validate_cred_id(claimant_cred_handle)) {
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL);
+      }
+   }
+
+   cred = (krb5_gss_cred_id_t) claimant_cred_handle;
+
+   /* verify that the target_name is valid and usable */
+
+   if (! kg_validate_name(target_name)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   /* is this a new connection or not? */
+
+   /*SUPPRESS 29*/
+   if (*context_handle == GSS_C_NO_CONTEXT) {
+      /* make sure the cred is usable for init */
+
+      if ((cred->usage != GSS_C_INITIATE) &&
+         (cred->usage != GSS_C_BOTH)) {
+        *minor_status = 0;
+        return(GSS_S_NO_CRED);
+      }
+
+      /* complain if the input token is nonnull */
+
+      if (input_token != GSS_C_NO_BUFFER) {
+        *minor_status = 0;
+        return(GSS_S_DEFECTIVE_TOKEN);
+      }
+
+      /* create the ctx */
+
+      if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+         == NULL) {
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+
+      /* fill in the ctx */
+
+      ctx->initiate = 1;
+      ctx->mutual = req_flags & GSS_C_MUTUAL_FLAG;
+      ctx->seed_init = 0;
+      ctx->cred = cred;
+
+      if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
+        ctx->endtime = 0;
+      } else {
+        if (code = krb5_timeofday(&now)) {
+           free(ctx);
+           *minor_status = code;
+           return(GSS_S_FAILURE);
+        }
+        ctx->endtime = now + time_req;
+      }
+
+      if (code = krb5_copy_principal(cred->princ, &ctx->here)) {
+        xfree(ctx);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      
+      if (code = krb5_copy_principal((krb5_principal) target_name,
+                                    &ctx->there)) {
+        krb5_free_principal(ctx->here);
+        xfree(ctx);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+      if (code = make_ap_req(ctx->cred, ctx->there, &ctx->endtime,
+                            input_chan_bindings, ctx->mutual,
+                            &ctx->subkey, &ctx->flags,
+                            &ctx->seq_send, &token)) {
+        krb5_free_principal(ctx->here);
+        krb5_free_principal(ctx->there);
+        xfree(ctx);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+      /* fill in the encryption descriptors */
+
+      /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */
+
+      krb5_use_cstype(&ctx->enc.eblock, ETYPE_RAW_DES_CBC);
+      ctx->enc.processed = 0;
+      if (code = krb5_copy_keyblock(ctx->subkey, &ctx->enc.key))
+        return(code); 
+      for (i=0; i<ctx->enc.key->length; i++)
+        /*SUPPRESS 113*/
+        ctx->enc.key->contents[i] ^= 0xf0;
+
+      krb5_use_cstype(&ctx->seq.eblock, ETYPE_RAW_DES_CBC);
+      ctx->seq.processed = 0;
+      ctx->seq.key = ctx->subkey;
+
+      /* at this point, the context is constructed and valid,
+        hence, releaseable */
+
+      /* intern the context handle */
+
+      if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+        xfree(token.value);
+        krb5_free_keyblock(ctx->subkey);
+        krb5_free_principal(ctx->here);
+        krb5_free_principal(ctx->there);
+        xfree(ctx);
+
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_FAILURE);
+      }
+
+      /* compute time_rec */
+
+      if (time_rec) {
+        if (code = krb5_timeofday(&now)) {
+           xfree(token.value);
+           (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t) ctx,
+                                        NULL);
+           *minor_status = code;
+           return(GSS_S_FAILURE);
+        }
+        *time_rec = ctx->endtime - now;
+      }
+
+      /* set the other returns */
+
+      *context_handle = (gss_ctx_id_t) ctx;
+
+      *output_token = token;
+
+      if (ret_flags)
+        *ret_flags = ((req_flags & GSS_C_MUTUAL_FLAG) | 
+                      GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
+
+      /* return successfully */
+
+      *minor_status = 0;
+      if (ctx->mutual) {
+        ctx->established = 0;
+        return(GSS_S_CONTINUE_NEEDED);
+      } else {
+        ctx->seq_recv = ctx->seq_send;
+        ctx->established = 1;
+        return(GSS_S_COMPLETE);
+      }
+   } else {
+      unsigned char *ptr;
+      krb5_data ap_rep;
+      krb5_ap_rep_enc_part *ap_rep_data;
+
+      /* validate the context handle */
+      /*SUPPRESS 29*/
+      if (! kg_validate_ctx_id(*context_handle)) {
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_NO_CONTEXT);
+      }
+
+      ctx = (gss_ctx_id_t) *context_handle;
+
+      /* make sure the context is non-established, and that certain
+        arguments are unchanged */
+
+      if ((ctx->established) ||
+         (((gss_cred_id_t) ctx->cred) != claimant_cred_handle) ||
+         ((req_flags & GSS_C_MUTUAL_FLAG) == 0)) {
+        (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+        *minor_status = KG_CONTEXT_ESTABLISHED;
+        return(GSS_S_FAILURE);
+      }
+
+      if (! krb5_principal_compare(ctx->there, (krb5_principal) target_name)) {
+        (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+        *minor_status = 0;
+        return(GSS_S_BAD_NAME);
+      }
+
+      /* verify the token and leave the AP_REP message in ap_rep */
+
+      if (input_token == GSS_C_NO_BUFFER) {
+        (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+        *minor_status = 0;
+        return(GSS_S_DEFECTIVE_TOKEN);
+      }
+
+      ptr = (unsigned char *) input_token->value;
+
+      if (! g_verify_token_header(gss_mech_krb5, &(ap_rep.length),
+                                 &ptr, KG_TOK_CTX_AP_REP,
+                                 input_token->length)) {
+        *minor_status = 0;
+        return(GSS_S_DEFECTIVE_TOKEN);
+      }
+
+      TREAD_STR(ptr, (unsigned char *) ap_rep.data, ap_rep.length);
+
+      /* decode the ap_rep */
+      if (code = krb5_rd_rep(&ap_rep, ctx->subkey, &ap_rep_data)) {
+        (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+      /* store away the sequence number */
+      ctx->seq_recv = ap_rep_data->seq_number;
+
+      /* free the ap_rep_data */
+      krb5_free_ap_rep_enc_part(ap_rep_data);
+
+      /* set established */
+      ctx->established = 1;
+
+      /* set returns */
+
+      if (time_rec) {
+        if (code = krb5_timeofday(&now)) {
+           (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t) ctx,
+                                        NULL);
+           *minor_status = code;
+           return(GSS_S_FAILURE);
+        }
+        *time_rec = ctx->endtime - now;
+      }
+
+      if (ret_flags)
+        *ret_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_MUTUAL_FLAG;
+
+      /* success */
+
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
+}
diff --git a/src/lib/gssapi/krb5/inquire_context.c b/src/lib/gssapi/krb5/inquire_context.c
new file mode 100644 (file)
index 0000000..771a352
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_inquire_context(OM_uint32 *minor_status,
+                        gss_ctx_id_t context_handle,
+                        gss_name_t *initiator_name,
+                        gss_name_t *acceptor_name,
+                        OM_uint32 *lifetime_rec,
+                        gss_OID *mech_type,
+                        int *ret_flags,
+                        int *locally_initiated)
+{
+   krb5_error_code code;
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_principal init, accept;
+   krb5_timestamp now;
+   krb5_deltat lifetime;
+
+   if (initiator_name)
+      *initiator_name = GSS_C_NO_NAME;
+   if (acceptor_name)
+      *acceptor_name = GSS_C_NO_NAME;
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   init = NULL;
+   accept = NULL;
+
+   if (code = krb5_timeofday(&now)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if ((lifetime = ctx->endtime - now) < 0)
+      lifetime = 0;
+
+   if (initiator_name) {
+      if (code = krb5_copy_principal(ctx->initiate?ctx->here:ctx->there,
+                                    &init)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      if (! kg_save_name((gss_name_t) init)) {
+        krb5_free_principal(init);
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   if (acceptor_name) {
+      if (code = krb5_copy_principal(ctx->initiate?ctx->there:ctx->here,
+                                    &accept)) {
+        if (init) krb5_free_principal(init);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+      if (! kg_save_name((gss_name_t) accept)) {
+        krb5_free_principal(accept);
+        if (init) {
+           kg_delete_name((gss_name_t) accept);
+           krb5_free_principal(init);
+        }
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   if (initiator_name)
+      *initiator_name = (gss_name_t) init;
+
+   if (acceptor_name)
+      *acceptor_name = (gss_name_t) accept;
+
+   if (lifetime_rec)
+      *lifetime_rec = lifetime;
+
+   if (mech_type)
+      *mech_type = (gss_OID) gss_mech_krb5;
+
+   if (ret_flags)
+      *ret_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | ctx->mutual;
+
+   if (locally_initiated)
+      *locally_initiated = ctx->initiate;
+
+   *minor_status = 0;
+   return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/inquire_cred.c b/src/lib/gssapi/krb5/inquire_cred.c
new file mode 100644 (file)
index 0000000..7795fca
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_inquire_cred(OM_uint32 *minor_status,
+                     gss_cred_id_t cred_handle,
+                     gss_name_t *name,
+                     OM_uint32 *lifetime_ret,
+                     int *cred_usage,
+                     gss_OID_set *mechanisms)
+{
+   krb5_gss_cred_id_t cred;
+   krb5_error_code code;
+   krb5_timestamp now;
+   krb5_deltat lifetime;
+   krb5_principal ret_name;
+   gss_OID_set mechs;
+
+   if (name) *name = NULL;
+   if (mechanisms) *mechanisms = NULL;
+
+   /* check for default credential */
+   /*SUPPRESS 29*/
+   if (cred_handle == GSS_C_NO_CREDENTIAL) {
+      OM_uint32 major;
+
+      if ((major = kg_get_defcred(minor_status, &cred_handle)) &&
+         GSS_ERROR(major)) {
+        return(major);
+      }
+   } else {
+      if (! kg_validate_cred_id(cred_handle)) {
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED);
+      }
+   }
+
+   cred = (krb5_gss_cred_id_t) cred_handle;
+
+   if (code = krb5_timeofday(&now)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if ((lifetime = cred->tgt_expire - now) < 0)
+      lifetime = 0;
+
+   if (name) {
+      if (code = krb5_copy_principal(cred->princ, &ret_name)) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+   }
+
+   if (mechanisms)
+      if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) {
+        krb5_free_principal(ret_name);
+        *minor_status = ENOMEM;
+        return(GSS_S_FAILURE);
+      }
+
+   if (name) {
+      if (! kg_save_name((gss_name_t) ret_name)) {
+        (void)gss_release_oid_set(minor_status, &mechs);
+        krb5_free_principal(ret_name);
+        *minor_status = G_VALIDATE_FAILED;
+        return(GSS_S_FAILURE);
+      }
+      *name = (gss_name_t) ret_name;
+   }
+
+   if (lifetime_ret)
+      *lifetime_ret = lifetime;
+
+   if (cred_usage)
+      *cred_usage = cred->usage;
+
+   if (mechanisms)
+      *mechanisms = mechs;
+
+   *minor_status = 0;
+   return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
new file mode 100644 (file)
index 0000000..dd5e563
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <netinet/in.h>
+#include <krb5/rsa-md5.h>
+
+/*
+ * $Id$
+ */
+
+static krb5_error_code
+make_seal_token(krb5_gss_enc_desc *enc_ed,
+               krb5_gss_enc_desc *seq_ed,
+               krb5_int32 *seqnum,
+               int direction,
+               gss_buffer_t text,
+               gss_buffer_t token,
+               int encrypt,
+               int toktype)
+{
+   krb5_error_code code;
+   MD5_CTX md5;
+   krb5_checksum desmac;
+   int tmsglen, tlen;
+   unsigned char *t, *ptr;
+
+   /* create the token buffer */
+
+   if (toktype == KG_TOK_SEAL_MSG) {
+      tmsglen = text->length;
+      if (encrypt)
+        tmsglen = (kg_confounder_size(enc_ed) +
+                   kg_encrypt_size(enc_ed, tmsglen+1));
+   } else {
+      tmsglen = 0;
+   }
+
+   tlen = g_token_size(gss_mech_krb5, 22+tmsglen);
+
+   if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
+      return(ENOMEM);
+
+   /*** fill in the token */
+
+   ptr = t;
+
+   g_make_token_header(gss_mech_krb5, 22+tmsglen, &ptr, toktype);
+
+   /* for now, only generate DES integrity */
+
+   ptr[0] = 0;
+   ptr[1] = 0;
+
+   /* SEAL_ALG, or filler */
+
+   if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+      ptr[2] = 0;
+      ptr[3] = 0;
+   } else {
+      ptr[2] = 0xff;
+      ptr[3] = 0xff;
+   }
+
+   /* filler */
+
+   ptr[4] = 0xff;
+   ptr[5] = 0xff;
+
+   /* compute the checksum */
+
+   MD5Init(&md5);
+   MD5Update(&md5, (unsigned char *) ptr-2, 8);
+   MD5Update(&md5, text->value, text->length);
+   MD5Final(&md5);
+
+   /* XXX this depends on the key being a single-des key, but that's
+      all that kerberos supports right now */
+
+   if (code = krb5_calculate_checksum(CKSUMTYPE_DESCBC, md5.digest, 16,
+                                     seq_ed->key->contents, 
+                                     seq_ed->key->length,
+                                     &desmac)) {
+      xfree(t);
+      return(code);
+   }
+
+   memcpy(ptr+14, desmac.contents, 8);
+
+   /* XXX krb5_free_checksum_contents? */
+   xfree(desmac.contents);
+
+   /* create the seq_num */
+
+   if (code = kg_make_seq_num(seq_ed, direction?0xff:0, *seqnum,
+                             ptr+14, ptr+6)) {
+      xfree(t);
+      return(code);
+   }
+
+   /* include seal token fields */
+
+   if (toktype == KG_TOK_SEAL_MSG) {
+      if (encrypt) {
+        unsigned char *plain;
+        unsigned char pad;
+
+        if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+           xfree(t);
+           return(ENOMEM);
+        }
+
+        if (code = kg_make_confounder(enc_ed, plain)) {
+           xfree(plain);
+           xfree(t);
+           return(code);
+        }
+
+        memcpy(plain+8, text->value, text->length);
+
+        pad = 8-(text->length%8);
+
+        memset(plain+8+text->length, pad, pad);
+
+        if (code = kg_encrypt(enc_ed, NULL, (krb5_pointer) plain,
+                              (krb5_pointer) (ptr+22), tmsglen)) {
+           xfree(plain);
+           xfree(t);
+           return(code);
+        }
+
+        xfree(plain);
+      } else {
+        memcpy(ptr+22, text->value, text->length);
+      }
+   }
+
+   /* that's it.  return the token */
+
+   (*seqnum)++;
+
+   token->length = tlen;
+   token->value = (void *) t;
+
+   return(0);
+}
+
+/* if signonly is true, ignore conf_req, conf_state, 
+   and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+
+OM_uint32
+kg_seal(OM_uint32 *minor_status,
+       gss_ctx_id_t context_handle,
+       int conf_req_flag,
+       int qop_req,
+       gss_buffer_t input_message_buffer,
+       int *conf_state,
+       gss_buffer_t output_message_buffer,
+       int toktype)
+{
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_error_code code;
+   krb5_timestamp now;
+
+   output_message_buffer->length = 0;
+   output_message_buffer->value = NULL;
+
+   /* only default qop is allowed */
+   if (qop_req != GSS_C_QOP_DEFAULT) {
+      *minor_status = G_UNKNOWN_QOP;
+      return(GSS_S_FAILURE);
+   }
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   if (code = krb5_timeofday(&now)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (code = make_seal_token(&ctx->enc, &ctx->seq, &ctx->seq_send,
+                             ctx->initiate,
+                             input_message_buffer, output_message_buffer,
+                             conf_req_flag, toktype)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if ((toktype == KG_TOK_SEAL_MSG) && conf_state)
+      *conf_state = conf_req_flag;
+
+   *minor_status = 0;
+   return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
new file mode 100644 (file)
index 0000000..2a83ac7
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+#include <netinet/in.h>
+#include <krb5/rsa-md5.h>
+
+/*
+ * $Id$
+ */
+
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+   conf_state is only valid if SEAL.
+   */
+
+OM_uint32
+kg_unseal(OM_uint32 *minor_status,
+         gss_ctx_id_t context_handle,
+         gss_buffer_t input_token_buffer,
+         gss_buffer_t message_buffer,
+         int *conf_state,
+         int *qop_state,
+         int toktype)
+{
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_error_code code;
+   int bodysize;
+   int tmsglen;
+   int signalg;
+   int sealalg;
+   gss_buffer_desc token;
+   unsigned char *ptr;
+   krb5_checksum desmac;
+   MD5_CTX md5;
+   unsigned char *cksum;
+   krb5_timestamp now;
+
+   if (toktype == KG_TOK_SEAL_MSG) {
+      message_buffer->length = 0;
+      message_buffer->value = NULL;
+   }
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   /* parse the token, leave the data in message_buffer, setting conf_state */
+
+   /* verify the header */
+
+   ptr = (unsigned char *) input_token_buffer->value;
+
+   if (! g_verify_token_header(gss_mech_krb5, &bodysize,
+                              &ptr, toktype, input_token_buffer->length)) {
+      *minor_status = 0;
+      return(GSS_S_DEFECTIVE_TOKEN);
+   }
+
+   if (toktype == KG_TOK_SEAL_MSG)
+      tmsglen = bodysize-22;
+
+   /* get the sign and seal algorithms */
+
+   signalg = ptr[0] + (ptr[1]<<8);
+   sealalg = ptr[2] + (ptr[3]<<8);
+
+   if (((signalg != 0) && (signalg != 1)) ||
+       ((toktype != KG_TOK_SEAL_MSG) && (sealalg != 0xffff)) ||
+       ((toktype == KG_TOK_SEAL_MSG) && 
+       ((sealalg != 0xffff) && (sealalg != 0))) ||
+       (ptr[4] != 0xff) ||
+       (ptr[5] != 0xff)) {
+      *minor_status = 0;
+      return(GSS_S_DEFECTIVE_TOKEN);
+   }
+
+   /* get the token parameters */
+
+   /* decode the message, if SEAL */
+
+   if (toktype == KG_TOK_SEAL_MSG) {
+      if (sealalg == 0) {
+        unsigned char *plain;
+
+        if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+           *minor_status = ENOMEM;
+           return(GSS_S_FAILURE);
+        }
+
+        if (code = kg_decrypt(&ctx->enc, NULL, ptr+22, plain, tmsglen)) {
+           xfree(plain);
+           *minor_status = code;
+           return(GSS_S_FAILURE);
+        }
+
+        token.length = tmsglen - 8 - plain[tmsglen-1];
+
+        if ((token.value = xmalloc(token.length)) == NULL) {
+           xfree(plain);
+           *minor_status = ENOMEM;
+           return(GSS_S_FAILURE);
+        }
+
+        memcpy(token.value, plain+8, token.length);
+
+        xfree(plain);
+      } else {
+        token.length = tmsglen;
+
+        if ((token.value = xmalloc(token.length)) == NULL) {
+           *minor_status = ENOMEM;
+           return(GSS_S_FAILURE);
+        }
+
+        memcpy(token.value, ptr+22, token.length);
+      }
+   } else if (toktype == KG_TOK_SIGN_MSG) {
+      token = *message_buffer;
+   } else {
+      token.length = 0;
+      token.value = NULL;
+   }
+
+   /* compute the checksum of the message */
+
+   if (signalg == 0) {
+      MD5Init(&md5);
+      MD5Update(&md5, (unsigned char *) ptr-2, 8);
+      MD5Update(&md5, token.value, token.length);
+      MD5Final(&md5);
+
+      /* XXX this depends on the key being a single-des key, but that's
+        all that kerberos supports right now */
+
+      if (code = krb5_calculate_checksum(CKSUMTYPE_DESCBC, md5.digest, 16,
+                                        ctx->seq.key->contents, 
+                                        ctx->seq.key->length,
+                                        &desmac)) {
+        if (toktype == KG_TOK_SEAL_MSG)
+           xfree(token.value);
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+      }
+
+      cksum = desmac.contents;
+   } else {
+      if (! ctx->seed_init) {
+        if (code = kg_make_seed(ctx->subkey, ctx->seed)) {
+           if (toktype == KG_TOK_SEAL_MSG)
+              xfree(token.value);
+           *minor_status = code;
+           return(GSS_S_FAILURE);
+        }
+        ctx->seed_init = 1;
+      }
+
+      MD5Init(&md5);
+      MD5Update(&md5, ctx->seed, sizeof(ctx->seed));
+      MD5Update(&md5, (unsigned char *) ptr-2, 8);
+      MD5Update(&md5, token.value, token.length);
+      MD5Final(&md5);
+
+      cksum = md5.digest;
+   }
+      
+   /* compare the computed checksum against the transmitted checksum */
+
+   if (memcmp(cksum, ptr+14, 8) != 0) {
+      if (signalg == 0)
+        xfree(desmac.contents);
+      if (toktype == KG_TOK_SEAL_MSG)
+        xfree(token.value);
+      *minor_status = 0;
+      return(GSS_S_BAD_SIG);
+   }
+
+   if (signalg == 0)
+      xfree(desmac.contents);
+
+   /* XXX this is where the seq_num check would go */
+   
+   /* it got through unscathed.  Make sure the context is unexpired */
+
+   if (toktype == KG_TOK_SEAL_MSG)
+      *message_buffer = token;
+
+   if (conf_state)
+      *conf_state = (sealalg == 0);
+
+   if (qop_state)
+      *qop_state = GSS_C_QOP_DEFAULT;
+
+   if (code = krb5_timeofday(&now)) {
+      *minor_status = code;
+      return(GSS_S_FAILURE);
+   }
+
+   if (now > ctx->endtime) {
+      *minor_status = 0;
+      return(GSS_S_CONTEXT_EXPIRED);
+   }
+
+   /* success */
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/krb5_gss_glue.c b/src/lib/gssapi/krb5/krb5_gss_glue.c
new file mode 100644 (file)
index 0000000..ecebdd1
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+OM_uint32
+gss_accept_sec_context(OM_uint32 *minor_status,
+                      gss_ctx_id_t *context_handle,
+                      gss_cred_id_t verifier_cred_handle,
+                      gss_buffer_t input_token,
+                      gss_channel_bindings_t input_chan_bindings,
+                      gss_name_t *src_name,
+                      gss_OID *mech_type,
+                      gss_buffer_t output_token,
+                      int *ret_flags,
+                      OM_uint32 *time_rec,
+                      gss_cred_id_t *delegated_cred_handle) {
+   return(krb5_gss_accept_sec_context(minor_status,
+                                     context_handle,
+                                     verifier_cred_handle,
+                                     input_token,
+                                     input_chan_bindings,
+                                     src_name,
+                                     mech_type,
+                                     output_token,
+                                     ret_flags,
+                                     time_rec,
+                                     delegated_cred_handle));
+}
+
+OM_uint32
+gss_acquire_cred(OM_uint32 *minor_status,
+                gss_name_t desired_name,
+                OM_uint32 time_req,
+                gss_OID_set desired_mechs,
+                int cred_usage,
+                gss_cred_id_t *output_cred_handle,
+                gss_OID_set *actual_mechs,
+                OM_uint32 *time_rec) {
+   return(krb5_gss_acquire_cred(minor_status,
+                               desired_name,
+                               time_req,
+                               desired_mechs,
+                               cred_usage,
+                               output_cred_handle,
+                               actual_mechs,
+                               time_rec));
+}
+
+OM_uint32
+gss_compare_name(OM_uint32 *minor_status,
+                gss_name_t name1,
+                gss_name_t name2,
+                int *name_equal) {
+   return(krb5_gss_compare_name(minor_status,
+                               name1,
+                               name2,
+                               name_equal));
+}
+
+OM_uint32
+gss_context_time(OM_uint32 *minor_status,
+                gss_ctx_id_t context_handle,
+                OM_uint32 *time_rec) {
+   return(krb5_gss_context_time(minor_status,
+                               context_handle,
+                               time_rec));
+}
+
+OM_uint32
+gss_delete_sec_context(OM_uint32 *minor_status,
+                      gss_ctx_id_t *context_handle,
+                      gss_buffer_t output_token) {
+   return(krb5_gss_delete_sec_context(minor_status,
+                                     context_handle,
+                                     output_token));
+}
+
+OM_uint32
+gss_display_name(OM_uint32 *minor_status,
+                gss_name_t input_name,
+                gss_buffer_t output_name_buffer,
+                gss_OID *output_name_type) {
+   return(krb5_gss_display_name(minor_status,
+                               input_name,
+                               output_name_buffer,
+                               output_name_type));
+}
+
+OM_uint32
+gss_display_status(OM_uint32 *minor_status,
+                  OM_uint32 status_value,
+                  int status_type,
+                  const_gss_OID mech_type,
+                  int *message_context,
+                  gss_buffer_t status_string) {
+   return(krb5_gss_display_status(minor_status,
+                                 status_value,
+                                 status_type,
+                                 mech_type,
+                                 message_context,
+                                 status_string));
+}
+
+OM_uint32
+gss_import_name(OM_uint32 *minor_status,
+               gss_buffer_t input_name_buffer,
+               const_gss_OID input_name_type,
+               gss_name_t *output_name) {
+   return(krb5_gss_import_name(minor_status,
+                              input_name_buffer,
+                              input_name_type,
+                              output_name));
+}
+
+OM_uint32
+gss_indicate_mechs(OM_uint32 *minor_status,
+                  gss_OID_set *mech_set) {
+   return(krb5_gss_indicate_mechs(minor_status,
+                                 mech_set));
+}
+
+OM_uint32
+gss_init_sec_context(OM_uint32 *minor_status,
+                    gss_cred_id_t claimant_cred_handle,
+                    gss_ctx_id_t *context_handle,
+                    gss_name_t target_name,
+                    const_gss_OID mech_type,
+                    int req_flags,
+                    OM_uint32 time_req,
+                    gss_channel_bindings_t input_chan_bindings,
+                    gss_buffer_t input_token,
+                    gss_OID *actual_mech_type,
+                    gss_buffer_t output_token,
+                    int *ret_flags,
+                    OM_uint32 *time_rec) {
+   return(krb5_gss_init_sec_context(minor_status,
+                                   claimant_cred_handle,
+                                   context_handle,
+                                   target_name,
+                                   mech_type,
+                                   req_flags,
+                                   time_req,
+                                   input_chan_bindings,
+                                   input_token,
+                                   actual_mech_type,
+                                   output_token,
+                                   ret_flags,
+                                   time_rec));
+}
+
+OM_uint32
+gss_inquire_context(OM_uint32 *minor_status,
+                   gss_ctx_id_t context_handle,
+                   gss_name_t *initiator_name,
+                   gss_name_t *acceptor_name,
+                   OM_uint32 *lifetime_rec,
+                   gss_OID *mech_type,
+                   int *ret_flags,
+                   int *locally_initiated) {
+   return(krb5_gss_inquire_context(minor_status,
+                                  context_handle,
+                                  initiator_name,
+                                  acceptor_name,
+                                  lifetime_rec,
+                                  mech_type,
+                                  ret_flags,
+                                  locally_initiated));
+}
+
+OM_uint32
+gss_inquire_cred(OM_uint32 *minor_status,
+                gss_cred_id_t cred_handle,
+                gss_name_t *name,
+                OM_uint32 *lifetime_ret,
+                int *cred_usage,
+                gss_OID_set *mechanisms) {
+   return(krb5_gss_inquire_cred(minor_status,
+                               cred_handle,
+                               name,
+                               lifetime_ret,
+                               cred_usage,
+                               mechanisms));
+}
+
+OM_uint32
+gss_process_context_token(OM_uint32 *minor_status,
+                         gss_ctx_id_t context_handle,
+                         gss_buffer_t token_buffer) {
+   return(krb5_gss_process_context_token(minor_status,
+                                        context_handle,
+                                        token_buffer));
+}
+
+OM_uint32
+gss_release_cred(OM_uint32 *minor_status,
+                gss_cred_id_t *cred_handle) {
+   return(krb5_gss_release_cred(minor_status,
+                               cred_handle));
+}
+
+OM_uint32
+gss_release_name(OM_uint32 *minor_status,
+                gss_name_t *input_name) {
+   return(krb5_gss_release_name(minor_status,
+                               input_name));
+}
+
+OM_uint32
+gss_release_buffer(OM_uint32 *minor_status,
+                  gss_buffer_t buffer)
+{
+   return(generic_gss_release_buffer(minor_status,
+                                    buffer));
+}
+
+OM_uint32
+gss_release_oid_set(OM_uint32* minor_status,
+                   gss_OID_set *set)
+{
+   return(generic_gss_release_oid_set(minor_status,
+                                     set));
+}
+
+OM_uint32
+gss_seal(OM_uint32 *minor_status,
+        gss_ctx_id_t context_handle,
+        int conf_req_flag,
+        int qop_req,
+        gss_buffer_t input_message_buffer,
+        int *conf_state,
+        gss_buffer_t output_message_buffer) {
+   return(krb5_gss_seal(minor_status,
+                       context_handle,
+                       conf_req_flag,
+                       qop_req,
+                       input_message_buffer,
+                       conf_state,
+                       output_message_buffer));
+}
+
+OM_uint32
+gss_sign(OM_uint32 *minor_status,
+        gss_ctx_id_t context_handle,
+        int qop_req,
+        gss_buffer_t message_buffer,
+        gss_buffer_t message_token) {
+   return(krb5_gss_sign(minor_status,
+                       context_handle,
+                       qop_req,
+                       message_buffer,
+                       message_token));
+}
+
+OM_uint32
+gss_unseal(OM_uint32 *minor_status,
+          gss_ctx_id_t context_handle,
+          gss_buffer_t input_message_buffer,
+          gss_buffer_t output_message_buffer,
+          int *conf_state,
+          int *qop_state) {
+   return(krb5_gss_unseal(minor_status,
+                         context_handle,
+                         input_message_buffer,
+                         output_message_buffer,
+                         conf_state,
+                         qop_state));
+}
+
+OM_uint32
+gss_verify(OM_uint32 *minor_status,
+          gss_ctx_id_t context_handle,
+          gss_buffer_t message_buffer,
+          gss_buffer_t token_buffer,
+          int *qop_state) {
+   return(krb5_gss_verify(minor_status,
+                         context_handle,
+                         message_buffer,
+                         token_buffer,
+                         qop_state));
+}
diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c
new file mode 100644 (file)
index 0000000..2b57bdc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_process_context_token(OM_uint32 *minor_status,
+                              gss_ctx_id_t context_handle,
+                              gss_buffer_t token_buffer)
+{
+   krb5_gss_ctx_id_rec *ctx;
+   OM_uint32 majerr;
+
+   /* validate the context handle */
+   if (! kg_validate_ctx_id(context_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+   if (! ctx->established) {
+      *minor_status = KG_CTX_INCOMPLETE;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   /* "unseal" the token */
+
+   if (GSS_ERROR(majerr = kg_unseal(minor_status, ctx, token_buffer,
+                                   GSS_C_NO_BUFFER, NULL, NULL,
+                                   KG_TOK_DEL_CTX)))
+      return(majerr);
+
+   /* that's it.  delete the context */
+
+   return(krb5_gss_delete_sec_context(minor_status, &context_handle,
+                                     GSS_C_NO_BUFFER));
+}
diff --git a/src/lib/gssapi/krb5/release_cred.c b/src/lib/gssapi/krb5/release_cred.c
new file mode 100644 (file)
index 0000000..02425f3
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_release_cred(OM_uint32 *minor_status,
+                     gss_cred_id_t *cred_handle)
+{
+   krb5_gss_cred_id_t cred;
+   krb5_error_code code1, code2;
+
+   if (*cred_handle == GSS_C_NO_CREDENTIAL)
+      return(kg_release_defcred(minor_status));
+
+   if (! kg_delete_cred_id(*cred_handle)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED);
+   }
+
+   cred = *cred_handle;
+
+   if (cred->ccache)
+      code1 = krb5_cc_close(cred->ccache);
+   else
+      code1 = 0;
+
+   if (cred->keytab)
+      code2 = krb5_kt_close(cred->keytab);
+   else
+      code2 = 0;
+
+   if (cred->princ)
+      krb5_free_principal(cred->princ);
+   xfree(cred);
+
+   *cred_handle = NULL;
+
+   *minor_status = 0;
+   if (code1)
+      *minor_status = code1;
+   if (code2)
+      *minor_status = code2;
+
+   return(*minor_status?GSS_S_FAILURE:GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/release_name.c b/src/lib/gssapi/krb5/release_name.c
new file mode 100644 (file)
index 0000000..6f7b026
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1993 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "gssapiP_krb5.h"
+
+OM_uint32
+krb5_gss_release_name(OM_uint32 *minor_status,
+                     gss_name_t *input_name)
+{
+   if (! kg_validate_name(*input_name)) {
+      *minor_status = G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   (void)kg_delete_name(*input_name);
+
+   krb5_free_principal((krb5_principal) *input_name);
+
+   *input_name = GSS_C_NO_NAME;
+
+   *minor_status = 0;
+   return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/krb5/seal.c b/src/lib/gssapi/krb5/seal.c
new file mode 100644 (file)
index 0000000..03b9716
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_seal(OM_uint32 *minor_status,
+             gss_ctx_id_t context_handle,
+             int conf_req_flag,
+             int qop_req,
+             gss_buffer_t input_message_buffer,
+             int *conf_state,
+             gss_buffer_t output_message_buffer)
+{
+   return(kg_seal(minor_status, context_handle, conf_req_flag,
+                 qop_req, input_message_buffer, conf_state,
+                 output_message_buffer, KG_TOK_SEAL_MSG));
+}
diff --git a/src/lib/gssapi/krb5/sign.c b/src/lib/gssapi/krb5/sign.c
new file mode 100644 (file)
index 0000000..f27f4ff
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_sign(OM_uint32 *minor_status,
+             gss_ctx_id_t context_handle,
+             int qop_req,
+             gss_buffer_t message_buffer,
+             gss_buffer_t message_token)
+{
+   return(kg_seal(minor_status, context_handle, 0,
+                 qop_req, message_buffer, NULL,
+                 message_token, KG_TOK_SIGN_MSG));
+}
diff --git a/src/lib/gssapi/krb5/unseal.c b/src/lib/gssapi/krb5/unseal.c
new file mode 100644 (file)
index 0000000..d555058
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_unseal(OM_uint32 *minor_status,
+               gss_ctx_id_t context_handle,
+               gss_buffer_t input_message_buffer,
+               gss_buffer_t output_message_buffer,
+               int *conf_state,
+               int *qop_state)
+{
+   return(kg_unseal(minor_status, context_handle,
+                   input_message_buffer, output_message_buffer,
+                   conf_state, qop_state, KG_TOK_SEAL_MSG));
+}
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
new file mode 100644 (file)
index 0000000..ff2c888
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+krb5_error_code kg_checksum_channel_bindings(gss_channel_bindings_t cb,
+                                            krb5_checksum *cksum)
+{
+   int len;
+   char *buf, *ptr;
+   long tmp;
+   krb5_error_code code;
+
+   /* generate a buffer full of zeros if no cb specified */
+
+   if (cb == GSS_C_NO_CHANNEL_BINDINGS) {
+      /* allocate the cksum contents buffer */
+      if ((cksum->contents = (krb5_octet *)
+          xmalloc(krb5_checksum_size(CKSUMTYPE_RSA_MD5))) == NULL)
+        return(ENOMEM);
+
+      cksum->checksum_type = CKSUMTYPE_RSA_MD5;
+      memset(cksum->contents, '\0',
+            (cksum->length = krb5_checksum_size(CKSUMTYPE_RSA_MD5)));
+      return(0);
+   }
+
+   /* create the buffer to checksum into */
+
+   len = (sizeof(tmp)*5+
+         cb->initiator_address.length+
+         cb->acceptor_address.length+
+         cb->application_data.length);
+
+   if ((buf = (char *) xmalloc(len)) == NULL)
+      return(ENOMEM);
+
+   /* allocate the cksum contents buffer */
+   if ((cksum->contents = (krb5_octet *)
+       xmalloc(krb5_checksum_size(CKSUMTYPE_RSA_MD5))) == NULL) {
+      free(buf);
+      return(ENOMEM);
+   }
+
+   /* helper macros.  This code currently depends on a long being 32
+      bits, and htonl dtrt. */
+
+   ptr = buf;
+
+   TWRITE_INT(ptr, tmp, cb->initiator_addrtype);
+   TWRITE_BUF(ptr, tmp, cb->initiator_address);
+   TWRITE_INT(ptr, tmp, cb->acceptor_addrtype);
+   TWRITE_BUF(ptr, tmp, cb->acceptor_address);
+   TWRITE_BUF(ptr, tmp, cb->application_data);
+
+   /* checksum the data */
+
+   if (code = krb5_calculate_checksum(CKSUMTYPE_RSA_MD5, buf, len,
+                                     NULL, 0, cksum)) {
+      xfree(cksum->contents);
+      xfree(buf);
+      return(code);
+   }
+
+   /* success */
+
+   xfree(buf);
+   return(0);
+}
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
new file mode 100644 (file)
index 0000000..b569cb6
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
+
+int kg_confounder_size(krb5_gss_enc_desc *ed)
+{
+   /* XXX Is this an abstraction violation? */
+
+   return(ed->eblock.crypto_entry->block_length);
+}
+
+krb5_error_code
+kg_make_confounder(krb5_gss_enc_desc *ed, unsigned char *buf)
+{
+   return(krb5_random_confounder(ed->eblock.crypto_entry->block_length, buf));
+}
+
+int kg_encrypt_size(krb5_gss_enc_desc *ed, int n)
+{
+   return(krb5_encrypt_size(n, ed->eblock.crypto_entry));
+}
+
+krb5_error_code
+kg_encrypt(krb5_gss_enc_desc *ed, krb5_pointer iv,
+          krb5_pointer in, krb5_pointer out, int length)
+{
+   krb5_error_code code;
+
+   if (! ed->processed) {
+      if (code = krb5_process_key(&ed->eblock, ed->key))
+        return(code);
+      ed->processed = 1;
+   }
+
+   if (code = krb5_encrypt(in, out, length, &ed->eblock, iv?iv:zeros))
+      return(code);
+
+   return(0);
+}
+
+/* length is the length of the cleartext. */
+
+krb5_error_code
+kg_decrypt(krb5_gss_enc_desc *ed, krb5_pointer iv,
+          krb5_pointer in, krb5_pointer out, int length)
+{
+   krb5_error_code code;
+   int elen;
+   char *buf;
+
+   if (! ed->processed) {
+      if (code = krb5_process_key(&ed->eblock, ed->key))
+        return(code);
+      ed->processed = 1;
+   }
+
+   elen = krb5_encrypt_size(length, ed->eblock.crypto_entry);
+   if ((buf = (char *) xmalloc(elen)) == NULL)
+      return(ENOMEM);
+
+   if (code = krb5_decrypt(in, buf, elen, &ed->eblock, iv?iv:zeros)) {
+      xfree(buf);
+      return(code);
+   }
+
+   memcpy(out, buf, length);
+   xfree(buf);
+
+   return(0);
+}
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
new file mode 100644 (file)
index 0000000..9eb57c1
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+#include <memory.h>
+
+/*
+ * $Id$
+ */
+
+static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
+
+krb5_error_code
+kg_make_seed(krb5_keyblock *key, unsigned char *seed)
+{
+   krb5_error_code code;
+   krb5_gss_enc_desc ed;
+   int i;
+
+   if (code = krb5_copy_keyblock(key, &ed.key))
+      return(code);
+
+   /* reverse the key bytes, as per spec */
+
+   for (i=0; i<ed.key->length; i++)
+      ed.key->contents[i] = key->contents[key->length - 1 - i];
+
+   krb5_use_cstype(&ed.eblock, ETYPE_RAW_DES_CBC);
+   ed.processed = 0;
+
+   code = kg_encrypt(&ed, NULL, zeros, seed, 16);
+
+   krb5_finish_key(&ed.eblock);
+   krb5_free_keyblock(ed.key);
+
+   return(code);
+}
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
new file mode 100644 (file)
index 0000000..9ab27bf
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+krb5_error_code kg_make_seq_num(krb5_gss_enc_desc *ed, int direction,
+                               int seqnum, unsigned char *cksum,
+                               unsigned char *buf)
+{
+   unsigned char plain[8];
+
+   plain[0] = seqnum&0xff;
+   plain[1] = (seqnum>>8)&0xff;
+   plain[2] = (seqnum>>16)&0xff;
+   plain[3] = (seqnum>>24)&0xff;
+
+   plain[4] = direction;
+   plain[5] = direction;
+   plain[6] = direction;
+   plain[7] = direction;
+
+   return(kg_encrypt(ed, cksum, plain, buf, 8));
+}
diff --git a/src/lib/gssapi/krb5/verify.c b/src/lib/gssapi/krb5/verify.c
new file mode 100644 (file)
index 0000000..1057e2d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1993 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.
+ */
+
+#include "gssapiP_krb5.h"
+
+/*
+ * $Id$
+ */
+
+OM_uint32
+krb5_gss_verify(OM_uint32 *minor_status,
+               gss_ctx_id_t context_handle,
+               gss_buffer_t message_buffer,
+               gss_buffer_t token_buffer,
+               int *qop_state)
+{
+   return(kg_unseal(minor_status, context_handle,
+                   token_buffer, message_buffer,
+                   NULL, qop_state, KG_TOK_SIGN_MSG));
+}