summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi
diff options
context:
space:
mode:
authorTheodore Tso <tytso@mit.edu>1993-12-18 03:14:21 +0000
committerTheodore Tso <tytso@mit.edu>1993-12-18 03:14:21 +0000
commit870d5a01e997b76cae1ad120c6c003edddab5205 (patch)
treec4acc37dae89d396cdb00706d878af4d47972d49 /src/lib/gssapi
parentbb08b522cb5381f36cb012220a1ecb47d75dee10 (diff)
downloadkrb5-870d5a01e997b76cae1ad120c6c003edddab5205.tar.gz
krb5-870d5a01e997b76cae1ad120c6c003edddab5205.tar.xz
krb5-870d5a01e997b76cae1ad120c6c003edddab5205.zip
As submitted by Openvision Technologies:
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
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/Makefile31
-rw-r--r--src/lib/gssapi/generic/Makefile74
-rw-r--r--src/lib/gssapi/generic/display_com_err_status.c68
-rw-r--r--src/lib/gssapi/generic/display_major_status.c304
-rw-r--r--src/lib/gssapi/generic/gssapi.h404
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h123
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c39
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.h37
-rw-r--r--src/lib/gssapi/generic/gssapi_generic_err.et38
-rw-r--r--src/lib/gssapi/generic/release_buffer.c42
-rw-r--r--src/lib/gssapi/generic/release_oid_set.c44
-rw-r--r--src/lib/gssapi/generic/util_buffer.c46
-rw-r--r--src/lib/gssapi/generic/util_canonhost.c53
-rw-r--r--src/lib/gssapi/generic/util_dup.c40
-rw-r--r--src/lib/gssapi/generic/util_oid.c54
-rw-r--r--src/lib/gssapi/generic/util_token.c183
-rw-r--r--src/lib/gssapi/generic/util_validate.c153
-rw-r--r--src/lib/gssapi/krb5/Makefile98
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c441
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c418
-rw-r--r--src/lib/gssapi/krb5/compare_name.c49
-rw-r--r--src/lib/gssapi/krb5/context_time.c66
-rw-r--r--src/lib/gssapi/krb5/delete_sec_context.c92
-rw-r--r--src/lib/gssapi/krb5/display_name.c64
-rw-r--r--src/lib/gssapi/krb5/display_status.c76
-rw-r--r--src/lib/gssapi/krb5/get_tkt_flags.c54
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h322
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c90
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.h44
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5_err.et38
-rw-r--r--src/lib/gssapi/krb5/import_name.c146
-rw-r--r--src/lib/gssapi/krb5/indicate_mechs.c36
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c417
-rw-r--r--src/lib/gssapi/krb5/inquire_context.c125
-rw-r--r--src/lib/gssapi/krb5/inquire_cred.c108
-rw-r--r--src/lib/gssapi/krb5/k5seal.c224
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c236
-rw-r--r--src/lib/gssapi/krb5/krb5_gss_glue.c304
-rw-r--r--src/lib/gssapi/krb5/process_context_token.c61
-rw-r--r--src/lib/gssapi/krb5/release_cred.c69
-rw-r--r--src/lib/gssapi/krb5/release_name.c46
-rw-r--r--src/lib/gssapi/krb5/seal.c41
-rw-r--r--src/lib/gssapi/krb5/sign.c39
-rw-r--r--src/lib/gssapi/krb5/unseal.c40
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c93
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c97
-rw-r--r--src/lib/gssapi/krb5/util_seed.c56
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c46
-rw-r--r--src/lib/gssapi/krb5/verify.c39
49 files changed, 5808 insertions, 0 deletions
diff --git a/src/lib/gssapi/Makefile b/src/lib/gssapi/Makefile
new file mode 100644
index 000000000..0ace19c8e
--- /dev/null
+++ b/src/lib/gssapi/Makefile
@@ -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
index 000000000..6fa6194d2
--- /dev/null
+++ b/src/lib/gssapi/generic/Makefile
@@ -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
index 000000000..0a36f91b4
--- /dev/null
+++ b/src/lib/gssapi/generic/display_com_err_status.c
@@ -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
index 000000000..0216cf116
--- /dev/null
+++ b/src/lib/gssapi/generic/display_major_status.c
@@ -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
index 000000000..c2a9af05f
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi.h
@@ -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
index 000000000..5d8275568
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -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
index 000000000..26d7eebf6
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -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
index 000000000..8d934dda5
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_generic.h
@@ -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
index 000000000..fed788c29
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_generic_err.et
@@ -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
index 000000000..ecb8eab08
--- /dev/null
+++ b/src/lib/gssapi/generic/release_buffer.c
@@ -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
index 000000000..e821e6eec
--- /dev/null
+++ b/src/lib/gssapi/generic/release_oid_set.c
@@ -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
index 000000000..63c10522e
--- /dev/null
+++ b/src/lib/gssapi/generic/util_buffer.c
@@ -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
index 000000000..8fb7a03fe
--- /dev/null
+++ b/src/lib/gssapi/generic/util_canonhost.c
@@ -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
index 000000000..4da654719
--- /dev/null
+++ b/src/lib/gssapi/generic/util_dup.c
@@ -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
index 000000000..40f730a36
--- /dev/null
+++ b/src/lib/gssapi/generic/util_oid.c
@@ -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
index 000000000..3fad4b9e5
--- /dev/null
+++ b/src/lib/gssapi/generic/util_token.c
@@ -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
index 000000000..0c25c2644
--- /dev/null
+++ b/src/lib/gssapi/generic/util_validate.c
@@ -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
index 000000000..0235b4d1f
--- /dev/null
+++ b/src/lib/gssapi/krb5/Makefile
@@ -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
index 000000000..ae51bdff3
--- /dev/null
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -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
index 000000000..d09c70809
--- /dev/null
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -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
index 000000000..455bd6ddd
--- /dev/null
+++ b/src/lib/gssapi/krb5/compare_name.c
@@ -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
index 000000000..00b8ae3ab
--- /dev/null
+++ b/src/lib/gssapi/krb5/context_time.c
@@ -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
index 000000000..04196072c
--- /dev/null
+++ b/src/lib/gssapi/krb5/delete_sec_context.c
@@ -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
index 000000000..d5a83127f
--- /dev/null
+++ b/src/lib/gssapi/krb5/display_name.c
@@ -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
index 000000000..974698d78
--- /dev/null
+++ b/src/lib/gssapi/krb5/display_status.c
@@ -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
index 000000000..a35259c06
--- /dev/null
+++ b/src/lib/gssapi/krb5/get_tkt_flags.c
@@ -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
index 000000000..e61dae7b3
--- /dev/null
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -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
index 000000000..ada5f6f4a
--- /dev/null
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -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
index 000000000..937609d64
--- /dev/null
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -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
index 000000000..ca7a5434b
--- /dev/null
+++ b/src/lib/gssapi/krb5/gssapi_krb5_err.et
@@ -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
index 000000000..51fbd9f43
--- /dev/null
+++ b/src/lib/gssapi/krb5/import_name.c
@@ -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
index 000000000..c20679f95
--- /dev/null
+++ b/src/lib/gssapi/krb5/indicate_mechs.c
@@ -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
index 000000000..a62a286d6
--- /dev/null
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -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
index 000000000..771a35213
--- /dev/null
+++ b/src/lib/gssapi/krb5/inquire_context.c
@@ -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
index 000000000..7795fca15
--- /dev/null
+++ b/src/lib/gssapi/krb5/inquire_cred.c
@@ -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
index 000000000..dd5e56310
--- /dev/null
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -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
index 000000000..2a83ac7b2
--- /dev/null
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -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
index 000000000..ecebdd161
--- /dev/null
+++ b/src/lib/gssapi/krb5/krb5_gss_glue.c
@@ -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
index 000000000..2b57bdcf4
--- /dev/null
+++ b/src/lib/gssapi/krb5/process_context_token.c
@@ -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
index 000000000..02425f30d
--- /dev/null
+++ b/src/lib/gssapi/krb5/release_cred.c
@@ -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
index 000000000..6f7b026a4
--- /dev/null
+++ b/src/lib/gssapi/krb5/release_name.c
@@ -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
index 000000000..03b9716df
--- /dev/null
+++ b/src/lib/gssapi/krb5/seal.c
@@ -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
index 000000000..f27f4ff16
--- /dev/null
+++ b/src/lib/gssapi/krb5/sign.c
@@ -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
index 000000000..d55505856
--- /dev/null
+++ b/src/lib/gssapi/krb5/unseal.c
@@ -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
index 000000000..ff2c88821
--- /dev/null
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -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
index 000000000..b569cb692
--- /dev/null
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -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
index 000000000..9eb57c1cc
--- /dev/null
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -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
index 000000000..9ab27bf4b
--- /dev/null
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -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
index 000000000..1057e2d06
--- /dev/null
+++ b/src/lib/gssapi/krb5/verify.c
@@ -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));
+}