summaryrefslogtreecommitdiff
path: root/src/lib/gssapi/generic
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
committerCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
commit33a9b234e7087f573ef08cd7318c6497ba08b439 (patch)
treed0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/lib/gssapi/generic
Notes
Diffstat (limited to 'src/lib/gssapi/generic')
-rw-r--r--src/lib/gssapi/generic/Makefile.in172
-rw-r--r--src/lib/gssapi/generic/deps96
-rw-r--r--src/lib/gssapi/generic/disp_com_err_status.c62
-rw-r--r--src/lib/gssapi/generic/disp_major_status.c301
-rw-r--r--src/lib/gssapi/generic/gssapi.hin920
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h330
-rw-r--r--src/lib/gssapi/generic/gssapi_alloc.h128
-rw-r--r--src/lib/gssapi/generic/gssapi_err_generic.et49
-rw-r--r--src/lib/gssapi/generic/gssapi_ext.h578
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c450
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.h59
-rw-r--r--src/lib/gssapi/generic/maptest.c68
-rw-r--r--src/lib/gssapi/generic/oid_ops.c553
-rw-r--r--src/lib/gssapi/generic/rel_buffer.c57
-rw-r--r--src/lib/gssapi/generic/rel_oid_set.c61
-rw-r--r--src/lib/gssapi/generic/t_seqstate.c197
-rw-r--r--src/lib/gssapi/generic/util_buffer.c48
-rw-r--r--src/lib/gssapi/generic/util_buffer_set.c126
-rw-r--r--src/lib/gssapi/generic/util_errmap.c264
-rw-r--r--src/lib/gssapi/generic/util_seqstate.c163
-rw-r--r--src/lib/gssapi/generic/util_set.c106
-rw-r--r--src/lib/gssapi/generic/util_token.c229
22 files changed, 5017 insertions, 0 deletions
diff --git a/src/lib/gssapi/generic/Makefile.in b/src/lib/gssapi/generic/Makefile.in
new file mode 100644
index 000000000000..a9e894899d1a
--- /dev/null
+++ b/src/lib/gssapi/generic/Makefile.in
@@ -0,0 +1,172 @@
+mydir=lib$(S)gssapi$(S)generic
+BUILDTOP=$(REL)..$(S)..$(S)..
+LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/..
+
+##DOS##BUILDTOP = ..\..\..
+##DOS##PREFIXDIR=generic
+##DOS##OBJFILE=..\$(OUTPRE)generic.lst
+
+##DOS##DLL_EXP_TYPE=GSS
+
+ETSRCS= gssapi_err_generic.c
+ETOBJS= $(OUTPRE)gssapi_err_generic.$(OBJEXT)
+ETHDRS= gssapi_err_generic.h
+
+EHDRDIR= $(BUILDTOP)$(S)include$(S)gssapi
+
+HDRS= $(EHDRDIR)$(S)gssapi.h \
+ $(EHDRDIR)$(S)gssapi_generic.h \
+ $(EHDRDIR)$(S)gssapi_alloc.h \
+ $(EHDRDIR)$(S)gssapi_ext.h
+
+MK_EHDRDIR=if test -d $(EHDRDIR); then :; else (set -x; mkdir $(EHDRDIR)); fi
+##DOS##MK_EHDRDIR=rem
+
+gssapi-include: $(EHDRDIR)$(S)gssapi.h
+
+$(EHDRDIR)$(S)gssapi.h: $(EHDRDIR)$(S)timestamp gssapi.h
+ $(CP) gssapi.h $@
+$(EHDRDIR)$(S)gssapi_generic.h: $(EHDRDIR)$(S)timestamp $(srcdir)$(S)gssapi_generic.h
+ $(CP) $(srcdir)$(S)gssapi_generic.h $@
+$(EHDRDIR)$(S)gssapi_alloc.h: $(EHDRDIR)$(S)timestamp $(srcdir)$(S)gssapi_alloc.h
+ $(CP) $(srcdir)$(S)gssapi_alloc.h $@
+$(EHDRDIR)$(S)gssapi_ext.h: $(EHDRDIR)$(S)timestamp $(srcdir)$(S)gssapi_ext.h
+ $(CP) $(srcdir)$(S)gssapi_ext.h $@
+
+$(EHDRDIR)$(S)timestamp:
+ $(MK_EHDRDIR)
+ echo timestamp > $(EHDRDIR)$(S)timestamp
+
+$(OUTPRE)gssapi_err_generic.$(OBJEXT): gssapi_err_generic.c
+gssapi_err_generic.h: gssapi_err_generic.et
+gssapi_err_generic.c: gssapi_err_generic.et
+
+##DOS##!if 0
+include_xom=@include_xom@
+##DOS##include_xom=rem
+gssapi.h: gssapi.hin
+ @echo "Creating gssapi.h" ; \
+ h=gss$$$$; $(RM) $$h; \
+ (echo "/* This is the gssapi.h prologue. */"; \
+ $(include_xom) && \
+ echo "/* End of gssapi.h prologue. */"&& \
+ cat $(srcdir)/gssapi.hin )> $$h && \
+ (set -x; $(MV) $$h $@) ; e=$$?; $(RM) $$h; exit $$e
+##DOS##!endif
+##DOS##gssapi.h: gssapi.hin
+##DOS## $(CP) $** $@
+
+SRCS = \
+ $(srcdir)/disp_com_err_status.c \
+ $(srcdir)/disp_major_status.c \
+ $(srcdir)/gssapi_generic.c \
+ $(srcdir)/oid_ops.c \
+ $(srcdir)/rel_buffer.c \
+ $(srcdir)/rel_oid_set.c \
+ $(srcdir)/util_buffer.c \
+ $(srcdir)/util_buffer_set.c \
+ $(srcdir)/util_errmap.c \
+ $(srcdir)/util_set.c \
+ $(srcdir)/util_seqstate.c \
+ $(srcdir)/util_token.c \
+ gssapi_err_generic.c
+
+EXTRADEPSRCS = t_seqstate.c
+
+OBJS = \
+ $(OUTPRE)disp_com_err_status.$(OBJEXT) \
+ $(OUTPRE)disp_major_status.$(OBJEXT) \
+ $(OUTPRE)gssapi_generic.$(OBJEXT) \
+ $(OUTPRE)oid_ops.$(OBJEXT) \
+ $(OUTPRE)rel_buffer.$(OBJEXT) \
+ $(OUTPRE)rel_oid_set.$(OBJEXT) \
+ $(OUTPRE)util_buffer.$(OBJEXT) \
+ $(OUTPRE)util_buffer_set.$(OBJEXT) \
+ $(OUTPRE)util_errmap.$(OBJEXT) \
+ $(OUTPRE)util_set.$(OBJEXT) \
+ $(OUTPRE)util_seqstate.$(OBJEXT) \
+ $(OUTPRE)util_token.$(OBJEXT) \
+ $(OUTPRE)gssapi_err_generic.$(OBJEXT)
+
+STLIBOBJS = \
+ disp_com_err_status.o \
+ disp_major_status.o \
+ gssapi_generic.o \
+ oid_ops.o \
+ rel_buffer.o \
+ rel_oid_set.o \
+ util_buffer.o \
+ util_buffer_set.o \
+ util_errmap.o \
+ util_set.o \
+ util_seqstate.o \
+ util_token.o \
+ gssapi_err_generic.o
+
+EXPORTED_HEADERS= gssapi_generic.h gssapi_ext.h
+EXPORTED_BUILT_HEADERS= gssapi.h
+
+$(OBJS): $(EXPORTED_HEADERS) $(ETHDRS)
+
+all-unix: $(EXPORTED_HEADERS) $(ETHDRS) $(HDRS)
+all-unix: all-libobjs
+
+errmap.h: $(top_srcdir)/util/gen.pl $(top_srcdir)/util/t_array.pm \
+ $(top_srcdir)/util/t_bimap.pm
+ $(PERL) -w -I$(top_srcdir)/util $(top_srcdir)/util/gen.pl bimap \
+ errmap.h \
+ NAME=mecherrmap LEFT=OM_uint32 RIGHT="struct mecherror" \
+ LEFTPRINT=print_OM_uint32 RIGHTPRINT=mecherror_print \
+ LEFTCMP=cmp_OM_uint32 RIGHTCMP=mecherror_cmp
+
+maptest.h: $(top_srcdir)/util/gen.pl $(top_srcdir)/util/t_array.pm \
+ $(top_srcdir)/util/t_bimap.pm
+ $(PERL) -w -I$(top_srcdir)/util $(top_srcdir)/util/gen.pl bimap \
+ maptest.h \
+ NAME=foo LEFT=int RIGHT=elt LEFTPRINT=intprt \
+ RIGHTPRINT=eltprt LEFTCMP=intcmp RIGHTCMP=eltcmp
+maptest.o: maptest.c maptest.h
+maptest: maptest.o
+ $(CC_LINK) -o maptest maptest.o
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-windows: win-create-ehdrdir
+all-windows: $(HDRS)
+
+win-create-ehdrdir:
+ if not exist $(EHDRDIR)\nul mkdir $(EHDRDIR)
+
+clean-unix:: clean-libobjs
+ $(RM) $(ETHDRS) $(ETSRCS) $(HDRS) $(EXPORTED_BUILT_HEADERS) \
+ $(EHDRDIR)$(S)timestamp errmap.h maptest.h
+ $(RM) t_seqstate.o t_seqstate
+
+clean-windows::
+ $(RM) $(HDRS) maptest.h
+ -if exist $(EHDRDIR)\nul rmdir $(EHDRDIR)
+
+t_seqstate: t_seqstate.o util_seqstate.o $(SUPPORT_DEPLIB)
+ $(CC_LINK) $(ALL_CFLAGS) -o $@ t_seqstate.o util_seqstate.o \
+ $(SUPPORT_LIB)
+
+check-unix: t_seqstate
+ $(RUN_TEST) ./t_seqstate
+
+generate-files-mac: gssapi.h errmap.h
+
+# Krb5InstallHeaders($(EXPORTED_HEADERS), $(KRB5_INCDIR)/krb5)
+install-headers-unix install: gssapi.h
+ @set -x; for f in $(EXPORTED_HEADERS) ; \
+ do $(INSTALL_DATA) $(srcdir)/$$f \
+ $(DESTDIR)$(KRB5_INCDIR)/gssapi/$$f ; \
+ done
+ @set -x; for f in $(EXPORTED_BUILT_HEADERS) ; \
+ do $(INSTALL_DATA) $$f \
+ $(DESTDIR)$(KRB5_INCDIR)/gssapi/$$f ; \
+ done
+
+depend: $(ETSRCS) $(ETHDRS) $(HDRS) errmap.h maptest.h
+
+@libobj_frag@
+
diff --git a/src/lib/gssapi/generic/deps b/src/lib/gssapi/generic/deps
new file mode 100644
index 000000000000..5b80e7f3876c
--- /dev/null
+++ b/src/lib/gssapi/generic/deps
@@ -0,0 +1,96 @@
+#
+# Generated makefile dependencies follow.
+#
+disp_com_err_status.so disp_com_err_status.po $(OUTPRE)disp_com_err_status.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h disp_com_err_status.c \
+ gssapiP_generic.h gssapi_err_generic.h gssapi_ext.h \
+ gssapi_generic.h
+disp_major_status.so disp_major_status.po $(OUTPRE)disp_major_status.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h disp_major_status.c \
+ gssapiP_generic.h gssapi_err_generic.h gssapi_ext.h \
+ gssapi_generic.h
+gssapi_generic.so gssapi_generic.po $(OUTPRE)gssapi_generic.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.c \
+ gssapi_generic.h
+oid_ops.so oid_ops.po $(OUTPRE)oid_ops.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_generic.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ oid_ops.c
+rel_buffer.so rel_buffer.po $(OUTPRE)rel_buffer.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ rel_buffer.c
+rel_oid_set.so rel_oid_set.po $(OUTPRE)rel_oid_set.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ rel_oid_set.c
+util_buffer.so util_buffer.po $(OUTPRE)util_buffer.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ util_buffer.c
+util_buffer_set.so util_buffer_set.po $(OUTPRE)util_buffer_set.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ util_buffer_set.c
+util_errmap.so util_errmap.po $(OUTPRE)util_errmap.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
+ errmap.h gssapiP_generic.h gssapi_err_generic.h gssapi_ext.h \
+ gssapi_generic.h util_errmap.c
+util_set.so util_set.po $(OUTPRE)util_set.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ util_set.c
+util_seqstate.so util_seqstate.po $(OUTPRE)util_seqstate.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ util_seqstate.c
+util_token.so util_token.po $(OUTPRE)util_token.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ util_token.c
+gssapi_err_generic.so gssapi_err_generic.po $(OUTPRE)gssapi_err_generic.$(OBJEXT): \
+ $(COM_ERR_DEPS) gssapi_err_generic.c
+t_seqstate.so t_seqstate.po $(OUTPRE)t_seqstate.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(COM_ERR_DEPS) \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h gssapiP_generic.h \
+ gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \
+ t_seqstate.c
diff --git a/src/lib/gssapi/generic/disp_com_err_status.c b/src/lib/gssapi/generic/disp_com_err_status.c
new file mode 100644
index 000000000000..bc416107e74e
--- /dev/null
+++ b/src/lib/gssapi/generic/disp_com_err_status.c
@@ -0,0 +1,62 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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 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 (! 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/disp_major_status.c b/src/lib/gssapi/generic/disp_major_status.c
new file mode 100644
index 000000000000..848af8fa5526
--- /dev/null
+++ b/src/lib/gssapi/generic/disp_major_status.c
@@ -0,0 +1,301 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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 <string.h>
+#include <stdio.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,
+ N_("A required input parameter could not be read"),
+ N_("A required input parameter could not be written"),
+ N_("A parameter was malformed"),
+};
+
+static const char * const calling_error = N_("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,
+ N_("An unsupported mechanism was requested"),
+ N_("An invalid name was supplied"),
+ N_("A supplied name was of an unsupported type"),
+ N_("Incorrect channel bindings were supplied"),
+ N_("An invalid status code was supplied"),
+ N_("A token had an invalid signature"),
+ N_("No credentials were supplied"),
+ N_("No context has been established"),
+ N_("A token was invalid"),
+ N_("A credential was invalid"),
+ N_("The referenced credentials have expired"),
+ N_("The context has expired"),
+ N_("Miscellaneous failure"),
+ N_("The quality-of-protection requested could not be provided"),
+ N_("The operation is forbidden by the local security policy"),
+ N_("The operation or option is not available"),
+};
+
+static const char * const routine_error = N_("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[] = {
+ N_("The routine must be called again to complete its function"),
+ N_("The token was a duplicate of an earlier token"),
+ N_("The token's validity period has expired"),
+ N_("A later token has already been processed"),
+};
+
+static const char * const sinfo_code = N_("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 = N_("No error");
+static const char * const unknown_error = N_("Unknown %s (field = %d)");
+
+/**/
+
+static int
+display_unknown(const char *kind, OM_uint32 value, gss_buffer_t buffer)
+{
+ char *str;
+
+ if (asprintf(&str, _(unknown_error), kind, value) < 0)
+ return(0);
+
+ buffer->length = strlen(str);
+ 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,
+ OM_uint32 *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_COMPLETE);
+ } 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_COMPLETE);
+ } 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 = (OM_uint32) G_BAD_MSG_CTX;
+ return(GSS_S_FAILURE);
+ }
+
+ /* compute the bit offset */
+ /*SUPPRESS 570*/
+ for (bit=0; (((OM_uint32) 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 -= ((OM_uint32) 1)<<bit;
+
+ if (status_value) {
+ *message_context = bit+3;
+ return(GSS_S_COMPLETE);
+ } else {
+ *message_context = 0;
+ return(GSS_S_COMPLETE);
+ }
+}
diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin
new file mode 100644
index 000000000000..59cd93e09f92
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi.hin
@@ -0,0 +1,920 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * 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_
+
+/*
+ * Determine platform-dependent configuration.
+ */
+
+#if defined(__MACH__) && defined(__APPLE__)
+# include <TargetConditionals.h>
+# if TARGET_RT_MAC_CFM
+# error "Use KfM 4.0 SDK headers for CFM compilation."
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if TARGET_OS_MAC
+# pragma pack(push,2)
+#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
+#endif
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#endif
+
+#include <stdint.h>
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#include <stddef.h>
+
+/*
+ * POSIX says that sys/types.h is where size_t is defined.
+ */
+#include <sys/types.h>
+
+/*
+ * $Id$
+ */
+
+/*
+ * First, define the three platform-dependent pointer types.
+ */
+
+struct gss_name_struct;
+typedef struct gss_name_struct * gss_name_t;
+
+struct gss_cred_id_struct;
+typedef struct gss_cred_id_struct * gss_cred_id_t;
+
+struct gss_ctx_id_struct;
+typedef struct gss_ctx_id_struct * gss_ctx_id_t;
+
+/*
+ * The following type must be defined as the smallest natural unsigned integer
+ * supported by the platform that has at least 32 bits of precision.
+ */
+typedef uint32_t gss_uint32;
+typedef int32_t gss_int32;
+
+#ifdef OM_STRING
+/*
+ * We have included the xom.h header file. Use the definition for
+ * OM_object identifier.
+ */
+typedef OM_object_identifier gss_OID_desc, *gss_OID;
+#else /* OM_STRING */
+/*
+ * We can't use X/Open definitions, so roll our own.
+ */
+typedef gss_uint32 OM_uint32;
+
+typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+} gss_OID_desc, *gss_OID;
+#endif /* OM_STRING */
+
+typedef struct gss_OID_set_desc_struct {
+ size_t 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;
+
+/*
+ * For now, define a QOP-type as an OM_uint32 (pending resolution of ongoing
+ * discussions).
+ */
+typedef OM_uint32 gss_qop_t;
+typedef int gss_cred_usage_t;
+
+/*
+ * Flag bits for context-level services.
+ */
+#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
+#define GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+#define GSS_C_DELEG_POLICY_FLAG 32768
+
+/*
+ * 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_NETBIOS 20
+#define GSS_C_AF_X25 21
+
+#define GSS_C_AF_NULLADDR 255
+
+/*
+ * Various Null values.
+ */
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_OID_SET ((gss_OID_set) 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}
+
+/*
+ * Some alternate names for a couple of the above values. These are defined
+ * for V1 compatibility.
+ */
+#define GSS_C_NULL_OID GSS_C_NO_OID
+#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+/*
+ * 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. However a value of 0 should always be interpreted by a GSSAPI
+ * implementation as a request for the default protection level.
+ */
+#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 ((OM_uint32) 0xfffffffful)
+
+
+/* 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 ((OM_uint32) 0377ul)
+#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
+
+/*
+ * The macros that test status codes for error conditions. Note that the
+ * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
+ * evaluates its argument only once.
+ */
+#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) \
+ ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+ (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+ (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MIC GSS_S_BAD_SIG
+#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL \
+ (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED \
+ (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED \
+ (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT \
+ (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN \
+ (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MECH_ATTR \
+ (((OM_uint32) 19ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * 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))
+#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+
+/*
+ * Finally, function prototypes for the GSSAPI routines.
+ */
+
+#if defined (_WIN32) && defined (_MSC_VER)
+# ifdef GSS_DLL_FILE
+# define GSS_DLLIMP __declspec(dllexport)
+# else
+# define GSS_DLLIMP __declspec(dllimport)
+# endif
+#else
+# define GSS_DLLIMP
+#endif
+
+/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744.
+ *
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_ANONYMOUS;
+
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+/* Function Prototypes */
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_release_cred(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t *); /* cred_handle */
+
+OM_uint32 KRB5_CALLCONV
+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 */
+ gss_OID, /* mech_type (used to be const) */
+ OM_uint32, /* 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 */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_accept_sec_context(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_cred_id_t, /* acceptor_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 */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 *, /* time_rec */
+ gss_cred_id_t *); /* delegated_cred_handle */
+
+OM_uint32 KRB5_CALLCONV
+gss_process_context_token(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t); /* token_buffer */
+
+
+OM_uint32 KRB5_CALLCONV
+gss_delete_sec_context(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t); /* output_token */
+
+
+OM_uint32 KRB5_CALLCONV
+gss_context_time(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ OM_uint32 *); /* time_rec */
+
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_get_mic(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t); /* message_token */
+
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_verify_mic(OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t, /* message_token */
+ gss_qop_t * /* qop_state */
+);
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_wrap(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ gss_buffer_t, /* input_message_buffer */
+ int *, /* conf_state */
+ gss_buffer_t); /* output_message_buffer */
+
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_unwrap(
+ 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 */
+ gss_qop_t *); /* qop_state */
+
+
+OM_uint32 KRB5_CALLCONV
+gss_display_status(
+ OM_uint32 *, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ gss_OID, /* mech_type (used to be const) */
+ OM_uint32 *, /* message_context */
+ gss_buffer_t); /* status_string */
+
+
+OM_uint32 KRB5_CALLCONV
+gss_indicate_mechs(
+ OM_uint32 *, /* minor_status */
+ gss_OID_set *); /* mech_set */
+
+
+OM_uint32 KRB5_CALLCONV
+gss_compare_name(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name1 */
+ gss_name_t, /* name2 */
+ int *); /* name_equal */
+
+
+OM_uint32 KRB5_CALLCONV
+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_CALLCONV
+gss_import_name(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* input_name_buffer */
+ gss_OID, /* input_name_type(used to be const) */
+ gss_name_t *); /* output_name */
+
+OM_uint32 KRB5_CALLCONV
+gss_release_name(
+ OM_uint32 *, /* minor_status */
+ gss_name_t *); /* input_name */
+
+OM_uint32 KRB5_CALLCONV
+gss_release_buffer(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t); /* buffer */
+
+OM_uint32 KRB5_CALLCONV
+gss_release_oid_set(
+ OM_uint32 *, /* minor_status */
+ gss_OID_set *); /* set */
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_cred(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* lifetime */
+ gss_cred_usage_t *, /* cred_usage */
+ gss_OID_set *); /* mechanisms */
+
+/* Last argument new for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_context(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_name_t *, /* src_name */
+ gss_name_t *, /* targ_name */
+ OM_uint32 *, /* lifetime_rec */
+ gss_OID *, /* mech_type */
+ OM_uint32 *, /* ctx_flags */
+ int *, /* locally_initiated */
+ int *); /* open */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_wrap_size_limit(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32 *); /* max_input_size */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_import_name_object(
+ OM_uint32 *, /* minor_status */
+ void *, /* input_name */
+ gss_OID, /* input_name_type */
+ gss_name_t *); /* output_name */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_export_name_object(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* input_name */
+ gss_OID, /* desired_name_type */
+ void **); /* output_name */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_add_cred(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_name_t, /* desired_name */
+ gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 *); /* acceptor_time_rec */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_cred_by_mech(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_OID, /* mech_type */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* initiator_lifetime */
+ OM_uint32 *, /* acceptor_lifetime */
+ gss_cred_usage_t *); /* cred_usage */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_export_sec_context(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t); /* interprocess_token */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_import_sec_context(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t *); /* context_handle */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_release_oid(
+ OM_uint32 *, /* minor_status */
+ gss_OID *); /* oid */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_create_empty_oid_set(
+ OM_uint32 *, /* minor_status */
+ gss_OID_set *); /* oid_set */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_add_oid_set_member(
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* member_oid */
+ gss_OID_set *); /* oid_set */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_test_oid_set_member(
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* member */
+ gss_OID_set, /* set */
+ int *); /* present */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_str_to_oid(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* oid_str */
+ gss_OID *); /* oid */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_oid_to_str(
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* oid */
+ gss_buffer_t); /* oid_str */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_names_for_mech(
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* mechanism */
+ gss_OID_set *); /* name_types */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_mechs_for_name(
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_OID_set *); /* mech_types */
+
+/*
+ * The following routines are obsolete variants of gss_get_mic, gss_wrap,
+ * gss_verify_mic and gss_unwrap. They should be provided by GSSAPI V2
+ * implementations for backwards compatibility with V1 applications. Distinct
+ * entrypoints (as opposed to #defines) should be provided, to allow GSSAPI
+ * V1 applications to link against GSSAPI V2 implementations.
+ */
+OM_uint32 KRB5_CALLCONV
+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_CALLCONV
+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_CALLCONV
+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_CALLCONV
+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 */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_export_name(
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t); /* exported_name */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_duplicate_name(
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_name_t *); /* dest_name */
+
+/* New for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_canonicalize_name(
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ const gss_OID, /* mech_type */
+ gss_name_t *); /* output_name */
+
+/* RFC 4401 */
+
+#define GSS_C_PRF_KEY_FULL 0
+#define GSS_C_PRF_KEY_PARTIAL 1
+
+OM_uint32 KRB5_CALLCONV
+gss_pseudo_random(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context */
+ int, /* prf_key */
+ const gss_buffer_t, /* prf_in */
+ ssize_t, /* desired_output_len */
+ gss_buffer_t); /* prf_out */
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred(
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t,/* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ const gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t *);/* cred_usage_stored */
+
+OM_uint32 KRB5_CALLCONV
+gss_set_neg_mechs(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ const gss_OID_set); /* mech_set */
+
+#if TARGET_OS_MAC
+# pragma pack(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* 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)
+
+/* XXXX This is a necessary evil until the spec is fixed */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+/*
+ * RFC 5587
+ */
+typedef const gss_buffer_desc *gss_const_buffer_t;
+typedef const struct gss_channel_bindings_struct *gss_const_channel_bindings_t;
+typedef const struct gss_ctx_id_struct *gss_const_ctx_id_t;
+typedef const struct gss_cred_id_struct *gss_const_cred_id_t;
+typedef const struct gss_name_struct *gss_const_name_t;
+typedef const gss_OID_desc *gss_const_OID;
+typedef const gss_OID_set_desc *gss_const_OID_set;
+
+OM_uint32 KRB5_CALLCONV
+gss_indicate_mechs_by_attrs(
+ OM_uint32 *, /* minor_status */
+ gss_const_OID_set, /* desired_mech_attrs */
+ gss_const_OID_set, /* except_mech_attrs */
+ gss_const_OID_set, /* critical_mech_attrs */
+ gss_OID_set *); /* mechs */
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_attrs_for_mech(
+ OM_uint32 *, /* minor_status */
+ gss_const_OID, /* mech */
+ gss_OID_set *, /* mech_attrs */
+ gss_OID_set *); /* known_mech_attrs */
+
+OM_uint32 KRB5_CALLCONV
+gss_display_mech_attr(
+ OM_uint32 *, /* minor_status */
+ gss_const_OID, /* mech_attr */
+ gss_buffer_t, /* name */
+ gss_buffer_t, /* short_desc */
+ gss_buffer_t); /* long_desc */
+
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MECH_CONCRETE;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MECH_PSEUDO;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MECH_COMPOSITE;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MECH_NEGO;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MECH_GLUE;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_NOT_MECH;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_DEPRECATED;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_NOT_DFLT_MECH;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_ITOK_FRAMED;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_INIT;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_TARG;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_INIT_INIT;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_TARG_INIT;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_INIT_ANON;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_AUTH_TARG_ANON;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_DELEG_CRED;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_INTEG_PROT;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_CONF_PROT;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_MIC;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_WRAP;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_PROT_READY;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_REPLAY_DET;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_OOS_DET;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_CBINDINGS;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_PFS;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_COMPRESS;
+GSS_DLLIMP extern gss_const_OID GSS_C_MA_CTX_TRANS;
+
+/*
+ * RFC 5801
+ */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_saslname_for_mech(
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* desired_mech */
+ gss_buffer_t, /* sasl_mech_name */
+ gss_buffer_t, /* mech_name */
+ gss_buffer_t /* mech_description */
+);
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_mech_for_saslname(
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* sasl_mech_name */
+ gss_OID * /* mech_type */
+);
+
+#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 000000000000..686a21772db8
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -0,0 +1,330 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * 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$
+ */
+
+#if defined(_WIN32)
+#include "k5-int.h"
+#else
+#include "autoconf.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#endif
+
+#include "k5-thread.h"
+
+#include "gssapi_generic.h"
+#include "gssapi_ext.h"
+#include <gssapi/gssapi_alloc.h>
+#include "gssapi_err_generic.h"
+#include <errno.h>
+
+#include "k5-platform.h"
+#include "k5-buf.h"
+
+/** helper macros **/
+
+#define g_OID_equal(o1, o2) \
+ (((o1)->length == (o2)->length) && \
+ (memcmp((o1)->elements, (o2)->elements, (o1)->length) == 0))
+
+/* this code knows that an int on the wire is 32 bits. The type of
+ num should be at least this big, or the extra shifts may do weird
+ things */
+
+#define TWRITE_INT(ptr, num, bigend) \
+ if (bigend) store_32_be(num, ptr); else store_32_le(num, ptr); \
+ (ptr) += 4;
+
+#define TWRITE_INT16(ptr, num, bigend) \
+ if (bigend) store_16_be((num)>>16, ptr); else store_16_le(num, ptr); \
+ (ptr) += 2;
+
+#define TREAD_INT(ptr, num, bigend) \
+ (num) = ((bigend) ? load_32_be(ptr) : load_32_le(ptr)); \
+ (ptr) += 4;
+
+#define TREAD_INT16(ptr, num, bigend) \
+ (num) = ((bigend) ? (load_16_be(ptr) << 16) : load_16_le(ptr)); \
+ (ptr) += 2;
+
+#define TWRITE_STR(ptr, str, len) \
+ memcpy((ptr), (str), (len)); \
+ (ptr) += (len);
+
+#define TREAD_STR(ptr, str, len) \
+ (str) = (ptr); \
+ (ptr) += (len);
+
+#define TWRITE_BUF(ptr, buf, bigend) \
+ TWRITE_INT((ptr), (buf).length, (bigend)); \
+ 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 **/
+
+/* hide names from applications, especially glib applications */
+#define g_set_init gssint_g_set_init
+#define g_set_destroy gssint_g_set_destroy
+#define g_set_entry_add gssint_g_set_entry_add
+#define g_set_entry_delete gssint_g_set_entry_delete
+#define g_set_entry_get gssint_g_set_entry_get
+#define g_make_string_buffer gssint_g_make_string_buffer
+#define g_token_size gssint_g_token_size
+#define g_make_token_header gssint_g_make_token_header
+#define g_verify_token_header gssint_g_verify_token_header
+#define g_display_major_status gssint_g_display_major_status
+#define g_display_com_err_status gssint_g_display_com_err_status
+#define g_seqstate_init gssint_g_seqstate_init
+#define g_seqstate_check gssint_g_seqstate_check
+#define g_seqstate_free gssint_g_seqstate_free
+#define g_seqstate_size gssint_g_seqstate_size
+#define g_seqstate_externalize gssint_g_seqstate_externalize
+#define g_seqstate_internalize gssint_g_seqstate_internalize
+#define g_canonicalize_host gssint_g_canonicalize_host
+#define g_local_host_name gssint_g_local_host_name
+#define g_strdup gssint_g_strdup
+
+typedef struct _g_set_elt *g_set_elt;
+typedef struct {
+ k5_mutex_t mutex;
+ void *data;
+} g_set;
+#define G_SET_INIT { K5_MUTEX_PARTIAL_INITIALIZER, 0 }
+
+typedef struct g_seqnum_state_st *g_seqnum_state;
+
+int g_set_init (g_set_elt *s);
+int g_set_destroy (g_set_elt *s);
+int g_set_entry_add (g_set_elt *s, void *key, void *value);
+int g_set_entry_delete (g_set_elt *s, void *key);
+int g_set_entry_get (g_set_elt *s, void *key, void **value);
+
+int g_save_name (g_set *vdb, gss_name_t name);
+int g_save_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_save_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_save_lucidctx_id (g_set *vdb, void *lctx);
+
+int g_validate_name (g_set *vdb, gss_name_t name);
+int g_validate_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_validate_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_validate_lucidctx_id (g_set *vdb, void *lctx);
+
+int g_delete_name (g_set *vdb, gss_name_t name);
+int g_delete_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_delete_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_delete_lucidctx_id (g_set *vdb, void *lctx);
+
+int g_make_string_buffer (const char *str, gss_buffer_t buffer);
+
+unsigned int g_token_size (const gss_OID_desc * mech, unsigned int body_size);
+
+void g_make_token_header (const gss_OID_desc * mech, unsigned int body_size,
+ unsigned char **buf, int tok_type);
+
+/* flags for g_verify_token_header() */
+#define G_VFY_TOKEN_HDR_WRAPPER_REQUIRED 0x01
+
+gss_int32 g_verify_token_header (const gss_OID_desc * mech,
+ unsigned int *body_size,
+ unsigned char **buf, int tok_type,
+ unsigned int toksize_in,
+ int flags);
+
+OM_uint32 g_display_major_status (OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ OM_uint32 *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);
+
+long g_seqstate_init(g_seqnum_state *state_out, uint64_t seqnum,
+ int do_replay, int do_sequence, int wide);
+OM_uint32 g_seqstate_check(g_seqnum_state state, uint64_t seqnum);
+void g_seqstate_free(g_seqnum_state state);
+void g_seqstate_size(g_seqnum_state state, size_t *sizep);
+long g_seqstate_externalize(g_seqnum_state state, unsigned char **buf,
+ size_t *lenremain);
+long g_seqstate_internalize(g_seqnum_state *state_out, unsigned char **buf,
+ size_t *lenremain);
+
+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 */
+
+OM_uint32
+generic_gss_release_oid(
+ OM_uint32 *, /* minor_status */
+ gss_OID *); /* set */
+
+OM_uint32
+generic_gss_copy_oid(
+ OM_uint32 *, /* minor_status */
+ const gss_OID_desc * const, /* oid */
+ gss_OID *); /* new_oid */
+
+OM_uint32
+generic_gss_create_empty_oid_set(
+ OM_uint32 *, /* minor_status */
+ gss_OID_set *); /* oid_set */
+
+OM_uint32
+generic_gss_add_oid_set_member(
+ OM_uint32 *, /* minor_status */
+ const gss_OID_desc * const, /* member_oid */
+ gss_OID_set *); /* oid_set */
+
+OM_uint32
+generic_gss_test_oid_set_member(
+ OM_uint32 *, /* minor_status */
+ const gss_OID_desc * const, /* member */
+ gss_OID_set, /* set */
+ int *); /* present */
+
+OM_uint32
+generic_gss_oid_to_str(
+ OM_uint32 *, /* minor_status */
+ const gss_OID_desc * const, /* oid */
+ gss_buffer_t); /* oid_str */
+
+OM_uint32
+generic_gss_str_to_oid(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* oid_str */
+ gss_OID *); /* oid */
+
+OM_uint32
+generic_gss_oid_compose(
+ OM_uint32 *, /* minor_status */
+ const char *, /* prefix */
+ size_t, /* prefix_len */
+ int, /* suffix */
+ gss_OID_desc *); /* oid */
+
+OM_uint32
+generic_gss_oid_decompose(
+ OM_uint32 *, /* minor_status */
+ const char *, /*prefix */
+ size_t, /* prefix_len */
+ gss_OID_desc *, /* oid */
+ int *); /* suffix */
+
+int gssint_mecherrmap_init(void);
+void gssint_mecherrmap_destroy(void);
+OM_uint32 gssint_mecherrmap_map(OM_uint32 minor, const gss_OID_desc *oid);
+int gssint_mecherrmap_get(OM_uint32 minor, gss_OID mech_oid,
+ OM_uint32 *mech_minor);
+OM_uint32 gssint_mecherrmap_map_errcode(OM_uint32 errcode);
+
+/*
+ * Transfer contents of a k5buf to a gss_buffer and invalidate the source
+ * On unix, this is a simple pointer copy
+ * On windows, memory is reallocated and copied.
+ */
+static inline OM_uint32
+k5buf_to_gss(OM_uint32 *minor,
+ struct k5buf *input_k5buf,
+ gss_buffer_t output_buffer)
+{
+ OM_uint32 status = GSS_S_COMPLETE;
+
+ if (k5_buf_status(input_k5buf) != 0) {
+ *minor = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ output_buffer->length = input_k5buf->len;
+#if defined(_WIN32) || defined(DEBUG_GSSALLOC)
+ if (output_buffer->length > 0) {
+ output_buffer->value = gssalloc_malloc(output_buffer->length);
+ if (output_buffer->value) {
+ memcpy(output_buffer->value, input_k5buf->data,
+ output_buffer->length);
+ } else {
+ status = GSS_S_FAILURE;
+ *minor = ENOMEM;
+ }
+ } else {
+ output_buffer->value = NULL;
+ }
+ k5_buf_free(input_k5buf);
+#else
+ output_buffer->value = input_k5buf->data;
+ memset(input_k5buf, 0, sizeof(*input_k5buf));
+#endif
+ return status;
+}
+
+OM_uint32 generic_gss_create_empty_buffer_set
+(OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 generic_gss_add_buffer_set_member
+(OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*member_buffer*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 generic_gss_release_buffer_set
+(OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 generic_gss_copy_oid_set
+(OM_uint32 *, /* minor_status */
+ const gss_OID_set_desc * const /*oidset*/,
+ gss_OID_set * /*new_oidset*/);
+
+extern gss_OID_set gss_ma_known_attrs;
+
+OM_uint32 generic_gss_display_mech_attr(
+ OM_uint32 *minor_status,
+ gss_const_OID mech_attr,
+ gss_buffer_t name,
+ gss_buffer_t short_desc,
+ gss_buffer_t long_desc);
+
+#endif /* _GSSAPIP_GENERIC_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_alloc.h b/src/lib/gssapi/generic/gssapi_alloc.h
new file mode 100644
index 000000000000..9a5cd9892c2c
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_alloc.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* To the extent possible under law, Painless Security, LLC has waived
+ * all copyright and related or neighboring rights to GSS-API Memory
+ * Management Header. This work is published from: United States.
+ */
+
+#ifndef GSSAPI_ALLOC_H
+#define GSSAPI_ALLOC_H
+
+#ifdef _WIN32
+#include "winbase.h"
+#endif
+#include <string.h>
+
+#if defined(_WIN32)
+
+static inline void
+gssalloc_free(void *value)
+{
+ if (value)
+ HeapFree(GetProcessHeap(), 0, value);
+}
+
+static inline void *
+gssalloc_malloc(size_t size)
+{
+ return HeapAlloc(GetProcessHeap(), 0, size);
+}
+
+static inline void *
+gssalloc_calloc(size_t count, size_t size)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * size);
+}
+
+static inline void *
+gssalloc_realloc(void *value, size_t size)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, value, size);
+}
+
+#elif defined(DEBUG_GSSALLOC)
+
+/* Be deliberately incompatible with malloc and free, to allow us to detect
+ * mismatched malloc/gssalloc usage on Unix. */
+
+static inline void
+gssalloc_free(void *value)
+{
+ char *p = (char *)value - 8;
+
+ if (value == NULL)
+ return;
+ if (memcmp(p, "gssalloc", 8) != 0)
+ abort();
+ free(p);
+}
+
+static inline void *
+gssalloc_malloc(size_t size)
+{
+ char *p = calloc(size + 8, 1);
+
+ memcpy(p, "gssalloc", 8);
+ return p + 8;
+}
+
+static inline void *
+gssalloc_calloc(size_t count, size_t size)
+{
+ return gssalloc_malloc(count * size);
+}
+
+static inline void *
+gssalloc_realloc(void *value, size_t size)
+{
+ char *p = (char *)value - 8;
+
+ if (value == NULL)
+ return gssalloc_malloc(size);
+ if (memcmp(p, "gssalloc", 8) != 0)
+ abort();
+ return (char *)realloc(p, size) + 8;
+}
+
+#else /* not _WIN32 or DEBUG_GSSALLOC */
+
+/* Normal Unix case, just use free/malloc/calloc/realloc. */
+
+static inline void
+gssalloc_free(void *value)
+{
+ free(value);
+}
+
+static inline void *
+gssalloc_malloc(size_t size)
+{
+ return malloc(size);
+}
+
+static inline void *
+gssalloc_calloc(size_t count, size_t size)
+{
+ return calloc(count, size);
+}
+
+static inline void *
+gssalloc_realloc(void *value, size_t size)
+{
+ return realloc(value, size);
+}
+
+#endif /* not _WIN32 or DEBUG_GSSALLOC */
+
+static inline char *
+gssalloc_strdup(const char *str)
+{
+ size_t size = strlen(str)+1;
+ char *copy = gssalloc_malloc(size);
+ if (copy) {
+ memcpy(copy, str, size);
+ copy[size-1] = '\0';
+ }
+ return copy;
+}
+
+#endif
diff --git a/src/lib/gssapi/generic/gssapi_err_generic.et b/src/lib/gssapi/generic/gssapi_err_generic.et
new file mode 100644
index 000000000000..3e976e3dbf50
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_err_generic.et
@@ -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$
+#
+
+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"
+error_code G_NO_HOSTNAME, "Local host name could not be determined"
+error_code G_BAD_HOSTNAME, "Hostname in SERVICE-NAME string could not be canonicalized"
+error_code G_WRONG_MECH, "Mechanism is incorrect"
+error_code G_BAD_TOK_HEADER, "Token header is malformed or corrupt"
+error_code G_BAD_DIRECTION, "Packet was replayed in wrong direction"
+error_code G_TOK_TRUNC, "Token is missing data"
+error_code G_REFLECT, "Token was reflected"
+error_code G_WRONG_TOKID, "Received token ID does not match expected token ID"
+error_code G_CRED_USAGE_MISMATCH, "The given credential's usage does not match the requested usage"
+error_code G_STORE_ACCEPTOR_CRED_NOSUPP, "Storing of acceptor credentials is not supported by the mechanism"
+error_code G_STORE_NON_DEFAULT_CRED_NOSUPP, "Storing of non-default credentials is not supported by the mechanism"
+end
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
new file mode 100644
index 000000000000..9ad44216d05e
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -0,0 +1,578 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef GSSAPI_EXT_H_
+#define GSSAPI_EXT_H_
+
+#include <gssapi/gssapi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Solaris extensions
+ */
+#ifndef _WIN32
+OM_uint32 KRB5_CALLCONV
+gss_pname_to_uid
+ (OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_OID mech_type,
+ uid_t *uidOut);
+#endif
+
+/**
+ * Provides a platform-specific name for a GSSAPI name as interpreted by a
+ * given mechanism.
+ *
+ * @param [out] minor Minor status code
+ * @param [in] name The gss name resulting from accept_sec_context
+ * @param [in] mech_type The mechanism that will be asked to map @a name to a
+ * local name
+ * @param [out] localname Caller-allocated buffer to be filled in with the
+ * local name on success
+ */
+OM_uint32 KRB5_CALLCONV
+gss_localname
+ (OM_uint32 *minor,
+ const gss_name_t name,
+ gss_const_OID mech_type,
+ gss_buffer_t localname);
+
+/**
+ * Determine whether a mechanism name is authorized to act as a username.
+ *
+ * @param [in] name Mechanism name
+ * @param [in] username System username
+ *
+ * This is a simple wrapper around gss_authorize_localname(). It only supports
+ * system usernames as local names, and cannot distinguish between lack of
+ * authorization and other errors.
+ *
+ * @retval 1 @a name is authorized to act as @a username
+ * @retval 0 @a name is not authorized or an error occurred
+ */
+int KRB5_CALLCONV
+gss_userok(const gss_name_t name,
+ const char *username);
+
+/**
+ * Determine whether a mechanism name is authorized to act as a local name.
+ *
+ * @param [out] minor Minor status code
+ * @param [in] name Mechanism name
+ * @param [in] user Local name
+ *
+ * @a name is a mechanism name, typically the result of a completed
+ * gss_accept_sec_context(). @a user is an internal name representing a local
+ * name, such as a name imported by gss_import_name() with an @a
+ * input_name_type of @c GSS_C_NT_USER_NAME.
+ *
+ * @return Return GSS_S_COMPLETE if @a name is authorized to act as @a user,
+ * GSS_S_UNAUTHORIZED if not, or an appropriate GSS error code if an error
+ * occured.
+ *
+ * @sa gss_userok
+ */
+OM_uint32 KRB5_CALLCONV
+gss_authorize_localname(OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_name_t user);
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_with_password(
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* desired_name */
+ const gss_buffer_t, /* password */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_with_password(
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t,/* input_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ const gss_buffer_t, /* password */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 *); /* acceptor_time_rec */
+
+/*
+ * GGF extensions
+ */
+typedef struct gss_buffer_set_desc_struct {
+ size_t count;
+ gss_buffer_desc *elements;
+} gss_buffer_set_desc, *gss_buffer_set_t;
+
+#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t) 0)
+
+OM_uint32 KRB5_CALLCONV gss_create_empty_buffer_set
+ (OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 KRB5_CALLCONV gss_add_buffer_set_member
+ (OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*member_buffer*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 KRB5_CALLCONV gss_release_buffer_set
+ (OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 KRB5_CALLCONV gss_inquire_sec_context_by_oid
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t * /*data_set*/);
+
+OM_uint32 KRB5_CALLCONV gss_inquire_cred_by_oid
+ (OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t * /*data_set*/);
+
+OM_uint32 KRB5_CALLCONV gss_set_sec_context_option
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32 KRB5_CALLCONV gss_set_cred_option
+ (OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * /*cred*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32 KRB5_CALLCONV gssspi_mech_invoke
+ (OM_uint32 * /*minor_status*/,
+ const gss_OID /*desired_mech*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_t /*value*/);
+
+/*
+ * AEAD extensions
+ */
+
+OM_uint32 KRB5_CALLCONV gss_wrap_aead
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ gss_buffer_t /*input_assoc_buffer*/,
+ gss_buffer_t /*input_payload_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t /*output_message_buffer*/);
+
+OM_uint32 KRB5_CALLCONV gss_unwrap_aead
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*input_assoc_buffer*/,
+ gss_buffer_t /*output_payload_buffer*/,
+ int * /*conf_state*/,
+ gss_qop_t * /*qop_state*/);
+
+/*
+ * SSPI extensions
+ */
+#define GSS_C_DCE_STYLE 0x1000
+#define GSS_C_IDENTIFY_FLAG 0x2000
+#define GSS_C_EXTENDED_ERROR_FLAG 0x4000
+
+/*
+ * Returns a buffer set with the first member containing the
+ * session key for SSPI compatibility. The optional second
+ * member contains an OID identifying the session key type.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_INQ_SSPI_SESSION_KEY;
+
+OM_uint32 KRB5_CALLCONV gss_complete_auth_token
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer);
+
+typedef struct gss_iov_buffer_desc_struct {
+ OM_uint32 type;
+ gss_buffer_desc buffer;
+} gss_iov_buffer_desc, *gss_iov_buffer_t;
+
+#define GSS_C_NO_IOV_BUFFER ((gss_iov_buffer_t)0)
+
+#define GSS_IOV_BUFFER_TYPE_EMPTY 0
+#define GSS_IOV_BUFFER_TYPE_DATA 1 /* Packet data */
+#define GSS_IOV_BUFFER_TYPE_HEADER 2 /* Mechanism header */
+#define GSS_IOV_BUFFER_TYPE_MECH_PARAMS 3 /* Mechanism specific parameters */
+#define GSS_IOV_BUFFER_TYPE_TRAILER 7 /* Mechanism trailer */
+#define GSS_IOV_BUFFER_TYPE_PADDING 9 /* Padding */
+#define GSS_IOV_BUFFER_TYPE_STREAM 10 /* Complete wrap token */
+#define GSS_IOV_BUFFER_TYPE_SIGN_ONLY 11 /* Sign only packet data */
+#define GSS_IOV_BUFFER_TYPE_MIC_TOKEN 12 /* MIC token destination */
+
+#define GSS_IOV_BUFFER_FLAG_MASK 0xFFFF0000
+#define GSS_IOV_BUFFER_FLAG_ALLOCATE 0x00010000 /* indicates GSS should allocate */
+#define GSS_IOV_BUFFER_FLAG_ALLOCATED 0x00020000 /* indicates caller should free */
+
+#define GSS_IOV_BUFFER_TYPE(_type) ((_type) & ~(GSS_IOV_BUFFER_FLAG_MASK))
+#define GSS_IOV_BUFFER_FLAGS(_type) ((_type) & GSS_IOV_BUFFER_FLAG_MASK)
+
+/*
+ * Sign and optionally encrypt a sequence of buffers. The buffers
+ * shall be ordered HEADER | DATA | PADDING | TRAILER. Suitable
+ * space for the header, padding and trailer should be provided
+ * by calling gss_wrap_iov_length(), or the ALLOCATE flag should
+ * be set on those buffers.
+ *
+ * Encryption is in-place. SIGN_ONLY buffers are untouched. Only
+ * a single PADDING buffer should be provided. The order of the
+ * buffers in memory does not matter. Buffers in the IOV should
+ * be arranged in the order above, and in the case of multiple
+ * DATA buffers the sender and receiver should agree on the
+ * order.
+ *
+ * With GSS_C_DCE_STYLE it is acceptable to not provide PADDING
+ * and TRAILER, but the caller must guarantee the plaintext data
+ * being encrypted is correctly padded, otherwise an error will
+ * be returned.
+ *
+ * While applications that have knowledge of the underlying
+ * cryptosystem may request a specific configuration of data
+ * buffers, the only generally supported configurations are:
+ *
+ * HEADER | DATA | PADDING | TRAILER
+ *
+ * which will emit GSS_Wrap() compatible tokens, and:
+ *
+ * HEADER | SIGN_ONLY | DATA | PADDING | TRAILER
+ *
+ * for AEAD.
+ *
+ * The typical (special cased) usage for DCE is as follows:
+ *
+ * SIGN_ONLY_1 | DATA | SIGN_ONLY_2 | HEADER
+ */
+OM_uint32 KRB5_CALLCONV gss_wrap_iov
+(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ int *, /* conf_state */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Verify and optionally decrypt a sequence of buffers. To process
+ * a GSS-API message without separate buffer, pass STREAM | DATA.
+ * Upon return DATA will contain the decrypted or integrity
+ * protected message. Only a single DATA buffer may be provided
+ * with this usage. DATA by default will point into STREAM, but if
+ * the ALLOCATE flag is set a copy will be returned.
+ *
+ * Otherwise, decryption is in-place. SIGN_ONLY buffers are
+ * untouched.
+ */
+OM_uint32 KRB5_CALLCONV gss_unwrap_iov
+(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int *, /* conf_state */
+ gss_qop_t *, /* qop_state */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Query HEADER, PADDING and TRAILER buffer lengths. DATA buffers
+ * should be provided so the correct padding length can be determined.
+ */
+OM_uint32 KRB5_CALLCONV gss_wrap_iov_length
+(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ int *, /* conf_state */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Produce a GSSAPI MIC token for a sequence of buffers. All SIGN_ONLY and
+ * DATA buffers will be signed, in the order they appear. One MIC_TOKEN buffer
+ * must be included for the result. Suitable space should be provided for the
+ * MIC_TOKEN buffer by calling gss_get_mic_iov_length, or the ALLOCATE flag
+ * should be set on that buffer. If the ALLOCATE flag is used, use
+ * gss_release_iov_buffer to free the allocated buffer within the iov list when
+ * it is no longer needed.
+ */
+OM_uint32 KRB5_CALLCONV gss_get_mic_iov
+(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Query the MIC_TOKEN buffer length within the iov list.
+ */
+OM_uint32 KRB5_CALLCONV gss_get_mic_iov_length(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Verify the MIC_TOKEN buffer within the iov list against the SIGN_ONLY and
+ * DATA buffers in the order they appear. Return values are the same as for
+ * gss_verify_mic.
+ */
+OM_uint32 KRB5_CALLCONV gss_verify_mic_iov
+(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t *, /* qop_state */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Release buffers that have the ALLOCATED flag set.
+ */
+OM_uint32 KRB5_CALLCONV gss_release_iov_buffer
+(
+ OM_uint32 *, /* minor_status */
+ gss_iov_buffer_desc *, /* iov */
+ int); /* iov_count */
+
+/*
+ * Protocol transition
+ */
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_impersonate_name(
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* impersonator_cred_handle */
+ const gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_impersonate_name(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ const gss_cred_id_t, /* impersonator_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 *); /* acceptor_time_rec */
+
+/*
+ * Naming extensions
+ */
+GSS_DLLIMP extern gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER;
+GSS_DLLIMP extern gss_OID GSS_C_NT_COMPOSITE_EXPORT;
+
+OM_uint32 KRB5_CALLCONV gss_display_name_ext
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_OID, /* display_as_name_type */
+ gss_buffer_t /* display_name */
+);
+
+OM_uint32 KRB5_CALLCONV gss_inquire_name
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int *, /* name_is_MN */
+ gss_OID *, /* MN_mech */
+ gss_buffer_set_t * /* attrs */
+);
+
+OM_uint32 KRB5_CALLCONV gss_get_name_attribute
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* attr */
+ int *, /* authenticated */
+ int *, /* complete */
+ gss_buffer_t, /* value */
+ gss_buffer_t, /* display_value */
+ int * /* more */
+);
+
+OM_uint32 KRB5_CALLCONV gss_set_name_attribute
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* complete */
+ gss_buffer_t, /* attr */
+ gss_buffer_t /* value */
+);
+
+OM_uint32 KRB5_CALLCONV gss_delete_name_attribute
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* attr */
+);
+
+OM_uint32 KRB5_CALLCONV gss_export_name_composite
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* exp_composite_name */
+);
+
+typedef struct gss_any *gss_any_t;
+
+OM_uint32 KRB5_CALLCONV gss_map_name_to_any
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* authenticated */
+ gss_buffer_t, /* type_id */
+ gss_any_t * /* output */
+);
+
+OM_uint32 KRB5_CALLCONV gss_release_any_name_mapping
+(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* type_id */
+ gss_any_t * /* input */
+);
+
+/* draft-josefsson-gss-capsulate */
+OM_uint32 KRB5_CALLCONV gss_encapsulate_token
+(
+ gss_const_buffer_t, /* input_token */
+ gss_const_OID, /* token_oid */
+ gss_buffer_t /* output_token */
+);
+
+OM_uint32 KRB5_CALLCONV gss_decapsulate_token
+(
+ gss_const_buffer_t, /* input_token */
+ gss_const_OID, /* token_oid */
+ gss_buffer_t /* output_token */
+);
+
+int KRB5_CALLCONV gss_oid_equal
+(
+ gss_const_OID, /* first_oid */
+ gss_const_OID /* second_oid */
+);
+
+/* Credential store extensions */
+
+struct gss_key_value_element_struct {
+ const char *key;
+ const char *value;
+};
+typedef struct gss_key_value_element_struct gss_key_value_element_desc;
+
+struct gss_key_value_set_struct {
+ OM_uint32 count;
+ gss_key_value_element_desc *elements;
+};
+typedef struct gss_key_value_set_struct gss_key_value_set_desc;
+typedef const gss_key_value_set_desc *gss_const_key_value_set_t;
+
+#define GSS_C_NO_CRED_STORE ((gss_const_key_value_set_t) 0)
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_name_t, /* desired_name */
+ gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 *); /* acceptor_time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t *); /* cred_usage_stored */
+
+OM_uint32 KRB5_CALLCONV
+gss_export_cred(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_buffer_t); /* token */
+
+OM_uint32 KRB5_CALLCONV
+gss_import_cred(
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* token */
+ gss_cred_id_t *); /* cred_handle */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GSSAPI_EXT_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
new file mode 100644
index 000000000000..5496aa33582c
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -0,0 +1,450 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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"
+
+/*
+ * See krb5/gssapi_krb5.c for a description of the algorithm for
+ * encoding an object identifier.
+ */
+
+/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744. */
+
+#define oids ((gss_OID_desc *)const_oids)
+static const gss_OID_desc const_oids[] = {
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) Unites States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) service_name(4)}.
+ * The constant GSS_C_NT_HOSTBASED_SERVICE should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ /* corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ /* corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x06"},
+ /* corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 6(gss-composite-export)}. The constant
+ * GSS_C_NT_COMPOSITE_EXPORT should be initialized to point
+ * to that gss_OID_desc.
+ */
+ /* GSS_C_INQ_SSPI_SESSION_KEY 1.2.840.113554.1.2.2.5.5 */
+ {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"},
+
+ /* RFC 5587 attributes, see below */
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x01"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x02"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x03"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x04"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x05"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x06"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x07"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x08"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x09"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0a"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0b"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0c"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0d"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0e"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0f"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x10"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x11"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x12"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x13"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x14"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x15"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x16"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x17"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x18"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"},
+ {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"},
+};
+
+/* Here are the constants which point to the static structure above.
+ *
+ * Constants of the form GSS_C_NT_* are specified by rfc 2744.
+ *
+ * Constants of the form gss_nt_* are the original MIT krb5 names
+ * found in gssapi_generic.h. They are provided for compatibility. */
+
+GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = oids+0;
+GSS_DLLIMP gss_OID gss_nt_user_name = oids+0;
+
+GSS_DLLIMP gss_OID GSS_C_NT_MACHINE_UID_NAME = oids+1;
+GSS_DLLIMP gss_OID gss_nt_machine_uid_name = oids+1;
+
+GSS_DLLIMP gss_OID GSS_C_NT_STRING_UID_NAME = oids+2;
+GSS_DLLIMP gss_OID gss_nt_string_uid_name = oids+2;
+
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3;
+gss_OID gss_nt_service_name_v2 = oids+3;
+
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE = oids+4;
+GSS_DLLIMP gss_OID gss_nt_service_name = oids+4;
+
+GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS = oids+5;
+
+GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME = oids+6;
+gss_OID gss_nt_exported_name = oids+6;
+
+GSS_DLLIMP gss_OID GSS_C_NT_COMPOSITE_EXPORT = oids+7;
+
+GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY = oids+8;
+
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_CONCRETE = oids+9;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_PSEUDO = oids+10;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_COMPOSITE = oids+11;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_NEGO = oids+12;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_GLUE = oids+13;
+GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_MECH = oids+14;
+GSS_DLLIMP gss_const_OID GSS_C_MA_DEPRECATED = oids+15;
+GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_DFLT_MECH = oids+16;
+GSS_DLLIMP gss_const_OID GSS_C_MA_ITOK_FRAMED = oids+17;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT = oids+18;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG = oids+19;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_INIT = oids+20;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_INIT = oids+21;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_ANON = oids+22;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_ANON = oids+23;
+GSS_DLLIMP gss_const_OID GSS_C_MA_DELEG_CRED = oids+24;
+GSS_DLLIMP gss_const_OID GSS_C_MA_INTEG_PROT = oids+25;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CONF_PROT = oids+26;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MIC = oids+27;
+GSS_DLLIMP gss_const_OID GSS_C_MA_WRAP = oids+28;
+GSS_DLLIMP gss_const_OID GSS_C_MA_PROT_READY = oids+29;
+GSS_DLLIMP gss_const_OID GSS_C_MA_REPLAY_DET = oids+30;
+GSS_DLLIMP gss_const_OID GSS_C_MA_OOS_DET = oids+31;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CBINDINGS = oids+32;
+GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33;
+GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35;
+
+static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 };
+gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc;
+
+static struct mech_attr_info_desc {
+ gss_OID mech_attr;
+ const char *name;
+ const char *short_desc;
+ const char *long_desc;
+} mech_attr_info[] = {
+ {
+ oids+9,
+ "GSS_C_MA_MECH_CONCRETE",
+ "concrete-mech",
+ "Mechanism is neither a pseudo-mechanism nor a composite mechanism.",
+ },
+ {
+ oids+10,
+ "GSS_C_MA_MECH_PSEUDO",
+ "pseudo-mech",
+ "Mechanism is a pseudo-mechanism.",
+ },
+ {
+ oids+11,
+ "GSS_C_MA_MECH_COMPOSITE",
+ "composite-mech",
+ "Mechanism is a composite of other mechanisms.",
+ },
+ {
+ oids+12,
+ "GSS_C_MA_MECH_NEGO",
+ "mech-negotiation-mech",
+ "Mechanism negotiates other mechanisms.",
+ },
+ {
+ oids+13,
+ "GSS_C_MA_MECH_GLUE",
+ "mech-glue",
+ "OID is not a mechanism but the GSS-API itself.",
+ },
+ {
+ oids+14,
+ "GSS_C_MA_NOT_MECH",
+ "not-mech",
+ "Known OID but not a mechanism OID.",
+ },
+ {
+ oids+15,
+ "GSS_C_MA_DEPRECATED",
+ "mech-deprecated",
+ "Mechanism is deprecated.",
+ },
+ {
+ oids+16,
+ "GSS_C_MA_NOT_DFLT_MECH",
+ "mech-not-default",
+ "Mechanism must not be used as a default mechanism.",
+ },
+ {
+ oids+17,
+ "GSS_C_MA_ITOK_FRAMED",
+ "initial-is-framed",
+ "Mechanism's initial contexts are properly framed.",
+ },
+ {
+ oids+18,
+ "GSS_C_MA_AUTH_INIT",
+ "auth-init-princ",
+ "Mechanism supports authentication of initiator to acceptor.",
+ },
+ {
+ oids+19,
+ "GSS_C_MA_AUTH_TARG",
+ "auth-targ-princ",
+ "Mechanism supports authentication of acceptor to initiator.",
+ },
+ {
+ oids+20,
+ "GSS_C_MA_AUTH_INIT_INIT",
+ "auth-init-princ-initial",
+ "Mechanism supports authentication of initiator using "
+ "initial credentials.",
+ },
+ {
+ oids+21,
+ "GSS_C_MA_AUTH_TARG_INIT",
+ "auth-target-princ-initial",
+ "Mechanism supports authentication of acceptor using "
+ "initial credentials.",
+ },
+ {
+ oids+22,
+ "GSS_C_MA_AUTH_INIT_ANON",
+ "auth-init-princ-anon",
+ "Mechanism supports GSS_C_NT_ANONYMOUS as an initiator name.",
+ },
+ {
+ oids+23,
+ "GSS_C_MA_AUTH_TARG_ANON",
+ "auth-targ-princ-anon",
+ "Mechanism supports GSS_C_NT_ANONYMOUS as an acceptor name.",
+ },
+ {
+ oids+24,
+ "GSS_C_MA_DELEG_CRED",
+ "deleg-cred",
+ "Mechanism supports credential delegation.",
+ },
+ {
+ oids+25,
+ "GSS_C_MA_INTEG_PROT",
+ "integ-prot",
+ "Mechanism supports per-message integrity protection.",
+ },
+ {
+ oids+26,
+ "GSS_C_MA_CONF_PROT",
+ "conf-prot",
+ "Mechanism supports per-message confidentiality protection.",
+ },
+ {
+ oids+27,
+ "GSS_C_MA_MIC",
+ "mic",
+ "Mechanism supports Message Integrity Code (MIC) tokens.",
+ },
+ {
+ oids+28,
+ "GSS_C_MA_WRAP",
+ "wrap",
+ "Mechanism supports wrap tokens.",
+ },
+ {
+ oids+29,
+ "GSS_C_MA_PROT_READY",
+ "prot-ready",
+ "Mechanism supports per-message proteciton prior to "
+ "full context establishment.",
+ },
+ {
+ oids+30,
+ "GSS_C_MA_REPLAY_DET",
+ "replay-detection",
+ "Mechanism supports replay detection.",
+ },
+ {
+ oids+31,
+ "GSS_C_MA_OOS_DET",
+ "oos-detection",
+ "Mechanism supports out-of-sequence detection.",
+ },
+ {
+ oids+32,
+ "GSS_C_MA_CBINDINGS",
+ "channel-bindings",
+ "Mechanism supports channel bindings.",
+ },
+ {
+ oids+33,
+ "GSS_C_MA_PFS",
+ "pfs",
+ "Mechanism supports Perfect Forward Security.",
+ },
+ {
+ oids+34,
+ "GSS_C_MA_COMPRESS",
+ "compress",
+ "Mechanism supports compression of data inputs to gss_wrap().",
+ },
+ {
+ oids+35,
+ "GSS_C_MA_CTX_TRANS",
+ "context-transfer",
+ "Mechanism supports security context export/import.",
+ },
+};
+
+OM_uint32
+generic_gss_display_mech_attr(
+ OM_uint32 *minor_status,
+ gss_const_OID mech_attr,
+ gss_buffer_t name,
+ gss_buffer_t short_desc,
+ gss_buffer_t long_desc)
+{
+ size_t i;
+
+ if (name != GSS_C_NO_BUFFER) {
+ name->length = 0;
+ name->value = NULL;
+ }
+ if (short_desc != GSS_C_NO_BUFFER) {
+ short_desc->length = 0;
+ short_desc->value = NULL;
+ }
+ if (long_desc != GSS_C_NO_BUFFER) {
+ long_desc->length = 0;
+ long_desc->value = NULL;
+ }
+ for (i = 0; i < sizeof(mech_attr_info)/sizeof(mech_attr_info[0]); i++) {
+ struct mech_attr_info_desc *mai = &mech_attr_info[i];
+
+ if (g_OID_equal(mech_attr, mai->mech_attr)) {
+ if (name != GSS_C_NO_BUFFER &&
+ !g_make_string_buffer(mai->name, name)) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ if (short_desc != GSS_C_NO_BUFFER &&
+ !g_make_string_buffer(mai->short_desc, short_desc)) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ if (long_desc != GSS_C_NO_BUFFER &&
+ !g_make_string_buffer(mai->long_desc, long_desc)) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ return GSS_S_COMPLETE;
+ }
+ }
+
+ return GSS_S_BAD_MECH_ATTR;
+}
+
+static gss_buffer_desc const_attrs[] = {
+ { sizeof("local-login-user") - 1,
+ "local-login-user" },
+};
+
+GSS_DLLIMP gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER = &const_attrs[0];
diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h
new file mode 100644
index 000000000000..e11f938c672b
--- /dev/null
+++ b/src/lib/gssapi/generic/gssapi_generic.h
@@ -0,0 +1,59 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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>
+
+#if defined(__cplusplus) && !defined(GSSAPIGENERIC_BEGIN_DECLS)
+#define GSSAPIGENERIC_BEGIN_DECLS extern "C" {
+#define GSSAPIGENERIC_END_DECLS }
+#else
+#define GSSAPIGENERIC_BEGIN_DECLS
+#define GSSAPIGENERIC_END_DECLS
+#endif
+
+#define GSS_EMPTY_BUFFER(buf) ((buf) == NULL || \
+ (buf)->value == NULL || (buf)->length == 0)
+
+GSSAPIGENERIC_BEGIN_DECLS
+
+/* Deprecated MIT krb5 oid names provided for compatibility.
+ * The correct oids (GSS_C_NT_USER_NAME, etc) from rfc 2744
+ * are defined in gssapi.h. */
+
+GSS_DLLIMP extern gss_OID gss_nt_user_name;
+GSS_DLLIMP extern gss_OID gss_nt_machine_uid_name;
+GSS_DLLIMP extern gss_OID gss_nt_string_uid_name;
+extern gss_OID gss_nt_service_name_v2;
+GSS_DLLIMP extern gss_OID gss_nt_service_name;
+extern gss_OID gss_nt_exported_name;
+
+GSSAPIGENERIC_END_DECLS
+
+#endif /* _GSSAPI_GENERIC_H_ */
diff --git a/src/lib/gssapi/generic/maptest.c b/src/lib/gssapi/generic/maptest.c
new file mode 100644
index 000000000000..566d88c316f1
--- /dev/null
+++ b/src/lib/gssapi/generic/maptest.c
@@ -0,0 +1,68 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+typedef struct { int a, b; } elt;
+static int eltcp(elt *dest, elt src)
+{
+ *dest = src;
+ return 0;
+}
+static int eltcmp(elt left, elt right)
+{
+ if (left.a < right.a)
+ return -1;
+ if (left.a > right.a)
+ return 1;
+ if (left.b < right.b)
+ return -1;
+ if (left.b > right.b)
+ return 1;
+ return 0;
+}
+static void eltprt(elt v, FILE *f)
+{
+ fprintf(f, "{%d,%d}", v.a, v.b);
+}
+static int intcmp(int left, int right)
+{
+ if (left < right)
+ return -1;
+ if (left > right)
+ return 1;
+ return 0;
+}
+static void intprt(int v, FILE *f)
+{
+ fprintf(f, "%d", v);
+}
+
+#include "maptest.h"
+
+foo foo1;
+
+int main ()
+{
+ elt v1 = { 1, 2 }, v2 = { 3, 4 };
+ const elt *vp;
+ const int *ip;
+
+ assert(0 == foo_init(&foo1));
+ vp = foo_findleft(&foo1, 47);
+ assert(vp == NULL);
+ assert(0 == foo_add(&foo1, 47, v1));
+ vp = foo_findleft(&foo1, 47);
+ assert(vp != NULL);
+ assert(0 == eltcmp(*vp, v1));
+ vp = foo_findleft(&foo1, 3);
+ assert(vp == NULL);
+ assert(0 == foo_add(&foo1, 93, v2));
+ ip = foo_findright(&foo1, v1);
+ assert(ip != NULL);
+ assert(*ip == 47);
+ printf("Map content: ");
+ foo_printmap(&foo1, stdout);
+ printf("\n");
+ return 0;
+}
diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c
new file mode 100644
index 000000000000..6e294b9bcf94
--- /dev/null
+++ b/src/lib/gssapi/generic/oid_ops.c
@@ -0,0 +1,553 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/generic/oid_ops.c */
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * 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.
+ */
+
+/* GSS-API V2 interfaces to manipulate OIDs */
+
+#include "gssapiP_generic.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <gssapi/gssapi_generic.h>
+#include <errno.h>
+#include <ctype.h>
+
+/*
+ * The functions for allocating and releasing individual OIDs use malloc and
+ * free instead of the gssalloc wrappers, because the mechglue currently mixes
+ * generic_gss_copy_oid() with hand-freeing of OIDs. We do not need to free
+ * free OIDs allocated by mechanisms, so this should not be a problem.
+ */
+
+OM_uint32
+generic_gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
+{
+ if (minor_status)
+ *minor_status = 0;
+
+ if (oid == NULL || *oid == GSS_C_NO_OID)
+ return(GSS_S_COMPLETE);
+
+ /*
+ * The V2 API says the following!
+ *
+ * gss_release_oid[()] will recognize any of the GSSAPI's own OID values,
+ * and will silently ignore attempts to free these OIDs; for other OIDs
+ * it will call the C free() routine for both the OID data and the
+ * descriptor. This allows applications to freely mix their own heap-
+ * allocated OID values with OIDs returned by GSS-API.
+ */
+
+ /*
+ * We use the official OID definitions instead of the unofficial OID
+ * defintions. But we continue to support the unofficial OID
+ * gss_nt_service_name just in case if some gss applications use
+ * the old OID.
+ */
+
+ if ((*oid != GSS_C_NT_USER_NAME) &&
+ (*oid != GSS_C_NT_MACHINE_UID_NAME) &&
+ (*oid != GSS_C_NT_STRING_UID_NAME) &&
+ (*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
+ (*oid != GSS_C_NT_ANONYMOUS) &&
+ (*oid != GSS_C_NT_EXPORT_NAME) &&
+ (*oid != GSS_C_NT_COMPOSITE_EXPORT) &&
+ (*oid != gss_nt_service_name)) {
+ free((*oid)->elements);
+ free(*oid);
+ }
+ *oid = GSS_C_NO_OID;
+ return(GSS_S_COMPLETE);
+}
+
+OM_uint32
+generic_gss_copy_oid(OM_uint32 *minor_status,
+ const gss_OID_desc * const oid,
+ gss_OID *new_oid)
+{
+ gss_OID p;
+
+ *minor_status = 0;
+
+ p = (gss_OID) malloc(sizeof(gss_OID_desc));
+ if (!p) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ p->length = oid->length;
+ p->elements = malloc(p->length);
+ if (!p->elements) {
+ free(p);
+ return GSS_S_FAILURE;
+ }
+ memcpy(p->elements, oid->elements, p->length);
+ *new_oid = p;
+ return(GSS_S_COMPLETE);
+}
+
+
+OM_uint32
+generic_gss_create_empty_oid_set(OM_uint32 *minor_status, gss_OID_set *oid_set)
+{
+ *minor_status = 0;
+
+ if (oid_set == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if ((*oid_set = (gss_OID_set) gssalloc_malloc(sizeof(gss_OID_set_desc)))) {
+ memset(*oid_set, 0, sizeof(gss_OID_set_desc));
+ return(GSS_S_COMPLETE);
+ }
+ else {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+}
+
+OM_uint32
+generic_gss_add_oid_set_member(OM_uint32 *minor_status,
+ const gss_OID_desc * const member_oid,
+ gss_OID_set *oid_set)
+{
+ gss_OID elist;
+ gss_OID lastel;
+
+ *minor_status = 0;
+
+ if (member_oid == NULL || member_oid->length == 0 ||
+ member_oid->elements == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (oid_set == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ elist = (*oid_set)->elements;
+ /* Get an enlarged copy of the array */
+ if (((*oid_set)->elements = (gss_OID) gssalloc_malloc(((*oid_set)->count+1) *
+ sizeof(gss_OID_desc)))) {
+ /* Copy in the old junk */
+ if (elist)
+ memcpy((*oid_set)->elements,
+ elist,
+ ((*oid_set)->count * sizeof(gss_OID_desc)));
+
+ /* Duplicate the input element */
+ lastel = &(*oid_set)->elements[(*oid_set)->count];
+ if ((lastel->elements =
+ (void *) gssalloc_malloc((size_t) member_oid->length))) {
+ /* Success - copy elements */
+ memcpy(lastel->elements, member_oid->elements,
+ (size_t) member_oid->length);
+ /* Set length */
+ lastel->length = member_oid->length;
+
+ /* Update count */
+ (*oid_set)->count++;
+ if (elist)
+ gssalloc_free(elist);
+ *minor_status = 0;
+ return(GSS_S_COMPLETE);
+ }
+ else
+ gssalloc_free((*oid_set)->elements);
+ }
+ /* Failure - restore old contents of list */
+ (*oid_set)->elements = elist;
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+}
+
+OM_uint32
+generic_gss_test_oid_set_member(OM_uint32 *minor_status,
+ const gss_OID_desc * const member,
+ gss_OID_set set,
+ int * present)
+{
+ OM_uint32 i;
+ int result;
+
+ *minor_status = 0;
+
+ if (member == NULL || set == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (present == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ result = 0;
+ for (i=0; i<set->count; i++) {
+ if ((set->elements[i].length == member->length) &&
+ !memcmp(set->elements[i].elements,
+ member->elements,
+ (size_t) member->length)) {
+ result = 1;
+ break;
+ }
+ }
+ *present = result;
+ return(GSS_S_COMPLETE);
+}
+
+OM_uint32
+generic_gss_oid_to_str(OM_uint32 *minor_status,
+ const gss_OID_desc * const oid,
+ gss_buffer_t oid_str)
+{
+ unsigned long number, n;
+ OM_uint32 i;
+ int first;
+ unsigned char *cp;
+ struct k5buf buf;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (oid_str != GSS_C_NO_BUFFER) {
+ oid_str->length = 0;
+ oid_str->value = NULL;
+ }
+
+ if (oid == NULL || oid->length == 0 || oid->elements == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (oid_str == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /* Decoded according to krb5/gssapi_krb5.c */
+
+ cp = (unsigned char *) oid->elements;
+ number = (unsigned long) cp[0];
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add(&buf, "{ ");
+ number = 0;
+ cp = (unsigned char *) oid->elements;
+ first = 1;
+ for (i = 0; i < oid->length; i++) {
+ number = (number << 7) | (cp[i] & 0x7f);
+ if ((cp[i] & 0x80) == 0) {
+ if (first) {
+ n = (number < 40) ? 0 : (number < 80) ? 1 : 2;
+ k5_buf_add_fmt(&buf, "%lu %lu ", n, number - (n * 40));
+ first = 0;
+ } else {
+ k5_buf_add_fmt(&buf, "%lu ", number);
+ }
+ number = 0;
+ }
+ }
+ k5_buf_add_len(&buf, "}\0", 2);
+ return k5buf_to_gss(minor_status, &buf, oid_str);
+}
+
+/* Return the length of a DER OID subidentifier encoding. */
+static size_t
+arc_encoded_length(unsigned long arc)
+{
+ size_t len = 1;
+
+ for (arc >>= 7; arc; arc >>= 7)
+ len++;
+ return len;
+}
+
+/* Encode a subidentifier into *bufp and advance it to the encoding's end. */
+static void
+arc_encode(unsigned long arc, unsigned char **bufp)
+{
+ unsigned char *p;
+
+ /* Advance to the end and encode backwards. */
+ p = *bufp = *bufp + arc_encoded_length(arc);
+ *--p = arc & 0x7f;
+ for (arc >>= 7; arc; arc >>= 7)
+ *--p = (arc & 0x7f) | 0x80;
+}
+
+/* Fetch an arc value from *bufp and advance past it and any following spaces
+ * or periods. Return 1 on success, 0 if *bufp is not at a valid arc value. */
+static int
+get_arc(const unsigned char **bufp, const unsigned char *end,
+ unsigned long *arc_out)
+{
+ const unsigned char *p = *bufp;
+ unsigned long arc = 0, newval;
+
+ if (p == end || !isdigit(*p))
+ return 0;
+ for (; p < end && isdigit(*p); p++) {
+ newval = arc * 10 + (*p - '0');
+ if (newval < arc)
+ return 0;
+ arc = newval;
+ }
+ while (p < end && (isspace(*p) || *p == '.'))
+ p++;
+ *bufp = p;
+ *arc_out = arc;
+ return 1;
+}
+
+/*
+ * Convert a sequence of two or more decimal arc values into a DER-encoded OID.
+ * The values may be separated by any combination of whitespace and period
+ * characters, and may be optionally surrounded with braces. Leading
+ * whitespace and trailing garbage is allowed. The first arc value must be 0,
+ * 1, or 2, and the second value must be less than 40 if the first value is not
+ * 2.
+ */
+OM_uint32
+generic_gss_str_to_oid(OM_uint32 *minor_status,
+ gss_buffer_t oid_str,
+ gss_OID *oid_out)
+{
+ const unsigned char *p, *end, *arc3_start;
+ unsigned char *out;
+ unsigned long arc, arc1, arc2;
+ size_t nbytes;
+ int brace = 0;
+ gss_OID oid;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (oid_out != NULL)
+ *oid_out = GSS_C_NO_OID;
+
+ if (GSS_EMPTY_BUFFER(oid_str))
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (oid_out == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /* Skip past initial spaces and, optionally, an open brace. */
+ brace = 0;
+ p = oid_str->value;
+ end = p + oid_str->length;
+ while (p < end && isspace(*p))
+ p++;
+ if (p < end && *p == '{') {
+ brace = 1;
+ p++;
+ }
+ while (p < end && isspace(*p))
+ p++;
+
+ /* Get the first two arc values, to be encoded as one subidentifier. */
+ if (!get_arc(&p, end, &arc1) || !get_arc(&p, end, &arc2))
+ return (GSS_S_FAILURE);
+ if (arc1 > 2 || (arc1 < 2 && arc2 > 39) || arc2 > ULONG_MAX - 80)
+ return (GSS_S_FAILURE);
+ arc3_start = p;
+
+ /* Compute the total length of the encoding while checking syntax. */
+ nbytes = arc_encoded_length(arc1 * 40 + arc2);
+ while (get_arc(&p, end, &arc))
+ nbytes += arc_encoded_length(arc);
+ if (brace && (p == end || *p != '}'))
+ return (GSS_S_FAILURE);
+
+ /* Allocate an oid structure. */
+ oid = malloc(sizeof(*oid));
+ if (oid == NULL)
+ return (GSS_S_FAILURE);
+ oid->elements = malloc(nbytes);
+ if (oid->elements == NULL) {
+ free(oid);
+ return (GSS_S_FAILURE);
+ }
+ oid->length = nbytes;
+
+ out = oid->elements;
+ arc_encode(arc1 * 40 + arc2, &out);
+ p = arc3_start;
+ while (get_arc(&p, end, &arc))
+ arc_encode(arc, &out);
+ assert(out - nbytes == oid->elements);
+ *oid_out = oid;
+ return(GSS_S_COMPLETE);
+}
+
+/* Compose an OID of a prefix and an integer suffix */
+OM_uint32
+generic_gss_oid_compose(OM_uint32 *minor_status,
+ const char *prefix,
+ size_t prefix_len,
+ int suffix,
+ gss_OID_desc *oid)
+{
+ int osuffix, i;
+ size_t nbytes;
+ unsigned char *op;
+
+ if (oid == GSS_C_NO_OID) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ if (oid->length < prefix_len) {
+ *minor_status = ERANGE;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy(oid->elements, prefix, prefix_len);
+
+ nbytes = 0;
+ osuffix = suffix;
+ while (suffix) {
+ nbytes++;
+ suffix >>= 7;
+ }
+ suffix = osuffix;
+
+ if (oid->length < prefix_len + nbytes) {
+ *minor_status = ERANGE;
+ return GSS_S_FAILURE;
+ }
+
+ op = (unsigned char *) oid->elements + prefix_len + nbytes;
+ i = -1;
+ while (suffix) {
+ op[i] = (unsigned char)suffix & 0x7f;
+ if (i != -1)
+ op[i] |= 0x80;
+ i--;
+ suffix >>= 7;
+ }
+
+ oid->length = prefix_len + nbytes;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+generic_gss_oid_decompose(OM_uint32 *minor_status,
+ const char *prefix,
+ size_t prefix_len,
+ gss_OID_desc *oid,
+ int *suffix)
+{
+ size_t i, slen;
+ unsigned char *op;
+
+ if (oid->length < prefix_len ||
+ memcmp(oid->elements, prefix, prefix_len) != 0) {
+ return GSS_S_BAD_MECH;
+ }
+
+ op = (unsigned char *) oid->elements + prefix_len;
+
+ *suffix = 0;
+
+ slen = oid->length - prefix_len;
+
+ for (i = 0; i < slen; i++) {
+ *suffix = (*suffix << 7) | (op[i] & 0x7f);
+ if (i + 1 != slen && (op[i] & 0x80) == 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+generic_gss_copy_oid_set(OM_uint32 *minor_status,
+ const gss_OID_set_desc * const oidset,
+ gss_OID_set *new_oidset)
+{
+ gss_OID_set_desc *copy;
+ OM_uint32 minor = 0;
+ OM_uint32 major = GSS_S_COMPLETE;
+ OM_uint32 i;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (new_oidset != NULL)
+ *new_oidset = GSS_C_NO_OID_SET;
+
+ if (oidset == GSS_C_NO_OID_SET)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (new_oidset == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if ((copy = (gss_OID_set_desc *) gssalloc_calloc(1, sizeof (*copy))) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+
+ if ((copy->elements = (gss_OID_desc *)
+ gssalloc_calloc(oidset->count, sizeof (*copy->elements))) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+ copy->count = oidset->count;
+
+ for (i = 0; i < copy->count; i++) {
+ gss_OID_desc *out = &copy->elements[i];
+ gss_OID_desc *in = &oidset->elements[i];
+
+ if ((out->elements = (void *) gssalloc_malloc(in->length)) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+ (void) memcpy(out->elements, in->elements, in->length);
+ out->length = in->length;
+ }
+
+ *new_oidset = copy;
+done:
+ if (major != GSS_S_COMPLETE) {
+ (void) generic_gss_release_oid_set(&minor, &copy);
+ }
+
+ return (major);
+}
diff --git a/src/lib/gssapi/generic/rel_buffer.c b/src/lib/gssapi/generic/rel_buffer.c
new file mode 100644
index 000000000000..44dc98157b79
--- /dev/null
+++ b/src/lib/gssapi/generic/rel_buffer.c
@@ -0,0 +1,57 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* #ident "@(#)g_rel_buffer.c 1.2 96/02/06 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, 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 Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS 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.
+ */
+
+/*
+ * glue routine for gss_release_buffer
+ */
+
+#include "gssapiP_generic.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+OM_uint32
+generic_gss_release_buffer(
+ OM_uint32 *minor_status,
+ gss_buffer_t buffer)
+{
+ if (minor_status)
+ *minor_status = 0;
+
+ /* if buffer is NULL, return */
+
+ if (buffer == GSS_C_NO_BUFFER)
+ return(GSS_S_COMPLETE);
+
+ if (buffer->value) {
+ gssalloc_free(buffer->value);
+ buffer->length = 0;
+ buffer->value = NULL;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/generic/rel_oid_set.c b/src/lib/gssapi/generic/rel_oid_set.c
new file mode 100644
index 000000000000..954542e40754
--- /dev/null
+++ b/src/lib/gssapi/generic/rel_oid_set.c
@@ -0,0 +1,61 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* #ident "@(#)gss_release_oid_set.c 1.12 95/08/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, 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 Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS 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.
+ */
+
+/*
+ * glue routine for gss_release_oid_set
+ */
+
+#include "gssapiP_generic.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+OM_uint32
+generic_gss_release_oid_set(
+ OM_uint32 *minor_status,
+ gss_OID_set *set)
+{
+ size_t i;
+ if (minor_status)
+ *minor_status = 0;
+
+ if (set == NULL)
+ return(GSS_S_COMPLETE);
+
+ if (*set == GSS_C_NULL_OID_SET)
+ return(GSS_S_COMPLETE);
+
+ for (i=0; i<(*set)->count; i++)
+ gssalloc_free((*set)->elements[i].elements);
+
+ gssalloc_free((*set)->elements);
+ gssalloc_free(*set);
+
+ *set = GSS_C_NULL_OID_SET;
+
+ return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/generic/t_seqstate.c b/src/lib/gssapi/generic/t_seqstate.c
new file mode 100644
index 000000000000..8f44fcf3edb2
--- /dev/null
+++ b/src/lib/gssapi/generic/t_seqstate.c
@@ -0,0 +1,197 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/generic/t_seqstate.c - Test program for sequence number state */
+/*
+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gssapiP_generic.h"
+
+enum resultcode {
+ NOERR = GSS_S_COMPLETE,
+ GAP = GSS_S_GAP_TOKEN,
+ UNSEQ = GSS_S_UNSEQ_TOKEN,
+ OLD = GSS_S_OLD_TOKEN,
+ REPLAY = GSS_S_DUPLICATE_TOKEN
+};
+
+enum replayflag { NO_REPLAY = 0, DO_REPLAY = 1 };
+enum sequenceflag { NO_SEQUENCE = 0, DO_SEQUENCE = 1 };
+enum width { NARROW = 0, WIDE = 1, BOTH = 2 };
+
+struct test {
+ uint64_t initial;
+ enum replayflag do_replay;
+ enum sequenceflag do_sequence;
+ enum width wide_seqnums;
+ size_t nseqs;
+ struct {
+ uint64_t seqnum;
+ enum resultcode result;
+ } seqs[10];
+} tests[] = {
+ /* No replay or sequence checking. */
+ {
+ 10, NO_REPLAY, NO_SEQUENCE, BOTH,
+ 4, { { 11, NOERR }, { 10, NOERR }, { 10, NOERR }, { 9, NOERR } }
+ },
+
+ /* Basic sequence checking, no wraparound. */
+ {
+ 100, NO_REPLAY, DO_SEQUENCE, BOTH,
+ 4, { { 100, NOERR }, { 102, GAP }, { 103, NOERR }, { 101, UNSEQ } }
+ },
+
+ /* Initial gap sequence checking, no wraparound. */
+ {
+ 200, NO_REPLAY, DO_SEQUENCE, BOTH,
+ 4, { { 201, GAP }, { 202, NOERR }, { 200, UNSEQ }, { 203, NOERR } }
+ },
+
+ /* Sequence checking with wraparound. */
+ {
+ UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,
+ 4, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, NOERR },
+ { 1, NOERR } }
+ },
+ {
+ UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,
+ 4, { { UINT32_MAX - 1, NOERR }, { 0, GAP }, { UINT32_MAX, UNSEQ },
+ { 1, NOERR } }
+ },
+ {
+ UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
+ 4, { { UINT64_MAX - 1, NOERR }, { UINT64_MAX, NOERR }, { 0, NOERR },
+ { 1, NOERR } }
+ },
+ {
+ UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
+ 4, { { UINT64_MAX - 1, NOERR }, { 0, GAP }, { UINT64_MAX, UNSEQ },
+ { 1, NOERR } }
+ },
+
+ /* 64-bit sequence checking beyond 32-bit range */
+ {
+ UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
+ 4, { { UINT32_MAX - 1, NOERR },
+ { UINT32_MAX, NOERR },
+ { (uint64_t)UINT32_MAX + 1, NOERR },
+ { (uint64_t)UINT32_MAX + 2, NOERR } }
+ },
+ {
+ UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
+ 4, { { UINT32_MAX - 1, NOERR },
+ { (uint64_t)UINT32_MAX + 1, GAP },
+ { UINT32_MAX, UNSEQ },
+ { (uint64_t)UINT32_MAX + 2, NOERR } }
+ },
+ {
+ UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
+ 3, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, GAP } }
+ },
+
+ /* Replay without the replay flag set. */
+ {
+ 250, NO_REPLAY, DO_SEQUENCE, BOTH,
+ 2, { { 250, NOERR }, { 250, UNSEQ } }
+ },
+
+ /* Basic replay detection with and without sequence checking. */
+ {
+ 0, DO_REPLAY, DO_SEQUENCE, BOTH,
+ 10, { { 5, GAP }, { 3, UNSEQ }, { 8, GAP }, { 3, REPLAY },
+ { 0, UNSEQ }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },
+ { 8, REPLAY }, { 9, NOERR } }
+ },
+ {
+ 0, DO_REPLAY, NO_SEQUENCE, BOTH,
+ 10, { { 5, NOERR }, { 3, NOERR }, { 8, NOERR }, { 3, REPLAY },
+ { 0, NOERR }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },
+ { 8, REPLAY }, { 9, NOERR } }
+ },
+
+ /* Replay and sequence detection with wraparound. The last seqnum produces
+ * GAP because it is before the initial sequence number. */
+ {
+ UINT64_MAX - 5, DO_REPLAY, DO_SEQUENCE, WIDE,
+ 10, { { UINT64_MAX, GAP }, { UINT64_MAX - 2, UNSEQ }, { 0, NOERR },
+ { UINT64_MAX, REPLAY }, { UINT64_MAX, REPLAY },
+ { 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },
+ { UINT64_MAX - 2, REPLAY }, { UINT64_MAX - 6, GAP } }
+ },
+ {
+ UINT32_MAX - 5, DO_REPLAY, DO_SEQUENCE, NARROW,
+ 10, { { UINT32_MAX, GAP }, { UINT32_MAX - 2, UNSEQ }, { 0, NOERR },
+ { UINT32_MAX, REPLAY }, { UINT32_MAX, REPLAY },
+ { 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },
+ { UINT32_MAX - 2, REPLAY }, { UINT32_MAX - 6, GAP } }
+ },
+
+ /* Old token edge cases. The current code can detect replays up to 64
+ * numbers behind the expected sequence number (1164 in this case). */
+ {
+ 1000, DO_REPLAY, NO_SEQUENCE, BOTH,
+ 10, { { 1163, NOERR }, { 1100, NOERR }, { 1100, REPLAY },
+ { 1163, REPLAY }, { 1099, OLD }, { 1100, REPLAY },
+ { 1150, NOERR }, { 1150, REPLAY }, { 1000, OLD },
+ { 999, NOERR } }
+ },
+};
+
+int
+main()
+{
+ size_t i, j;
+ enum width w;
+ struct test *t;
+ g_seqnum_state seqstate;
+ OM_uint32 status;
+
+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
+ t = &tests[i];
+ /* Try both widths if t->wide_seqnums is both, otherwise just one. */
+ for (w = NARROW; w <= WIDE; w++) {
+ if (t->wide_seqnums != BOTH && t->wide_seqnums != w)
+ continue;
+ if (g_seqstate_init(&seqstate, t->initial, t->do_replay,
+ t->do_sequence, w))
+ abort();
+ for (j = 0; j < t->nseqs; j++) {
+ status = g_seqstate_check(seqstate, t->seqs[j].seqnum);
+ if (status != t->seqs[j].result) {
+ fprintf(stderr, "Test %d seq %d failed: %d != %d\n",
+ (int)i, (int)j, status, t->seqs[j].result);
+ return 1;
+ }
+ }
+ g_seqstate_free(seqstate);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/lib/gssapi/generic/util_buffer.c b/src/lib/gssapi/generic/util_buffer.c
new file mode 100644
index 000000000000..da2d83291370
--- /dev/null
+++ b/src/lib/gssapi/generic/util_buffer.c
@@ -0,0 +1,48 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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)
+{
+ if (buffer == GSS_C_NO_BUFFER)
+ return (1);
+
+ buffer->length = strlen(str);
+
+ if ((buffer->value = gssalloc_strdup(str)) == NULL) {
+ buffer->length = 0;
+ return(0);
+ }
+
+ return(1);
+}
diff --git a/src/lib/gssapi/generic/util_buffer_set.c b/src/lib/gssapi/generic/util_buffer_set.c
new file mode 100644
index 000000000000..f7472a0807ba
--- /dev/null
+++ b/src/lib/gssapi/generic/util_buffer_set.c
@@ -0,0 +1,126 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include "gssapiP_generic.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32
+generic_gss_create_empty_buffer_set(OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+
+ set = (gss_buffer_set_desc *) gssalloc_malloc(sizeof(*set));
+ if (set == GSS_C_NO_BUFFER_SET) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ set->count = 0;
+ set->elements = NULL;
+
+ *buffer_set = set;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+generic_gss_add_buffer_set_member(OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+ gss_buffer_t p;
+ OM_uint32 ret;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET) {
+ ret = generic_gss_create_empty_buffer_set(minor_status,
+ buffer_set);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ set = *buffer_set;
+ set->elements = (gss_buffer_desc *)gssalloc_realloc(set->elements,
+ (set->count + 1) *
+ sizeof(gss_buffer_desc));
+ if (set->elements == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = &set->elements[set->count];
+
+ p->value = gssalloc_malloc(member_buffer->length);
+ if (p->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(p->value, member_buffer->value, member_buffer->length);
+ p->length = member_buffer->length;
+
+ set->count++;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+generic_gss_release_buffer_set(OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ size_t i;
+ OM_uint32 minor;
+
+ *minor_status = 0;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET) {
+ return GSS_S_COMPLETE;
+ }
+
+ for (i = 0; i < (*buffer_set)->count; i++) {
+ generic_gss_release_buffer(&minor, &((*buffer_set)->elements[i]));
+ }
+
+ if ((*buffer_set)->elements != NULL) {
+ gssalloc_free((*buffer_set)->elements);
+ (*buffer_set)->elements = NULL;
+ }
+
+ (*buffer_set)->count = 0;
+
+ gssalloc_free(*buffer_set);
+ *buffer_set = GSS_C_NO_BUFFER_SET;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/src/lib/gssapi/generic/util_errmap.c b/src/lib/gssapi/generic/util_errmap.c
new file mode 100644
index 000000000000..628a455d2ad4
--- /dev/null
+++ b/src/lib/gssapi/generic/util_errmap.c
@@ -0,0 +1,264 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2007, 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include "gssapiP_generic.h"
+#include <string.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+/* The mapping table is 0-based, but let's export codes that are
+ 1-based, keeping 0 for errors or unknown errors.
+
+ The elements in the mapping table currently have separate copies of
+ each OID stored. This is a bit wasteful, but we are assuming the
+ table isn't likely to grow very large. */
+
+struct mecherror {
+ gss_OID_desc mech;
+ OM_uint32 code;
+};
+
+static inline int
+cmp_OM_uint32(OM_uint32 m1, OM_uint32 m2)
+{
+ if (m1 < m2)
+ return -1;
+ else if (m1 > m2)
+ return 1;
+ else
+ return 0;
+}
+
+static inline int
+mecherror_cmp(struct mecherror m1, struct mecherror m2)
+{
+ if (m1.code < m2.code)
+ return -1;
+ if (m1.code > m2.code)
+ return 1;
+ if (m1.mech.length < m2.mech.length)
+ return -1;
+ if (m1.mech.length > m2.mech.length)
+ return 1;
+ if (m1.mech.length == 0)
+ return 0;
+ return memcmp(m1.mech.elements, m2.mech.elements, m1.mech.length);
+}
+
+static void
+print_OM_uint32 (OM_uint32 value, FILE *f)
+{
+ fprintf(f, "%lu", (unsigned long) value);
+}
+
+static inline int
+mecherror_copy(struct mecherror *dest, struct mecherror src)
+{
+ *dest = src;
+ if (src.mech.length > 0) {
+ dest->mech.elements = malloc(src.mech.length);
+ if (dest->mech.elements == NULL)
+ return ENOMEM;
+ memcpy(dest->mech.elements, src.mech.elements, src.mech.length);
+ } else {
+ dest->mech.elements = NULL;
+ }
+ return 0;
+}
+
+static void
+mecherror_print(struct mecherror value, FILE *f)
+{
+ OM_uint32 minor;
+ gss_buffer_desc str;
+ static const struct {
+ const char *oidstr, *name;
+ } mechnames[] = {
+ { "{ 1 2 840 113554 1 2 2 }", "krb5-new" },
+ { "{ 1 3 5 1 5 2 }", "krb5-old" },
+ { "{ 1 2 840 48018 1 2 2 }", "krb5-microsoft" },
+ { "{ 1 3 6 1 5 5 2 }", "spnego" },
+ };
+ unsigned int i;
+
+ fprintf(f, "%lu@", (unsigned long) value.code);
+
+ if (value.mech.length == 0) {
+ fprintf(f, "(com_err)");
+ return;
+ }
+ fprintf(f, "%p=", value.mech.elements);
+ if (generic_gss_oid_to_str(&minor, &value.mech, &str)) {
+ fprintf(f, "(error in conversion)");
+ return;
+ }
+ /* Note: generic_gss_oid_to_str returns a null-terminated string. */
+ for (i = 0; i < sizeof(mechnames)/sizeof(mechnames[0]); i++) {
+ if (!strcmp(str.value, mechnames[i].oidstr) && mechnames[i].name != 0) {
+ fprintf(f, "%s", mechnames[i].name);
+ break;
+ }
+ }
+ if (i == sizeof(mechnames)/sizeof(mechnames[0]))
+ fprintf(f, "%s", (char *) str.value);
+ generic_gss_release_buffer(&minor, &str);
+}
+
+#include "errmap.h"
+#include "krb5.h" /* for KRB5KRB_AP_WRONG_PRINC */
+
+static mecherrmap m;
+static k5_mutex_t mutex = K5_MUTEX_PARTIAL_INITIALIZER;
+static OM_uint32 next_fake = 100000;
+
+int gssint_mecherrmap_init(void)
+{
+ int err;
+
+ err = mecherrmap_init(&m);
+ if (err)
+ return err;
+ err = k5_mutex_finish_init(&mutex);
+ if (err) {
+ mecherrmap_destroy(&m);
+ return err;
+ }
+
+ return 0;
+}
+
+/* Currently the enumeration template doesn't handle freeing
+ element storage when destroying the collection. */
+static int free_one(OM_uint32 i, struct mecherror value, void *p)
+{
+ free(value.mech.elements);
+ return 0;
+}
+
+void gssint_mecherrmap_destroy(void)
+{
+ mecherrmap_foreach(&m, free_one, NULL);
+ mecherrmap_destroy(&m);
+ k5_mutex_destroy(&mutex);
+}
+
+OM_uint32 gssint_mecherrmap_map(OM_uint32 minor, const gss_OID_desc * oid)
+{
+ const struct mecherror *mep;
+ struct mecherror me, me_copy;
+ const OM_uint32 *p;
+ int err;
+ OM_uint32 new_status;
+
+#ifdef DEBUG
+ FILE *f;
+ f = fopen("/dev/pts/9", "w+");
+ if (f == NULL)
+ f = stderr;
+#endif
+
+ me.code = minor;
+ me.mech = *oid;
+ k5_mutex_lock(&mutex);
+
+ /* Is this status+oid already mapped? */
+ p = mecherrmap_findright(&m, me);
+ if (p != NULL) {
+ k5_mutex_unlock(&mutex);
+#ifdef DEBUG
+ fprintf(f, "%s: found ", __FUNCTION__);
+ mecherror_print(me, f);
+ fprintf(f, " in map as %lu\n", (unsigned long) *p);
+ if (f != stderr) fclose(f);
+#endif
+ return *p;
+ }
+ /* Is this status code already mapped to something else
+ mech-specific? */
+ mep = mecherrmap_findleft(&m, minor);
+ if (mep == NULL) {
+ /* Map it to itself plus this mech-oid. */
+ new_status = minor;
+ } else {
+ /* Already assigned. Pick a fake new value and map it. */
+ /* There's a theoretical infinite loop risk here, if we fill
+ in 2**32 values. Also, returning 0 has a special
+ meaning. */
+ do {
+ next_fake++;
+ new_status = next_fake;
+ if (new_status == 0)
+ /* ??? */;
+ } while (mecherrmap_findleft(&m, new_status) != NULL);
+ }
+ err = mecherror_copy(&me_copy, me);
+ if (err) {
+ k5_mutex_unlock(&mutex);
+ return err;
+ }
+ err = mecherrmap_add(&m, new_status, me_copy);
+ k5_mutex_unlock(&mutex);
+ if (err)
+ free(me_copy.mech.elements);
+#ifdef DEBUG
+ fprintf(f, "%s: mapping ", __FUNCTION__);
+ mecherror_print(me, f);
+ fprintf(f, " to %lu: err=%d\nnew map: ", (unsigned long) new_status, err);
+ mecherrmap_printmap(&m, f);
+ fprintf(f, "\n");
+ if (f != stderr) fclose(f);
+#endif
+ if (err)
+ return 0;
+ else
+ return new_status;
+}
+
+static gss_OID_desc no_oid = { 0, 0 };
+OM_uint32 gssint_mecherrmap_map_errcode(OM_uint32 errcode)
+{
+ return gssint_mecherrmap_map(errcode, &no_oid);
+}
+
+int gssint_mecherrmap_get(OM_uint32 minor, gss_OID mech_oid,
+ OM_uint32 *mech_minor)
+{
+ const struct mecherror *p;
+
+ if (minor == 0) {
+ return EINVAL;
+ }
+ k5_mutex_lock(&mutex);
+ p = mecherrmap_findleft(&m, minor);
+ k5_mutex_unlock(&mutex);
+ if (!p) {
+ return EINVAL;
+ }
+ *mech_oid = p->mech;
+ *mech_minor = p->code;
+ return 0;
+}
diff --git a/src/lib/gssapi/generic/util_seqstate.c b/src/lib/gssapi/generic/util_seqstate.c
new file mode 100644
index 000000000000..a0bc2cc1c1d4
--- /dev/null
+++ b/src/lib/gssapi/generic/util_seqstate.c
@@ -0,0 +1,163 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/generic/util_seqstate.c - sequence number checking */
+/*
+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gssapiP_generic.h"
+#include <string.h>
+
+struct g_seqnum_state_st {
+ /* Flags to indicate whether we are supposed to check for replays or
+ * enforce strict sequencing. */
+ int do_replay;
+ int do_sequence;
+
+ /* UINT32_MAX for 32-bit sequence numbers, UINT64_MAX for 64-bit. Mask
+ * against this after arithmetic to stay within the correct range. */
+ uint64_t seqmask;
+
+ /* The initial sequence number for this context. This value will be
+ * subtracted from all received sequence numbers to simplify wraparound. */
+ uint64_t base;
+
+ /* The expected next sequence number (one more than the highest previously
+ * seen sequence number), relative to base. */
+ uint64_t next;
+
+ /*
+ * A bitmap for the 64 sequence numbers prior to next. If the 1<<(i-1) bit
+ * is set, then we have seen seqnum next-i relative to base. The least
+ * significant bit is always set if we have received any sequence numbers,
+ * and indicates the highest sequence number we have seen (next-1). When
+ * we advance next, we shift recvmap to the left.
+ */
+ uint64_t recvmap;
+};
+
+long
+g_seqstate_init(g_seqnum_state *state_out, uint64_t seqnum, int do_replay,
+ int do_sequence, int wide)
+{
+ g_seqnum_state state;
+
+ *state_out = NULL;
+ state = malloc(sizeof(*state));
+ if (state == NULL)
+ return ENOMEM;
+ state->do_replay = do_replay;
+ state->do_sequence = do_sequence;
+ state->seqmask = wide ? UINT64_MAX : UINT32_MAX;
+ state->base = seqnum;
+ state->next = state->recvmap = 0;
+ *state_out = state;
+ return 0;
+}
+
+OM_uint32
+g_seqstate_check(g_seqnum_state state, uint64_t seqnum)
+{
+ uint64_t rel_seqnum, offset, bit;
+
+ if (!state->do_replay && !state->do_sequence)
+ return GSS_S_COMPLETE;
+
+ /* Use the difference from the base seqnum, to simplify wraparound. */
+ rel_seqnum = (seqnum - state->base) & state->seqmask;
+
+ if (rel_seqnum >= state->next) {
+ /* seqnum is the expected sequence number or in the future. Update the
+ * received bitmap and expected next sequence number. */
+ offset = rel_seqnum - state->next;
+ state->recvmap = (state->recvmap << (offset + 1)) | 1;
+ state->next = (rel_seqnum + 1) & state->seqmask;
+
+ return (offset > 0 && state->do_sequence) ? GSS_S_GAP_TOKEN :
+ GSS_S_COMPLETE;
+ }
+
+ /* seqnum is in the past. Check if it's too old for replay detection. */
+ offset = state->next - rel_seqnum;
+ if (offset > 64)
+ return state->do_sequence ? GSS_S_UNSEQ_TOKEN : GSS_S_OLD_TOKEN;
+
+ /* Check for replay and mark as received. */
+ bit = (uint64_t)1 << (offset - 1);
+ if (state->do_replay && (state->recvmap & bit))
+ return GSS_S_DUPLICATE_TOKEN;
+ state->recvmap |= bit;
+
+ return state->do_sequence ? GSS_S_UNSEQ_TOKEN : GSS_S_COMPLETE;
+}
+
+void
+g_seqstate_free(g_seqnum_state state)
+{
+ free(state);
+}
+
+/*
+ * These support functions are for the serialization routines
+ */
+void
+g_seqstate_size(g_seqnum_state state, size_t *sizep)
+{
+ *sizep += sizeof(*state);
+}
+
+long
+g_seqstate_externalize(g_seqnum_state state, unsigned char **buf,
+ size_t *lenremain)
+{
+ if (*lenremain < sizeof(*state))
+ return ENOMEM;
+ memcpy(*buf, state, sizeof(*state));
+ *buf += sizeof(*state);
+ *lenremain -= sizeof(*state);
+ return 0;
+}
+
+long
+g_seqstate_internalize(g_seqnum_state *state_out, unsigned char **buf,
+ size_t *lenremain)
+{
+ g_seqnum_state state;
+
+ *state_out = NULL;
+ if (*lenremain < sizeof(*state))
+ return EINVAL;
+ state = malloc(sizeof(*state));
+ if (state == NULL)
+ return ENOMEM;
+ memcpy(state, *buf, sizeof(*state));
+ *buf += sizeof(*state);
+ *lenremain -= sizeof(*state);
+ *state_out = state;
+ return 0;
+}
diff --git a/src/lib/gssapi/generic/util_set.c b/src/lib/gssapi/generic/util_set.c
new file mode 100644
index 000000000000..8866f525fbc9
--- /dev/null
+++ b/src/lib/gssapi/generic/util_set.c
@@ -0,0 +1,106 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 1995 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"
+
+struct _g_set_elt {
+ void *key;
+ void *value;
+ struct _g_set_elt *next;
+};
+
+int g_set_init(g_set_elt *s)
+{
+ *s = NULL;
+
+ return(0);
+}
+
+#if 0
+int g_set_destroy(g_set_elt *s)
+{
+ g_set next;
+
+ while (*s) {
+ next = (*s)->next;
+ free(*s);
+ *s = next;
+ }
+
+ return(0);
+}
+#endif
+
+int g_set_entry_add(g_set_elt *s, void *key, void *value)
+{
+ g_set_elt first;
+
+ if ((first = (struct _g_set_elt *) malloc(sizeof(struct _g_set_elt))) == NULL)
+ return(ENOMEM);
+
+ first->key = key;
+ first->value = value;
+ first->next = *s;
+
+ *s = first;
+
+ return(0);
+}
+
+int g_set_entry_delete(g_set_elt *s, void *key)
+{
+ g_set_elt *p;
+
+ for (p=s; *p; p = &((*p)->next)) {
+ if ((*p)->key == key) {
+ g_set_elt next = (*p)->next;
+ free(*p);
+ *p = next;
+
+ return(0);
+ }
+ }
+
+ return(-1);
+}
+
+int g_set_entry_get(g_set_elt *s, void *key, void **value)
+{
+ g_set_elt p;
+
+ for (p = *s; p; p = p->next) {
+ if (p->key == key) {
+ *value = p->value;
+
+ return(0);
+ }
+ }
+
+ *value = NULL;
+
+ 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 000000000000..6e339f4ac7f7
--- /dev/null
+++ b/src/lib/gssapi/generic/util_token.c
@@ -0,0 +1,229 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * 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"
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <limits.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
+ *
+ * Note that the token type field is a feature of RFC 1964 mechanisms and
+ * is not used by other GSSAPI mechanisms. As such, a token type of -1
+ * is interpreted to mean that no token type should be expected or
+ * generated.
+ *
+ * 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 unsigned int
+der_length_size(int length)
+{
+ if (length < (1<<7))
+ return(1);
+ else if (length < (1<<8))
+ return(2);
+#if INT_MAX == 0x7fff
+ else
+ return(3);
+#else
+ else if (length < (1<<16))
+ return(3);
+ else if (length < (1<<24))
+ return(4);
+ else
+ return(5);
+#endif
+}
+
+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 INT_MAX > 0x7fff
+ if (length >= (1<<24))
+ *(*buf)++ = (unsigned char) (length>>24);
+ if (length >= (1<<16))
+ *(*buf)++ = (unsigned char) ((length>>16)&0xff);
+#endif
+ 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);
+ if (sf > sizeof(int))
+ 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 */
+
+unsigned int
+g_token_size(const gss_OID_desc * mech, unsigned int body_size)
+{
+ /* set body_size to sequence contents size */
+ body_size += 4 + (unsigned int)mech->length; /* NEED overflow check */
+ 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_desc * mech,
+ unsigned int body_size,
+ unsigned char **buf,
+ int tok_type)
+{
+ *(*buf)++ = 0x60;
+ der_write_length(buf, ((tok_type == -1) ? 2 : 4) + mech->length + body_size);
+ *(*buf)++ = 0x06;
+ *(*buf)++ = (unsigned char) mech->length;
+ TWRITE_STR(*buf, mech->elements, mech->length);
+ if (tok_type != -1) {
+ *(*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. Returns 0 on success,
+ * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
+ * mechanism in the token does not match the mech argument. buf and
+ * *body_size are left unmodified on error.
+ */
+
+gss_int32
+g_verify_token_header(
+ const gss_OID_desc * mech,
+ unsigned int *body_size,
+ unsigned char **buf_in,
+ int tok_type,
+ unsigned int toksize_in,
+ int flags)
+{
+ unsigned char *buf = *buf_in;
+ int seqsize;
+ gss_OID_desc toid;
+ int toksize = toksize_in;
+
+ if ((toksize-=1) < 0)
+ return(G_BAD_TOK_HEADER);
+ if (*buf++ != 0x60) {
+ if (flags & G_VFY_TOKEN_HDR_WRAPPER_REQUIRED)
+ return(G_BAD_TOK_HEADER);
+ buf--;
+ toksize++;
+ goto skip_wrapper;
+ }
+
+ if ((seqsize = der_read_length(&buf, &toksize)) < 0)
+ return(G_BAD_TOK_HEADER);
+
+ if (seqsize != toksize)
+ return(G_BAD_TOK_HEADER);
+
+ if ((toksize-=1) < 0)
+ return(G_BAD_TOK_HEADER);
+ if (*buf++ != 0x06)
+ return(G_BAD_TOK_HEADER);
+
+ if ((toksize-=1) < 0)
+ return(G_BAD_TOK_HEADER);
+ toid.length = *buf++;
+
+ if ((toksize-=toid.length) < 0)
+ return(G_BAD_TOK_HEADER);
+ toid.elements = buf;
+ buf+=toid.length;
+
+ if (! g_OID_equal(&toid, mech))
+ return G_WRONG_MECH;
+skip_wrapper:
+ if (tok_type != -1) {
+ if ((toksize-=2) < 0)
+ return(G_BAD_TOK_HEADER);
+
+ if ((*buf++ != ((tok_type>>8)&0xff)) ||
+ (*buf++ != (tok_type&0xff)))
+ return(G_WRONG_TOKID);
+ }
+ *buf_in = buf;
+ *body_size = toksize;
+
+ return 0;
+}