diff options
Diffstat (limited to 'src/lib/gssapi')
103 files changed, 9647 insertions, 2723 deletions
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in index 353e8d2158..6937f8f07e 100644 --- a/src/lib/gssapi/Makefile.in +++ b/src/lib/gssapi/Makefile.in @@ -2,8 +2,8 @@ thisconfigdir=../.. myfulldir=lib/gssapi mydir=lib/gssapi BUILDTOP=$(REL)..$(S).. -SUBDIRS= generic mechglue krb5 spnego -DEFS= +SUBDIRS= generic krb5 spnego mechglue +DEFS=-D_GSS_STATIC_LINK=1 ##DOSLIBNAME=$(OUTPRE)gssapi.lib ##DOSOBJFILELIST=@$(OUTPRE)mechglue.lst @$(OUTPRE)spnego.lst @$(OUTPRE)generic.lst @$(OUTPRE)krb5.lst @$(OUTPRE)gssapi.lst @@ -15,20 +15,16 @@ DEFS= ##DOS##DLL_EXP_TYPE=GSS LOCALINCLUDES = -Igeneric -I$(srcdir)/generic -Ikrb5 -I$(srcdir)/krb5 -I$(srcdir)/mechglue -STLIBOBJS=\ - gss_libinit.o +STLIBOBJS= -OBJS=\ - $(OUTPRE)gss_libinit.$(OBJEXT) - -SRCS=\ - $(srcdir)/gss_libinit.c +OBJS= +SRCS= LIBBASE=gssapi_krb5 LIBMAJOR=2 LIBMINOR=2 -LIBINITFUNC=gssint_lib_init -LIBFINIFUNC=gssint_lib_fini +#LIBINITFUNC=gssint_lib_init +#LIBFINIFUNC=gssint_lib_fini STOBJLISTS=OBJS.ST generic/OBJS.ST mechglue/OBJS.ST krb5/OBJS.ST spnego/OBJS.ST SUBDIROBJLISTS=generic/OBJS.ST mechglue/OBJS.ST krb5/OBJS.ST spnego/OBJS.ST SHLIB_EXPDEPS=\ @@ -144,18 +140,3 @@ $(EXPORTED_HEADERS) generic/gssapi.h krb5/gssapi_err_krb5.h generic/gssapi_err_g # Makefile dependencies follow. This must be the last section in # the Makefile.in file # -gss_libinit.so gss_libinit.po $(OUTPRE)gss_libinit.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h \ - $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ - $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ - $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ - $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ - $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ - $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ - $(SRCTOP)/include/socket-utils.h $(srcdir)/generic/gssapiP_generic.h \ - $(srcdir)/generic/gssapi_generic.h $(srcdir)/krb5/gssapiP_krb5.h \ - $(srcdir)/mechglue/mechglue.h $(srcdir)/mechglue/mglueP.h \ - generic/gssapi_err_generic.h gss_libinit.c gss_libinit.h \ - krb5/gssapi_err_krb5.h krb5/gssapi_krb5.h diff --git a/src/lib/gssapi/generic/Makefile.in b/src/lib/gssapi/generic/Makefile.in index 4a4a005ad8..9ed3b139cb 100644 --- a/src/lib/gssapi/generic/Makefile.in +++ b/src/lib/gssapi/generic/Makefile.in @@ -18,7 +18,8 @@ ETHDRS= gssapi_err_generic.h EHDRDIR= $(BUILDTOP)$(S)include$(S)gssapi HDRS= $(EHDRDIR)$(S)gssapi.h \ - $(EHDRDIR)$(S)gssapi_generic.h + $(EHDRDIR)$(S)gssapi_generic.h \ + $(EHDRDIR)$(S)gssapi_ext.h MK_EHDRDIR=if test -d $(EHDRDIR); then :; else (set -x; mkdir $(EHDRDIR)); fi ##DOS##MK_EHDRDIR=rem @@ -29,6 +30,8 @@ $(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_ext.h: $(EHDRDIR)$(S)timestamp $(srcdir)$(S)gssapi_ext.h + $(CP) $(srcdir)$(S)gssapi_ext.h $@ $(EHDRDIR)$(S)timestamp: $(MK_EHDRDIR) @@ -67,9 +70,11 @@ 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_ordering.c \ $(srcdir)/util_set.c \ @@ -81,9 +86,11 @@ 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_ordering.$(OBJEXT) \ $(OUTPRE)util_set.$(OBJEXT) \ @@ -95,9 +102,11 @@ 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_ordering.o \ util_set.o \ @@ -105,7 +114,7 @@ STLIBOBJS = \ util_validate.o \ gssapi_err_generic.o -EXPORTED_HEADERS= gssapi_generic.h +EXPORTED_HEADERS= gssapi_generic.h gssapi_ext.h EXPORTED_BUILT_HEADERS= gssapi.h $(OBJS): $(EXPORTED_HEADERS) $(ETHDRS) @@ -169,61 +178,71 @@ depend:: $(ETSRCS) # 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 \ - $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ - $(srcdir)/../gss_libinit.h disp_com_err_status.c gssapiP_generic.h \ - gssapi_err_generic.h gssapi_generic.h + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/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 \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h disp_major_status.c gssapiP_generic.h \ - gssapi_err_generic.h gssapi_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 \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.c gssapi_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_generic.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/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 \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h rel_buffer.c + 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 \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h rel_oid_set.c + 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 \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h util_buffer.c + 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 \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/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/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h errmap.h gssapiP_generic.h \ - gssapi_err_generic.h gssapi_generic.h util_errmap.c + gssapi_err_generic.h gssapi_ext.h gssapi_generic.h \ + util_errmap.c util_ordering.so util_ordering.po $(OUTPRE)util_ordering.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h util_ordering.c + gssapi_ext.h gssapi_generic.h util_ordering.c util_set.so util_set.po $(OUTPRE)util_set.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h util_set.c + gssapi_ext.h gssapi_generic.h util_set.c util_token.so util_token.po $(OUTPRE)util_token.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h util_token.c + gssapi_ext.h gssapi_generic.h util_token.c util_validate.so util_validate.po $(OUTPRE)util_validate.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ - $(srcdir)/../gss_libinit.h gssapiP_generic.h gssapi_err_generic.h \ - gssapi_generic.h util_validate.c + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h gssapiP_generic.h gssapi_err_generic.h \ + gssapi_ext.h gssapi_generic.h util_validate.c gssapi_err_generic.so gssapi_err_generic.po $(OUTPRE)gssapi_err_generic.$(OBJEXT): \ $(COM_ERR_DEPS) gssapi_err_generic.c diff --git a/src/lib/gssapi/generic/disp_com_err_status.c b/src/lib/gssapi/generic/disp_com_err_status.c index baf7e70379..d7a2e1d85c 100644 --- a/src/lib/gssapi/generic/disp_com_err_status.c +++ b/src/lib/gssapi/generic/disp_com_err_status.c @@ -26,7 +26,6 @@ */ #include "gssapiP_generic.h" -#include "gss_libinit.h" #include "com_err.h" /* XXXX internationalization!! */ @@ -54,8 +53,6 @@ g_display_com_err_status(minor_status, status_value, status_string) status_string->length = 0; status_string->value = NULL; - (void) gssint_initialize_library(); - if (! g_make_string_buffer(((status_value == 0)?no_error: error_message(status_value)), status_string)) { diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin index 4dc33133b6..d33a0b505b 100644 --- a/src/lib/gssapi/generic/gssapi.hin +++ b/src/lib/gssapi/generic/gssapi.hin @@ -178,6 +178,7 @@ typedef int gss_cred_usage_t; #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 diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h index 03f4a1305f..894899b95c 100644 --- a/src/lib/gssapi/generic/gssapiP_generic.h +++ b/src/lib/gssapi/generic/gssapiP_generic.h @@ -40,7 +40,7 @@ #include "k5-thread.h" #include "gssapi_generic.h" - +#include "gssapi_ext.h" #include "gssapi_err_generic.h" #include <errno.h> @@ -174,11 +174,15 @@ 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 +#define G_VFY_TOKEN_HDR_IGNORE_SEQ_SIZE 0x02 + 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 wrapper_required); + int flags); OM_uint32 g_display_major_status (OM_uint32 *minor_status, OM_uint32 status_value, @@ -257,6 +261,22 @@ generic_gss_str_to_oid( 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); @@ -264,4 +284,22 @@ int gssint_mecherrmap_get(OM_uint32 minor, gss_OID mech_oid, OM_uint32 *mech_minor); OM_uint32 gssint_mecherrmap_map_errcode(OM_uint32 errcode); +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*/); + #endif /* _GSSAPIP_GENERIC_H_ */ diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h new file mode 100644 index 0000000000..40f5ab8093 --- /dev/null +++ b/src/lib/gssapi/generic/gssapi_ext.h @@ -0,0 +1,261 @@ +/* + * 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 */ + +#if 0 +/* + * Solaris extensions + */ +int KRB5_CALLCONV gssd_pname_to_uid + (char *, + gss_OID, + gss_OID, + uid_t *); + +int KRB5_CALLCONV __gss_userok + (const gss_name_t /*name*/, + const char * /*username*/); +#endif + +/* + * 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*/); + +/* XXX do these really belong in this header? */ +OM_uint32 KRB5_CALLCONV gssspi_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_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 */ + +/* + * 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 */ + +#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 index b5314ed7b6..9497c3dc31 100644 --- a/src/lib/gssapi/generic/gssapi_generic.c +++ b/src/lib/gssapi/generic/gssapi_generic.c @@ -119,6 +119,9 @@ static const gss_OID_desc const_oids[] = { * GSS_C_NT_EXPORT_NAME 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"}, }; /* Here are the constants which point to the static structure above. @@ -147,3 +150,6 @@ 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_INQ_SSPI_SESSION_KEY = oids+7; + diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h index eee79655e6..cd872e6edb 100644 --- a/src/lib/gssapi/generic/gssapi_generic.h +++ b/src/lib/gssapi/generic/gssapi_generic.h @@ -38,6 +38,9 @@ #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. diff --git a/src/lib/gssapi/mechglue/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c index 9e77ef1be2..bd78e262b3 100644 --- a/src/lib/gssapi/mechglue/oid_ops.c +++ b/src/lib/gssapi/generic/oid_ops.c @@ -30,7 +30,7 @@ * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs */ -#include "mglueP.h" +#include "gssapiP_generic.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -316,7 +316,8 @@ generic_gss_str_to_oid(minor_status, oid_str, oid) } while ((bp < &cp[oid_str->length]) && isdigit(*bp)) bp++; - while ((bp < &cp[oid_str->length]) && isspace(*bp)) + while ((bp < &cp[oid_str->length]) && + (isspace(*bp) || *bp == '.')) bp++; if (sscanf((char *)bp, "%ld", &numbuf) != 1) { *minor_status = EINVAL; @@ -402,6 +403,92 @@ generic_gss_str_to_oid(minor_status, oid_str, oid) return(GSS_S_FAILURE); } +/* 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 = 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 = 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; +} + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -424,7 +511,7 @@ generic_gss_str_to_oid(minor_status, oid_str, oid) * PERFORMANCE OF THIS SOFTWARE. */ OM_uint32 -gssint_copy_oid_set( +generic_gss_copy_oid_set( OM_uint32 *minor_status, const gss_OID_set_desc * const oidset, gss_OID_set *new_oidset @@ -479,3 +566,4 @@ done: return (major); } + 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 0000000000..edb61b80f5 --- /dev/null +++ b/src/lib/gssapi/generic/util_buffer_set.c @@ -0,0 +1,126 @@ +/* + * 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 *) 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 *)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 = 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) +{ + int 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) { + free((*buffer_set)->elements); + (*buffer_set)->elements = NULL; + } + + (*buffer_set)->count = 0; + + free(*buffer_set); + *buffer_set = GSS_C_NO_BUFFER_SET; + + return GSS_S_COMPLETE; +} + diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c index b37d9065dd..24d5325483 100644 --- a/src/lib/gssapi/generic/util_token.c +++ b/src/lib/gssapi/generic/util_token.c @@ -174,7 +174,7 @@ g_verify_token_header( unsigned char **buf_in, int tok_type, unsigned int toksize_in, - int wrapper_required) + int flags) { unsigned char *buf = *buf_in; int seqsize; @@ -184,7 +184,7 @@ g_verify_token_header( if ((toksize-=1) < 0) return(G_BAD_TOK_HEADER); if (*buf++ != 0x60) { - if (wrapper_required) + if (flags & G_VFY_TOKEN_HDR_WRAPPER_REQUIRED) return(G_BAD_TOK_HEADER); buf--; toksize++; @@ -194,7 +194,8 @@ g_verify_token_header( if ((seqsize = der_read_length(&buf, &toksize)) < 0) return(G_BAD_TOK_HEADER); - if (seqsize != toksize) + if ((flags & G_VFY_TOKEN_HDR_IGNORE_SEQ_SIZE) == 0 && + seqsize != toksize) return(G_BAD_TOK_HEADER); if ((toksize-=1) < 0) diff --git a/src/lib/gssapi/generic/util_validate.c b/src/lib/gssapi/generic/util_validate.c index 24a1bc5189..00dac321c3 100644 --- a/src/lib/gssapi/generic/util_validate.c +++ b/src/lib/gssapi/generic/util_validate.c @@ -30,7 +30,6 @@ */ #include "gssapiP_generic.h" -#include "gss_libinit.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -73,9 +72,6 @@ static int g_save(db, type, ptr) vkey vk; DBT key; - ret = gssint_initialize_library(); - if (ret) - return 0; ret = k5_mutex_lock(&db->mutex); if (ret) return 0; @@ -97,9 +93,6 @@ static int g_save(db, type, ptr) #else g_set_elt *gs; - ret = gssint_initialize_library(); - if (ret) - return 0; ret = k5_mutex_lock(&db->mutex); if (ret) return 0; diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c deleted file mode 100644 index 82e620d2db..0000000000 --- a/src/lib/gssapi/gss_libinit.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ -#include <assert.h> - -#include "gssapi_err_generic.h" -#include "gssapi_err_krb5.h" -#include "gssapiP_krb5.h" -#include "gssapiP_generic.h" - -#include "gss_libinit.h" -#include "k5-platform.h" - -#include "mglueP.h" - -/* - * Initialize the GSSAPI library. - */ - -MAKE_INIT_FUNCTION(gssint_lib_init); -MAKE_FINI_FUNCTION(gssint_lib_fini); - -int gssint_lib_init(void) -{ - int err; - -#ifdef SHOW_INITFINI_FUNCS - printf("gssint_lib_init\n"); -#endif - - add_error_table(&et_k5g_error_table); - add_error_table(&et_ggss_error_table); - - err = gssint_mechglue_init(); - if (err) - return err; -#ifndef LEAN_CLIENT - err = k5_mutex_finish_init(&gssint_krb5_keytab_lock); - if (err) - return err; -#endif /* LEAN_CLIENT */ - err = k5_key_register(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, free); - if (err) - return err; - err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free); - if (err) - return err; - err = k5_key_register(K5_KEY_GSS_KRB5_ERROR_MESSAGE, - krb5_gss_delete_error_info); - if (err) - return err; - err = gssint_mecherrmap_init(); - if (err) - return err; -#ifndef _WIN32 - err = k5_mutex_finish_init(&kg_kdc_flag_mutex); - if (err) - return err; -#endif - return k5_mutex_finish_init(&kg_vdb.mutex); -} - -void gssint_lib_fini(void) -{ - if (!INITIALIZER_RAN(gssint_lib_init) || PROGRAM_EXITING()) { -#ifdef SHOW_INITFINI_FUNCS - printf("gssint_lib_fini: skipping\n"); -#endif - return; - } -#ifdef SHOW_INITFINI_FUNCS - printf("gssint_lib_fini\n"); -#endif - remove_error_table(&et_k5g_error_table); - remove_error_table(&et_ggss_error_table); - - k5_key_delete(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME); - k5_key_delete(K5_KEY_GSS_KRB5_CCACHE_NAME); - k5_mutex_destroy(&kg_vdb.mutex); -#ifndef _WIN32 - k5_mutex_destroy(&kg_kdc_flag_mutex); -#endif -#ifndef LEAN_CLIENT - k5_mutex_destroy(&gssint_krb5_keytab_lock); -#endif /* LEAN_CLIENT */ - gssint_mecherrmap_destroy(); - gssint_mechglue_fini(); -} - -OM_uint32 gssint_initialize_library (void) -{ - return CALL_INIT_FUNCTION(gssint_lib_init); -} diff --git a/src/lib/gssapi/gss_libinit.h b/src/lib/gssapi/gss_libinit.h deleted file mode 100644 index 11849923c6..0000000000 --- a/src/lib/gssapi/gss_libinit.h +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ -#ifndef GSSAPI_LIBINIT_H -#define GSSAPI_LIBINIT_H - -#include "gssapi.h" - -OM_uint32 gssint_initialize_library (void); -void gssint_cleanup_library (void); - -#endif /* GSSAPI_LIBINIT_H */ diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in index 2236711053..3ad504429c 100644 --- a/src/lib/gssapi/krb5/Makefile.in +++ b/src/lib/gssapi/krb5/Makefile.in @@ -3,7 +3,24 @@ myfulldir=lib/gssapi/krb5 mydir=lib/gssapi/krb5 BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/.. -I../generic -I$(srcdir)/../generic -I../mechglue -I$(srcdir)/../mechglue -DEFS= +DEFS=-D_GSS_STATIC_LINK=1 + +#PROG_LIBPATH=-L$(TOPLIBD) +#PROG_RPATH=$(KRB5_LIBDIR) +#MODULE_INSTALL_DIR = $(GSS_MODULE_DIR) +#LIBBASE=mech_krb5 +#LIBMAJOR=0 +#LIBMINOR=0 +#SO_EXT=.so +#LIBINITFUNC=gss_krb5int_init +#LIBFINIFUNC=gss_krb5int_fini +#STOBJLISTS=../generic/OBJS.ST OBJS.ST +#SUBDIROBJLISTS=../generic/OBJS.ST +#SHLIB_EXPDEPS=$(KRB5_DEPLIB) $(CRYPTO_DEPLIB) $(SUPPORT_DEPLIB) $(COM_ERR_DEPLIB) +#SHLIB_EXPLIBS=-lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB) $(DL_LIB) $(LIBS) +#SHLIB_DIRS=-L$(TOPLIBD) +#SHLIB_RDIRS=$(KRB5_LIBDIR) +#RELDIR=gssapi/krb5 ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=krb5 @@ -45,8 +62,11 @@ SRCS = \ $(srcdir)/inq_cred.c \ $(srcdir)/inq_names.c \ $(srcdir)/k5seal.c \ + $(srcdir)/k5sealiov.c \ $(srcdir)/k5sealv3.c \ + $(srcdir)/k5sealv3iov.c \ $(srcdir)/k5unseal.c \ + $(srcdir)/k5unsealiov.c \ $(srcdir)/krb5_gss_glue.c \ $(srcdir)/lucid_context.c \ $(srcdir)/process_context_token.c \ @@ -65,11 +85,8 @@ SRCS = \ $(srcdir)/util_seqnum.c \ $(srcdir)/val_cred.c \ $(srcdir)/verify.c \ - $(srcdir)/wrap_size_limit.c \ - gssapi_err_krb5.c + $(srcdir)/wrap_size_limit.c -# $(srcdir)/pname_to_uid.c \ -# $(srcdir)/k5mech.c OBJS = \ $(OUTPRE)accept_sec_context.$(OBJEXT) \ @@ -95,8 +112,11 @@ OBJS = \ $(OUTPRE)inq_cred.$(OBJEXT) \ $(OUTPRE)inq_names.$(OBJEXT) \ $(OUTPRE)k5seal.$(OBJEXT) \ + $(OUTPRE)k5sealiov.$(OBJEXT) \ $(OUTPRE)k5sealv3.$(OBJEXT) \ + $(OUTPRE)k5sealv3iov.$(OBJEXT) \ $(OUTPRE)k5unseal.$(OBJEXT) \ + $(OUTPRE)k5unsealiov.$(OBJEXT) \ $(OUTPRE)krb5_gss_glue.$(OBJEXT) \ $(OUTPRE)lucid_context.$(OBJEXT) \ $(OUTPRE)process_context_token.$(OBJEXT) \ @@ -145,8 +165,11 @@ STLIBOBJS = \ inq_cred.o \ inq_names.o \ k5seal.o \ + k5sealiov.o \ k5sealv3.o \ + k5sealv3iov.o \ k5unseal.o \ + k5unsealiov.o \ krb5_gss_glue.o \ lucid_context.o \ process_context_token.o \ @@ -255,296 +278,303 @@ install:: # accept_sec_context.so accept_sec_context.po $(OUTPRE)accept_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h accept_sec_context.c \ gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h acquire_cred.so acquire_cred.po $(OUTPRE)acquire_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h \ - $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h $(srcdir)/../gss_libinit.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h acquire_cred.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h add_cred.so add_cred.po $(OUTPRE)add_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h add_cred.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h canon_name.so canon_name.po $(OUTPRE)canon_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h canon_name.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h compare_name.so compare_name.po $(OUTPRE)compare_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h compare_name.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h context_time.so context_time.po $(OUTPRE)context_time.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h context_time.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h copy_ccache.so copy_ccache.po $(OUTPRE)copy_ccache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h copy_ccache.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h delete_sec_context.so delete_sec_context.po $(OUTPRE)delete_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h delete_sec_context.c \ gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h disp_name.so disp_name.po $(OUTPRE)disp_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h disp_name.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h disp_status.so disp_status.po $(OUTPRE)disp_status.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h \ - $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h $(srcdir)/../gss_libinit.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h disp_status.c error_map.h \ gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h duplicate_name.so duplicate_name.po $(OUTPRE)duplicate_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h duplicate_name.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h export_name.so export_name.po $(OUTPRE)export_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h export_name.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h export_sec_context.so export_sec_context.po $(OUTPRE)export_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h export_sec_context.c \ gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h get_tkt_flags.so get_tkt_flags.po $(OUTPRE)get_tkt_flags.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h get_tkt_flags.c gssapiP_krb5.h \ gssapi_err_krb5.h gssapi_krb5.h gssapi_krb5.so gssapi_krb5.po $(OUTPRE)gssapi_krb5.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../mechglue/mechglue.h $(srcdir)/../mechglue/mglueP.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.c gssapi_krb5.h import_name.so import_name.po $(OUTPRE)import_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h import_name.c import_sec_context.so import_sec_context.po $(OUTPRE)import_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h import_sec_context.c indicate_mechs.so indicate_mechs.po $(OUTPRE)indicate_mechs.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ $(srcdir)/../mechglue/mechglue.h $(srcdir)/../mechglue/mglueP.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h indicate_mechs.c init_sec_context.so init_sec_context.po $(OUTPRE)init_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h \ - $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h $(srcdir)/../gss_libinit.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h init_sec_context.c inq_context.so inq_context.po $(OUTPRE)inq_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h inq_context.c inq_cred.so inq_cred.po $(OUTPRE)inq_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h inq_cred.c inq_names.so inq_names.po $(OUTPRE)inq_names.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h inq_names.c -k5seal.so k5seal.po $(OUTPRE)k5seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -553,36 +583,11 @@ k5seal.so k5seal.po $(OUTPRE)k5seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h k5seal.c -k5sealv3.so k5sealv3.po $(OUTPRE)k5sealv3.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h k5sealv3.c -k5unseal.so k5unseal.po $(OUTPRE)k5unseal.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h k5unseal.c -krb5_gss_glue.so krb5_gss_glue.po $(OUTPRE)krb5_gss_glue.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + gssapi_krb5.h inq_names.c +k5seal.so k5seal.po $(OUTPRE)k5seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -591,51 +596,40 @@ krb5_gss_glue.so krb5_gss_glue.po $(OUTPRE)krb5_gss_glue.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - $(srcdir)/../mechglue/mechglue.h $(srcdir)/../mechglue/mglueP.h \ - $(srcdir)/../spnego/gssapiP_spnego.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h krb5_gss_glue.c -lucid_context.so lucid_context.po $(OUTPRE)lucid_context.$(OBJEXT): \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h k5seal.c +k5sealiov.so k5sealiov.po $(OUTPRE)k5sealiov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h lucid_context.c -process_context_token.so process_context_token.po $(OUTPRE)process_context_token.$(OBJEXT): \ + gssapi_krb5.h k5sealiov.c +k5sealv3.so k5sealv3.po $(OUTPRE)k5sealv3.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h process_context_token.c -rel_cred.so rel_cred.po $(OUTPRE)rel_cred.$(OBJEXT): \ + gssapi_krb5.h k5sealv3.c +k5sealv3iov.so k5sealv3iov.po $(OUTPRE)k5sealv3iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h rel_cred.c -rel_oid.so rel_oid.po $(OUTPRE)rel_oid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -644,23 +638,12 @@ rel_oid.so rel_oid.po $(OUTPRE)rel_oid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h rel_oid.c -rel_name.so rel_name.po $(OUTPRE)rel_name.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h rel_name.c -seal.so seal.po $(OUTPRE)seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + gssapi_krb5.h k5sealv3iov.c +k5unseal.so k5unseal.po $(OUTPRE)k5unseal.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -669,11 +652,12 @@ seal.so seal.po $(OUTPRE)seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h seal.c -set_allowable_enctypes.so set_allowable_enctypes.po \ - $(OUTPRE)set_allowable_enctypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h k5unseal.c +k5unsealiov.so k5unsealiov.po $(OUTPRE)k5unsealiov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -682,37 +666,26 @@ set_allowable_enctypes.so set_allowable_enctypes.po \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h set_allowable_enctypes.c -ser_sctx.so ser_sctx.po $(OUTPRE)ser_sctx.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h ser_sctx.c -set_ccache.so set_ccache.po $(OUTPRE)set_ccache.$(OBJEXT): \ + gssapi_krb5.h k5unsealiov.c +krb5_gss_glue.so krb5_gss_glue.po $(OUTPRE)krb5_gss_glue.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h \ - $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h $(srcdir)/../gss_libinit.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h set_ccache.c -sign.so sign.po $(OUTPRE)sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + gssapi_krb5.h krb5_gss_glue.c +lucid_context.so lucid_context.po $(OUTPRE)lucid_context.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -721,10 +694,12 @@ sign.so sign.po $(OUTPRE)sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h sign.c -unseal.so unseal.po $(OUTPRE)unseal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h lucid_context.c +process_context_token.so process_context_token.po $(OUTPRE)process_context_token.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -733,10 +708,25 @@ unseal.so unseal.po $(OUTPRE)unseal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h unseal.c -util_cksum.so util_cksum.po $(OUTPRE)util_cksum.$(OBJEXT): \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h process_context_token.c +rel_cred.so rel_cred.po $(OUTPRE)rel_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h rel_cred.c +rel_oid.so rel_oid.po $(OUTPRE)rel_oid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -745,11 +735,25 @@ util_cksum.so util_cksum.po $(OUTPRE)util_cksum.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h util_cksum.c -util_crypt.so util_crypt.po $(OUTPRE)util_crypt.$(OBJEXT): \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h rel_oid.c +rel_name.so rel_name.po $(OUTPRE)rel_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h rel_name.c +seal.so seal.po $(OUTPRE)seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -758,11 +762,12 @@ util_crypt.so util_crypt.po $(OUTPRE)util_crypt.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h util_crypt.c -util_seed.so util_seed.po $(OUTPRE)util_seed.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h seal.c +set_allowable_enctypes.so set_allowable_enctypes.po \ + $(OUTPRE)set_allowable_enctypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -771,11 +776,39 @@ util_seed.so util_seed.po $(OUTPRE)util_seed.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h set_allowable_enctypes.c +ser_sctx.so ser_sctx.po $(OUTPRE)ser_sctx.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h util_seed.c -util_seqnum.so util_seqnum.po $(OUTPRE)util_seqnum.$(OBJEXT): \ + gssapi_krb5.h ser_sctx.c +set_ccache.so set_ccache.po $(OUTPRE)set_ccache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h set_ccache.c +sign.so sign.po $(OUTPRE)sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -784,11 +817,11 @@ util_seqnum.so util_seqnum.po $(OUTPRE)util_seqnum.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h util_seqnum.c -val_cred.so val_cred.po $(OUTPRE)val_cred.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h sign.c +unseal.so unseal.po $(OUTPRE)unseal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -797,11 +830,26 @@ val_cred.so val_cred.po $(OUTPRE)val_cred.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h unseal.c +util_cksum.so util_cksum.po $(OUTPRE)util_cksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ - gssapi_krb5.h val_cred.c -verify.so verify.po $(OUTPRE)verify.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ + gssapi_krb5.h util_cksum.c +util_crypt.so util_crypt.po $(OUTPRE)util_crypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ @@ -810,10 +858,53 @@ verify.so verify.po $(OUTPRE)verify.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h verify.c -wrap_size_limit.so wrap_size_limit.po $(OUTPRE)wrap_size_limit.$(OBJEXT): \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h util_crypt.c +util_seed.so util_seed.po $(OUTPRE)util_seed.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h util_seed.c +util_seqnum.so util_seqnum.po $(OUTPRE)util_seqnum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h util_seqnum.c +val_cred.so val_cred.po $(OUTPRE)val_cred.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ + gssapi_krb5.h val_cred.c +verify.so verify.po $(OUTPRE)verify.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ @@ -822,8 +913,20 @@ wrap_size_limit.so wrap_size_limit.po $(OUTPRE)wrap_size_limit.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \ + $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ + gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h verify.c +wrap_size_limit.so wrap_size_limit.po $(OUTPRE)wrap_size_limit.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h gssapiP_krb5.h gssapi_err_krb5.h \ gssapi_krb5.h wrap_size_limit.c -gssapi_err_krb5.so gssapi_err_krb5.po $(OUTPRE)gssapi_err_krb5.$(OBJEXT): \ - $(COM_ERR_DEPS) gssapi_err_krb5.c diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 8d01f5e674..2e2433a2a0 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -70,6 +70,33 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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 "k5-int.h" #include "gssapiP_krb5.h" @@ -211,12 +238,117 @@ cleanup: } -OM_uint32 -krb5_gss_accept_sec_context(minor_status, context_handle, - verifier_cred_handle, input_token, - input_chan_bindings, src_name, mech_type, - output_token, ret_flags, time_rec, - delegated_cred_handle) +/* + * Performs third leg of DCE authentication + */ +static OM_uint32 +kg_accept_dce(minor_status, context_handle, verifier_cred_handle, + input_token, input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, delegated_cred_handle) + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_cred_id_t verifier_cred_handle; + gss_buffer_t input_token; + gss_channel_bindings_t input_chan_bindings; + gss_name_t *src_name; + gss_OID *mech_type; + gss_buffer_t output_token; + OM_uint32 *ret_flags; + OM_uint32 *time_rec; + gss_cred_id_t *delegated_cred_handle; +{ + krb5_error_code code; + krb5_gss_ctx_id_rec *ctx = 0; + krb5_timestamp now; + krb5_principal name = NULL; + krb5_ui_4 nonce = 0; + krb5_data ap_rep; + OM_uint32 major_status = GSS_S_FAILURE; + + output_token->length = 0; + output_token->value = NULL; + + if (mech_type) + *mech_type = GSS_C_NULL_OID; + /* return a bogus cred handle */ + if (delegated_cred_handle) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + + ctx = (krb5_gss_ctx_id_rec *)*context_handle; + + code = krb5_timeofday(ctx->k5_context, &now); + if (code != 0) { + major_status = GSS_S_FAILURE; + goto fail; + } + + if (ctx->krb_times.endtime < now) { + code = 0; + major_status = GSS_S_CREDENTIALS_EXPIRED; + goto fail; + } + + ap_rep.data = input_token->value; + ap_rep.length = input_token->length; + + code = krb5_rd_rep_dce(ctx->k5_context, + ctx->auth_context, + &ap_rep, + &nonce); + if (code != 0) { + major_status = GSS_S_FAILURE; + goto fail; + } + + ctx->established = 1; + + if (src_name) { + if ((code = krb5_copy_principal(ctx->k5_context, ctx->there, &name))) { + major_status = GSS_S_FAILURE; + goto fail; + } + /* intern the src_name */ + if (! kg_save_name((gss_name_t) name)) { + code = G_VALIDATE_FAILED; + major_status = GSS_S_FAILURE; + goto fail; + } + *src_name = (gss_name_t) name; + } + + if (mech_type) + *mech_type = ctx->mech_used; + + if (time_rec) + *time_rec = ctx->krb_times.endtime - now; + + if (ret_flags) + *ret_flags = ctx->gss_flags; + + /* XXX no support for delegated credentials yet */ + + *minor_status = 0; + + return GSS_S_COMPLETE; + + fail: + /* real failure code follows */ + + if (ctx) + (void) krb5_gss_delete_sec_context(minor_status, + (gss_ctx_id_t *) &ctx, NULL); + *context_handle = GSS_C_NO_CONTEXT; + *minor_status = code; + + return major_status; +} + +static OM_uint32 +kg_accept_krb5(minor_status, context_handle, + verifier_cred_handle, input_token, + input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, + delegated_cred_handle) OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_cred_id_t verifier_cred_handle; @@ -232,7 +364,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_context context; unsigned char *ptr, *ptr2; char *sptr; - long tmp; + OM_uint32 tmp; size_t md5len; int bigend; krb5_gss_cred_id_t cred = 0; @@ -245,7 +377,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_principal name = NULL; krb5_ui_4 gss_flags = 0; int decode_req_message = 0; - krb5_gss_ctx_id_rec *ctx = 0; + krb5_gss_ctx_id_rec *ctx = NULL; krb5_timestamp now; gss_buffer_desc token; krb5_auth_context auth_context = NULL; @@ -261,6 +393,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_gss_cred_id_t deleg_cred = NULL; krb5int_access kaccess; int cred_rcache = 0; + int no_encap = 0; + krb5_flags ap_req_options = 0; code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); if (code) { @@ -291,19 +425,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (delegated_cred_handle) *delegated_cred_handle = GSS_C_NO_CREDENTIAL; - /* - * Context handle must be unspecified. Actually, it must be - * non-established, but currently, accept_sec_context never returns - * a non-established context handle. - */ - /*SUPPRESS 29*/ - if (*context_handle != GSS_C_NO_CONTEXT) { - *minor_status = EINVAL; - save_error_string(EINVAL, "accept_sec_context called with existing context handle"); - krb5_free_context(context); - return(GSS_S_FAILURE); - } - /* handle default cred handle */ if (verifier_cred_handle == GSS_C_NO_CREDENTIAL) { major_status = krb5_gss_acquire_cred(minor_status, GSS_C_NO_NAME, @@ -369,6 +490,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle, code = KRB5KRB_AP_ERR_MSG_TYPE; mech_used = gss_mech_krb5; goto fail; + } else if (code == G_BAD_TOK_HEADER) { + /* DCE style not encapsulated */ + ap_req.length = input_token->length; + ap_req.data = input_token->value; + mech_used = gss_mech_krb5; + no_encap = 1; } else { major_status = GSS_S_DEFECTIVE_TOKEN; goto fail; @@ -398,7 +525,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if ((code = krb5_auth_con_init(context, &auth_context))) { major_status = GSS_S_FAILURE; - save_error_info(code, context); + save_error_info((OM_uint32)code, context); goto fail; } if (cred->rcache) { @@ -414,7 +541,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, } if ((code = krb5_rd_req(context, &auth_context, &ap_req, cred->princ, - cred->keytab, NULL, &ticket))) { + cred->keytab, &ap_req_options, &ticket))) { major_status = GSS_S_FAILURE; goto fail; } @@ -434,7 +561,39 @@ krb5_gss_accept_sec_context(minor_status, context_handle, } #endif - { + if (authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) { + /* Samba does not send 0x8003 GSS-API checksums */ + krb5_boolean valid; + krb5_keyblock *subkey; + krb5_data zero; + + code = krb5_auth_con_getkey(context, auth_context, &subkey); + if (code) { + major_status = GSS_S_FAILURE; + goto fail; + } + + zero.length = 0; + zero.data = ""; + + code = krb5_c_verify_checksum(context, + subkey, + KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, + &zero, + authdat->checksum, + &valid); + if (code || !valid) { + major_status = GSS_S_BAD_SIG; + krb5_free_keyblock(context, subkey); + goto fail; + } + + gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + bigend = 0; + decode_req_message = 0; + + krb5_free_keyblock(context, subkey); + } else { /* gss krb5 v1 */ /* stash this now, for later. */ @@ -612,6 +771,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle, } } + /* only DCE_STYLE clients are allowed to send raw AP-REQs */ + if (no_encap != ((gss_flags & GSS_C_DCE_STYLE) != 0)) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + /* create the ctx struct and start filling it in */ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) @@ -628,7 +793,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ctx->gss_flags = (GSS_C_TRANS_FLAG | ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | - GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))); + GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG | + GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG | + GSS_C_EXTENDED_ERROR_FLAG))); ctx->seed_init = 0; ctx->big_endian = bigend; ctx->cred_rcache = cred_rcache; @@ -643,6 +810,14 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } + /* XXX move this into gss_name_t */ + if (ticket->enc_part2->authorization_data != NULL && + (code = krb5_copy_authdata(context, + ticket->enc_part2->authorization_data, + &ctx->authdata))) { + major_status = GSS_S_FAILURE; + goto fail; + } if ((code = krb5_copy_principal(context, ticket->server, &ctx->here))) { major_status = GSS_S_FAILURE; goto fail; @@ -677,76 +852,24 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - ctx->proto = 0; - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = SGN_ALG_DES_MAC_MD5; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_DES; - - /* fill in the encryption descriptors */ - - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { - major_status = GSS_S_FAILURE; - goto fail; - } - - for (i=0; i<ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xf0; - - goto copy_subkey_to_seq; - - case ENCTYPE_DES3_CBC_SHA1: - ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; - ctx->cksum_size = 20; - ctx->sealalg = SEAL_ALG_DES3KD; - - /* fill in the encryption descriptors */ - copy_subkey: - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { - major_status = GSS_S_FAILURE; - goto fail; - } - copy_subkey_to_seq: - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { - major_status = GSS_S_FAILURE; - goto fail; - } - break; - - case ENCTYPE_ARCFOUR_HMAC: - ctx->signalg = SGN_ALG_HMAC_MD5 ; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ; - goto copy_subkey; - - default: - ctx->signalg = -1; - ctx->sealalg = -1; - ctx->proto = 1; - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype, - &ctx->cksumtype); - if (code) - goto fail; - code = krb5_c_checksum_length(context, ctx->cksumtype, - &ctx->cksum_size); - if (code) - goto fail; - ctx->have_acceptor_subkey = 0; - goto copy_subkey; + ctx->enc = NULL; + ctx->seq = NULL; + ctx->have_acceptor_subkey = 0; + /* DCE_STYLE implies acceptor_subkey */ + if ((ctx->gss_flags & GSS_C_DCE_STYLE) == 0) { + code = kg_setup_keys(context, ctx, ctx->subkey, &ctx->cksumtype); + if (code) { + major_status = GSS_S_FAILURE; + goto fail; + } } - - ctx->endtime = ticket->enc_part2->times.endtime; + ctx->krb_times = ticket->enc_part2->times; /* struct copy */ ctx->krb_flags = ticket->enc_part2->flags; krb5_free_ticket(context, ticket); /* Done with ticket */ { - krb5_ui_4 seq_temp; + krb5_int32 seq_temp; krb5_auth_con_getremoteseqnumber(context, auth_context, &seq_temp); ctx->seq_recv = seq_temp; } @@ -756,7 +879,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - if (ctx->endtime < now) { + if (ctx->krb_times.endtime < now) { code = 0; major_status = GSS_S_CREDENTIALS_EXPIRED; goto fail; @@ -766,6 +889,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle, (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto); + /* DCE_STYLE implies mutual authentication */ + if (ctx->gss_flags & GSS_C_DCE_STYLE) + ctx->gss_flags |= GSS_C_MUTUAL_FLAG; + /* at this point, the entire context structure is filled in, so it can be released. */ @@ -773,10 +900,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) { unsigned char * ptr3; - krb5_ui_4 seq_temp; + krb5_int32 seq_temp; int cfx_generate_subkey; - if (ctx->proto == 1) + if (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) || + (ap_req_options & AP_OPTS_USE_SUBKEY)) cfx_generate_subkey = CFX_ACCEPTOR_SUBKEY; else cfx_generate_subkey = 0; @@ -811,18 +939,38 @@ krb5_gss_accept_sec_context(minor_status, context_handle, major_status = GSS_S_FAILURE; goto fail; } - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, - ctx->acceptor_subkey->enctype, - &ctx->acceptor_subkey_cksumtype); - if (code) { - major_status = GSS_S_FAILURE; - goto fail; - } ctx->have_acceptor_subkey = 1; + + code = kg_setup_keys(context, ctx, ctx->acceptor_subkey, + &ctx->acceptor_subkey_cksumtype); + if (code) { + major_status = GSS_S_FAILURE; + goto fail; + } } /* the reply token hasn't been sent yet, but that's ok. */ - ctx->gss_flags |= GSS_C_PROT_READY_FLAG; + if (ctx->gss_flags & GSS_C_DCE_STYLE) { + assert(ctx->have_acceptor_subkey); + + /* in order to force acceptor subkey to be used, don't set PROT_READY */ + + /* Raw AP-REP is returned */ + output_token->length = ap_rep.length; + output_token->value = ap_rep.data; + ap_rep.data = NULL; /* don't double free */ + + ctx->established = 0; + + *context_handle = (gss_ctx_id_t)ctx; + *minor_status = 0; + major_status = GSS_S_CONTINUE_NEEDED; + + /* Only last leg should set return arguments */ + goto fail; + } else + ctx->gss_flags |= GSS_C_PROT_READY_FLAG; + ctx->established = 1; token.length = g_token_size(mech_used, ap_rep.length); @@ -868,7 +1016,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, *mech_type = (gss_OID) mech_used; if (time_rec) - *time_rec = ctx->endtime - now; + *time_rec = ctx->krb_times.endtime - now; if (ret_flags) *ret_flags = ctx->gss_flags; @@ -908,8 +1056,8 @@ fail: xfree(reqcksum.contents); if (ap_rep.data) krb5_free_data_contents(context, &ap_rep); - - if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED) { + if (major_status == GSS_S_COMPLETE || + (major_status == GSS_S_CONTINUE_NEEDED && code != KRB5KRB_AP_ERR_MSG_TYPE)) { ctx->k5_context = context; context = NULL; goto done; @@ -1007,3 +1155,50 @@ done: return (major_status); } #endif /* LEAN_CLIENT */ + +OM_uint32 +krb5_gss_accept_sec_context(minor_status, context_handle, + verifier_cred_handle, input_token, + input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, + delegated_cred_handle) + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_cred_id_t verifier_cred_handle; + gss_buffer_t input_token; + gss_channel_bindings_t input_chan_bindings; + gss_name_t *src_name; + gss_OID *mech_type; + gss_buffer_t output_token; + OM_uint32 *ret_flags; + OM_uint32 *time_rec; + gss_cred_id_t *delegated_cred_handle; +{ + krb5_gss_ctx_id_rec *ctx = (krb5_gss_ctx_id_rec *)*context_handle; + + /* + * Context handle must be unspecified. Actually, it must be + * non-established, but currently, accept_sec_context never returns + * a non-established context handle. + */ + /*SUPPRESS 29*/ + if (ctx != NULL) { + if (ctx->established == 0 && (ctx->gss_flags & GSS_C_DCE_STYLE)) { + return kg_accept_dce(minor_status, context_handle, + verifier_cred_handle, input_token, + input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, + delegated_cred_handle); + } else { + *minor_status = EINVAL; + save_error_string(EINVAL, "accept_sec_context called with existing context handle"); + return GSS_S_FAILURE; + } + } + + return kg_accept_krb5(minor_status, context_handle, + verifier_cred_handle, input_token, + input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, + delegated_cred_handle); +} diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 02cefc2d74..98617d570f 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -72,7 +72,6 @@ */ #include "k5-int.h" -#include "gss_libinit.h" #include "gssapiP_krb5.h" #ifdef HAVE_STRING_H #include <string.h> @@ -98,20 +97,23 @@ k5_mutex_t gssint_krb5_keytab_lock = K5_MUTEX_PARTIAL_INITIALIZER; static char *krb5_gss_keytab = NULL; /* Heimdal calls this gsskrb5_register_acceptor_identity. */ -OM_uint32 KRB5_CALLCONV -krb5_gss_register_acceptor_identity(const char *keytab) +OM_uint32 +gss_krb5int_register_acceptor_identity(OM_uint32 *minor_status, + const gss_OID desired_mech, + const gss_OID desired_object, + gss_buffer_t value) { char *new, *old; int err; - err = gssint_initialize_library(); + err = gss_krb5int_initialize_library(); if (err != 0) return GSS_S_FAILURE; - if (keytab == NULL) + if (value->value == NULL) return GSS_S_FAILURE; - new = strdup(keytab); + new = strdup((char *)value->value); if (new == NULL) return GSS_S_FAILURE; @@ -153,7 +155,7 @@ acquire_accept_cred(context, minor_status, desired_name, output_princ, cred) /* open the default keytab */ - code = gssint_initialize_library(); + code = gss_krb5int_initialize_library(); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; @@ -181,7 +183,7 @@ acquire_accept_cred(context, minor_status, desired_name, output_princ, cred) if ((code = krb5_kt_get_entry(context, kt, princ, 0, 0, &entry))) { (void) krb5_kt_close(context, kt); if (code == KRB5_KT_NOTFOUND) { - char *errstr = krb5_get_error_message(context, code); + char *errstr = (char *)krb5_get_error_message(context, code); krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", errstr); krb5_free_error_message(context, errstr); *minor_status = KG_KEYTAB_NOMATCH; @@ -464,7 +466,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, OM_uint32 ret; krb5_error_code code; - code = gssint_initialize_library(); + code = gss_krb5int_initialize_library(); if (code) { *minor_status = code; return GSS_S_FAILURE; @@ -712,3 +714,48 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, krb5_free_context(context); return(GSS_S_COMPLETE); } + +OM_uint32 +gss_krb5int_set_cred_rcache(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID desired_oid, + const gss_buffer_t value) +{ + krb5_gss_cred_id_t cred; + krb5_error_code code; + krb5_context context; + krb5_rcache rcache; + + assert(value->length == sizeof(rcache)); + + if (value->length != sizeof(rcache)) + return GSS_S_FAILURE; + + rcache = (krb5_rcache)value->value; + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_NO_CRED; + + cred = (krb5_gss_cred_id_t)cred_handle; + + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + if (cred->rcache != NULL) { + code = krb5_rc_close(context, cred->rcache); + if (code) { + *minor_status = code; + krb5_free_context(context); + return GSS_S_FAILURE; + } + } + + cred->rcache = rcache; + + krb5_free_context(context); + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/src/lib/gssapi/krb5/canon_name.c b/src/lib/gssapi/krb5/canon_name.c index b113a343e6..b4f4d4bc17 100644 --- a/src/lib/gssapi/krb5/canon_name.c +++ b/src/lib/gssapi/krb5/canon_name.c @@ -42,5 +42,5 @@ OM_uint32 krb5_gss_canonicalize_name(OM_uint32 *minor_status, return(GSS_S_BAD_MECH); } - return(gss_duplicate_name(minor_status, input_name, output_name)); + return(krb5_gss_duplicate_name(minor_status, input_name, output_name)); } diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c index ec16239c4a..b263b50e65 100644 --- a/src/lib/gssapi/krb5/context_time.c +++ b/src/lib/gssapi/krb5/context_time.c @@ -57,7 +57,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) return(GSS_S_FAILURE); } - if ((lifetime = ctx->endtime - now) <= 0) { + if ((lifetime = ctx->krb_times.endtime - now) <= 0) { *time_rec = 0; *minor_status = 0; return(GSS_S_CONTEXT_EXPIRED); diff --git a/src/lib/gssapi/krb5/copy_ccache.c b/src/lib/gssapi/krb5/copy_ccache.c index 2071df44a1..430b50d282 100644 --- a/src/lib/gssapi/krb5/copy_ccache.c +++ b/src/lib/gssapi/krb5/copy_ccache.c @@ -2,22 +2,26 @@ #include "gssapiP_krb5.h" OM_uint32 KRB5_CALLCONV -gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache) - OM_uint32 *minor_status; - gss_cred_id_t cred_handle; - krb5_ccache out_ccache; +gss_krb5int_copy_ccache(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID desired_object, + const gss_buffer_t value) { - OM_uint32 major_status; krb5_gss_cred_id_t k5creds; krb5_cc_cursor cursor; krb5_creds creds; krb5_error_code code; krb5_context context; + krb5_ccache out_ccache; + + assert(value->length == sizeof(out_ccache)); + + if (value->length != sizeof(out_ccache)) + return GSS_S_FAILURE; + + out_ccache = (krb5_ccache)value->value; - /* validate the cred handle */ - major_status = krb5_gss_validate_cred(minor_status, cred_handle); - if (major_status) - return(major_status); + /* cred handle will have been validated by gssspi_set_cred_option() */ k5creds = (krb5_gss_cred_id_t) cred_handle; code = k5_mutex_lock(&k5creds->lock); diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index b2ace922c3..9544524d30 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -104,7 +104,10 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) } if (ctx->mech_used) - gss_release_oid(minor_status, &ctx->mech_used); + krb5_gss_release_oid(minor_status, &ctx->mech_used); + + if (ctx->authdata) + krb5_free_authdata(context, ctx->authdata); if (ctx->k5_context) krb5_free_context(ctx->k5_context); diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c index 2ee6aceec4..6cc1bc144c 100644 --- a/src/lib/gssapi/krb5/disp_status.c +++ b/src/lib/gssapi/krb5/disp_status.c @@ -22,7 +22,6 @@ */ #include "gssapiP_krb5.h" -#include "gss_libinit.h" #include "com_err.h" /* XXXX internationalization!! */ @@ -47,7 +46,7 @@ free_string (char *s) char *get_error_message(OM_uint32 minor_code) { gsserrmap *p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE); - char *msg = 0; + char *msg = NULL; #ifdef DEBUG fprintf(stderr, "%s(%lu, p=%p)", __func__, (unsigned long) minor_code, (void *) p); @@ -62,7 +61,7 @@ char *get_error_message(OM_uint32 minor_code) } } if (msg == 0) - msg = error_message(minor_code); + msg = (char *)error_message((krb5_error_code)minor_code); #ifdef DEBUG fprintf(stderr, " -> %p/%s\n", (void *) msg, msg); #endif @@ -135,7 +134,7 @@ void krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx) fprintf(stderr, "%s(%lu, ctx=%p)\n", __func__, (unsigned long) minor_code, (void *)ctx); #endif - s = krb5_get_error_message(ctx, minor_code); + s = (char *)krb5_get_error_message(ctx, (krb5_error_code)minor_code); #ifdef DEBUG fprintf(stderr, "%s(%lu, ctx=%p) saving: %s\n", __func__, (unsigned long) minor_code, (void *)ctx, s); @@ -143,7 +142,7 @@ void krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx) save_error_string(minor_code, s); /* The get_error_message call above resets the error message in ctx. Put it back, in case we make this call again *sigh*. */ - krb5_set_error_message(ctx, minor_code, "%s", s); + krb5_set_error_message(ctx, (krb5_error_code)minor_code, "%s", s); krb5_free_error_message(ctx, s); } void krb5_gss_delete_error_info(void *p) @@ -177,7 +176,7 @@ krb5_gss_display_status(minor_status, status_value, status_type, return(g_display_major_status(minor_status, status_value, message_context, status_string)); } else if (status_type == GSS_C_MECH_CODE) { - (void) gssint_initialize_library(); + (void) gss_krb5int_initialize_library(); if (*message_context) { *minor_status = (OM_uint32) G_BAD_MSG_CTX; diff --git a/src/lib/gssapi/krb5/export_name.c b/src/lib/gssapi/krb5/export_name.c index d55a174e01..46664e5a06 100644 --- a/src/lib/gssapi/krb5/export_name.c +++ b/src/lib/gssapi/krb5/export_name.c @@ -35,7 +35,8 @@ OM_uint32 krb5_gss_export_name(OM_uint32 *minor_status, krb5_context context; krb5_error_code code; size_t length; - char *str, *cp; + char *str; + unsigned char *cp; if (minor_status) *minor_status = 0; @@ -61,7 +62,7 @@ OM_uint32 krb5_gss_export_name(OM_uint32 *minor_status, &str))) { if (minor_status) *minor_status = code; - save_error_info(code, context); + save_error_info((OM_uint32)code, context); krb5_free_context(context); return(GSS_S_FAILURE); } diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c index 6b618d7956..f408d09ff3 100644 --- a/src/lib/gssapi/krb5/export_sec_context.c +++ b/src/lib/gssapi/krb5/export_sec_context.c @@ -95,7 +95,7 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token) error_out: if (retval != GSS_S_COMPLETE) if (kret != 0 && context != 0) - save_error_info(kret, context); + save_error_info((OM_uint32)kret, context); if (obuffer && bufsize) { memset(obuffer, 0, bufsize); xfree(obuffer); diff --git a/src/lib/gssapi/krb5/get_tkt_flags.c b/src/lib/gssapi/krb5/get_tkt_flags.c index f4d9b92d2d..2c12080bb1 100644 --- a/src/lib/gssapi/krb5/get_tkt_flags.c +++ b/src/lib/gssapi/krb5/get_tkt_flags.c @@ -28,29 +28,18 @@ */ OM_uint32 KRB5_CALLCONV -gss_krb5int_get_tkt_flags(minor_status, context_handle, ticket_flags) - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - krb5_flags *ticket_flags; +gss_krb5int_get_tkt_flags(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) { krb5_gss_ctx_id_rec *ctx; - - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } + gss_buffer_desc rep; ctx = (krb5_gss_ctx_id_rec *) context_handle; - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - if (ticket_flags) - *ticket_flags = ctx->krb_flags; + rep.value = &ctx->krb_flags; + rep.length = sizeof(ctx->krb_flags); - *minor_status = 0; - return(GSS_S_COMPLETE); + return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); } diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 617024b7c3..76dfd4429a 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -69,6 +69,7 @@ */ #include "gssapi_krb5.h" #include "gssapi_err_krb5.h" +#include "gssapi_ext.h" /* for debugging */ #undef CFX_EXERCISE @@ -96,18 +97,20 @@ #define KG_TOK_MIC_MSG 0x0101 #define KG_TOK_WRAP_MSG 0x0201 #define KG_TOK_DEL_CTX 0x0102 - -#define KG2_TOK_INITIAL 0x0101 -#define KG2_TOK_RESPONSE 0x0202 -#define KG2_TOK_MIC 0x0303 -#define KG2_TOK_WRAP_INTEG 0x0404 -#define KG2_TOK_WRAP_PRIV 0x0505 +#define KG2_TOK_MIC_MSG 0x0404 +#define KG2_TOK_WRAP_MSG 0x0504 +#define KG2_TOK_DEL_CTX 0x0405 #define KRB5_GSS_FOR_CREDS_OPTION 1 #define KG2_RESP_FLAG_ERROR 0x0001 #define KG2_RESP_FLAG_DELEG_OK 0x0002 +/** CFX flags **/ +#define FLAG_SENDER_IS_ACCEPTOR 0x01 +#define FLAG_WRAP_CONFIDENTIAL 0x02 +#define FLAG_ACCEPTOR_SUBKEY 0x04 + /* These are to be stored in little-endian order, i.e., des-mac is stored as 02 00. */ enum sgn_alg { @@ -188,7 +191,7 @@ typedef struct _krb5_gss_ctx_id_rec { int sealalg; krb5_keyblock *enc; krb5_keyblock *seq; - krb5_timestamp endtime; + krb5_ticket_times krb_times; krb5_flags krb_flags; /* XXX these used to be signed. the old spec is inspecific, and the new spec specifies unsigned. I don't believe that the change @@ -208,6 +211,7 @@ typedef struct _krb5_gss_ctx_id_rec { krb5_keyblock *acceptor_subkey; /* CFX only */ krb5_cksumtype acceptor_subkey_cksumtype; int cred_rcache; /* did we get rcache from creds? */ + krb5_authdata **authdata; } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; extern g_set kg_vdb; @@ -258,6 +262,12 @@ krb5_error_code kg_make_seed (krb5_context context, krb5_keyblock *key, unsigned char *seed); +krb5_error_code +kg_setup_keys(krb5_context context, + krb5_gss_ctx_id_rec *ctx, + krb5_keyblock *subkey, + krb5_cksumtype *cksumtype); + int kg_confounder_size (krb5_context context, krb5_keyblock *key); krb5_error_code kg_make_confounder (krb5_context context, @@ -269,12 +279,28 @@ krb5_error_code kg_encrypt (krb5_context context, krb5_const_pointer in, krb5_pointer out, unsigned int length); + +krb5_error_code kg_encrypt_iov (krb5_context context, + int proto, int dce_style, + size_t ec, size_t rrc, + krb5_keyblock *key, int usage, + krb5_pointer iv, + gss_iov_buffer_desc *iov, + int iov_count); + krb5_error_code kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, const unsigned char *kd_data, size_t kd_data_len, const unsigned char *input_buf, size_t input_len, unsigned char *output_buf); +krb5_error_code +kg_arcfour_docrypt_iov (krb5_context context, + const krb5_keyblock *longterm_key , int ms_usage, + const unsigned char *kd_data, size_t kd_data_len, + gss_iov_buffer_desc *iov, + int iov_count); + krb5_error_code kg_decrypt (krb5_context context, krb5_keyblock *key, int usage, krb5_pointer iv, @@ -282,10 +308,18 @@ krb5_error_code kg_decrypt (krb5_context context, krb5_pointer out, unsigned int length); +krb5_error_code kg_decrypt_iov (krb5_context context, + int proto, int dce_style, + size_t ec, size_t rrc, + krb5_keyblock *key, int usage, + krb5_pointer iv, + gss_iov_buffer_desc *iov, + int iov_count); + OM_uint32 kg_seal (OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, - int qop_req, + gss_qop_t qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer, @@ -296,7 +330,7 @@ OM_uint32 kg_unseal (OM_uint32 *minor_status, gss_buffer_t input_token_buffer, gss_buffer_t message_buffer, int *conf_state, - int *qop_state, + gss_qop_t *qop_state, int toktype); OM_uint32 kg_seal_size (OM_uint32 *minor_status, @@ -331,6 +365,102 @@ OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, const char *name); +/* AEAD */ + +krb5_error_code gss_krb5int_make_seal_token_v3_iov(krb5_context context, + krb5_gss_ctx_id_rec *ctx, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype); + +OM_uint32 gss_krb5int_unseal_v3_iov(krb5_context context, + OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + gss_iov_buffer_desc *iov, + int iov_count, + int *conf_state, + gss_qop_t *qop_state, + int toktype); + +gss_iov_buffer_t kg_locate_iov (gss_iov_buffer_desc *iov, + int iov_count, + OM_uint32 type); + +void kg_iov_msglen(gss_iov_buffer_desc *iov, + int iov_count, + size_t *data_length, + size_t *assoc_data_length); + +void kg_release_iov(gss_iov_buffer_desc *iov, + int iov_count); + +krb5_error_code kg_make_checksum_iov_v1(krb5_context context, + krb5_cksumtype type, + size_t token_cksum_len, + krb5_keyblock *seq, + krb5_keyblock *enc, /* for conf len */ + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype, + krb5_checksum *checksum); + +krb5_error_code kg_make_checksum_iov_v3(krb5_context context, + krb5_cksumtype type, + size_t rrc, + krb5_keyblock *key, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count); + +krb5_error_code kg_verify_checksum_iov_v3(krb5_context context, + krb5_cksumtype type, + size_t rrc, + krb5_keyblock *key, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count, + krb5_boolean *valid); + +OM_uint32 kg_seal_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, + int toktype); + +OM_uint32 kg_unseal_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, + int toktype); + +OM_uint32 kg_seal_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); + +krb5_cryptotype kg_translate_flag_iov(OM_uint32 type); + +OM_uint32 kg_fixup_padding_iov(OM_uint32 *minor_status, + gss_iov_buffer_desc *iov, + int iov_count); + +int kg_map_toktype(int proto, int toktype); + +krb5_boolean kg_integ_only_iov(gss_iov_buffer_desc *iov, int iov_count); + +krb5_error_code kg_allocate_iov(gss_iov_buffer_t iov, size_t size); + /** declarations of internal name mechanism functions **/ OM_uint32 krb5_gss_acquire_cred @@ -401,41 +531,6 @@ OM_uint32 krb5_gss_context_time OM_uint32* /* time_rec */ ); -OM_uint32 krb5_gss_sign -(OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - int, /* qop_req */ - gss_buffer_t, /* message_buffer */ - gss_buffer_t /* message_token */ -); - -OM_uint32 krb5_gss_verify -(OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - gss_buffer_t, /* message_buffer */ - gss_buffer_t, /* token_buffer */ - int* /* qop_state */ -); - -OM_uint32 krb5_gss_seal -(OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - int, /* conf_req_flag */ - int, /* qop_req */ - gss_buffer_t, /* input_message_buffer */ - int*, /* conf_state */ - gss_buffer_t /* output_message_buffer */ -); - -OM_uint32 krb5_gss_unseal -(OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - gss_buffer_t, /* input_message_buffer */ - gss_buffer_t, /* output_message_buffer */ - int*, /* conf_state */ - int* /* qop_state */ -); - OM_uint32 krb5_gss_display_status (OM_uint32*, /* minor_status */ OM_uint32, /* status_value */ @@ -525,6 +620,27 @@ OM_uint32 krb5_gss_wrap gss_buffer_t /* output_message_buffer */ ); +OM_uint32 krb5_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 */ +); + +OM_uint32 +krb5_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 */ +); + OM_uint32 krb5_gss_unwrap (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ @@ -534,6 +650,15 @@ OM_uint32 krb5_gss_unwrap gss_qop_t * /* qop_state */ ); +OM_uint32 krb5_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 */ +); + OM_uint32 krb5_gss_wrap_size_limit (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ @@ -655,41 +780,132 @@ OM_uint32 gss_krb5int_unseal_token_v3(krb5_context *contextptr, unsigned char *ptr, unsigned int bodysize, gss_buffer_t message_buffer, - int *conf_state, int *qop_state, + int *conf_state, gss_qop_t *qop_state, int toktype); +int gss_krb5int_rotate_left (void *ptr, size_t bufsiz, size_t rc); + /* * These take unglued krb5-mech-specific contexts. */ +#define GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH 11 +#define GSS_KRB5_GET_TKT_FLAGS_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x01" + OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags (OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - krb5_flags *ticket_flags); + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set); + +#define GSS_KRB5_COPY_CCACHE_OID_LENGTH 11 +#define GSS_KRB5_COPY_CCACHE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x02" OM_uint32 KRB5_CALLCONV gss_krb5int_copy_ccache (OM_uint32 *minor_status, gss_cred_id_t cred_handle, - krb5_ccache out_ccache); + const gss_OID desired_oid, + const gss_buffer_t value); + +#define GSS_KRB5_CCACHE_NAME_OID_LENGTH 11 +#define GSS_KRB5_CCACHE_NAME_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x03" + +struct krb5_gss_ccache_name_req { + const char *name; + const char **out_name; +}; + +OM_uint32 KRB5_CALLCONV gss_krb5int_ccache_name + (OM_uint32 *minor_status, + const gss_OID, + const gss_OID, + const gss_buffer_t); + +#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH 11 +#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x04" + +struct krb5_gss_set_allowable_enctypes_req { + OM_uint32 num_ktypes; + krb5_enctype *ktypes; +}; + +#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11 +#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05" + +OM_uint32 +gss_krb5int_inq_session_key(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *); OM_uint32 KRB5_CALLCONV gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, gss_cred_id_t cred, - OM_uint32 num_ktypes, - krb5_enctype *ktypes); + const gss_OID desired_oid, + const gss_buffer_t value); -OM_uint32 KRB5_CALLCONV +#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH 11 +#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x06" + +OM_uint32 gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - OM_uint32 version, - void **kctx); + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set); +#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH 11 +#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x07" + +OM_uint32 +gss_krb5int_free_lucid_sec_context(OM_uint32 *, const gss_OID, + const gss_OID, gss_buffer_t); extern k5_mutex_t kg_kdc_flag_mutex; krb5_error_code krb5_gss_init_context (krb5_context *ctxp); +#define GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH 11 +#define GSS_KRB5_USE_KDC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x08" + +OM_uint32 krb5int_gss_use_kdc_context(OM_uint32 *, const gss_OID, + const gss_OID, gss_buffer_t); + krb5_error_code krb5_gss_use_kdc_context(void); +#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH 11 +#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x09" + +OM_uint32 +gss_krb5int_register_acceptor_identity(OM_uint32 *, const gss_OID, const gss_OID, gss_buffer_t); + +#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH 11 +#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a" + +OM_uint32 +gss_krb5int_extract_authz_data_from_sec_context(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *ad_data); + +#define GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH 11 +#define GSS_KRB5_SET_CRED_RCACHE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0b" + +OM_uint32 +gss_krb5int_set_cred_rcache(OM_uint32 *, gss_cred_id_t, const gss_OID, const gss_buffer_t); + +#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH 11 +#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0c" + +OM_uint32 +gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *, + const gss_ctx_id_t, + const gss_OID, + gss_buffer_set_t *); + +#ifdef _GSS_STATIC_LINK +int gss_krb5int_lib_init(void); +void gss_krb5int_lib_fini(void); +#endif /* _GSS_STATIC_LINK */ + +OM_uint32 gss_krb5int_initialize_library(void); +void gss_krb5int_cleanup_library(void); + /* For error message handling. */ /* Returns a shared string, not a private copy! */ extern char * @@ -710,4 +926,8 @@ krb5_gss_save_error_message(OM_uint32 minor_code, const char *format, ...) #define save_error_info krb5_gss_save_error_info extern void krb5_gss_delete_error_info(void *p); +/* Prefix concatenated with Kerberos encryption type */ +#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 10 +#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04" + #endif /* _GSSAPIP_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 12e553f2ff..16ab581a9b 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -46,6 +46,33 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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. + */ /* * $Id$ @@ -55,6 +82,7 @@ /* For declaration of krb5_ser_context_init */ #include "k5-int.h" #include "gssapiP_krb5.h" +#include "mglueP.h" /** exported constants defined in gssapi_krb5{,_nx}.h **/ @@ -76,7 +104,13 @@ * The OID of the proposed standard krb5 v2 mechanism is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) * krb5v2(3) = 1.2.840.113554.1.2.3 - * + * Provisionally reserved for Kerberos session key algorithm + * identifiers is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_enctype(4) = 1.2.840.113554.1.2.2.4 + * Provisionally reserved for Kerberos mechanism-specific APIs: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_gssapi_ext(5) = 1.2.840.113554.1.2.2.5 */ /* @@ -270,3 +304,491 @@ kg_set_ccache_name (OM_uint32 *minor_status, const char *name) *minor_status = 0; return GSS_S_COMPLETE; } + +#define g_OID_prefix_equal(o1, o2) \ + (((o1)->length >= (o2)->length) && \ + (memcmp((o1)->elements, (o2)->elements, (o2)->length) == 0)) + +/* + * gss_inquire_sec_context_by_oid() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *); +} krb5_gss_inquire_sec_context_by_oid_ops[] = { + { + {GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH, GSS_KRB5_GET_TKT_FLAGS_OID}, + gss_krb5int_get_tkt_flags + }, + { + {GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID}, + gss_krb5int_extract_authz_data_from_sec_context + }, + { + {GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, GSS_KRB5_INQ_SSPI_SESSION_KEY_OID}, + gss_krb5int_inq_session_key + }, + { + {GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID}, + gss_krb5int_export_lucid_sec_context + }, + { + {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID}, + gss_krb5int_extract_authtime_from_sec_context + } +}; + +static OM_uint32 +krb5_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) +{ + krb5_gss_ctx_id_rec *ctx; + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (data_set == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *data_set = GSS_C_NO_BUFFER_SET; + + if (!kg_validate_ctx_id(context_handle)) + return GSS_S_NO_CONTEXT; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + if (!ctx->established) + return GSS_S_NO_CONTEXT; + + for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/ + sizeof(krb5_gss_inquire_sec_context_by_oid_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_sec_context_by_oid_ops[i].oid)) { + return (*krb5_gss_inquire_sec_context_by_oid_ops[i].func)(minor_status, + context_handle, + desired_object, + data_set); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + +/* + * gss_inquire_cred_by_oid() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, const gss_cred_id_t, const gss_OID, gss_buffer_set_t *); +} krb5_gss_inquire_cred_by_oid_ops[] = { +}; + +static OM_uint32 +krb5_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 major_status = GSS_S_FAILURE; + krb5_gss_cred_id_t cred; + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (data_set == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *data_set = GSS_C_NO_BUFFER_SET; + if (cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = (OM_uint32)KRB5_NOCREDS_SUPPLIED; + return GSS_S_NO_CRED; + } + + major_status = krb5_gss_validate_cred(minor_status, cred_handle); + if (GSS_ERROR(major_status)) + return major_status; + + cred = (krb5_gss_cred_id_t) cred_handle; + + for (i = 0; i < sizeof(krb5_gss_inquire_cred_by_oid_ops)/ + sizeof(krb5_gss_inquire_cred_by_oid_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_cred_by_oid_ops[i].oid)) { + return (*krb5_gss_inquire_cred_by_oid_ops[i].func)(minor_status, + cred_handle, + desired_object, + data_set); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + +/* + * gss_set_sec_context_option() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, gss_ctx_id_t *, const gss_OID, const gss_buffer_t); +} krb5_gss_set_sec_context_option_ops[] = { +}; + +static OM_uint32 +krb5_gss_set_sec_context_option (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (context_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (*context_handle != GSS_C_NO_CONTEXT) { + krb5_gss_ctx_id_rec *ctx; + + if (!kg_validate_ctx_id(*context_handle)) + return GSS_S_NO_CONTEXT; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + if (!ctx->established) + return GSS_S_NO_CONTEXT; + } + + for (i = 0; i < sizeof(krb5_gss_set_sec_context_option_ops)/ + sizeof(krb5_gss_set_sec_context_option_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gss_set_sec_context_option_ops[i].oid)) { + return (*krb5_gss_set_sec_context_option_ops[i].func)(minor_status, + context_handle, + desired_object, + value); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + +/* + * gssspi_set_cred_option() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, gss_cred_id_t, const gss_OID, const gss_buffer_t); +} krb5_gssspi_set_cred_option_ops[] = { + { + {GSS_KRB5_COPY_CCACHE_OID_LENGTH, GSS_KRB5_COPY_CCACHE_OID}, + gss_krb5int_copy_ccache + }, + { + {GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID}, + gss_krb5int_set_allowable_enctypes + }, + { + {GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH, GSS_KRB5_SET_CRED_RCACHE_OID}, + gss_krb5int_set_cred_rcache + } +}; + +static OM_uint32 +krb5_gssspi_set_cred_option(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + OM_uint32 major_status = GSS_S_FAILURE; + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = (OM_uint32)KRB5_NOCREDS_SUPPLIED; + return GSS_S_NO_CRED; + } + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + major_status = krb5_gss_validate_cred(minor_status, cred_handle); + if (GSS_ERROR(major_status)) + return major_status; + + for (i = 0; i < sizeof(krb5_gssspi_set_cred_option_ops)/ + sizeof(krb5_gssspi_set_cred_option_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gssspi_set_cred_option_ops[i].oid)) { + return (*krb5_gssspi_set_cred_option_ops[i].func)(minor_status, + cred_handle, + desired_object, + value); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + +/* + * gssspi_mech_invoke() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, const gss_OID, const gss_OID, gss_buffer_t); +} krb5_gssspi_mech_invoke_ops[] = { + { + {GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID}, + gss_krb5int_register_acceptor_identity + }, + { + {GSS_KRB5_CCACHE_NAME_OID_LENGTH, GSS_KRB5_CCACHE_NAME_OID}, + gss_krb5int_ccache_name + }, + { + {GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID}, + gss_krb5int_free_lucid_sec_context + }, + { + {GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH, GSS_KRB5_USE_KDC_CONTEXT_OID}, + krb5int_gss_use_kdc_context + } +}; + +static OM_uint32 +krb5_gssspi_mech_invoke (OM_uint32 *minor_status, + const gss_OID desired_mech, + const gss_OID desired_object, + gss_buffer_t value) +{ + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (desired_mech == GSS_C_NO_OID) + return GSS_S_BAD_MECH; + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + for (i = 0; i < sizeof(krb5_gssspi_mech_invoke_ops)/ + sizeof(krb5_gssspi_mech_invoke_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gssspi_mech_invoke_ops[i].oid)) { + return (*krb5_gssspi_mech_invoke_ops[i].func)(minor_status, + desired_mech, + desired_object, + value); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + +static struct gss_config krb5_mechanism = { + { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, + NULL, + krb5_gss_acquire_cred, + krb5_gss_release_cred, + krb5_gss_init_sec_context, +#ifdef LEAN_CLIENT + NULL, +#else + krb5_gss_accept_sec_context, +#endif + krb5_gss_process_context_token, + krb5_gss_delete_sec_context, + krb5_gss_context_time, + krb5_gss_get_mic, + krb5_gss_verify_mic, +#ifdef IOV_SHIM_EXERCISE + NULL, + NULL, +#else + krb5_gss_wrap, + krb5_gss_unwrap, +#endif + krb5_gss_display_status, + krb5_gss_indicate_mechs, + krb5_gss_compare_name, + krb5_gss_display_name, + krb5_gss_import_name, + krb5_gss_release_name, + krb5_gss_inquire_cred, + krb5_gss_add_cred, +#ifdef LEAN_CLIENT + NULL, + NULL, +#else + krb5_gss_export_sec_context, + krb5_gss_import_sec_context, +#endif + krb5_gss_inquire_cred_by_mech, + krb5_gss_inquire_names_for_mech, + krb5_gss_inquire_context, + krb5_gss_internal_release_oid, + krb5_gss_wrap_size_limit, + krb5_gss_export_name, + NULL, /* store_cred */ + NULL, /* import_name_object */ + NULL, /* export_name_object */ + krb5_gss_inquire_sec_context_by_oid, + krb5_gss_inquire_cred_by_oid, + krb5_gss_set_sec_context_option, + krb5_gssspi_set_cred_option, + krb5_gssspi_mech_invoke, + NULL, /* wrap_aead */ + NULL, /* unwrap_aead */ + krb5_gss_wrap_iov, + krb5_gss_unwrap_iov, + krb5_gss_wrap_iov_length, + NULL, /* complete_auth_token */ +}; + + +#ifdef _GSS_STATIC_LINK +#include "mglueP.h" +static int gss_krb5mechglue_init(void) +{ + struct gss_mech_config mech_krb5; + + memset(&mech_krb5, 0, sizeof(mech_krb5)); + mech_krb5.mech = &krb5_mechanism; + mech_krb5.mechNameStr = "kerberos_v5"; + mech_krb5.mech_type = (gss_OID)gss_mech_krb5; + + gssint_register_mechinfo(&mech_krb5); + + mech_krb5.mechNameStr = "kerberos_v5_old"; + mech_krb5.mech_type = (gss_OID)gss_mech_krb5_old; + gssint_register_mechinfo(&mech_krb5); + + mech_krb5.mechNameStr = "mskrb"; + mech_krb5.mech_type = (gss_OID)gss_mech_krb5_wrong; + gssint_register_mechinfo(&mech_krb5); + + return 0; +} +#else +MAKE_INIT_FUNCTION(gss_krb5int_lib_init); +MAKE_FINI_FUNCTION(gss_krb5int_lib_fini); + +gss_mechanism KRB5_CALLCONV +gss_mech_initialize(void) +{ + return &krb5_mechanism; +} +#endif /* _GSS_STATIC_LINK */ + +int gss_krb5int_lib_init(void) +{ + int err; + +#ifdef SHOW_INITFINI_FUNCS + printf("gss_krb5int_lib_init\n"); +#endif + + add_error_table(&et_ggss_error_table); + +#ifndef LEAN_CLIENT + err = k5_mutex_finish_init(&gssint_krb5_keytab_lock); + if (err) + return err; +#endif /* LEAN_CLIENT */ + err = k5_key_register(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, free); + if (err) + return err; + err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free); + if (err) + return err; + err = k5_key_register(K5_KEY_GSS_KRB5_ERROR_MESSAGE, + krb5_gss_delete_error_info); + if (err) + return err; +#ifndef _WIN32 + err = k5_mutex_finish_init(&kg_kdc_flag_mutex); + if (err) + return err; + err = k5_mutex_finish_init(&kg_vdb.mutex); + if (err) + return err; +#endif +#ifdef _GSS_STATIC_LINK + err = gss_krb5mechglue_init(); + if (err) + return err; +#endif + + return 0; +} + +void gss_krb5int_lib_fini(void) +{ +#ifndef _GSS_STATIC_LINK + if (!INITIALIZER_RAN(gss_krb5int_lib_init) || PROGRAM_EXITING()) { +# ifdef SHOW_INITFINI_FUNCS + printf("gss_krb5int_lib_fini: skipping\n"); +# endif + return; + } +#endif +#ifdef SHOW_INITFINI_FUNCS + printf("gss_krb5int_lib_fini\n"); +#endif + remove_error_table(&et_k5g_error_table); + + k5_key_delete(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME); + k5_key_delete(K5_KEY_GSS_KRB5_CCACHE_NAME); + k5_mutex_destroy(&kg_vdb.mutex); +#ifndef _WIN32 + k5_mutex_destroy(&kg_kdc_flag_mutex); +#endif +#ifndef LEAN_CLIENT + k5_mutex_destroy(&gssint_krb5_keytab_lock); +#endif /* LEAN_CLIENT */ +} + +#ifdef _GSS_STATIC_LINK +extern OM_uint32 gssint_lib_init(void); +#endif + +OM_uint32 gss_krb5int_initialize_library (void) +{ +#ifdef _GSS_STATIC_LINK + return gssint_mechglue_initialize_library(); +#else + return CALL_INIT_FUNCTION(gss_krb5int_lib_init); +#endif +} + diff --git a/src/lib/gssapi/krb5/gssapi_krb5.hin b/src/lib/gssapi/krb5/gssapi_krb5.hin index 67791a5802..bf74fe9d04 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.hin +++ b/src/lib/gssapi/krb5/gssapi_krb5.hin @@ -25,6 +25,7 @@ #define _GSSAPI_KRB5_H_ #include <gssapi/gssapi.h> +#include <gssapi/gssapi_ext.h> #include <krb5.h> /* C++ friendlyness */ @@ -266,6 +267,20 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *kctx); +OM_uint32 KRB5_CALLCONV +gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + int ad_type, + gss_buffer_t ad_data); + +OM_uint32 KRB5_CALLCONV +gss_krb5_set_cred_rcache(OM_uint32 *minor_status, + gss_cred_id_t cred, + krb5_rcache rcache); + +OM_uint32 KRB5_CALLCONV +gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, krb5_timestamp *); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/lib/gssapi/krb5/import_sec_context.c b/src/lib/gssapi/krb5/import_sec_context.c index fc6b6aff28..b31d7acf13 100644 --- a/src/lib/gssapi/krb5/import_sec_context.c +++ b/src/lib/gssapi/krb5/import_sec_context.c @@ -46,7 +46,7 @@ gss_OID krb5_gss_convert_static_mech_oid(oid) for (p = krb5_gss_oid_array; p->length; p++) { if ((oid->length == p->length) && (memcmp(oid->elements, p->elements, p->length) == 0)) { - gss_release_oid(&minor_status, &oid); + generic_gss_release_oid(&minor_status, &oid); return (gss_OID) p; } } diff --git a/src/lib/gssapi/krb5/indicate_mechs.c b/src/lib/gssapi/krb5/indicate_mechs.c index 53b8be3e0d..d744af724a 100644 --- a/src/lib/gssapi/krb5/indicate_mechs.c +++ b/src/lib/gssapi/krb5/indicate_mechs.c @@ -33,13 +33,5 @@ krb5_gss_indicate_mechs(minor_status, mech_set) OM_uint32 *minor_status; gss_OID_set *mech_set; { - *minor_status = 0; - - if (gssint_copy_oid_set(minor_status, gss_mech_set_krb5_both, mech_set)) { - *mech_set = GSS_C_NO_OID_SET; - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - return(GSS_S_COMPLETE); + return generic_gss_copy_oid_set(minor_status, gss_mech_set_krb5_both, mech_set); } diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index aee355d774..1b1e11d6f0 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -1,6 +1,7 @@ /* -*- mode: c; indent-tabs-mode: nil -*- */ /* - * Copyright 2000,2002, 2003, 2007, 2008 by the Massachusetts Institute of Technology. + * Copyright 2000, 2002, 2003, 2007, 2008 +>>>>>>> trunk:src/lib/gssapi/krb5/init_sec_context.c * All Rights Reserved. * * Export of this software from the United States of America may @@ -70,9 +71,35 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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 "k5-int.h" -#include "gss_libinit.h" #include "gssapiP_krb5.h" #ifdef HAVE_MEMORY_H #include <memory.h> @@ -222,7 +249,7 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context, return(ENOMEM); } - ptr = data->checksum_data.data; + ptr = (unsigned char *)data->checksum_data.data; TWRITE_INT(ptr, data->md5.length, 0); TWRITE_STR(ptr, (unsigned char *) data->md5.contents, data->md5.length); @@ -301,7 +328,7 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token) mk_req_flags = AP_OPTS_USE_SUBKEY; if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) - mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; + mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_ETYPE_NEGOTIATION; code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, checksum_data, k_cred, &ap_req); @@ -310,32 +337,41 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token) goto cleanup; /* store the interesting stuff from creds and authent */ - ctx->endtime = k_cred->times.endtime; + ctx->krb_times = k_cred->times; ctx->krb_flags = k_cred->ticket_flags; /* build up the token */ + if (ctx->gss_flags & GSS_C_DCE_STYLE) { + /* + * For DCE RPC, do not encapsulate the AP-REQ in the + * typical GSS wrapping. + */ + token->length = ap_req.length; + token->value = ap_req.data; + + ap_req.data = NULL; /* don't double free */ + } else { + /* allocate space for the token */ + tlen = g_token_size((gss_OID) mech_type, ap_req.length); - /* allocate space for the token */ - tlen = g_token_size((gss_OID) mech_type, ap_req.length); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { - code = ENOMEM; - goto cleanup; - } - - /* fill in the buffer */ + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { + code = ENOMEM; + goto cleanup; + } - ptr = t; + /* fill in the buffer */ + ptr = t; - g_make_token_header(mech_type, ap_req.length, - &ptr, KG_TOK_CTX_AP_REQ); + g_make_token_header(mech_type, ap_req.length, + &ptr, KG_TOK_CTX_AP_REQ); - TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); + TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); - /* pass it back */ + /* pass it back */ - token->length = tlen; - token->value = (void *) t; + token->length = tlen; + token->value = (void *) t; + } code = 0; @@ -349,96 +385,6 @@ cleanup: } /* - * setup_enc - * - * Fill in the encryption descriptors. Called after AP-REQ is made. - */ -static OM_uint32 -setup_enc( - OM_uint32 *minor_status, - krb5_gss_ctx_id_rec *ctx, - krb5_context context) -{ - krb5_error_code code; - unsigned int i; - krb5int_access kaccess; - - code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); - if (code) - goto fail; - - ctx->have_acceptor_subkey = 0; - ctx->proto = 0; - ctx->cksumtype = 0; - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_CRC: - ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = SGN_ALG_DES_MAC_MD5; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_DES; - - /* The encryption key is the session key XOR - 0xf0f0f0f0f0f0f0f0. */ - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) - goto fail; - - for (i=0; i<ctx->enc->length; i++) - ctx->enc->contents[i] ^= 0xf0; - - goto copy_subkey_to_seq; - - case ENCTYPE_DES3_CBC_SHA1: - /* MIT extension */ - ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; - ctx->cksum_size = 20; - ctx->sealalg = SEAL_ALG_DES3KD; - - copy_subkey: - code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc); - if (code) - goto fail; - copy_subkey_to_seq: - code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq); - if (code) { - krb5_free_keyblock (context, ctx->enc); - goto fail; - } - break; - - case ENCTYPE_ARCFOUR_HMAC: - /* Microsoft extension */ - ctx->signalg = SGN_ALG_HMAC_MD5 ; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ; - - goto copy_subkey; - - default: - /* Fill some fields we shouldn't be using on this path - with garbage. */ - ctx->signalg = -10; - ctx->sealalg = -10; - - ctx->proto = 1; - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype, - &ctx->cksumtype); - if (code) - goto fail; - code = krb5_c_checksum_length(context, ctx->cksumtype, - &ctx->cksum_size); - if (code) - goto fail; - goto copy_subkey; - } -fail: - *minor_status = code; - return GSS_S_FAILURE; -} - -/* * new_connection * * Do the grunt work of setting up a new context. @@ -516,18 +462,23 @@ new_connection( ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG | ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | - GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))); + GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG | + GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG | + GSS_C_EXTENDED_ERROR_FLAG))); ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ ctx->seqstate = 0; + if (req_flags & GSS_C_DCE_STYLE) + ctx->gss_flags |= GSS_C_MUTUAL_FLAG; + if ((code = krb5_timeofday(context, &now))) goto fail; if (time_req == 0 || time_req == GSS_C_INDEFINITE) { - ctx->endtime = 0; + ctx->krb_times.endtime = 0; } else { - ctx->endtime = now + time_req; + ctx->krb_times.endtime = now + time_req; } if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) @@ -538,10 +489,12 @@ new_connection( goto fail; code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, &k_cred); + ctx->krb_times.endtime, &k_cred); if (code) goto fail; + ctx->krb_times = k_cred->times; + if (default_mech) { mech_type = (gss_OID) gss_mech_krb5; } @@ -558,7 +511,7 @@ new_connection( { /* gsskrb5 v1 */ - krb5_ui_4 seq_temp; + krb5_int32 seq_temp; if ((code = make_ap_req_v1(context, ctx, cred, k_cred, input_chan_bindings, mech_type, &token))) { @@ -576,12 +529,16 @@ new_connection( &ctx->subkey); } - major_status = setup_enc(minor_status, ctx, context); - if (k_cred) { krb5_free_creds(context, k_cred); - k_cred = 0; + k_cred = NULL; } + ctx->enc = NULL; + ctx->seq = NULL; + ctx->have_acceptor_subkey = 0; + code = kg_setup_keys(context, ctx, ctx->subkey, &ctx->cksumtype); + if (code != 0) + goto fail; /* at this point, the context is constructed and valid, hence, releaseable */ @@ -599,7 +556,7 @@ new_connection( if (time_rec) { if ((code = krb5_timeofday(context, &now))) goto fail; - *time_rec = ctx->endtime - now; + *time_rec = ctx->krb_times.endtime - now; } /* set the other returns */ @@ -722,7 +679,11 @@ mutual_auth( ptr = (unsigned char *) input_token->value; - if (g_verify_token_header(ctx->mech_used, + if (ctx->gss_flags & GSS_C_DCE_STYLE) { + /* Raw AP-REP */ + ap_rep.length = input_token->length; + ap_rep.data = (char *)input_token->value; + } else if (g_verify_token_header(ctx->mech_used, &(ap_rep.length), &ptr, KG_TOK_CTX_AP_REP, input_token->length, 1)) { @@ -740,7 +701,7 @@ mutual_auth( if (code) goto fail; if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; + code = (krb5_error_code)krb_error->error + ERROR_TABLE_BASE_krb5; else code = 0; krb5_free_error(context, krb_error); @@ -774,23 +735,38 @@ mutual_auth( (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto); - if (ctx->proto == 1 && ap_rep_data->subkey) { + if (ap_rep_data->subkey != NULL && + (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) || + ap_rep_data->subkey->enctype != ctx->subkey->enctype)) { /* Keep acceptor's subkey. */ ctx->have_acceptor_subkey = 1; code = krb5_copy_keyblock(context, ap_rep_data->subkey, &ctx->acceptor_subkey); - if (code) - goto fail; - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, - ctx->acceptor_subkey->enctype, - &ctx->acceptor_subkey_cksumtype); - if (code) + if (code) { + krb5_free_ap_rep_enc_part(context, ap_rep_data); goto fail; + } + code = kg_setup_keys(context, ctx, ctx->acceptor_subkey, + &ctx->acceptor_subkey_cksumtype); + if (code) { + krb5_free_ap_rep_enc_part(context, ap_rep_data); + goto fail; + } } - /* free the ap_rep_data */ krb5_free_ap_rep_enc_part(context, ap_rep_data); + if (ctx->gss_flags & GSS_C_DCE_STYLE) { + krb5_data outbuf; + + code = krb5_mk_rep_dce(context, ctx->auth_context, &outbuf); + if (code) + goto fail; + + output_token->value = outbuf.data; + output_token->length = outbuf.length; + } + /* set established */ ctx->established = 1; @@ -799,7 +775,7 @@ mutual_auth( if (time_rec) { if ((code = krb5_timeofday(context, &now))) goto fail; - *time_rec = ctx->endtime - now; + *time_rec = ctx->krb_times.endtime - now; } if (ret_flags) @@ -993,7 +969,7 @@ krb5_gss_init_context (krb5_context *ctxp) int is_kdc; #endif - err = gssint_initialize_library(); + err = gss_krb5int_initialize_library(); if (err) return err; #ifndef _WIN32 @@ -1011,19 +987,25 @@ krb5_gss_init_context (krb5_context *ctxp) } #ifndef _WIN32 -krb5_error_code -krb5_gss_use_kdc_context() +OM_uint32 +krb5int_gss_use_kdc_context(OM_uint32 *minor_status, + const gss_OID desired_mech, + const gss_OID desired_object, + gss_buffer_t value) { - krb5_error_code err; + OM_uint32 err; - err = gssint_initialize_library(); - if (err) - return err; - err = k5_mutex_lock(&kg_kdc_flag_mutex); + *minor_status = 0; + + err = gss_krb5int_initialize_library(); if (err) return err; + *minor_status = k5_mutex_lock(&kg_kdc_flag_mutex); + if (*minor_status) { + return GSS_S_FAILURE; + } kdc_flag = 1; k5_mutex_unlock(&kg_kdc_flag_mutex); - return 0; + return GSS_S_COMPLETE; } #endif diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c index 74ae178d81..ed46d9d51a 100644 --- a/src/lib/gssapi/krb5/inq_context.c +++ b/src/lib/gssapi/krb5/inq_context.c @@ -20,6 +20,60 @@ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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. + */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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_krb5.h" @@ -72,7 +126,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, return(GSS_S_FAILURE); } - if ((lifetime = ctx->endtime - now) < 0) + if ((lifetime = ctx->krb_times.endtime - now) < 0) lifetime = 0; if (initiator_name) { @@ -134,3 +188,126 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, *minor_status = 0; return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } + +OM_uint32 +gss_krb5int_inq_session_key( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + krb5_gss_ctx_id_rec *ctx; + krb5_keyblock *key; + gss_buffer_desc keyvalue, keyinfo; + OM_uint32 major_status, minor; + unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6]; + gss_OID_desc oid; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; + + keyvalue.value = key->contents; + keyvalue.length = key->length; + + major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set); + if (GSS_ERROR(major_status)) + goto cleanup; + + oid.elements = oid_buf; + oid.length = sizeof(oid_buf); + + major_status = generic_gss_oid_compose(minor_status, + GSS_KRB5_SESSION_KEY_ENCTYPE_OID, + GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH, + key->enctype, + &oid); + if (GSS_ERROR(major_status)) + goto cleanup; + + keyinfo.value = oid.elements; + keyinfo.length = oid.length; + + major_status = generic_gss_add_buffer_set_member(minor_status, &keyinfo, data_set); + if (GSS_ERROR(major_status)) + goto cleanup; + + return GSS_S_COMPLETE; + +cleanup: + if (*data_set != GSS_C_NO_BUFFER_SET) { + if ((*data_set)->count != 0) + memset((*data_set)->elements[0].value, 0, (*data_set)->elements[0].length); + gss_release_buffer_set(&minor, data_set); + } + + return major_status; +} + +OM_uint32 +gss_krb5int_extract_authz_data_from_sec_context( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + OM_uint32 major_status; + krb5_gss_ctx_id_rec *ctx; + int ad_type = 0; + size_t i; + + *data_set = GSS_C_NO_BUFFER_SET; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + major_status = generic_gss_oid_decompose(minor_status, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, + desired_object, + &ad_type); + if (major_status != GSS_S_COMPLETE || ad_type == 0) { + *minor_status = ENOENT; + return GSS_S_FAILURE; + } + + if (ctx->authdata != NULL) { + for (i = 0; ctx->authdata[i] != NULL; i++) { + if (ctx->authdata[i]->ad_type == ad_type) { + gss_buffer_desc ad_data; + + ad_data.length = ctx->authdata[i]->length; + ad_data.value = ctx->authdata[i]->contents; + + major_status = generic_gss_add_buffer_set_member(minor_status, + &ad_data, data_set); + if (GSS_ERROR(major_status)) + break; + } + } + } + + if (GSS_ERROR(major_status)) { + OM_uint32 tmp; + + generic_gss_release_buffer_set(&tmp, data_set); + } + + return major_status; +} + +OM_uint32 +gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_oid, + gss_buffer_set_t *data_set) +{ + krb5_gss_ctx_id_rec *ctx; + gss_buffer_desc rep; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + rep.value = &ctx->krb_times.authtime; + rep.length = sizeof(ctx->krb_times.authtime); + + return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); +} + diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index d23d7f9510..8560135abe 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -180,7 +180,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, if (cred_handle == GSS_C_NO_CREDENTIAL) krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred); - (void) gss_release_oid_set(minor_status, &mechs); + (void) generic_gss_release_oid_set(minor_status, &mechs); krb5_free_principal(context, ret_name); *minor_status = (OM_uint32) G_VALIDATE_FAILED; krb5_free_context(context); diff --git a/src/lib/gssapi/krb5/inq_names.c b/src/lib/gssapi/krb5/inq_names.c index 2301b1ff4a..5db0ae0ee9 100644 --- a/src/lib/gssapi/krb5/inq_names.c +++ b/src/lib/gssapi/krb5/inq_names.c @@ -50,7 +50,7 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) } /* We're okay. Create an empty OID set */ - major = gss_create_empty_oid_set(minor_status, name_types); + major = generic_gss_create_empty_oid_set(minor_status, name_types); if (major == GSS_S_COMPLETE) { /* Now add our members. */ if ( @@ -93,8 +93,7 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) * status with the release call. */ if (major != GSS_S_COMPLETE) - (void) gss_release_oid_set(&minor, - name_types); + (void) generic_gss_release_oid_set(&minor, name_types); } return(major); } diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index d51fb7344f..dd3603b269 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -79,7 +79,7 @@ make_seal_token_v1 (krb5_context context, * we plan to write out to the token. * tlen is the length of the token * including header. */ - unsigned conflen=0, tmsglen, tlen, msglen; + unsigned int conflen=0, tmsglen, tlen, msglen; unsigned char *t, *ptr; unsigned char *plain; unsigned char pad; @@ -246,8 +246,8 @@ make_seal_token_v1 (krb5_context context, /* create the seq_num */ - if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, - ptr+14, ptr+6))) { + if ((code = kg_make_seq_num(context, seq, direction?0:0xff, + (krb5_ui_4)*seqnum, ptr+14, ptr+6))) { xfree (plain); xfree(t); return(code); @@ -324,7 +324,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req, OM_uint32 *minor_status; gss_ctx_id_t context_handle; int conf_req_flag; - int qop_req; + gss_qop_t qop_req; gss_buffer_t input_message_buffer; int *conf_state; gss_buffer_t output_message_buffer; @@ -400,5 +400,5 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req, *conf_state = conf_req_flag; *minor_status = 0; - return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); + return((ctx->krb_times.endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c new file mode 100644 index 0000000000..a0808addb0 --- /dev/null +++ b/src/lib/gssapi/krb5/k5sealiov.c @@ -0,0 +1,517 @@ +/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* + * lib/gssapi/krb5/k5sealiov.c + * + * 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 <assert.h> +#include "k5-platform.h" /* for 64-bit support */ +#include "k5-int.h" /* for zap() */ +#include "gssapiP_krb5.h" +#include <stdarg.h> + +static krb5_error_code +make_seal_token_v1_iov(krb5_context context, + krb5_gss_ctx_id_rec *ctx, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype) +{ + krb5_error_code code = 0; + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; + krb5_checksum md5cksum; + krb5_checksum cksum; + size_t k5_headerlen = 0, k5_trailerlen = 0; + size_t data_length = 0, assoc_data_length = 0; + size_t tmsglen = 0, tlen; + unsigned char *ptr; + krb5_keyusage sign_usage = KG_USAGE_SIGN; + + assert(toktype == KG_TOK_WRAP_MSG); + + md5cksum.length = cksum.length = 0; + md5cksum.contents = cksum.contents = NULL; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) + return EINVAL; + + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padding == NULL && (ctx->gss_flags & GSS_C_DCE_STYLE) == 0) + return EINVAL; + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + if (trailer != NULL) + trailer->buffer.length = 0; + + /* Determine confounder length */ + if (toktype == KG_TOK_WRAP_MSG || conf_req_flag) + k5_headerlen = kg_confounder_size(context, ctx->enc); + + /* Check padding length */ + if (toktype == KG_TOK_WRAP_MSG) { + size_t k5_padlen = (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) ? 1 : 8; + size_t gss_padlen; + size_t conf_data_length; + + kg_iov_msglen(iov, iov_count, &data_length, &assoc_data_length); + conf_data_length = k5_headerlen + data_length - assoc_data_length; + + if (k5_padlen == 1) + gss_padlen = 1; /* one byte to indicate one byte of padding */ + else + gss_padlen = k5_padlen - (conf_data_length % k5_padlen); + + if (ctx->gss_flags & GSS_C_DCE_STYLE) { + /* DCE will pad the actual data itself; padding buffer optional and will be zeroed */ + gss_padlen = 0; + + if (conf_data_length % k5_padlen) + code = KRB5_BAD_MSIZE; + } else if (padding->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) { + code = kg_allocate_iov(padding, gss_padlen); + } else if (padding->buffer.length < gss_padlen) { + code = KRB5_BAD_MSIZE; + } + if (code != 0) + goto cleanup; + + /* Initialize padding buffer to pad itself */ + if (padding != NULL) { + padding->buffer.length = gss_padlen; + memset(padding->buffer.value, (int)gss_padlen, gss_padlen); + } + + if (ctx->gss_flags & GSS_C_DCE_STYLE) + tmsglen = k5_headerlen; /* confounder length */ + else + tmsglen = conf_data_length + padding->buffer.length; + } + + /* Determine token size */ + tlen = g_token_size(ctx->mech_used, 14 + ctx->cksum_size + tmsglen); + + k5_headerlen += tlen - tmsglen; + + if (header->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) + code = kg_allocate_iov(header, k5_headerlen); + else if (header->buffer.length < k5_headerlen) + code = KRB5_BAD_MSIZE; + if (code != 0) + goto cleanup; + + header->buffer.length = k5_headerlen; + + ptr = (unsigned char *)header->buffer.value; + g_make_token_header(ctx->mech_used, 14 + ctx->cksum_size + tmsglen, &ptr, toktype); + + /* 0..1 SIGN_ALG */ + ptr[0] = (ctx->signalg ) & 0xFF; + ptr[1] = (ctx->signalg >> 8) & 0xFF; + + /* 2..3 SEAL_ALG or Filler */ + if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) { + ptr[2] = (ctx->sealalg ) & 0xFF; + ptr[3] = (ctx->sealalg >> 8) & 0xFF; + } else { + /* No seal */ + ptr[2] = 0xFF; + ptr[3] = 0xFF; + } + + /* 4..5 Filler */ + ptr[4] = 0xFF; + ptr[5] = 0xFF; + + /* pad the plaintext, encrypt if needed, and stick it in the token */ + + /* initialize the checksum */ + switch (ctx->signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + case SGN_ALG_HMAC_MD5: + md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR; + if (toktype != KG_TOK_WRAP_MSG) + sign_usage = 15; + break; + default: + case SGN_ALG_DES_MAC: + abort (); + } + + code = krb5_c_checksum_length(context, md5cksum.checksum_type, &k5_trailerlen); + if (code != 0) + goto cleanup; + md5cksum.length = k5_trailerlen; + + if (k5_headerlen != 0) { + code = kg_make_confounder(context, ctx->enc, ptr + 14 + ctx->cksum_size); + if (code != 0) + goto cleanup; + } + + /* compute the checksum */ + code = kg_make_checksum_iov_v1(context, md5cksum.checksum_type, + ctx->cksum_size, ctx->seq, ctx->enc, + sign_usage, iov, iov_count, toktype, + &md5cksum); + if (code != 0) + goto cleanup; + + switch (ctx->signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_3: + code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? + ctx->seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16); + if (code != 0) + goto cleanup; + + cksum.length = ctx->cksum_size; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + memcpy(ptr + 14, cksum.contents, cksum.length); + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + assert(md5cksum.length == ctx->cksum_size); + memcpy(ptr + 14, md5cksum.contents, md5cksum.length); + break; + case SGN_ALG_HMAC_MD5: + memcpy(ptr + 14, md5cksum.contents, ctx->cksum_size); + break; + } + + /* create the seq_num */ + code = kg_make_seq_num(context, ctx->seq, ctx->initiate ? 0 : 0xFF, + (OM_uint32)ctx->seq_send, ptr + 14, ptr + 6); + if (code != 0) + goto cleanup; + + if (conf_req_flag) { + if (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) { + unsigned char bigend_seqnum[4]; + krb5_keyblock *enc_key; + size_t i; + + bigend_seqnum[0] = (ctx->seq_send >> 24) & 0xFF; + bigend_seqnum[1] = (ctx->seq_send >> 16) & 0xFF; + bigend_seqnum[2] = (ctx->seq_send >> 8 ) & 0xFF; + bigend_seqnum[3] = (ctx->seq_send ) & 0xFF; + + code = krb5_copy_keyblock(context, ctx->enc, &enc_key); + if (code != 0) + goto cleanup; + + assert(enc_key->length == 16); + + for (i = 0; i < enc_key->length; i++) + ((char *)enc_key->contents)[i] ^= 0xF0; + + code = kg_arcfour_docrypt_iov(context, enc_key, 0, + bigend_seqnum, 4, + iov, iov_count); + krb5_free_keyblock(context, enc_key); + } else { + code = kg_encrypt_iov(context, ctx->proto, + ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0), + 0 /*EC*/, 0 /*RRC*/, + ctx->enc, KG_USAGE_SEAL, NULL, + iov, iov_count); + } + if (code != 0) + goto cleanup; + } + + ctx->seq_send++; + ctx->seq_send &= 0xFFFFFFFFL; + + code = 0; + + if (conf_state != NULL) + *conf_state = conf_req_flag; + +cleanup: + if (code != 0) + kg_release_iov(iov, iov_count); + krb5_free_checksum_contents(context, &md5cksum); + + return code; +} + +OM_uint32 +kg_seal_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, + int toktype) +{ + krb5_gss_ctx_id_rec *ctx; + krb5_error_code code; + krb5_timestamp now; + krb5_context context; + + if (qop_req != 0) { + *minor_status = (OM_uint32)G_UNKNOWN_QOP; + return GSS_S_FAILURE; + } + + if (!kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32)G_VALIDATE_FAILED; + return GSS_S_NO_CONTEXT; + } + + ctx = (krb5_gss_ctx_id_rec *)context_handle; + if (!ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + context = ctx->k5_context; + code = krb5_timeofday(context, &now); + if (code != 0) { + *minor_status = code; + save_error_info(*minor_status, context); + return GSS_S_FAILURE; + } + + if (conf_req_flag && kg_integ_only_iov(iov, iov_count)) { + /* may be more sensible to return an error here */ + conf_req_flag = FALSE; + } + + switch (ctx->proto) { + case 0: + code = make_seal_token_v1_iov(context, ctx, conf_req_flag, + conf_state, iov, iov_count, toktype); + break; + case 1: + code = gss_krb5int_make_seal_token_v3_iov(context, ctx, conf_req_flag, + conf_state, iov, iov_count, toktype); + break; + default: + code = G_UNKNOWN_QOP; + break; + } + + if (code != 0) { + *minor_status = code; + save_error_info(*minor_status, context); + return GSS_S_FAILURE; + } + + *minor_status = 0; + + return (ctx->krb_times.endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; +} + +#define INIT_IOV_DATA(_iov) do { (_iov)->buffer.value = NULL; \ + (_iov)->buffer.length = 0; } \ + while (0) + +OM_uint32 +kg_seal_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) +{ + krb5_gss_ctx_id_rec *ctx; + gss_iov_buffer_t header, trailer, padding; + size_t data_length, assoc_data_length; + size_t gss_headerlen, gss_padlen, gss_trailerlen; + unsigned int k5_headerlen = 0, k5_trailerlen = 0, k5_padlen = 0; + krb5_error_code code; + krb5_context context; + int dce_style; + + if (qop_req != GSS_C_QOP_DEFAULT) { + *minor_status = (OM_uint32)G_UNKNOWN_QOP; + return GSS_S_FAILURE; + } + + if (!kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32)G_VALIDATE_FAILED; + return GSS_S_NO_CONTEXT; + } + + ctx = (krb5_gss_ctx_id_rec *)context_handle; + if (!ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + INIT_IOV_DATA(header); + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + if (trailer != NULL) { + INIT_IOV_DATA(trailer); + } + + dce_style = ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0); + + /* For CFX, EC is used instead of padding, and is placed in header or trailer */ + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padding == NULL) { + if (conf_req_flag && ctx->proto == 0 && !dce_style) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } else { + INIT_IOV_DATA(padding); + } + + kg_iov_msglen(iov, iov_count, &data_length, &assoc_data_length); + + if (conf_req_flag && kg_integ_only_iov(iov, iov_count)) + conf_req_flag = FALSE; + + context = ctx->k5_context; + + gss_headerlen = gss_padlen = gss_trailerlen = 0; + + if (ctx->proto == 1) { + krb5_enctype enctype; + size_t ec; + + if (ctx->have_acceptor_subkey) + enctype = ctx->acceptor_subkey->enctype; + else + enctype = ctx->subkey->enctype; + + code = krb5_c_crypto_length(context, enctype, + conf_req_flag ? + KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, + &k5_trailerlen); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + + if (conf_req_flag) { + code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + } + + gss_headerlen = 16; /* Header */ + if (conf_req_flag) { + gss_headerlen += k5_headerlen; /* Kerb-Header */ + gss_trailerlen = 16 /* E(Header) */ + k5_trailerlen; /* Kerb-Trailer */ + + code = krb5_c_padding_length(context, enctype, + data_length - assoc_data_length + 16 /* E(Header) */, &k5_padlen); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + + if (k5_padlen == 0 && dce_style) { + /* Windows rejects AEAD tokens with non-zero EC */ + code = krb5_c_block_size(context, enctype, &ec); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + } else + ec = k5_padlen; + + gss_trailerlen += ec; + } else { + gss_trailerlen = k5_trailerlen; /* Kerb-Checksum */ + } + } else if (!dce_style) { + k5_padlen = (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) ? 1 : 8; + + if (k5_padlen == 1) + gss_padlen = 1; + else + gss_padlen = k5_padlen - ((data_length - assoc_data_length) % k5_padlen); + } + + data_length += gss_padlen; + + if (ctx->proto == 0) { + /* Header | Checksum | Confounder | Data | Pad */ + size_t data_size; + + k5_headerlen = kg_confounder_size(context, ctx->enc); + + data_size = 14 /* Header */ + ctx->cksum_size + k5_headerlen; + + if (!dce_style) + data_size += data_length; + + gss_headerlen = g_token_size(ctx->mech_used, data_size); + + /* g_token_size() will include data_size as well as the overhead, so + * subtract data_length just to get the overhead (ie. token size) */ + if (!dce_style) + gss_headerlen -= data_length; + } + + if (minor_status != NULL) + *minor_status = 0; + + if (trailer == NULL) + gss_headerlen += gss_trailerlen; + else + trailer->buffer.length = gss_trailerlen; + + assert(gss_padlen == 0 || padding != NULL); + + if (padding != NULL) + padding->buffer.length = gss_padlen; + + header->buffer.length = gss_headerlen; + + if (conf_state != NULL) + *conf_state = conf_req_flag; + + return GSS_S_COMPLETE; +} + diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c index 53da04d8d7..71e832e15b 100644 --- a/src/lib/gssapi/krb5/k5sealv3.c +++ b/src/lib/gssapi/krb5/k5sealv3.c @@ -34,8 +34,8 @@ #include "gssapiP_krb5.h" #include <stdarg.h> -static int -rotate_left (void *ptr, size_t bufsiz, size_t rc) +int +gss_krb5int_rotate_left (void *ptr, size_t bufsiz, size_t rc) { /* Optimize for receiving. After some debugging is done, the MIT implementation won't do any rotates on sending, and while @@ -62,10 +62,6 @@ rotate_left (void *ptr, size_t bufsiz, size_t rc) static const gss_buffer_desc empty_message = { 0, 0 }; -#define FLAG_SENDER_IS_ACCEPTOR 0x01 -#define FLAG_WRAP_CONFIDENTIAL 0x02 -#define FLAG_ACCEPTOR_SUBKEY 0x04 - krb5_error_code gss_krb5int_make_seal_token_v3 (krb5_context context, krb5_gss_ctx_id_rec *ctx, @@ -86,8 +82,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, unsigned short tok_id; krb5_checksum sum; krb5_keyblock *key; + krb5_cksumtype cksumtype; - assert(toktype != KG_TOK_SEAL_MSG || ctx->enc != 0); assert(ctx->big_endian == 0); acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR; @@ -100,9 +96,12 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, : KG_USAGE_ACCEPTOR_SIGN)); if (ctx->have_acceptor_subkey) { key = ctx->acceptor_subkey; + cksumtype = ctx->acceptor_subkey_cksumtype; } else { - key = ctx->enc; + key = ctx->subkey; + cksumtype = ctx->cksumtype; } + assert(key != NULL); #ifdef CFX_EXERCISE { @@ -137,7 +136,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, return ENOMEM; /* Get size of ciphertext. */ - bufsize = 16 + krb5_encrypt_size (plain.length, ctx->enc->enctype); + bufsize = 16 + krb5_encrypt_size (plain.length, key->enctype); /* Allocate space for header plus encrypted data. */ outbuf = malloc(bufsize); if (outbuf == NULL) { @@ -146,7 +145,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, } /* TOK_ID */ - store_16_be(0x0504, outbuf); + store_16_be(KG2_TOK_WRAP_MSG, outbuf); /* flags */ outbuf[2] = (acceptor_flag | (conf_req_flag ? FLAG_WRAP_CONFIDENTIAL : 0) @@ -163,7 +162,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, memset(plain.data + message->length, 'x', ec); memcpy(plain.data + message->length + ec, outbuf, 16); - cipher.ciphertext.data = outbuf + 16; + cipher.ciphertext.data = (char *)outbuf + 16; cipher.ciphertext.length = bufsize - 16; cipher.enctype = key->enctype; err = krb5_c_encrypt(context, key, key_usage, 0, &plain, &cipher); @@ -178,19 +177,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, #ifdef CFX_EXERCISE rrc = rand() & 0xffff; - if (rotate_left(outbuf+16, bufsize-16, + if (gss_krb5int_rotate_left(outbuf+16, bufsize-16, (bufsize-16) - (rrc % (bufsize - 16)))) store_16_be(rrc, outbuf+6); /* If the rotate fails, don't worry about it. */ #endif } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) { krb5_data plain; + size_t cksumsize; /* Here, message is the application-supplied data; message2 is what goes into the output token. They may be the same, or message2 may be empty (for MIC). */ - tok_id = 0x0504; + tok_id = KG2_TOK_WRAP_MSG; wrap_with_checksum: plain.length = message->length + 16; @@ -198,10 +198,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, if (plain.data == NULL) return ENOMEM; - if (ctx->cksum_size > 0xffff) - abort(); + err = krb5_c_checksum_length(context, cksumtype, &cksumsize); + if (err) + goto error; + + assert(cksumsize <= 0xffff); - bufsize = 16 + message2->length + ctx->cksum_size; + bufsize = 16 + message2->length + cksumsize; outbuf = malloc(bufsize); if (outbuf == NULL) { free(plain.data); @@ -240,9 +243,9 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, memcpy(outbuf + 16, message2->value, message2->length); sum.contents = outbuf + 16 + message2->length; - sum.length = ctx->cksum_size; + sum.length = cksumsize; - err = krb5_c_make_checksum(context, ctx->cksumtype, key, + err = krb5_c_make_checksum(context, cksumtype, key, key_usage, &plain, &sum); zap(plain.data, plain.length); free(plain.data); @@ -251,9 +254,9 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, zap(outbuf,bufsize); goto error; } - if (sum.length != ctx->cksum_size) + if (sum.length != cksumsize) abort(); - memcpy(outbuf + 16 + message2->length, sum.contents, ctx->cksum_size); + memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize); krb5_free_checksum_contents(context, &sum); sum.contents = 0; /* Now that we know we're actually generating the token... */ @@ -263,21 +266,21 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, #ifdef CFX_EXERCISE rrc = rand() & 0xffff; /* If the rotate fails, don't worry about it. */ - if (rotate_left(outbuf+16, bufsize-16, + if (gss_krb5int_rotate_left(outbuf+16, bufsize-16, (bufsize-16) - (rrc % (bufsize - 16)))) store_16_be(rrc, outbuf+6); #endif /* Fix up EC field. */ - store_16_be(ctx->cksum_size, outbuf+4); + store_16_be(cksumsize, outbuf+4); } else { store_16_be(0xffff, outbuf+6); } } else if (toktype == KG_TOK_MIC_MSG) { - tok_id = 0x0404; + tok_id = KG2_TOK_MIC_MSG; message2 = &empty_message; goto wrap_with_checksum; } else if (toktype == KG_TOK_DEL_CTX) { - tok_id = 0x0405; + tok_id = KG2_TOK_DEL_CTX; message = message2 = &empty_message; goto wrap_with_checksum; } else @@ -303,7 +306,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, krb5_gss_ctx_id_rec *ctx, unsigned char *ptr, unsigned int bodysize, gss_buffer_t message_buffer, - int *conf_state, int *qop_state, int toktype) + int *conf_state, gss_qop_t *qop_state, int toktype) { krb5_context context = *contextptr; krb5_data plain; @@ -315,8 +318,8 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, krb5_error_code err; krb5_boolean valid; krb5_keyblock *key; + krb5_cksumtype cksumtype; - assert(toktype != KG_TOK_SEAL_MSG || ctx->enc != 0); assert(ctx->big_endian == 0); assert(ctx->proto == 1); @@ -343,7 +346,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, return GSS_S_DEFECTIVE_TOKEN; } if ((ptr[2] & FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) { - *minor_status = G_BAD_DIRECTION; + *minor_status = (OM_uint32)G_BAD_DIRECTION; return GSS_S_BAD_SIG; } @@ -364,19 +367,22 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, value in that case, though, so we can just ignore the flag. */ if (ctx->have_acceptor_subkey && (ptr[2] & FLAG_ACCEPTOR_SUBKEY)) { key = ctx->acceptor_subkey; + cksumtype = ctx->acceptor_subkey_cksumtype; } else { - key = ctx->enc; + key = ctx->subkey; + cksumtype = ctx->cksumtype; } + assert(key != NULL); if (toktype == KG_TOK_WRAP_MSG) { - if (load_16_be(ptr) != 0x0504) + if (load_16_be(ptr) != KG2_TOK_WRAP_MSG) goto defective; if (ptr[3] != 0xff) goto defective; ec = load_16_be(ptr+4); rrc = load_16_be(ptr+6); seqnum = load_64_be(ptr+8); - if (!rotate_left(ptr+16, bodysize-16, rrc)) { + if (!gss_krb5int_rotate_left(ptr+16, bodysize-16, rrc)) { no_mem: *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -394,7 +400,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, be larger than the plaintext size. */ cipher.enctype = key->enctype; cipher.ciphertext.length = bodysize - 16; - cipher.ciphertext.data = ptr + 16; + cipher.ciphertext.data = (char *)ptr + 16; plain.length = bodysize - 16; plain.data = malloc(plain.length); if (plain.data == NULL) @@ -408,8 +414,8 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, /* Don't use bodysize here! Use the fact that cipher.ciphertext.length has been adjusted to the correct length. */ - althdr = plain.data + plain.length - 16; - if (load_16_be(althdr) != 0x0504 + althdr = (unsigned char *)plain.data + plain.length - 16; + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG || althdr[2] != ptr[2] || althdr[3] != ptr[3] || memcmp(althdr+8, ptr+8, 8)) { @@ -423,6 +429,12 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, message_buffer->value = NULL; } } else { + size_t cksumsize; + + err = krb5_c_checksum_length(context, cksumtype, &cksumsize); + if (err) + goto error; + /* no confidentiality */ if (conf_state) *conf_state = 0; @@ -437,16 +449,16 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, store_16_be(0, ptr+4); store_16_be(0, ptr+6); plain.length = bodysize-ec; - plain.data = ptr; - if (!rotate_left(ptr, bodysize-ec, 16)) + plain.data = (char *)ptr; + if (!gss_krb5int_rotate_left(ptr, bodysize-ec, 16)) goto no_mem; sum.length = ec; - if (sum.length != ctx->cksum_size) { + if (sum.length != cksumsize) { *minor_status = 0; return GSS_S_BAD_SIG; } sum.contents = ptr+bodysize-ec; - sum.checksum_type = ctx->cksumtype; + sum.checksum_type = cksumtype; err = krb5_c_verify_checksum(context, key, key_usage, &plain, &sum, &valid); if (err) @@ -466,7 +478,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, return err; } else if (toktype == KG_TOK_MIC_MSG) { /* wrap token, no confidentiality */ - if (load_16_be(ptr) != 0x0404) + if (load_16_be(ptr) != KG2_TOK_MIC_MSG) goto defective; verify_mic_1: if (ptr[3] != 0xff) @@ -483,7 +495,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, memcpy(plain.data + message_buffer->length, ptr, 16); sum.length = bodysize - 16; sum.contents = ptr + 16; - sum.checksum_type = ctx->cksumtype; + sum.checksum_type = cksumtype; err = krb5_c_verify_checksum(context, key, key_usage, &plain, &sum, &valid); free(plain.data); @@ -502,9 +514,9 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, *minor_status = 0; return err; } else if (toktype == KG_TOK_DEL_CTX) { - if (load_16_be(ptr) != 0x0405) + if (load_16_be(ptr) != KG2_TOK_DEL_CTX) goto defective; - message_buffer = &empty_message; + message_buffer = (gss_buffer_t)&empty_message; goto verify_mic_1; } else { goto defective; diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c new file mode 100644 index 0000000000..41e6132cd9 --- /dev/null +++ b/src/lib/gssapi/krb5/k5sealv3iov.c @@ -0,0 +1,469 @@ +/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* + * lib/gssapi/krb5/k5sealv3iov.c + * + * 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 <assert.h> +#include "k5-platform.h" /* for 64-bit support */ +#include "k5-int.h" /* for zap() */ +#include "gssapiP_krb5.h" +#include <stdarg.h> + +krb5_error_code +gss_krb5int_make_seal_token_v3_iov(krb5_context context, + krb5_gss_ctx_id_rec *ctx, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype) +{ + krb5_error_code code = 0; + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; + unsigned char acceptor_flag; + unsigned short tok_id; + unsigned char *outbuf = NULL; + unsigned char *tbuf = NULL; + int key_usage; + size_t rrc = 0; + size_t gss_headerlen, gss_trailerlen; + krb5_keyblock *key; + krb5_cksumtype cksumtype; + size_t data_length, assoc_data_length; + + assert(ctx->big_endian == 0); + assert(ctx->proto == 1); + + acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR; + key_usage = (toktype == KG_TOK_WRAP_MSG + ? (ctx->initiate + ? KG_USAGE_INITIATOR_SEAL + : KG_USAGE_ACCEPTOR_SEAL) + : (ctx->initiate + ? KG_USAGE_INITIATOR_SIGN + : KG_USAGE_ACCEPTOR_SIGN)); + if (ctx->have_acceptor_subkey) { + key = ctx->acceptor_subkey; + cksumtype = ctx->acceptor_subkey_cksumtype; + } else { + key = ctx->subkey; + cksumtype = ctx->cksumtype; + } + assert(key != NULL); + assert(cksumtype != 0); + + kg_iov_msglen(iov, iov_count, &data_length, &assoc_data_length); + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) + return EINVAL; + + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padding != NULL) + padding->buffer.length = 0; + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + outbuf = (unsigned char *)header->buffer.value; + + if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) { + unsigned int k5_headerlen, k5_trailerlen, k5_padlen; + size_t ec = 0; + size_t conf_data_length = data_length - assoc_data_length; + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + if (code != 0) + goto cleanup; + + code = krb5_c_padding_length(context, key->enctype, + conf_data_length + 16 /* E(Header) */, &k5_padlen); + if (code != 0) + goto cleanup; + + if (k5_padlen == 0 && (ctx->gss_flags & GSS_C_DCE_STYLE)) { + /* Windows rejects AEAD tokens with non-zero EC */ + code = krb5_c_block_size(context, key->enctype, &ec); + if (code != 0) + goto cleanup; + } else + ec = k5_padlen; + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); + if (code != 0) + goto cleanup; + + gss_headerlen = 16 /* Header */ + k5_headerlen; + gss_trailerlen = ec + 16 /* E(Header) */ + k5_trailerlen; + + if (trailer == NULL) { + rrc = gss_trailerlen; + /* Workaround for Windows bug where it rotates by EC + RRC */ + if (ctx->gss_flags & GSS_C_DCE_STYLE) + rrc -= ec; + gss_headerlen += gss_trailerlen; + } + + if (header->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) + code = kg_allocate_iov(header, gss_headerlen); + else if (header->buffer.length < gss_headerlen) + code = KRB5_BAD_MSIZE; + if (code != 0) + goto cleanup; + header->buffer.length = gss_headerlen; + + if (trailer != NULL) { + if (trailer->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) + code = kg_allocate_iov(trailer, gss_trailerlen); + else if (trailer->buffer.length < gss_trailerlen) + code = KRB5_BAD_MSIZE; + if (code != 0) + goto cleanup; + trailer->buffer.length = gss_trailerlen; + } + + /* TOK_ID */ + store_16_be(KG2_TOK_WRAP_MSG, outbuf); + /* flags */ + outbuf[2] = (acceptor_flag + | (conf_req_flag ? FLAG_WRAP_CONFIDENTIAL : 0) + | (ctx->have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0)); + /* filler */ + outbuf[3] = 0xFF; + /* EC */ + store_16_be(ec, outbuf + 4); + /* RRC */ + store_16_be(0, outbuf + 6); + store_64_be(ctx->seq_send, outbuf + 8); + + /* EC | copy of header to be encrypted, located in (possibly rotated) trailer */ + if (trailer == NULL) + tbuf = (unsigned char *)header->buffer.value + 16; /* Header */ + else + tbuf = (unsigned char *)trailer->buffer.value; + + memset(tbuf, 0xFF, ec); + memcpy(tbuf + ec, header->buffer.value, 16); + + code = kg_encrypt_iov(context, ctx->proto, + ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0), + ec, rrc, key, key_usage, 0, iov, iov_count); + if (code != 0) + goto cleanup; + + /* RRC */ + store_16_be(rrc, outbuf + 6); + + ctx->seq_send++; + } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) { + tok_id = KG2_TOK_WRAP_MSG; + + wrap_with_checksum: + + gss_headerlen = 16; + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &gss_trailerlen); + if (code != 0) + goto cleanup; + + assert(gss_trailerlen <= 0xFFFF); + + if (trailer == NULL) { + rrc = gss_trailerlen; + gss_headerlen += gss_trailerlen; + } + + if (header->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) + code = kg_allocate_iov(header, gss_headerlen); + else if (header->buffer.length < gss_headerlen) + code = KRB5_BAD_MSIZE; + if (code != 0) + goto cleanup; + header->buffer.length = gss_headerlen; + + if (trailer != NULL) { + if (trailer->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) + code = kg_allocate_iov(trailer, gss_trailerlen); + else if (trailer->buffer.length < gss_trailerlen) + code = KRB5_BAD_MSIZE; + if (code != 0) + goto cleanup; + trailer->buffer.length = gss_trailerlen; + } + + /* TOK_ID */ + store_16_be(tok_id, outbuf); + /* flags */ + outbuf[2] = (acceptor_flag + | (ctx->have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0)); + /* filler */ + outbuf[3] = 0xFF; + if (toktype == KG_TOK_WRAP_MSG) { + /* Use 0 for checksum calculation, substitute + * checksum length later. + */ + /* EC */ + store_16_be(0, outbuf + 4); + /* RRC */ + store_16_be(0, outbuf + 6); + } else { + /* MIC and DEL store 0xFF in EC and RRC */ + store_16_be(0xFFFF, outbuf + 4); + store_16_be(0xFFFF, outbuf + 6); + } + store_64_be(ctx->seq_send, outbuf + 8); + + code = kg_make_checksum_iov_v3(context, cksumtype, + rrc, key, key_usage, + iov, iov_count); + if (code != 0) + goto cleanup; + + ctx->seq_send++; + + if (toktype == KG_TOK_WRAP_MSG) { + /* Fix up EC field */ + store_16_be(gss_trailerlen, outbuf + 4); + /* Fix up RRC field */ + store_16_be(rrc, outbuf + 6); + } + } else if (toktype == KG_TOK_MIC_MSG) { + tok_id = KG2_TOK_MIC_MSG; + trailer = NULL; + goto wrap_with_checksum; + } else if (toktype == KG_TOK_DEL_CTX) { + tok_id = KG2_TOK_DEL_CTX; + goto wrap_with_checksum; + } else { + abort(); + } + + code = 0; + +cleanup: + if (code != 0) + kg_release_iov(iov, iov_count); + + return code; +} + +OM_uint32 +gss_krb5int_unseal_v3_iov(krb5_context context, + OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + gss_iov_buffer_desc *iov, + int iov_count, + int *conf_state, + gss_qop_t *qop_state, + int toktype) +{ + OM_uint32 code; + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; + unsigned char acceptor_flag; + unsigned char *ptr = NULL; + int key_usage; + size_t rrc, ec; + size_t data_length, assoc_data_length; + krb5_keyblock *key; + gssint_uint64 seqnum; + krb5_boolean valid; + krb5_cksumtype cksumtype; + int conf_flag = 0; + + assert(ctx->big_endian == 0); + assert(ctx->proto == 1); + + if (qop_state != NULL) + *qop_state = GSS_C_QOP_DEFAULT; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padding != NULL && padding->buffer.length != 0) + return GSS_S_DEFECTIVE_TOKEN; + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + acceptor_flag = ctx->initiate ? FLAG_SENDER_IS_ACCEPTOR : 0; + key_usage = (toktype == KG_TOK_WRAP_MSG + ? (!ctx->initiate + ? KG_USAGE_INITIATOR_SEAL + : KG_USAGE_ACCEPTOR_SEAL) + : (!ctx->initiate + ? KG_USAGE_INITIATOR_SIGN + : KG_USAGE_ACCEPTOR_SIGN)); + + kg_iov_msglen(iov, iov_count, &data_length, &assoc_data_length); + + ptr = (unsigned char *)header->buffer.value; + + if (header->buffer.length < 16) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + if ((ptr[2] & FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) { + *minor_status = (OM_uint32)G_BAD_DIRECTION; + return GSS_S_BAD_SIG; + } + + if (ctx->have_acceptor_subkey && (ptr[2] & FLAG_ACCEPTOR_SUBKEY)) { + key = ctx->acceptor_subkey; + cksumtype = ctx->acceptor_subkey_cksumtype; + } else { + key = ctx->subkey; + cksumtype = ctx->cksumtype; + } + assert(key != NULL); + + + if (toktype == KG_TOK_WRAP_MSG) { + unsigned int k5_trailerlen; + + if (load_16_be(ptr) != KG2_TOK_WRAP_MSG) + goto defective; + conf_flag = ((ptr[2] & FLAG_WRAP_CONFIDENTIAL) != 0); + if (ptr[3] != 0xFF) + goto defective; + ec = load_16_be(ptr + 4); + rrc = load_16_be(ptr + 6); + seqnum = load_64_be(ptr + 8); + + code = krb5_c_crypto_length(context, key->enctype, + conf_flag ? KRB5_CRYPTO_TYPE_TRAILER : + KRB5_CRYPTO_TYPE_CHECKSUM, + &k5_trailerlen); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + + /* Deal with RRC */ + if (trailer == NULL) { + size_t desired_rrc = k5_trailerlen; + + if (conf_flag) { + desired_rrc += 16; /* E(Header) */ + + if ((ctx->gss_flags & GSS_C_DCE_STYLE) == 0) + desired_rrc += ec; + } + + /* According to MS, we only need to deal with a fixed RRC for DCE */ + if (rrc != desired_rrc) + goto defective; + } else if (rrc != 0) { + /* Should have been rotated by kg_unseal_stream_iov() */ + goto defective; + } + + if (conf_flag) { + unsigned char *althdr; + + /* Decrypt */ + code = kg_decrypt_iov(context, ctx->proto, + ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0), + ec, rrc, + key, key_usage, 0, iov, iov_count); + if (code != 0) { + *minor_status = code; + return GSS_S_BAD_SIG; + } + + /* Validate header integrity */ + if (trailer == NULL) + althdr = (unsigned char *)header->buffer.value + 16 + ec; + else + althdr = (unsigned char *)trailer->buffer.value + ec; + + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG + || althdr[2] != ptr[2] + || althdr[3] != ptr[3] + || memcmp(althdr + 8, ptr + 8, 8) != 0) { + *minor_status = 0; + return GSS_S_BAD_SIG; + } + } else { + /* Verify checksum: note EC is checksum size here, not padding */ + if (ec != k5_trailerlen) + goto defective; + + /* Zero EC, RRC before computing checksum */ + store_16_be(0, ptr + 4); + store_16_be(0, ptr + 6); + + code = kg_verify_checksum_iov_v3(context, cksumtype, rrc, + key, key_usage, + iov, iov_count, &valid); + if (code != 0 || valid == FALSE) { + *minor_status = code; + return GSS_S_BAD_SIG; + } + } + + code = g_order_check(&ctx->seqstate, seqnum); + } else if (toktype == KG_TOK_MIC_MSG) { + if (load_16_be(ptr) != KG2_TOK_MIC_MSG) + goto defective; + + verify_mic_1: + if (ptr[3] != 0xFF) + goto defective; + seqnum = load_64_be(ptr + 8); + + code = kg_verify_checksum_iov_v3(context, cksumtype, 0, + key, key_usage, + iov, iov_count, &valid); + if (code != 0 || valid == FALSE) { + *minor_status = code; + return GSS_S_BAD_SIG; + } + code = g_order_check(&ctx->seqstate, seqnum); + } else if (toktype == KG_TOK_DEL_CTX) { + if (load_16_be(ptr) != KG2_TOK_DEL_CTX) + goto defective; + goto verify_mic_1; + } else { + goto defective; + } + + *minor_status = 0; + + if (conf_state != NULL) + *conf_state = conf_flag; + + return code; + +defective: + *minor_status = 0; + + return GSS_S_DEFECTIVE_TOKEN; +} diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index f80be3fa27..4b70fd02ad 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -165,13 +165,13 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, /* decode the message, if SEAL */ if (toktype == KG_TOK_SEAL_MSG) { - int tmsglen = bodysize-(14+cksum_len); + size_t tmsglen = bodysize-(14+cksum_len); if (sealalg != 0xffff) { if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { *minor_status = ENOMEM; return(GSS_S_FAILURE); } - if (ctx->enc->enctype == ENCTYPE_ARCFOUR_HMAC) { + if (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) { unsigned char bigend_seqnum[4]; krb5_keyblock *enc_key; int i; @@ -449,7 +449,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, return(GSS_S_FAILURE); } - if (now > ctx->endtime) { + if (now > ctx->krb_times.endtime) { *minor_status = 0; return(GSS_S_CONTEXT_EXPIRED); } @@ -463,11 +463,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, message_buffer->value = NULL; message_buffer->length = 0; } - *minor_status = G_BAD_DIRECTION; + *minor_status = (OM_uint32)G_BAD_DIRECTION; return(GSS_S_BAD_SIG); } - retval = g_order_check(&(ctx->seqstate), seqnum); + retval = g_order_check(&(ctx->seqstate), (gssint_uint64)seqnum); /* success or ordering violation */ @@ -486,7 +486,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer, gss_buffer_t input_token_buffer; gss_buffer_t message_buffer; int *conf_state; - int *qop_state; + gss_qop_t *qop_state; int toktype; { krb5_gss_ctx_id_rec *ctx; @@ -515,23 +515,8 @@ kg_unseal(minor_status, context_handle, input_token_buffer, ptr = (unsigned char *) input_token_buffer->value; - if (ctx->proto) - switch (toktype) { - case KG_TOK_SIGN_MSG: - toktype2 = 0x0404; - break; - case KG_TOK_SEAL_MSG: - toktype2 = 0x0504; - break; - case KG_TOK_DEL_CTX: - toktype2 = 0x0405; - break; - default: - toktype2 = toktype; - break; - } - else - toktype2 = toktype; + toktype2 = kg_map_toktype(ctx->proto, toktype); + err = g_verify_token_header(ctx->mech_used, &bodysize, &ptr, toktype2, input_token_buffer->length, diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c new file mode 100644 index 0000000000..c72e2db39c --- /dev/null +++ b/src/lib/gssapi/krb5/k5unsealiov.c @@ -0,0 +1,631 @@ +/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* + * lib/gssapi/krb5/k5unsealiov.c + * + * 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 <assert.h> +#include "k5-platform.h" /* for 64-bit support */ +#include "k5-int.h" /* for zap() */ +#include "gssapiP_krb5.h" +#include <stdarg.h> + +static OM_uint32 +kg_unseal_v1_iov(krb5_context context, + OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + gss_iov_buffer_desc *iov, + int iov_count, + size_t token_wrapper_len, + int *conf_state, + gss_qop_t *qop_state, + int toktype) +{ + OM_uint32 code; + gss_iov_buffer_t header; + gss_iov_buffer_t trailer; + unsigned char *ptr; + int sealalg; + int signalg; + krb5_checksum cksum; + krb5_checksum md5cksum; + krb5_timestamp now; + size_t cksum_len = 0; + size_t conflen = 0; + int direction; + krb5_ui_4 seqnum; + OM_uint32 retval; + size_t sumlen; + krb5_keyusage sign_usage = KG_USAGE_SIGN; + + assert(toktype == KG_TOK_WRAP_MSG); + + md5cksum.length = cksum.length = 0; + md5cksum.contents = cksum.contents = NULL; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + if (trailer != NULL && trailer->buffer.length != 0) { + *minor_status = (OM_uint32)KRB5_BAD_MSIZE; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (header->buffer.length < token_wrapper_len + 14) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + ptr = (unsigned char *)header->buffer.value + token_wrapper_len; + + signalg = ptr[0]; + signalg |= ptr[1] << 8; + + sealalg = ptr[2]; + sealalg |= ptr[3] << 8; + + if (ptr[4] != 0xFF || ptr[5] != 0xFF) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (toktype != KG_TOK_WRAP_MSG && sealalg != 0xFFFF) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (toktype == KG_TOK_WRAP_MSG && + !(sealalg == 0xFFFF || sealalg == ctx->sealalg)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) || + (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) || + (ctx->sealalg == SEAL_ALG_DES3KD && + signalg != SGN_ALG_HMAC_SHA1_DES3_KD)|| + (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4 && + signalg != SGN_ALG_HMAC_MD5)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + cksum_len = 8; + if (toktype != KG_TOK_WRAP_MSG) + sign_usage = 15; + break; + case SGN_ALG_3: + cksum_len = 16; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + cksum_len = 20; + break; + default: + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + /* get the token parameters */ + code = kg_get_seq_num(context, ctx->seq, ptr + 14, ptr + 6, &direction, + &seqnum); + if (code != 0) { + *minor_status = code; + return GSS_S_BAD_SIG; + } + + assert(ctx->big_endian == 0); + + /* decode the message, if SEAL */ + if (toktype == KG_TOK_WRAP_MSG) { + if (sealalg != 0xFFFF) { + if (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) { + unsigned char bigend_seqnum[4]; + krb5_keyblock *enc_key; + size_t i; + + bigend_seqnum[0] = (seqnum >> 24) & 0xFF; + bigend_seqnum[1] = (seqnum >> 16) & 0xFF; + bigend_seqnum[2] = (seqnum >> 8 ) & 0xFF; + bigend_seqnum[3] = (seqnum ) & 0xFF; + + code = krb5_copy_keyblock(context, ctx->enc, &enc_key); + if (code != 0) { + retval = GSS_S_FAILURE; + goto cleanup; + } + + assert(enc_key->length == 16); + + for (i = 0; i < enc_key->length; i++) + ((char *)enc_key->contents)[i] ^= 0xF0; + + code = kg_arcfour_docrypt_iov(context, enc_key, 0, + &bigend_seqnum[0], 4, + iov, iov_count); + krb5_free_keyblock(context, enc_key); + } else { + code = kg_decrypt_iov(context, ctx->proto, + ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0), + 0 /*EC*/, 0 /*RRC*/, + ctx->enc, KG_USAGE_SEAL, NULL, + iov, iov_count); + } + if (code != 0) { + retval = GSS_S_FAILURE; + goto cleanup; + } + } + conflen = kg_confounder_size(context, ctx->enc); + } + + if (header->buffer.length != token_wrapper_len + 14 + cksum_len + conflen) { + retval = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; + } + + /* compute the checksum of the message */ + + /* initialize the checksum */ + + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_DES_MAC: + case SGN_ALG_3: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_MD5: + md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + default: + abort(); + } + + code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen); + if (code != 0) { + retval = GSS_S_FAILURE; + goto cleanup; + } + md5cksum.length = sumlen; + + /* compute the checksum of the message */ + code = kg_make_checksum_iov_v1(context, md5cksum.checksum_type, + cksum_len, ctx->seq, ctx->enc, + sign_usage, iov, iov_count, toktype, + &md5cksum); + if (code != 0) { + retval = GSS_S_FAILURE; + goto cleanup; + } + + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_3: + code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? + ctx->seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16); + if (code != 0) { + retval = GSS_S_FAILURE; + goto cleanup; + } + + cksum.length = cksum_len; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + code = memcmp(cksum.contents, ptr + 14, cksum.length); + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + case SGN_ALG_HMAC_MD5: + code = memcmp(md5cksum.contents, ptr + 14, cksum_len); + break; + default: + code = 0; + retval = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; + break; + } + + if (code != 0) { + code = 0; + retval = GSS_S_BAD_SIG; + goto cleanup; + } + + /* + * For GSS_C_DCE_STYLE, the caller manages the padding, because the + * pad length is in the RPC PDU. The value of the padding may be + * uninitialized. For normal GSS, the last bytes of the decrypted + * data contain the pad length. kg_fixup_padding_iov() will find + * this and fixup the last data IOV appropriately. + */ + if (toktype == KG_TOK_WRAP_MSG && + (ctx->gss_flags & GSS_C_DCE_STYLE) == 0) { + retval = kg_fixup_padding_iov(&code, iov, iov_count); + if (retval != GSS_S_COMPLETE) + goto cleanup; + } + + if (conf_state != NULL) + *conf_state = (sealalg != 0xFFFF); + + if (qop_state != NULL) + *qop_state = GSS_C_QOP_DEFAULT; + + code = krb5_timeofday(context, &now); + if (code != 0) { + *minor_status = code; + retval = GSS_S_FAILURE; + goto cleanup; + } + + if (now > ctx->krb_times.endtime) { + *minor_status = 0; + retval = GSS_S_CONTEXT_EXPIRED; + goto cleanup; + } + + if ((ctx->initiate && direction != 0xff) || + (!ctx->initiate && direction != 0)) { + *minor_status = (OM_uint32)G_BAD_DIRECTION; + retval = GSS_S_BAD_SIG; + } + + code = 0; + retval = g_order_check(&ctx->seqstate, (gssint_uint64)seqnum); + +cleanup: + krb5_free_checksum_contents(context, &md5cksum); + + *minor_status = code; + + return retval; +} + +/* + * Caller must provide TOKEN | DATA | PADDING | TRAILER, except + * for DCE in which case it can just provide TOKEN | DATA (must + * guarantee that DATA is padded) + */ +static OM_uint32 +kg_unseal_iov_token(OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype, + int toktype2) +{ + krb5_error_code code; + krb5_context context = ctx->k5_context; + unsigned char *ptr; + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; + size_t input_length; + unsigned int bodysize; + int vfyflags = 0; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + ptr = (unsigned char *)header->buffer.value; + input_length = header->buffer.length; + + if ((ctx->gss_flags & GSS_C_DCE_STYLE) == 0) { + size_t data_length, assoc_data_length; + + kg_iov_msglen(iov, iov_count, &data_length, &assoc_data_length); + + input_length += data_length - assoc_data_length; + + if (padding != NULL) + input_length += padding->buffer.length; + + if (trailer != NULL) + input_length += trailer->buffer.length; + } + + if (ctx->proto == 0) + vfyflags |= G_VFY_TOKEN_HDR_WRAPPER_REQUIRED; + if (ctx->gss_flags & GSS_C_DCE_STYLE) + vfyflags |= G_VFY_TOKEN_HDR_IGNORE_SEQ_SIZE; + + code = g_verify_token_header(ctx->mech_used, + &bodysize, &ptr, toktype2, + input_length, vfyflags); + if (code != 0) { + *minor_status = code; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (ctx->proto == 0) + code = kg_unseal_v1_iov(context, minor_status, ctx, iov, iov_count, + (size_t)(ptr - (unsigned char *)header->buffer.value), + conf_state, qop_state, toktype); + else + code = gss_krb5int_unseal_v3_iov(context, minor_status, ctx, iov, iov_count, + conf_state, qop_state, toktype); + + if (code != 0) + save_error_info(*minor_status, context); + + return code; +} + +/* + * Split a STREAM | SIGN_DATA | DATA into + * HEADER | SIGN_DATA | DATA | PADDING | TRAILER + */ +static OM_uint32 +kg_unseal_stream_iov(OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype, + int toktype2) +{ + unsigned char *ptr; + unsigned int bodysize; + OM_uint32 code = 0, major_status = GSS_S_FAILURE; + krb5_context context = ctx->k5_context; + int conf_req_flag; + int i = 0, j; + gss_iov_buffer_desc *tiov = NULL; + gss_iov_buffer_t stream, data = NULL; + gss_iov_buffer_t theader, tdata = NULL, tpadding, ttrailer; + + assert(toktype == KG_TOK_WRAP_MSG); + assert(toktype2 == KG_TOK_WRAP_MSG || toktype2 == KG2_TOK_WRAP_MSG); + + if (toktype != KG_TOK_WRAP_MSG || (ctx->gss_flags & GSS_C_DCE_STYLE)) { + code = EINVAL; + goto cleanup; + } + + stream = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM); + assert(stream != NULL); + + ptr = (unsigned char *)stream->buffer.value; + + code = g_verify_token_header(ctx->mech_used, + &bodysize, &ptr, toktype2, + stream->buffer.length, + ctx->proto ? 0 : G_VFY_TOKEN_HDR_WRAPPER_REQUIRED); + if (code != 0) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; + } + + tiov = (gss_iov_buffer_desc *)calloc((size_t)iov_count + 2, sizeof(gss_iov_buffer_desc)); + if (tiov == NULL) { + code = ENOMEM; + goto cleanup; + } + + /* HEADER */ + theader = &tiov[i++]; + theader->type = GSS_IOV_BUFFER_TYPE_HEADER; + theader->buffer.value = stream->buffer.value; + theader->buffer.length = ptr - (unsigned char *)stream->buffer.value; + if (bodysize < 14 || + stream->buffer.length != theader->buffer.length + bodysize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; + } + theader->buffer.length += 14; + + /* n[SIGN_DATA] | DATA | m[SIGN_DATA] */ + for (j = 0; j < iov_count; j++) { + OM_uint32 type = GSS_IOV_BUFFER_TYPE(iov[j].type); + + if (type == GSS_IOV_BUFFER_TYPE_DATA) { + if (data != NULL) { + /* only a single DATA buffer can appear */ + code = EINVAL; + goto cleanup; + } + + data = &iov[j]; + tdata = &tiov[i]; + } + if (type == GSS_IOV_BUFFER_TYPE_DATA || + type == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + tiov[i++] = iov[j]; + } + + if (data == NULL) { + /* a single DATA buffer must be present */ + code = EINVAL; + goto cleanup; + } + + /* PADDING | TRAILER */ + tpadding = &tiov[i++]; + tpadding->type = GSS_IOV_BUFFER_TYPE_PADDING; + tpadding->buffer.length = 0; + tpadding->buffer.value = NULL; + + ttrailer = &tiov[i++]; + ttrailer->type = GSS_IOV_BUFFER_TYPE_TRAILER; + + if (ctx->proto == 1) { + size_t ec, rrc; + krb5_enctype enctype = ctx->enc->enctype; + unsigned int k5_headerlen = 0; + unsigned int k5_trailerlen = 0; + + conf_req_flag = ((ptr[0] & FLAG_WRAP_CONFIDENTIAL) != 0); + ec = conf_req_flag ? load_16_be(ptr + 2) : 0; + rrc = load_16_be(ptr + 4); + + if (rrc != 0) { + if (!gss_krb5int_rotate_left((unsigned char *)stream->buffer.value + 16, + stream->buffer.length - 16, rrc)) { + code = ENOMEM; + goto cleanup; + } + store_16_be(0, ptr + 4); /* set RRC to zero */ + } + + if (conf_req_flag) { + code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + if (code != 0) + goto cleanup; + theader->buffer.length += k5_headerlen; /* length validated later */ + } + + /* no PADDING for CFX, EC is used instead */ + code = krb5_c_crypto_length(context, enctype, + conf_req_flag ? KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, + &k5_trailerlen); + if (code != 0) + goto cleanup; + + ttrailer->buffer.length = ec + (conf_req_flag ? 16 : 0 /* E(Header) */) + k5_trailerlen; + ttrailer->buffer.value = (unsigned char *)stream->buffer.value + + stream->buffer.length - ttrailer->buffer.length; + } else { + theader->buffer.length += ctx->cksum_size + kg_confounder_size(context, ctx->enc); + + /* + * we can't set the padding accurately until decryption; + * kg_fixup_padding_iov() will take care of this + */ + tpadding->buffer.length = 1; + tpadding->buffer.value = (unsigned char *)stream->buffer.value + stream->buffer.length - 1; + + /* no TRAILER for pre-CFX */ + ttrailer->buffer.length = 0; + ttrailer->buffer.value = NULL; + } + + /* IOV: -----------0-------------+---1---+--2--+----------------3--------------*/ + /* Old: GSS-Header | Conf | Data | Pad | */ + /* CFX: GSS-Header | Kerb-Header | Data | | EC | E(Header) | Kerb-Trailer */ + /* GSS: -------GSS-HEADER--------+-DATA--+-PAD-+----------GSS-TRAILER----------*/ + + /* validate lengths */ + if (stream->buffer.length < theader->buffer.length + + tpadding->buffer.length + + ttrailer->buffer.length) + { + code = (OM_uint32)KRB5_BAD_MSIZE; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; + } + + /* setup data */ + tdata->buffer.length = stream->buffer.length - ttrailer->buffer.length - + tpadding->buffer.length - theader->buffer.length; + + assert(data != NULL); + + if (data->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) { + code = kg_allocate_iov(tdata, tdata->buffer.length); + if (code != 0) + goto cleanup; + memcpy(tdata->buffer.value, + (unsigned char *)stream->buffer.value + theader->buffer.length, tdata->buffer.length); + } else + tdata->buffer.value = (unsigned char *)stream->buffer.value + theader->buffer.length; + + assert(i <= iov_count + 2); + + major_status = kg_unseal_iov_token(&code, ctx, conf_state, qop_state, + tiov, i, toktype, toktype2); + if (major_status == GSS_S_COMPLETE) + *data = *tdata; + else if (tdata->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { + OM_uint32 tmp; + + gss_release_buffer(&tmp, &tdata->buffer); + tdata->type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); + } + +cleanup: + if (tiov != NULL) + free(tiov); + + *minor_status = code; + + return major_status; +} + +OM_uint32 +kg_unseal_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, + int toktype) +{ + krb5_gss_ctx_id_rec *ctx; + OM_uint32 code; + int toktype2; + + if (!kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32)G_VALIDATE_FAILED; + return GSS_S_NO_CONTEXT; + } + + ctx = (krb5_gss_ctx_id_rec *)context_handle; + if (!ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + toktype2 = kg_map_toktype(ctx->proto, toktype); + + if (kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM) != NULL) { + code = kg_unseal_stream_iov(minor_status, ctx, conf_state, qop_state, + iov, iov_count, toktype, toktype2); + } else { + code = kg_unseal_iov_token(minor_status, ctx, conf_state, qop_state, + iov, iov_count, toktype, toktype2); + } + + return code; +} + diff --git a/src/lib/gssapi/krb5/krb5_gss_glue.c b/src/lib/gssapi/krb5/krb5_gss_glue.c index 265818bf68..5b7cbdf21c 100644 --- a/src/lib/gssapi/krb5/krb5_gss_glue.c +++ b/src/lib/gssapi/krb5/krb5_gss_glue.c @@ -20,1191 +20,391 @@ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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. + */ /* * $Id$ */ #include "gssapiP_krb5.h" -#include "mglueP.h" -#include "../spnego/gssapiP_spnego.h" - - -/** mechglue wrappers **/ - -static OM_uint32 k5glue_acquire_cred( - void *, - 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 */ -); - -static OM_uint32 k5glue_release_cred( - void *, - OM_uint32*, /* minor_status */ - gss_cred_id_t* /* cred_handle */ -); - -static OM_uint32 k5glue_init_sec_context( - void *, - 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 */ - 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 */ -); - -#ifndef LEAN_CLIENT -static OM_uint32 k5glue_accept_sec_context( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t*, /* context_handle */ - gss_cred_id_t, /* verifier_cred_handle */ - gss_buffer_t, /* input_token_buffer */ - gss_channel_bindings_t, - /* input_chan_bindings */ - gss_name_t*, /* src_name */ - gss_OID*, /* mech_type */ - gss_buffer_t, /* output_token */ - OM_uint32*, /* ret_flags */ - OM_uint32*, /* time_rec */ - gss_cred_id_t* /* delegated_cred_handle */ -); -#endif /* LEAN_CLIENT */ - -static OM_uint32 k5glue_process_context_token( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - gss_buffer_t /* token_buffer */ -); - -static OM_uint32 k5glue_delete_sec_context( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t*, /* context_handle */ - gss_buffer_t /* output_token */ -); - -static OM_uint32 k5glue_context_time( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - OM_uint32* /* time_rec */ -); - -static OM_uint32 k5glue_sign( - void *, OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - int, /* qop_req */ - gss_buffer_t, /* message_buffer */ - gss_buffer_t /* message_token */ -); - -static OM_uint32 k5glue_verify( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - gss_buffer_t, /* message_buffer */ - gss_buffer_t, /* token_buffer */ - int* /* qop_state */ -); - -static OM_uint32 k5glue_seal( - void *, - 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 */ -); - -static OM_uint32 k5glue_unseal( - void *, - 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 */ -); - -static OM_uint32 k5glue_display_status( - void *, - OM_uint32*, /* minor_status */ - OM_uint32, /* status_value */ - int, /* status_type */ - gss_OID, /* mech_type */ - OM_uint32*, /* message_context */ - gss_buffer_t /* status_string */ -); - -static OM_uint32 k5glue_indicate_mechs( - void *, - OM_uint32*, /* minor_status */ - gss_OID_set* /* mech_set */ -); - -static OM_uint32 k5glue_compare_name( - void *, - OM_uint32*, /* minor_status */ - gss_name_t, /* name1 */ - gss_name_t, /* name2 */ - int* /* name_equal */ -); - -static OM_uint32 k5glue_display_name( - void *, - OM_uint32*, /* minor_status */ - gss_name_t, /* input_name */ - gss_buffer_t, /* output_name_buffer */ - gss_OID* /* output_name_type */ -); - -static OM_uint32 k5glue_import_name( - void *, - OM_uint32*, /* minor_status */ - gss_buffer_t, /* input_name_buffer */ - gss_OID, /* input_name_type */ - gss_name_t* /* output_name */ -); - -static OM_uint32 k5glue_release_name( - void *, - OM_uint32*, /* minor_status */ - gss_name_t* /* input_name */ -); - -static OM_uint32 k5glue_inquire_cred( - void *, - 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 */ -); - -static OM_uint32 k5glue_inquire_context( - void *, - OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ - gss_name_t*, /* initiator_name */ - gss_name_t*, /* acceptor_name */ - OM_uint32*, /* lifetime_rec */ - gss_OID*, /* mech_type */ - OM_uint32*, /* ret_flags */ - int*, /* locally_initiated */ - int* /* open */ -); - -#if 0 -/* New V2 entry points */ -static OM_uint32 k5glue_get_mic( - void *, - 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 */ -); - -static OM_uint32 k5glue_verify_mic( - void *, - 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 */ -); - -static OM_uint32 k5glue_wrap( - void *, - 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 */ -); - -static OM_uint32 k5glue_unwrap( - void *, - 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 */ -); -#endif - -static OM_uint32 k5glue_wrap_size_limit( - void *, - 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 */ -); - -#if 0 -static OM_uint32 k5glue_import_name_object( - void *, - OM_uint32 *, /* minor_status */ - void *, /* input_name */ - gss_OID, /* input_name_type */ - gss_name_t * /* output_name */ -); - -static OM_uint32 k5glue_export_name_object( - void *, - OM_uint32 *, /* minor_status */ - gss_name_t, /* input_name */ - gss_OID, /* desired_name_type */ - void * * /* output_name */ -); -#endif - -static OM_uint32 k5glue_add_cred( - void *, - 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 */ -); - -static OM_uint32 k5glue_inquire_cred_by_mech( - void *, - 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 */ -); - -#ifndef LEAN_CLIENT -static OM_uint32 k5glue_export_sec_context( - void *, - OM_uint32 *, /* minor_status */ - gss_ctx_id_t *, /* context_handle */ - gss_buffer_t /* interprocess_token */ -); - -static OM_uint32 k5glue_import_sec_context( - void *, - OM_uint32 *, /* minor_status */ - gss_buffer_t, /* interprocess_token */ - gss_ctx_id_t * /* context_handle */ -); -#endif /* LEAN_CLIENT */ - -krb5_error_code k5glue_ser_init(krb5_context); - -static OM_uint32 k5glue_internal_release_oid( - void *, - OM_uint32 *, /* minor_status */ - gss_OID * /* oid */ -); - -static OM_uint32 k5glue_inquire_names_for_mech( - void *, - OM_uint32 *, /* minor_status */ - gss_OID, /* mechanism */ - gss_OID_set * /* name_types */ -); - -#if 0 -static OM_uint32 k5glue_canonicalize_name( - void *, - OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - const gss_OID, /* mech_type */ - gss_name_t * /* output_name */ -); -#endif - -static OM_uint32 k5glue_export_name( - void *, - OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - gss_buffer_t /* exported_name */ -); - -#if 0 -static OM_uint32 k5glue_duplicate_name( - void *, - OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - gss_name_t * /* dest_name */ -); -#endif - -#if 0 -static OM_uint32 k5glue_validate_cred( - void *, - OM_uint32 *, /* minor_status */ - gss_cred_id_t /* cred */ -); -#endif -/* - * The krb5 mechanism provides two mech OIDs; use this initializer to - * ensure that both dispatch tables contain identical function - * pointers. - */ -#ifndef LEAN_CLIENT -#define KRB5_GSS_CONFIG_INIT \ - NULL, \ - k5glue_acquire_cred, \ - k5glue_release_cred, \ - k5glue_init_sec_context, \ - k5glue_accept_sec_context, \ - k5glue_process_context_token, \ - k5glue_delete_sec_context, \ - k5glue_context_time, \ - k5glue_sign, \ - k5glue_verify, \ - k5glue_seal, \ - k5glue_unseal, \ - k5glue_display_status, \ - k5glue_indicate_mechs, \ - k5glue_compare_name, \ - k5glue_display_name, \ - k5glue_import_name, \ - k5glue_release_name, \ - k5glue_inquire_cred, \ - k5glue_add_cred, \ - k5glue_export_sec_context, \ - k5glue_import_sec_context, \ - k5glue_inquire_cred_by_mech, \ - k5glue_inquire_names_for_mech, \ - k5glue_inquire_context, \ - k5glue_internal_release_oid, \ - k5glue_wrap_size_limit, \ - k5glue_export_name, \ - NULL /* store_cred */ - -#else /* LEAN_CLIENT */ - -#define KRB5_GSS_CONFIG_INIT \ - NULL, \ - k5glue_acquire_cred, \ - k5glue_release_cred, \ - k5glue_init_sec_context, \ - NULL, \ - k5glue_process_context_token, \ - k5glue_delete_sec_context, \ - k5glue_context_time, \ - k5glue_sign, \ - k5glue_verify, \ - k5glue_seal, \ - k5glue_unseal, \ - k5glue_display_status, \ - k5glue_indicate_mechs, \ - k5glue_compare_name, \ - k5glue_display_name, \ - k5glue_import_name, \ - k5glue_release_name, \ - k5glue_inquire_cred, \ - k5glue_add_cred, \ - NULL, \ - NULL, \ - k5glue_inquire_cred_by_mech, \ - k5glue_inquire_names_for_mech, \ - k5glue_inquire_context, \ - k5glue_internal_release_oid, \ - k5glue_wrap_size_limit, \ - k5glue_export_name, \ - NULL /* store_cred */ - -#endif /* LEAN_CLIENT */ - - -static struct gss_config krb5_mechanism = { - 100, "kerberos_v5", - { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, - KRB5_GSS_CONFIG_INIT -}; - -static struct gss_config krb5_mechanism_old = { - 200, "kerberos_v5 (pre-RFC OID)", - { GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID }, - KRB5_GSS_CONFIG_INIT -}; - -static struct gss_config krb5_mechanism_wrong = { - 300, "kerberos_v5 (wrong OID)", - { GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID }, - KRB5_GSS_CONFIG_INIT -}; - -static gss_mechanism krb5_mech_configs[] = { - &krb5_mechanism, &krb5_mechanism_old, &krb5_mechanism_wrong, NULL -}; - -#ifdef MS_BUG_TEST -static gss_mechanism krb5_mech_configs_hack[] = { - &krb5_mechanism, &krb5_mechanism_old, NULL -}; -#endif - -#define gssint_get_mech_configs krb5_gss_get_mech_configs - -gss_mechanism * -gssint_get_mech_configs(void) +OM_uint32 KRB5_CALLCONV +gss_krb5_get_tkt_flags( + OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_flags *ticket_flags) { -#ifdef MS_BUG_TEST - char *envstr = getenv("MS_FORCE_NO_MSOID"); - - if (envstr != NULL && strcmp(envstr, "1") == 0) { - return krb5_mech_configs_hack; + static const gss_OID_desc const req_oid = { + GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH, + GSS_KRB5_GET_TKT_FLAGS_OID }; + OM_uint32 major_status; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (ticket_flags == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + major_status = gss_inquire_sec_context_by_oid(minor_status, + context_handle, + (const gss_OID)&req_oid, + &data_set); + if (major_status != GSS_S_COMPLETE) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1 || + data_set->elements[0].length != sizeof(*ticket_flags)) { + *minor_status = EINVAL; + return GSS_S_FAILURE; } -#endif - return krb5_mech_configs; -} -#ifndef LEAN_CLIENT -static OM_uint32 -k5glue_accept_sec_context(ctx, minor_status, context_handle, verifier_cred_handle, - input_token, input_chan_bindings, src_name, mech_type, - output_token, ret_flags, time_rec, delegated_cred_handle) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t *context_handle; - gss_cred_id_t verifier_cred_handle; - gss_buffer_t input_token; - gss_channel_bindings_t input_chan_bindings; - gss_name_t *src_name; - gss_OID *mech_type; - gss_buffer_t output_token; - OM_uint32 *ret_flags; - OM_uint32 *time_rec; - gss_cred_id_t *delegated_cred_handle; -{ - return(krb5_gss_accept_sec_context(minor_status, - context_handle, - verifier_cred_handle, - input_token, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle)); -} -#endif /* LEAN_CLIENT */ - -static OM_uint32 -k5glue_acquire_cred(ctx, minor_status, desired_name, time_req, desired_mechs, - cred_usage, output_cred_handle, actual_mechs, time_rec) - void *ctx; - 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; -{ - return(krb5_gss_acquire_cred(minor_status, - desired_name, - time_req, - desired_mechs, - cred_usage, - output_cred_handle, - actual_mechs, - time_rec)); -} + *ticket_flags = *((krb5_flags *)data_set->elements[0].value); -/* V2 */ -static OM_uint32 -k5glue_add_cred(ctx, minor_status, input_cred_handle, desired_name, desired_mech, - cred_usage, initiator_time_req, acceptor_time_req, - output_cred_handle, actual_mechs, initiator_time_rec, - acceptor_time_rec) - void *ctx; - 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; -{ - return(krb5_gss_add_cred(minor_status, input_cred_handle, desired_name, - desired_mech, cred_usage, initiator_time_req, - acceptor_time_req, output_cred_handle, - actual_mechs, initiator_time_rec, - acceptor_time_rec)); -} + gss_release_buffer_set(minor_status, &data_set); -#if 0 -/* V2 */ -static OM_uint32 -k5glue_add_oid_set_member(ctx, minor_status, member_oid, oid_set) - void *ctx; - OM_uint32 *minor_status; - gss_OID member_oid; - gss_OID_set *oid_set; -{ - return(generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)); -} -#endif - -static OM_uint32 -k5glue_compare_name(ctx, minor_status, name1, name2, name_equal) - void *ctx; - OM_uint32 *minor_status; - gss_name_t name1; - gss_name_t name2; - int *name_equal; -{ - return(krb5_gss_compare_name(minor_status, name1, - name2, name_equal)); -} + *minor_status = 0; -static OM_uint32 -k5glue_context_time(ctx, minor_status, context_handle, time_rec) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - OM_uint32 *time_rec; -{ - return(krb5_gss_context_time(minor_status, context_handle, - time_rec)); + return GSS_S_COMPLETE; } -#if 0 -/* V2 */ -static OM_uint32 -k5glue_create_empty_oid_set(ctx, minor_status, oid_set) - void *ctx; - OM_uint32 *minor_status; - gss_OID_set *oid_set; -{ - return(generic_gss_create_empty_oid_set(minor_status, oid_set)); -} -#endif - -static OM_uint32 -k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t *context_handle; - gss_buffer_t output_token; +OM_uint32 KRB5_CALLCONV +gss_krb5_copy_ccache( + OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + krb5_ccache out_ccache) { - return(krb5_gss_delete_sec_context(minor_status, - context_handle, output_token)); -} + static const gss_OID_desc const req_oid = { + GSS_KRB5_COPY_CCACHE_OID_LENGTH, + GSS_KRB5_COPY_CCACHE_OID }; + OM_uint32 major_status; + gss_buffer_desc req_buffer; -static OM_uint32 -k5glue_display_name(ctx, minor_status, input_name, output_name_buffer, output_name_type) - void *ctx; - OM_uint32 *minor_status; - gss_name_t input_name; - gss_buffer_t output_name_buffer; - gss_OID *output_name_type; -{ - return(krb5_gss_display_name(minor_status, input_name, - output_name_buffer, output_name_type)); -} + if (out_ccache == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; -static OM_uint32 -k5glue_display_status(ctx, minor_status, status_value, status_type, - mech_type, message_context, status_string) - void *ctx; - OM_uint32 *minor_status; - OM_uint32 status_value; - int status_type; - gss_OID mech_type; - OM_uint32 *message_context; - gss_buffer_t status_string; -{ - return(krb5_gss_display_status(minor_status, status_value, - status_type, mech_type, message_context, - status_string)); -} -#ifndef LEAN_CLIENT -/* V2 */ -static OM_uint32 -k5glue_export_sec_context(ctx, minor_status, context_handle, interprocess_token) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t *context_handle; - gss_buffer_t interprocess_token; -{ - return(krb5_gss_export_sec_context(minor_status, - context_handle, - interprocess_token)); -} -#endif /* LEAN_CLIENT */ -#if 0 -/* V2 */ -static OM_uint32 -k5glue_get_mic(ctx, minor_status, context_handle, qop_req, - message_buffer, message_token) - void *ctx; - 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; -{ - return(krb5_gss_get_mic(minor_status, context_handle, - qop_req, message_buffer, message_token)); + req_buffer.value = out_ccache; + req_buffer.length = sizeof(out_ccache); + + major_status = gssspi_set_cred_option(minor_status, + cred_handle, + (const gss_OID)&req_oid, + &req_buffer); + + return major_status; } -#endif - -static OM_uint32 -k5glue_import_name(ctx, minor_status, input_name_buffer, input_name_type, output_name) - void *ctx; - OM_uint32 *minor_status; - gss_buffer_t input_name_buffer; - gss_OID input_name_type; - gss_name_t *output_name; + +OM_uint32 KRB5_CALLCONV +gss_krb5_export_lucid_sec_context( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx) { -#if 0 - OM_uint32 err; - err = gssint_initialize_library(); - if (err) { - *minor_status = err; - return GSS_S_FAILURE; + unsigned char oid_buf[GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH + 6]; + gss_OID_desc req_oid; + OM_uint32 major_status, minor; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (kctx == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *kctx = NULL; + + req_oid.elements = oid_buf; + req_oid.length = sizeof(oid_buf); + + major_status = generic_gss_oid_compose(minor_status, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, + (int)version, + &req_oid); + if (GSS_ERROR(major_status)) + return major_status; + + major_status = gss_inquire_sec_context_by_oid(minor_status, + *context_handle, + &req_oid, + &data_set); + if (GSS_ERROR(major_status)) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1 || + data_set->elements[0].length != sizeof(void *)) { + *minor_status = EINVAL; + return GSS_S_FAILURE; } -#endif - return(krb5_gss_import_name(minor_status, input_name_buffer, - input_name_type, output_name)); -} -#ifndef LEAN_CLIENT -/* V2 */ -static OM_uint32 -k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle) - void *ctx; - OM_uint32 *minor_status; - gss_buffer_t interprocess_token; - gss_ctx_id_t *context_handle; -{ - return(krb5_gss_import_sec_context(minor_status, - interprocess_token, - context_handle)); -} -#endif /* LEAN_CLIENT */ + *kctx = *((void **)data_set->elements[0].value); -static OM_uint32 -k5glue_indicate_mechs(ctx, minor_status, mech_set) - void *ctx; - OM_uint32 *minor_status; - gss_OID_set *mech_set; -{ - return(krb5_gss_indicate_mechs(minor_status, mech_set)); -} + /* Clean up the context state (it is an error for + * someone to attempt to use this context again) + */ + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *context_handle = GSS_C_NO_CONTEXT; -static OM_uint32 -k5glue_init_sec_context(ctx, minor_status, claimant_cred_handle, context_handle, - target_name, mech_type, req_flags, time_req, - input_chan_bindings, input_token, actual_mech_type, - output_token, ret_flags, time_rec) - void *ctx; - 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; - 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; -{ - return(krb5_gss_init_sec_context(minor_status, - claimant_cred_handle, context_handle, - target_name, mech_type, req_flags, - time_req, input_chan_bindings, input_token, - actual_mech_type, output_token, ret_flags, - time_rec)); -} + generic_gss_release_buffer_set(&minor, &data_set); -static OM_uint32 -k5glue_inquire_context(ctx, minor_status, context_handle, initiator_name, acceptor_name, - lifetime_rec, mech_type, ret_flags, - locally_initiated, opened) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_name_t *initiator_name; - gss_name_t *acceptor_name; - OM_uint32 *lifetime_rec; - gss_OID *mech_type; - OM_uint32 *ret_flags; - int *locally_initiated; - int *opened; -{ - return(krb5_gss_inquire_context(minor_status, context_handle, - initiator_name, acceptor_name, lifetime_rec, - mech_type, ret_flags, locally_initiated, - opened)); + return GSS_S_COMPLETE; } -static OM_uint32 -k5glue_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, - cred_usage, mechanisms) - void *ctx; - OM_uint32 *minor_status; - gss_cred_id_t cred_handle; - gss_name_t *name; - OM_uint32 *lifetime_ret; - gss_cred_usage_t *cred_usage; - gss_OID_set *mechanisms; +OM_uint32 KRB5_CALLCONV +gss_krb5_set_allowable_enctypes( + OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_ktypes, + krb5_enctype *ktypes) { - return(krb5_gss_inquire_cred(minor_status, cred_handle, - name, lifetime_ret, cred_usage, mechanisms)); -} + static const gss_OID_desc const req_oid = { + GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH, + GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID }; + OM_uint32 major_status; + struct krb5_gss_set_allowable_enctypes_req req; + gss_buffer_desc req_buffer; + + req.num_ktypes = num_ktypes; + req.ktypes = ktypes; -/* V2 */ -static OM_uint32 -k5glue_inquire_cred_by_mech(ctx, minor_status, cred_handle, mech_type, name, - initiator_lifetime, acceptor_lifetime, cred_usage) - void *ctx; - 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; -{ - return(krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, - mech_type, name, initiator_lifetime, - acceptor_lifetime, cred_usage)); -} + req_buffer.length = sizeof(req); + req_buffer.value = &req; -/* V2 */ -static OM_uint32 -k5glue_inquire_names_for_mech(ctx, minor_status, mechanism, name_types) - void *ctx; - OM_uint32 *minor_status; - gss_OID mechanism; - gss_OID_set *name_types; -{ - return(krb5_gss_inquire_names_for_mech(minor_status, - mechanism, - name_types)); -} + major_status = gssspi_set_cred_option(minor_status, + cred, + (const gss_OID)&req_oid, + &req_buffer); -#if 0 -/* V2 */ -static OM_uint32 -k5glue_oid_to_str(ctx, minor_status, oid, oid_str) - void *ctx; - OM_uint32 *minor_status; - gss_OID oid; - gss_buffer_t oid_str; -{ - return(generic_gss_oid_to_str(minor_status, oid, oid_str)); -} -#endif - -static OM_uint32 -k5glue_process_context_token(ctx, minor_status, context_handle, token_buffer) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t token_buffer; -{ - return(krb5_gss_process_context_token(minor_status, - context_handle, token_buffer)); + return major_status; } -static OM_uint32 -k5glue_release_cred(ctx, minor_status, cred_handle) - void *ctx; - OM_uint32 *minor_status; - gss_cred_id_t *cred_handle; +OM_uint32 KRB5_CALLCONV +gss_krb5_ccache_name( + OM_uint32 *minor_status, + const char *name, + const char **out_name) { - return(krb5_gss_release_cred(minor_status, cred_handle)); -} + static const gss_OID_desc const req_oid = { + GSS_KRB5_CCACHE_NAME_OID_LENGTH, + GSS_KRB5_CCACHE_NAME_OID }; + OM_uint32 major_status; + struct krb5_gss_ccache_name_req req; + gss_buffer_desc req_buffer; -static OM_uint32 -k5glue_release_name(ctx, minor_status, input_name) - void *ctx; - OM_uint32 *minor_status; - gss_name_t *input_name; -{ - return(krb5_gss_release_name(minor_status, input_name)); -} + req.name = name; + req.out_name = out_name; -#if 0 -static OM_uint32 -k5glue_release_buffer(ctx, minor_status, buffer) - void *ctx; - OM_uint32 *minor_status; - gss_buffer_t buffer; -{ - return(generic_gss_release_buffer(minor_status, - buffer)); -} -#endif - -/* V2 */ -static OM_uint32 -k5glue_internal_release_oid(ctx, minor_status, oid) - void *ctx; - OM_uint32 *minor_status; - gss_OID *oid; -{ - return(krb5_gss_internal_release_oid(minor_status, oid)); -} + req_buffer.length = sizeof(req); + req_buffer.value = &req; -#if 0 -static OM_uint32 -k5glue_release_oid_set(ctx, minor_status, set) - void *ctx; - OM_uint32 * minor_status; - gss_OID_set *set; -{ - return(generic_gss_release_oid_set(minor_status, set)); -} -#endif - -/* V1 only */ -static OM_uint32 -k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req, - input_message_buffer, conf_state, output_message_buffer) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int conf_req_flag; - int qop_req; - gss_buffer_t input_message_buffer; - int *conf_state; - gss_buffer_t output_message_buffer; -{ - return(krb5_gss_seal(minor_status, context_handle, - conf_req_flag, qop_req, input_message_buffer, - conf_state, output_message_buffer)); -} + major_status = gssspi_mech_invoke(minor_status, + (const gss_OID)gss_mech_krb5, + (const gss_OID)&req_oid, + &req_buffer); -static OM_uint32 -k5glue_sign(ctx, minor_status, context_handle, - qop_req, message_buffer, - message_token) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int qop_req; - gss_buffer_t message_buffer; - gss_buffer_t message_token; -{ - return(krb5_gss_sign(minor_status, context_handle, - qop_req, message_buffer, message_token)); + return major_status; } -#if 0 -/* V2 */ -static OM_uint32 -k5glue_verify_mic(ctx, minor_status, context_handle, - message_buffer, token_buffer, qop_state) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t message_buffer; - gss_buffer_t token_buffer; - gss_qop_t *qop_state; +OM_uint32 KRB5_CALLCONV +gss_krb5_free_lucid_sec_context( + OM_uint32 *minor_status, + void *kctx) { - return(krb5_gss_verify_mic(minor_status, context_handle, - message_buffer, token_buffer, qop_state)); -} + static const gss_OID_desc const req_oid = { + GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH, + GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID }; + OM_uint32 major_status; + gss_buffer_desc req_buffer; -/* V2 */ -static OM_uint32 -k5glue_wrap(ctx, minor_status, context_handle, conf_req_flag, qop_req, - input_message_buffer, conf_state, output_message_buffer) - void *ctx; - 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; -{ - return(krb5_gss_wrap(minor_status, context_handle, conf_req_flag, qop_req, - input_message_buffer, conf_state, - output_message_buffer)); -} + req_buffer.length = sizeof(kctx); + req_buffer.value = kctx; -/* V2 */ -static OM_uint32 -k5glue_str_to_oid(ctx, minor_status, oid_str, oid) - void *ctx; - OM_uint32 *minor_status; - gss_buffer_t oid_str; - gss_OID *oid; -{ - return(generic_gss_str_to_oid(minor_status, oid_str, oid)); -} + major_status = gssspi_mech_invoke(minor_status, + (const gss_OID)gss_mech_krb5, + (const gss_OID)&req_oid, + &req_buffer); -/* V2 */ -static OM_uint32 -k5glue_test_oid_set_member(ctx, minor_status, member, set, present) - void *ctx; - OM_uint32 *minor_status; - gss_OID member; - gss_OID_set set; - int *present; -{ - return(generic_gss_test_oid_set_member(minor_status, member, set, - present)); -} -#endif - -/* V1 only */ -static OM_uint32 -k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer, - output_message_buffer, conf_state, qop_state) - void *ctx; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_message_buffer; - gss_buffer_t output_message_buffer; - int *conf_state; - int *qop_state; -{ - return(krb5_gss_unseal(minor_status, context_handle, - input_message_buffer, output_message_buffer, - conf_state, qop_state)); + return major_status; } -#if 0 -/* V2 */ -static OM_uint32 -k5glue_unwrap(ctx, minor_status, context_handle, input_message_buffer, - output_message_buffer, conf_state, qop_state) - void *ctx; - 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; -{ - return(krb5_gss_unwrap(minor_status, context_handle, input_message_buffer, - output_message_buffer, conf_state, qop_state)); -} -#endif - -/* V1 only */ -static OM_uint32 -k5glue_verify(ctx, minor_status, context_handle, message_buffer, - token_buffer, qop_state) - void *ctx; - 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 +krb5_gss_register_acceptor_identity(const char *keytab) { - return(krb5_gss_verify(minor_status, - context_handle, - message_buffer, - token_buffer, - qop_state)); -} + static const gss_OID_desc const req_oid = { + GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH, + GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID }; + OM_uint32 major_status; + OM_uint32 minor_status; + gss_buffer_desc req_buffer; -/* V2 interface */ -static OM_uint32 -k5glue_wrap_size_limit(ctx, minor_status, context_handle, conf_req_flag, - qop_req, req_output_size, max_input_size) - void *ctx; - 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; -{ - return(krb5_gss_wrap_size_limit(minor_status, context_handle, - conf_req_flag, qop_req, - req_output_size, max_input_size)); -} + req_buffer.length = strlen(keytab); + req_buffer.value = (char *)keytab; -#if 0 -/* V2 interface */ -static OM_uint32 -k5glue_canonicalize_name(ctx, minor_status, input_name, mech_type, output_name) - void *ctx; - OM_uint32 *minor_status; - const gss_name_t input_name; - const gss_OID mech_type; - gss_name_t *output_name; -{ - return krb5_gss_canonicalize_name(minor_status, input_name, - mech_type, output_name); -} -#endif - -/* V2 interface */ -static OM_uint32 -k5glue_export_name(ctx, minor_status, input_name, exported_name) - void *ctx; - OM_uint32 *minor_status; - const gss_name_t input_name; - gss_buffer_t exported_name; -{ - return krb5_gss_export_name(minor_status, input_name, exported_name); -} + major_status = gssspi_mech_invoke(&minor_status, + (const gss_OID)gss_mech_krb5, + (const gss_OID)&req_oid, + &req_buffer); -#if 0 -/* V2 interface */ -static OM_uint32 -k5glue_duplicate_name(ctx, minor_status, input_name, dest_name) - void *ctx; - OM_uint32 *minor_status; - const gss_name_t input_name; - gss_name_t *dest_name; -{ - return krb5_gss_duplicate_name(minor_status, input_name, dest_name); + return major_status; } -#endif -OM_uint32 KRB5_CALLCONV -gss_krb5_get_tkt_flags( - OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - krb5_flags *ticket_flags) +krb5_error_code +krb5_gss_use_kdc_context(void) { - gss_union_ctx_id_t uctx; - - uctx = (gss_union_ctx_id_t)context_handle; - if (!g_OID_equal(uctx->mech_type, &krb5_mechanism.mech_type) && - !g_OID_equal(uctx->mech_type, &krb5_mechanism_old.mech_type)) - return GSS_S_BAD_MECH; - return gss_krb5int_get_tkt_flags(minor_status, uctx->internal_ctx_id, - ticket_flags); + static const gss_OID_desc const req_oid = { + GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH, + GSS_KRB5_USE_KDC_CONTEXT_OID }; + OM_uint32 major_status; + OM_uint32 minor_status; + gss_buffer_desc req_buffer; + + req_buffer.length = 0; + req_buffer.value = NULL; + + major_status = gssspi_mech_invoke(&minor_status, + (const gss_OID)gss_mech_krb5, + (const gss_OID)&req_oid, + &req_buffer); + + return major_status; } +/* + * This API should go away and be replaced with an accessor + * into a gss_name_t. + */ OM_uint32 KRB5_CALLCONV -gss_krb5_copy_ccache( +gsskrb5_extract_authz_data_from_sec_context( OM_uint32 *minor_status, - gss_cred_id_t cred_handle, - krb5_ccache out_ccache) -{ - gss_union_cred_t ucred; - gss_cred_id_t mcred; + const gss_ctx_id_t context_handle, + int ad_type, + gss_buffer_t ad_data) +{ + gss_OID_desc req_oid; + unsigned char oid_buf[GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH + 6]; + OM_uint32 major_status; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (ad_data == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + req_oid.elements = oid_buf; + req_oid.length = sizeof(oid_buf); + + major_status = generic_gss_oid_compose(minor_status, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, + ad_type, + &req_oid); + if (GSS_ERROR(major_status)) + return major_status; + + major_status = gss_inquire_sec_context_by_oid(minor_status, + context_handle, + (const gss_OID)&req_oid, + &data_set); + if (major_status != GSS_S_COMPLETE) { + return major_status; + } + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1) { + return GSS_S_FAILURE; + } + + ad_data->length = data_set->elements[0].length; + ad_data->value = data_set->elements[0].value; - ucred = (gss_union_cred_t)cred_handle; + data_set->elements[0].length = 0; + data_set->elements[0].value = NULL; - mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type); - if (mcred != GSS_C_NO_CREDENTIAL) - return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache); + data_set->count = 0; - mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type); - if (mcred != GSS_C_NO_CREDENTIAL) - return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache); + gss_release_buffer_set(minor_status, &data_set); - return GSS_S_DEFECTIVE_CREDENTIAL; + return GSS_S_COMPLETE; } OM_uint32 KRB5_CALLCONV -gss_krb5_export_lucid_sec_context( +gss_krb5_set_cred_rcache( OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - OM_uint32 version, - void **kctx) + gss_cred_id_t cred, + krb5_rcache rcache) { - gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)*context_handle; - gss_union_ctx_id_t kerb_ctx; - OM_uint32 major = GSS_S_COMPLETE, minor = 0; - int is_spnego = 0; - - if (minor_status != NULL) - *minor_status = 0; - if (minor_status == NULL || context_handle == NULL || kctx == NULL) - return (GSS_S_CALL_INACCESSIBLE_WRITE); - *kctx = GSS_C_NO_CONTEXT; - - if (uctx == GSS_C_NO_CONTEXT) - return (GSS_S_CALL_INACCESSIBLE_READ); - - if (g_OID_equal(uctx->mech_type, gss_mech_spnego)) { - kerb_ctx = uctx->internal_ctx_id; - is_spnego = 1; - } - else - kerb_ctx = uctx; - - major = gss_krb5int_export_lucid_sec_context(minor_status, - &kerb_ctx->internal_ctx_id, - version, kctx); - - if (major == GSS_S_COMPLETE) { - if (is_spnego) { - uctx->internal_ctx_id = GSS_C_NO_CONTEXT; - (void) gss_delete_sec_context(&minor, (gss_ctx_id_t *)&kerb_ctx, NULL); - } - (void) gss_delete_sec_context(&minor, context_handle, NULL); - } + static const gss_OID_desc const req_oid = { + GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH, + GSS_KRB5_SET_CRED_RCACHE_OID }; + OM_uint32 major_status; + gss_buffer_desc req_buffer; + + req_buffer.length = sizeof(rcache); + req_buffer.value = rcache; - return (major); + major_status = gssspi_set_cred_option(minor_status, + cred, + (const gss_OID)&req_oid, + &req_buffer); + + return major_status; } OM_uint32 KRB5_CALLCONV -gss_krb5_set_allowable_enctypes( - OM_uint32 *minor_status, - gss_cred_id_t cred, - OM_uint32 num_ktypes, - krb5_enctype *ktypes) -{ - gss_union_cred_t ucred; - gss_cred_id_t mcred; +gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_timestamp *authtime) +{ + static const gss_OID_desc const req_oid = { + GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, + GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID }; + OM_uint32 major_status; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (authtime == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + major_status = gss_inquire_sec_context_by_oid(minor_status, + context_handle, + (const gss_OID)&req_oid, + &data_set); + if (major_status != GSS_S_COMPLETE) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1 || + data_set->elements[0].length != sizeof(*authtime)) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } - ucred = (gss_union_cred_t)cred; - mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type); - if (mcred != GSS_C_NO_CREDENTIAL) - return gss_krb5int_set_allowable_enctypes(minor_status, mcred, - num_ktypes, ktypes); + *authtime = *((krb5_timestamp *)data_set->elements[0].value); - mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type); - if (mcred != GSS_C_NO_CREDENTIAL) - return gss_krb5int_set_allowable_enctypes(minor_status, mcred, - num_ktypes, ktypes); + gss_release_buffer_set(minor_status, &data_set); - return GSS_S_DEFECTIVE_CREDENTIAL; + *minor_status = 0; + + return GSS_S_COMPLETE; } + diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c index 338c38b8c0..b66fe5c7b5 100644 --- a/src/lib/gssapi/krb5/lucid_context.c +++ b/src/lib/gssapi/krb5/lucid_context.c @@ -52,7 +52,7 @@ copy_keyblock_to_lucid_key( static krb5_error_code make_external_lucid_ctx_v1( krb5_gss_ctx_id_rec * gctx, - unsigned int version, + int version, void **out_ptr); @@ -63,33 +63,29 @@ make_external_lucid_ctx_v1( OM_uint32 KRB5_CALLCONV gss_krb5int_export_lucid_sec_context( OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - OM_uint32 version, - void **kctx) + gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) { krb5_error_code kret = 0; OM_uint32 retval; - krb5_gss_ctx_id_t ctx; + krb5_gss_ctx_id_t ctx = (krb5_gss_ctx_id_t)context_handle; void *lctx = NULL; + int version = 0; + gss_buffer_desc rep; /* Assume failure */ retval = GSS_S_FAILURE; *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; - if (kctx) - *kctx = NULL; - else { - kret = EINVAL; - goto error_out; - } - - if (!kg_validate_ctx_id(*context_handle)) { - kret = (OM_uint32) G_VALIDATE_FAILED; - retval = GSS_S_NO_CONTEXT; - goto error_out; - } - - ctx = (krb5_gss_ctx_id_t) *context_handle; + retval = generic_gss_oid_decompose(minor_status, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, + desired_object, + &version); + if (GSS_ERROR(retval)) + return retval; /* Externalize a structure of the right version */ switch (version) { @@ -111,17 +107,12 @@ gss_krb5int_export_lucid_sec_context( goto error_out; } - *kctx = lctx; - *minor_status = 0; - retval = GSS_S_COMPLETE; - - /* Clean up the context state (it is an error for - * someone to attempt to use this context again) - */ - (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); - *context_handle = GSS_C_NO_CONTEXT; + rep.value = lctx; + rep.length = sizeof(lctx); - return (retval); + retval = generic_gss_add_buffer_set_member(minor_status, &rep, data_set); + if (GSS_ERROR(retval)) + goto error_out; error_out: if (*minor_status == 0) @@ -133,19 +124,23 @@ error_out: * Frees the storage associated with an * exported lucid context structure. */ -OM_uint32 KRB5_CALLCONV -gss_krb5_free_lucid_sec_context( +OM_uint32 +gss_krb5int_free_lucid_sec_context( OM_uint32 *minor_status, - void *kctx) + const gss_OID desired_mech, + const gss_OID desired_object, + gss_buffer_t value) { OM_uint32 retval; krb5_error_code kret = 0; int version; + void *kctx; /* Assume failure */ retval = GSS_S_FAILURE; *minor_status = 0; + kctx = value->value; if (!kctx) { kret = EINVAL; goto error_out; @@ -191,7 +186,7 @@ error_out: static krb5_error_code make_external_lucid_ctx_v1( krb5_gss_ctx_id_rec * gctx, - unsigned int version, + int version, void **out_ptr) { gss_krb5_lucid_context_v1_t *lctx = NULL; @@ -208,7 +203,7 @@ make_external_lucid_ctx_v1( lctx->version = 1; lctx->initiate = gctx->initiate ? 1 : 0; - lctx->endtime = gctx->endtime; + lctx->endtime = gctx->krb_times.endtime; lctx->send_seq = gctx->seq_send; lctx->recv_seq = gctx->seq_recv; lctx->protocol = gctx->proto; diff --git a/src/lib/gssapi/krb5/seal.c b/src/lib/gssapi/krb5/seal.c index 9598de7d96..7265193b3b 100644 --- a/src/lib/gssapi/krb5/seal.c +++ b/src/lib/gssapi/krb5/seal.c @@ -27,23 +27,6 @@ * $Id$ */ -OM_uint32 -krb5_gss_seal(minor_status, context_handle, conf_req_flag, - qop_req, input_message_buffer, conf_state, - output_message_buffer) - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int conf_req_flag; - int qop_req; - gss_buffer_t input_message_buffer; - int *conf_state; - gss_buffer_t output_message_buffer; -{ - return(kg_seal(minor_status, context_handle, conf_req_flag, - qop_req, input_message_buffer, conf_state, - output_message_buffer, KG_TOK_SEAL_MSG)); -} - /* V2 interface */ OM_uint32 krb5_gss_wrap(minor_status, context_handle, conf_req_flag, @@ -58,6 +41,42 @@ krb5_gss_wrap(minor_status, context_handle, conf_req_flag, gss_buffer_t output_message_buffer; { return(kg_seal(minor_status, context_handle, conf_req_flag, - (int) qop_req, input_message_buffer, conf_state, + qop_req, input_message_buffer, conf_state, output_message_buffer, KG_TOK_WRAP_MSG)); } + +/* AEAD interfaces */ +OM_uint32 +krb5_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) +{ + OM_uint32 major_status; + + major_status = kg_seal_iov(minor_status, context_handle, conf_req_flag, + qop_req, conf_state, + iov, iov_count, KG_TOK_WRAP_MSG); + + return major_status; +} + +OM_uint32 +krb5_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) +{ + OM_uint32 major_status; + + major_status = kg_seal_iov_length(minor_status, context_handle, conf_req_flag, + qop_req, conf_state, iov, iov_count); + return major_status; +} + diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 5babd76682..20cc6f9dd0 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -99,7 +99,7 @@ kg_oid_internalize(kcontext, argp, buffer, lenremain) return EINVAL; } oid->length = ibuf; - oid->elements = malloc(ibuf); + oid->elements = malloc((size_t)ibuf); if (oid->elements == 0) { free(oid); return ENOMEM; @@ -263,7 +263,10 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for sealalg. * ... for enc * ... for seq + * krb5_int32 for authtime. + * krb5_int32 for starttime. * krb5_int32 for endtime. + * krb5_int32 for renew_till. * krb5_int32 for flags. * krb5_int64 for seq_send. * krb5_int64 for seq_recv. @@ -275,11 +278,13 @@ kg_ctx_size(kcontext, arg, sizep) * ... for acceptor_subkey * krb5_int32 for acceptor_key_cksumtype * krb5_int32 for cred_rcache + * krb5_int32 for number of elements in authdata array + * ... for authdata array * krb5_int32 for trailer. */ kret = EINVAL; if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { - required = 17*sizeof(krb5_int32); + required = 21*sizeof(krb5_int32); required += 2*sizeof(krb5_int64); required += sizeof(ctx->seed); @@ -337,6 +342,16 @@ kg_ctx_size(kcontext, arg, sizep) KV5M_KEYBLOCK, (krb5_pointer) ctx->acceptor_subkey, &required); + if (!kret && ctx->authdata) { + krb5_int32 i; + + for (i = 0; !kret && ctx->authdata[i]; i++) { + kret = krb5_size_opaque(kcontext, + KV5M_AUTHDATA, + (krb5_pointer)ctx->authdata[i], + &required); + } + } if (!kret) *sizep += required; } @@ -397,7 +412,13 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->sealalg, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->endtime, + (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_times.authtime, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_times.starttime, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_times.endtime, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_times.renew_till, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags, &bp, &remain); @@ -477,6 +498,25 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) if (!kret) kret = krb5_ser_pack_int32((krb5_int32) ctx->cred_rcache, &bp, &remain); + if (!kret) { + krb5_int32 i = 0; + + if (ctx->authdata) { + for (; ctx->authdata[i]; i++) + ; + } + /* authdata count */ + kret = krb5_ser_pack_int32(i, &bp, &remain); + if (!kret && ctx->authdata) { + /* authdata */ + for (i = 0; !kret && ctx->authdata[i]; i++) + kret = krb5_externalize_opaque(kcontext, + KV5M_AUTHDATA, + ctx->authdata[i], + &bp, + &remain); + } + } /* trailer */ if (!kret) kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); @@ -552,11 +592,17 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->sealalg = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->endtime = (krb5_timestamp) ibuf; + ctx->krb_times.authtime = (krb5_timestamp) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->krb_times.starttime = (krb5_timestamp) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->krb_times.endtime = (krb5_timestamp) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->krb_times.renew_till = (krb5_timestamp) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->krb_flags = (krb5_flags) ibuf; - (void) (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_send, &bp, &remain); - kret = (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_recv, &bp, &remain); + (void) (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_send, &bp, &remain); + kret = (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_recv, &bp, &remain); if (kret) { free(ctx); return kret; @@ -647,11 +693,31 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) } if (!kret) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->acceptor_subkey_cksumtype = ibuf; + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->cred_rcache = ibuf; + /* authdata */ if (!kret) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->acceptor_subkey_cksumtype = ibuf; - + if (!kret) { + krb5_int32 nadata = ibuf, i; + + if (nadata > 0) { + ctx->authdata = (krb5_authdata **)calloc((size_t)nadata + 1, + sizeof(krb5_authdata *)); + if (ctx->authdata == NULL) { + kret = ENOMEM; + } else { + for (i = 0; !kret && i < nadata; i++) + kret = krb5_internalize_opaque(kcontext, + KV5M_AUTHDATA, + (krb5_pointer *)&ctx->authdata[i], + &bp, + &remain); + } + } + } /* Get trailer */ if (!kret) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); diff --git a/src/lib/gssapi/krb5/set_allowable_enctypes.c b/src/lib/gssapi/krb5/set_allowable_enctypes.c index e35a153c42..5cc72df8bd 100644 --- a/src/lib/gssapi/krb5/set_allowable_enctypes.c +++ b/src/lib/gssapi/krb5/set_allowable_enctypes.c @@ -62,8 +62,8 @@ OM_uint32 KRB5_CALLCONV gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, gss_cred_id_t cred_handle, - OM_uint32 num_ktypes, - krb5_enctype *ktypes) + const gss_OID desired_oid, + const gss_buffer_t value) { unsigned int i; krb5_enctype * new_ktypes; @@ -71,11 +71,15 @@ gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, krb5_gss_cred_id_t cred; krb5_error_code kerr = 0; OM_uint32 temp_status; + struct krb5_gss_set_allowable_enctypes_req *req; /* Assume a failure */ *minor_status = 0; major_status = GSS_S_FAILURE; + assert(value->length == sizeof(*req)); + req = (struct krb5_gss_set_allowable_enctypes_req *)value->value; + /* verify and valildate cred handle */ if (cred_handle == GSS_C_NO_CREDENTIAL) { kerr = KRB5_NOCREDS_SUPPLIED; @@ -88,9 +92,9 @@ gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, } cred = (krb5_gss_cred_id_t) cred_handle; - if (ktypes) { - for (i = 0; i < num_ktypes && ktypes[i]; i++) { - if (!krb5_c_valid_enctype(ktypes[i])) { + if (req->ktypes) { + for (i = 0; i < req->num_ktypes && req->ktypes[i]; i++) { + if (!krb5_c_valid_enctype(req->ktypes[i])) { kerr = KRB5_PROG_ETYPE_NOSUPP; goto error_out; } @@ -108,7 +112,7 @@ gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, /* Copy the requested ktypes into the cred structure */ if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * (i + 1)))) { - memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); + memcpy(new_ktypes, req->ktypes, sizeof(krb5_enctype) * i); new_ktypes[i] = 0; /* "null-terminate" the list */ } else { diff --git a/src/lib/gssapi/krb5/set_ccache.c b/src/lib/gssapi/krb5/set_ccache.c index 2c82cfdfc3..883eb97e56 100644 --- a/src/lib/gssapi/krb5/set_ccache.c +++ b/src/lib/gssapi/krb5/set_ccache.c @@ -30,28 +30,35 @@ #include <string.h> #include "gssapiP_krb5.h" -#include "gss_libinit.h" OM_uint32 KRB5_CALLCONV -gss_krb5_ccache_name(minor_status, name, out_name) - OM_uint32 *minor_status; - const char *name; - const char **out_name; +gss_krb5int_ccache_name(OM_uint32 *minor_status, + const gss_OID desired_mech, + const gss_OID desired_object, + gss_buffer_t value) { char *old_name = NULL; OM_uint32 err = 0; OM_uint32 minor = 0; char *gss_out_name; + struct krb5_gss_ccache_name_req *req; - err = gssint_initialize_library(); + err = gss_krb5int_initialize_library(); if (err) { *minor_status = err; return GSS_S_FAILURE; } + assert(value->length == sizeof(*req)); + + if (value->length != sizeof(*req)) + return GSS_S_FAILURE; + + req = (struct krb5_gss_ccache_name_req *)value->value; + gss_out_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME); - if (out_name) { + if (req->out_name) { const char *tmp_name = NULL; if (!err) { @@ -59,14 +66,14 @@ gss_krb5_ccache_name(minor_status, name, out_name) } if (!err) { old_name = gss_out_name; - gss_out_name = tmp_name; + gss_out_name = (char *)tmp_name; } } /* If out_name was NULL, we keep the same gss_out_name value, and don't free up any storage (leave old_name NULL). */ if (!err) - kg_set_ccache_name (&err, name); + kg_set_ccache_name (&err, req->name); minor = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, gss_out_name); if (minor) { @@ -79,8 +86,8 @@ gss_krb5_ccache_name(minor_status, name, out_name) } if (!err) { - if (out_name) { - *out_name = gss_out_name; + if (req->out_name) { + *(req->out_name) = gss_out_name; } } diff --git a/src/lib/gssapi/krb5/sign.c b/src/lib/gssapi/krb5/sign.c index cc09f32281..2d047206cf 100644 --- a/src/lib/gssapi/krb5/sign.c +++ b/src/lib/gssapi/krb5/sign.c @@ -27,21 +27,6 @@ * $Id$ */ -OM_uint32 -krb5_gss_sign(minor_status, context_handle, - qop_req, message_buffer, - message_token) - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int qop_req; - gss_buffer_t message_buffer; - gss_buffer_t message_token; -{ - return(kg_seal(minor_status, context_handle, 0, - qop_req, message_buffer, NULL, - message_token, KG_TOK_SIGN_MSG)); -} - /* V2 interface */ OM_uint32 krb5_gss_get_mic(minor_status, context_handle, qop_req, @@ -53,6 +38,40 @@ krb5_gss_get_mic(minor_status, context_handle, qop_req, gss_buffer_t message_token; { return(kg_seal(minor_status, context_handle, 0, - (int) qop_req, message_buffer, NULL, + qop_req, message_buffer, NULL, message_token, KG_TOK_MIC_MSG)); } + +#if 0 +OM_uint32 +krb5_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) +{ + OM_uint32 major_status; + + major_status = kg_seal_iov(minor_status, context_handle, FALSE, + qop_req, NULL, + iov, iov_count, KG_TOK_MIC_MSG); + + return major_status; +} + +OM_uint32 +krb5_gss_get_mic_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) +{ + OM_uint32 major_status; + + major_status = kg_seal_iov_length(minor_status, context_handle, conf_req_flag, + qop_req, conf_state, iov, iov_count); + return major_status; +} +#endif diff --git a/src/lib/gssapi/krb5/unseal.c b/src/lib/gssapi/krb5/unseal.c index 381df93642..82764a9939 100644 --- a/src/lib/gssapi/krb5/unseal.c +++ b/src/lib/gssapi/krb5/unseal.c @@ -27,22 +27,6 @@ * $Id$ */ -OM_uint32 -krb5_gss_unseal(minor_status, context_handle, - input_message_buffer, output_message_buffer, - conf_state, qop_state) - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_message_buffer; - gss_buffer_t output_message_buffer; - int *conf_state; - int *qop_state; -{ - return(kg_unseal(minor_status, context_handle, - input_message_buffer, output_message_buffer, - conf_state, qop_state, KG_TOK_SEAL_MSG)); -} - /* V2 interface */ OM_uint32 krb5_gss_unwrap(minor_status, context_handle, @@ -56,12 +40,28 @@ krb5_gss_unwrap(minor_status, context_handle, gss_qop_t *qop_state; { OM_uint32 rstat; - int qstate; rstat = kg_unseal(minor_status, context_handle, input_message_buffer, output_message_buffer, - conf_state, &qstate, KG_TOK_WRAP_MSG); - if (!rstat && qop_state) - *qop_state = (gss_qop_t) qstate; + conf_state, qop_state, KG_TOK_WRAP_MSG); return(rstat); } + +/* AEAD interface */ +OM_uint32 +krb5_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) +{ + OM_uint32 major_status; + + major_status = kg_unseal_iov(minor_status, context_handle, + conf_state, qop_state, + iov, iov_count, KG_TOK_WRAP_MSG); + + return major_status; +} + diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index b863572a78..8dcf751292 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -107,3 +107,189 @@ cleanup: xfree(buf); return code; } + +krb5_error_code +kg_make_checksum_iov_v1(krb5_context context, + krb5_cksumtype type, + size_t cksum_len, + krb5_keyblock *seq, + krb5_keyblock *enc, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count, + int toktype, + krb5_checksum *checksum) +{ + krb5_error_code code; + gss_iov_buffer_desc *header; + krb5_crypto_iov *kiov; + size_t kiov_count; + int i = 0, j; + size_t conf_len = 0, token_header_len; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + kiov_count = 3 + iov_count; + kiov = (krb5_crypto_iov *)xmalloc(kiov_count * sizeof(krb5_crypto_iov)); + if (kiov == NULL) + return ENOMEM; + + /* Checksum over ( Header | Confounder | Data | Pad ) */ + if (toktype == KG_TOK_WRAP_MSG) + conf_len = kg_confounder_size(context, (krb5_keyblock *)enc); + + /* Checksum output */ + kiov[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + kiov[i].data.length = checksum->length; + kiov[i].data.data = xmalloc(checksum->length); + if (kiov[i].data.data == NULL) { + xfree(kiov); + return ENOMEM; + } + i++; + + /* Header | SND_SEQ | SGN_CKSUM | Confounder */ + token_header_len = 16 + cksum_len + conf_len; + + /* Header (calculate from end because of variable length ASN.1 header) */ + kiov[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + kiov[i].data.length = 8; + kiov[i].data.data = (char *)header->buffer.value + header->buffer.length - token_header_len; + i++; + + /* Confounder */ + if (toktype == KG_TOK_WRAP_MSG) { + kiov[i].flags = KRB5_CRYPTO_TYPE_DATA; + kiov[i].data.length = conf_len; + kiov[i].data.data = (char *)header->buffer.value + header->buffer.length - conf_len; + i++; + } + + for (j = 0; j < iov_count; j++) { + kiov[i].flags = kg_translate_flag_iov(iov[j].type); + kiov[i].data.length = iov[j].buffer.length; + kiov[i].data.data = (char *)iov[j].buffer.value; + i++; + } + + code = krb5_c_make_checksum_iov(context, type, seq, sign_usage, kiov, kiov_count); + if (code == 0) { + checksum->length = kiov[0].data.length; + checksum->contents = (unsigned char *)kiov[0].data.data; + } else + free(kiov[0].data.data); + + xfree(kiov); + + return code; +} + +static krb5_error_code +checksum_iov_v3(krb5_context context, + krb5_cksumtype type, + size_t rrc, + krb5_keyblock *key, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count, + krb5_boolean verify, + krb5_boolean *valid) +{ + krb5_error_code code; + gss_iov_buffer_desc *header; + gss_iov_buffer_desc *trailer; + krb5_crypto_iov *kiov; + size_t kiov_count; + int i = 0, j; + unsigned int k5_checksumlen; + + if (verify) + *valid = FALSE; + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen); + if (code != 0) + return code; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + assert(rrc != 0 || trailer != NULL); + + if (trailer == NULL) { + if (rrc != k5_checksumlen) + return KRB5_BAD_MSIZE; + if (header->buffer.length != 16 + k5_checksumlen) + return KRB5_BAD_MSIZE; + } else if (trailer->buffer.length != k5_checksumlen) + return KRB5_BAD_MSIZE; + + kiov_count = 2 + iov_count; + kiov = (krb5_crypto_iov *)xmalloc(kiov_count * sizeof(krb5_crypto_iov)); + if (kiov == NULL) + return ENOMEM; + + /* Checksum over ( Data | Header ) */ + + /* Data */ + for (j = 0; j < iov_count; j++) { + kiov[i].flags = kg_translate_flag_iov(iov[j].type); + kiov[i].data.length = iov[j].buffer.length; + kiov[i].data.data = (char *)iov[j].buffer.value; + i++; + } + + /* Header */ + kiov[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + kiov[i].data.length = 16; + kiov[i].data.data = (char *)header->buffer.value; + i++; + + /* Checksum */ + kiov[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + if (trailer == NULL) { + kiov[i].data.length = header->buffer.length - 16; + kiov[i].data.data = (char *)header->buffer.value + 16; + } else { + kiov[i].data.length = trailer->buffer.length; + kiov[i].data.data = (char *)trailer->buffer.value; + } + i++; + + if (verify) + code = krb5_c_verify_checksum_iov(context, type, key, sign_usage, kiov, kiov_count, valid); + else + code = krb5_c_make_checksum_iov(context, type, key, sign_usage, kiov, kiov_count); + + xfree(kiov); + + return code; +} + +krb5_error_code +kg_make_checksum_iov_v3(krb5_context context, + krb5_cksumtype type, + size_t rrc, + krb5_keyblock *key, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count) +{ + return checksum_iov_v3(context, type, rrc, key, + sign_usage, iov, iov_count, 0, NULL); +} + +krb5_error_code +kg_verify_checksum_iov_v3(krb5_context context, + krb5_cksumtype type, + size_t rrc, + krb5_keyblock *key, + krb5_keyusage sign_usage, + gss_iov_buffer_desc *iov, + int iov_count, + krb5_boolean *valid) +{ + return checksum_iov_v3(context, type, rrc, key, + sign_usage, iov, iov_count, 1, valid); +} diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index a0d0747e6b..d718ae0b18 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -1,6 +1,6 @@ /* -*- mode: c; indent-tabs-mode: nil -*- */ /* - * Copyright2001 by the Massachusetts Institute of Technology. + * Copyright 2001, 2008 by the Massachusetts Institute of Technology. * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -54,6 +54,85 @@ #include <memory.h> #endif +const char const kg_arcfour_l40[] = "fortybits"; + +krb5_error_code +kg_setup_keys(krb5_context context, + krb5_gss_ctx_id_rec *ctx, + krb5_keyblock *subkey, + krb5_cksumtype *cksumtype) +{ + krb5_error_code code; + unsigned int i; + krb5int_access kaccess; + + assert(ctx != NULL); + assert(subkey != NULL); + + *cksumtype = 0; + ctx->proto = 0; + + code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION); + if (code != 0) + return code; + + if (ctx->enc != NULL) { + krb5_free_keyblock(context, ctx->enc); + ctx->enc = NULL; + } + code = krb5_copy_keyblock(context, subkey, &ctx->enc); + if (code != 0) + return code; + + if (ctx->seq != NULL) { + krb5_free_keyblock(context, ctx->seq); + ctx->seq = NULL; + } + code = krb5_copy_keyblock(context, subkey, &ctx->seq); + if (code != 0) + return code; + + switch (subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_CRC: + ctx->enc->enctype = ENCTYPE_DES_CBC_RAW; + ctx->seq->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = SGN_ALG_DES_MAC_MD5; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_DES; + + for (i = 0; i < ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xF0; + break; + case ENCTYPE_DES3_CBC_SHA1: + ctx->enc->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->seq->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; + break; + case ENCTYPE_ARCFOUR_HMAC: + case ENCTYPE_ARCFOUR_HMAC_EXP: + ctx->signalg = SGN_ALG_HMAC_MD5; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_MICROSOFT_RC4; + break; + default: + ctx->signalg = -1; + ctx->sealalg = -1; + ctx->proto = 1; + + code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype, + cksumtype); + if (code != 0) + return code; + } + + return 0; +} + int kg_confounder_size(context, key) krb5_context context; @@ -62,7 +141,8 @@ kg_confounder_size(context, key) krb5_error_code code; size_t blocksize; /* We special case rc4*/ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC) + if (key->enctype == ENCTYPE_ARCFOUR_HMAC || + key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) return 8; code = krb5_c_block_size(context, key->enctype, &blocksize); if (code) @@ -77,16 +157,15 @@ kg_make_confounder(context, key, buf) krb5_keyblock *key; unsigned char *buf; { - krb5_error_code code; - size_t blocksize; + int confsize; krb5_data lrandom; - code = krb5_c_block_size(context, key->enctype, &blocksize); - if (code) - return(code); + confsize = kg_confounder_size(context, key); + if (confsize < 0) + return KRB5_BAD_MSIZE; - lrandom.length = blocksize; - lrandom.data = buf; + lrandom.length = confsize; + lrandom.data = (char *)buf; return(krb5_c_random_make_octets(context, &lrandom)); } @@ -122,7 +201,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) } inputd.length = length; - inputd.data = in; + inputd.data = (char *)in; outputd.ciphertext.length = length; outputd.ciphertext.data = out; @@ -167,7 +246,7 @@ kg_decrypt(context, key, usage, iv, in, out, length) inputd.enctype = ENCTYPE_UNKNOWN; inputd.ciphertext.length = length; - inputd.ciphertext.data = in; + inputd.ciphertext.data = (char *)in; outputd.length = length; outputd.data = out; @@ -188,7 +267,9 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, krb5_data input, output; krb5int_access kaccess; krb5_keyblock seq_enc_key, usage_key; - unsigned char t[4]; + unsigned char t[14]; + size_t i = 0; + int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP); usage_key.length = longterm_key->length; usage_key.contents = malloc(usage_key.length); @@ -204,18 +285,24 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, if (code) goto cleanup_arcfour; - t[0] = ms_usage &0xff; - t[1] = (ms_usage>>8) & 0xff; - t[2] = (ms_usage>>16) & 0xff; - t[3] = (ms_usage>>24) & 0xff; + if (exportable) { + memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40)); + i += sizeof(kg_arcfour_l40); + } + t[i++] = ms_usage &0xff; + t[i++] = (ms_usage>>8) & 0xff; + t[i++] = (ms_usage>>16) & 0xff; + t[i++] = (ms_usage>>24) & 0xff; input.data = (void *) &t; - input.length = 4; + input.length = i; output.data = (void *) usage_key.contents; output.length = usage_key.length; code = (*kaccess.krb5_hmac) (kaccess.md5_hash_provider, longterm_key, 1, &input, &output); if (code) goto cleanup_arcfour; + if (exportable) + memset(usage_key.contents + 7, 0xab, 9); input.data = ( void *) kd_data; input.length = kd_data_len; @@ -238,3 +325,595 @@ cleanup_arcfour: free ((void *) seq_enc_key.contents); return (code); } + +/* AEAD */ +static krb5_error_code +kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count) + krb5_context context; + const krb5_keyblock *key; + gss_iov_buffer_desc *iov; + int iov_count; + krb5_crypto_iov **pkiov; + size_t *pkiov_count; +{ + gss_iov_buffer_desc *header; + gss_iov_buffer_desc *trailer; + int i = 0, j; + size_t kiov_count; + krb5_crypto_iov *kiov; + size_t conf_len; + + *pkiov = NULL; + *pkiov_count = 0; + + conf_len = kg_confounder_size(context, (krb5_keyblock *)key); + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + if (header->buffer.length < conf_len) + return KRB5_BAD_MSIZE; + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + assert(trailer == NULL || trailer->buffer.length == 0); + + kiov_count = 3 + iov_count; + kiov = (krb5_crypto_iov *)malloc(kiov_count * sizeof(krb5_crypto_iov)); + if (kiov == NULL) + return ENOMEM; + + /* For pre-CFX (raw enctypes) there is no krb5 header */ + kiov[i].flags = KRB5_CRYPTO_TYPE_HEADER; + kiov[i].data.length = 0; + kiov[i].data.data = NULL; + i++; + + /* For pre-CFX, the confounder is at the end of the GSS header */ + kiov[i].flags = KRB5_CRYPTO_TYPE_DATA; + kiov[i].data.length = conf_len; + kiov[i].data.data = (char *)header->buffer.value + header->buffer.length - conf_len; + i++; + + for (j = 0; j < iov_count; j++) { + kiov[i].flags = kg_translate_flag_iov(iov[j].type); + if (kiov[i].flags == KRB5_CRYPTO_TYPE_EMPTY) + continue; + + kiov[i].data.length = iov[j].buffer.length; + kiov[i].data.data = (char *)iov[j].buffer.value; + i++; + } + + kiov[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + kiov[i].data.length = 0; + kiov[i].data.data = NULL; + i++; + + *pkiov = kiov; + *pkiov_count = i; + + return 0; +} + +static krb5_error_code +kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pkiov_count) + krb5_context context; + int dce_style; /* DCE_STYLE indicates actual RRC is EC + RRC */ + size_t ec; /* Extra rotate count for DCE_STYLE, pad length otherwise */ + size_t rrc; /* Rotate count */ + const krb5_keyblock *key; + gss_iov_buffer_desc *iov; + int iov_count; + krb5_crypto_iov **pkiov; + size_t *pkiov_count; +{ + gss_iov_buffer_t header; + gss_iov_buffer_t trailer; + int i = 0, j; + size_t kiov_count; + krb5_crypto_iov *kiov; + unsigned int k5_headerlen = 0, k5_trailerlen = 0; + size_t gss_headerlen, gss_trailerlen; + krb5_error_code code; + + *pkiov = NULL; + *pkiov_count = 0; + + header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + assert(header != NULL); + + trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + assert(trailer == NULL || rrc == 0); + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + if (code != 0) + return code; + + code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); + if (code != 0) + return code; + + /* Check header and trailer sizes */ + gss_headerlen = 16 /* GSS-Header */ + k5_headerlen; /* Kerb-Header */ + gss_trailerlen = ec + 16 /* E(GSS-Header) */ + k5_trailerlen; /* Kerb-Trailer */ + + /* If we're caller without a trailer, we must rotate by trailer length */ + if (trailer == NULL) { + size_t actual_rrc = rrc; + + if (dce_style) + actual_rrc += ec; /* compensate for Windows bug */ + + if (actual_rrc != gss_trailerlen) + return KRB5_BAD_MSIZE; + + gss_headerlen += gss_trailerlen; + gss_trailerlen = 0; + } else { + if (trailer->buffer.length != gss_trailerlen) + return KRB5_BAD_MSIZE; + } + + if (header->buffer.length != gss_headerlen) + return KRB5_BAD_MSIZE; + + kiov_count = 3 + iov_count; + kiov = (krb5_crypto_iov *)malloc(kiov_count * sizeof(krb5_crypto_iov)); + if (kiov == NULL) + return ENOMEM; + + /* + * The krb5 header is located at the end of the GSS header. + */ + kiov[i].flags = KRB5_CRYPTO_TYPE_HEADER; + kiov[i].data.length = k5_headerlen; + kiov[i].data.data = (char *)header->buffer.value + header->buffer.length - k5_headerlen; + i++; + + for (j = 0; j < iov_count; j++) { + kiov[i].flags = kg_translate_flag_iov(iov[j].type); + if (kiov[i].flags == KRB5_CRYPTO_TYPE_EMPTY) + continue; + + kiov[i].data.length = iov[j].buffer.length; + kiov[i].data.data = (char *)iov[j].buffer.value; + i++; + } + + /* + * The EC and encrypted GSS header are placed in the trailer, which may + * be rotated directly after the plaintext header if no trailer buffer + * is provided. + */ + kiov[i].flags = KRB5_CRYPTO_TYPE_DATA; + kiov[i].data.length = ec + 16; /* E(Header) */ + if (trailer == NULL) + kiov[i].data.data = (char *)header->buffer.value + 16; + else + kiov[i].data.data = (char *)trailer->buffer.value; + i++; + + /* + * The krb5 trailer is placed after the encrypted copy of the + * krb5 header (which may be in the GSS header or trailer). + */ + kiov[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + kiov[i].data.length = k5_trailerlen; + kiov[i].data.data = kiov[i - 1].data.data + ec + 16; /* E(Header) */ + i++; + + *pkiov = kiov; + *pkiov_count = i; + + return 0; +} + +static krb5_error_code +kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, pkiov, pkiov_count) + krb5_context context; + int proto; /* 1 if CFX, 0 for pre-CFX */ + int dce_style; + size_t ec; + size_t rrc; + const krb5_keyblock *key; + gss_iov_buffer_desc *iov; + int iov_count; + krb5_crypto_iov **pkiov; + size_t *pkiov_count; +{ + return proto ? + kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pkiov_count) : + kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count); +} + +krb5_error_code +kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_count) + krb5_context context; + int proto; + int dce_style; + size_t ec; + size_t rrc; + krb5_keyblock *key; + int usage; + krb5_pointer iv; + gss_iov_buffer_desc *iov; + int iov_count; +{ + krb5_error_code code; + size_t blocksize; + krb5_data ivd, *pivd; + size_t kiov_count; + krb5_crypto_iov *kiov; + + if (iv) { + code = krb5_c_block_size(context, key->enctype, &blocksize); + if (code) + return(code); + + ivd.length = blocksize; + ivd.data = malloc(ivd.length); + if (ivd.data == NULL) + return ENOMEM; + memcpy(ivd.data, iv, ivd.length); + pivd = &ivd; + } else { + pivd = NULL; + } + + code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, + iov, iov_count, &kiov, &kiov_count); + if (code == 0) { + code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count); + free(kiov); + } + + if (pivd != NULL) + free(pivd->data); + + return code; +} + +/* length is the length of the cleartext. */ + +krb5_error_code +kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_count) + krb5_context context; + int proto; + int dce_style; + size_t ec; + size_t rrc; + krb5_keyblock *key; + int usage; + krb5_pointer iv; + gss_iov_buffer_desc *iov; + int iov_count; +{ + krb5_error_code code; + size_t blocksize; + krb5_data ivd, *pivd; + size_t kiov_count; + krb5_crypto_iov *kiov; + + if (iv) { + code = krb5_c_block_size(context, key->enctype, &blocksize); + if (code) + return(code); + + ivd.length = blocksize; + ivd.data = malloc(ivd.length); + if (ivd.data == NULL) + return ENOMEM; + memcpy(ivd.data, iv, ivd.length); + pivd = &ivd; + } else { + pivd = NULL; + } + + code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, + iov, iov_count, &kiov, &kiov_count); + if (code == 0) { + code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count); + free(kiov); + } + + if (pivd != NULL) + free(pivd->data); + + return code; +} + +krb5_error_code +kg_arcfour_docrypt_iov (krb5_context context, + const krb5_keyblock *longterm_key , int ms_usage, + const unsigned char *kd_data, size_t kd_data_len, + gss_iov_buffer_desc *iov, int iov_count) +{ + krb5_error_code code; + krb5_data input, output; + krb5int_access kaccess; + krb5_keyblock seq_enc_key, usage_key; + unsigned char t[14]; + size_t i = 0; + int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP); + krb5_crypto_iov *kiov = NULL; + size_t kiov_count = 0; + + usage_key.length = longterm_key->length; + usage_key.contents = malloc(usage_key.length); + if (usage_key.contents == NULL) + return (ENOMEM); + seq_enc_key.length = longterm_key->length; + seq_enc_key.contents = malloc(seq_enc_key.length); + if (seq_enc_key.contents == NULL) { + free ((void *) usage_key.contents); + return (ENOMEM); + } + code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (code) + goto cleanup_arcfour; + + if (exportable) { + memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40)); + i += sizeof(kg_arcfour_l40); + } + t[i++] = ms_usage &0xff; + t[i++] = (ms_usage>>8) & 0xff; + t[i++] = (ms_usage>>16) & 0xff; + t[i++] = (ms_usage>>24) & 0xff; + input.data = (void *) &t; + input.length = i; + output.data = (void *) usage_key.contents; + output.length = usage_key.length; + code = (*kaccess.krb5_hmac) (kaccess.md5_hash_provider, + longterm_key, 1, &input, &output); + if (code) + goto cleanup_arcfour; + if (exportable) + memset(usage_key.contents + 7, 0xab, 9); + + input.data = ( void *) kd_data; + input.length = kd_data_len; + output.data = (void *) seq_enc_key.contents; + code = (*kaccess.krb5_hmac) (kaccess.md5_hash_provider, + &usage_key, 1, &input, &output); + if (code) + goto cleanup_arcfour; + + code = kg_translate_iov(context, 0 /* proto */, 0 /* dce_style */, + 0 /* ec */, 0 /* rrc */, longterm_key, + iov, iov_count, &kiov, &kiov_count); + if (code) + goto cleanup_arcfour; + + code = ((*kaccess.arcfour_enc_provider->encrypt_iov)( + &seq_enc_key, 0, + kiov, kiov_count)); +cleanup_arcfour: + memset ((void *) seq_enc_key.contents, 0, seq_enc_key.length); + memset ((void *) usage_key.contents, 0, usage_key.length); + free ((void *) usage_key.contents); + free ((void *) seq_enc_key.contents); + if (kiov != NULL) + free(kiov); + return (code); +} + +krb5_cryptotype +kg_translate_flag_iov(OM_uint32 type) +{ + krb5_cryptotype ktype; + + switch (GSS_IOV_BUFFER_TYPE(type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + ktype = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + ktype = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + ktype = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + + return ktype; +} + +gss_iov_buffer_t +kg_locate_iov(gss_iov_buffer_desc *iov, + int iov_count, + OM_uint32 type) +{ + int i; + gss_iov_buffer_t p = GSS_C_NO_IOV_BUFFER; + + if (iov == GSS_C_NO_IOV_BUFFER) + return GSS_C_NO_IOV_BUFFER; + + for (i = iov_count - 1; i >= 0; i--) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == type) { + if (p == GSS_C_NO_IOV_BUFFER) + p = &iov[i]; + else + return GSS_C_NO_IOV_BUFFER; + } + } + + return p; +} + +void +kg_iov_msglen(gss_iov_buffer_desc *iov, + int iov_count, + size_t *data_length_p, + size_t *assoc_data_length_p) +{ + int i; + size_t data_length = 0, assoc_data_length = 0; + + assert(iov != GSS_C_NO_IOV_BUFFER); + + *data_length_p = *assoc_data_length_p = 0; + + for (i = 0; i < iov_count; i++) { + OM_uint32 type = GSS_IOV_BUFFER_TYPE(iov[i].type); + + if (type == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + assoc_data_length += iov[i].buffer.length; + + if (type == GSS_IOV_BUFFER_TYPE_DATA || + type == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + data_length += iov[i].buffer.length; + } + + *data_length_p = data_length; + *assoc_data_length_p = assoc_data_length; +} + +void +kg_release_iov(gss_iov_buffer_desc *iov, int iov_count) +{ + int i; + OM_uint32 min_stat; + + assert(iov != GSS_C_NO_IOV_BUFFER); + + for (i = 0; i < iov_count; i++) { + if (iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { + gss_release_buffer(&min_stat, &iov[i].buffer); + iov[i].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); + } + } +} + +OM_uint32 +kg_fixup_padding_iov(OM_uint32 *minor_status, + gss_iov_buffer_desc *iov, + int iov_count) +{ + gss_iov_buffer_t padding = NULL; + gss_iov_buffer_t data = NULL; + size_t padlength, relative_padlength; + unsigned char *p; + OM_uint32 minor; + + data = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_DATA); + padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + + if (data == NULL) { + *minor_status = 0; + return GSS_S_COMPLETE; + } + + if (padding == NULL || padding->buffer.length == 0) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + p = (unsigned char *)padding->buffer.value; + padlength = p[padding->buffer.length - 1]; + + if (data->buffer.length + padding->buffer.length < padlength || + padlength == 0) { + *minor_status = (OM_uint32)KRB5_BAD_MSIZE; + return GSS_S_DEFECTIVE_TOKEN; + } + + /* + * kg_unseal_stream_iov() will place one byte of padding in the + * padding buffer; its true value is unknown until after decryption. + * + * relative_padlength contains the number of bytes to compensate the + * padding and data buffers by; it will be zero if the caller manages + * the padding length. + * + * If the caller manages the padding length, then relative_padlength + * wil be zero. + * + * eg. if the buffers are structured as follows: + * + * +---DATA---+-PAD-+ + * | ABCDE444 | 4 | + * +----------+-----+ + * + * after compensation they would look like: + * + * +-DATA--+-PAD--+ + * | ABCDE | NULL | + * +-------+------+ + */ + relative_padlength = padlength - padding->buffer.length; + + assert(data->buffer.length >= relative_padlength); + + data->buffer.length -= relative_padlength; + + if (padding->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { + gss_release_buffer(&minor, &padding->buffer); + padding->type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); + } + + padding->buffer.length = 0; + padding->buffer.value = NULL; + + return GSS_S_COMPLETE; +} + +int kg_map_toktype(int proto, int toktype) +{ + int toktype2; + + if (proto) + switch (toktype) { + case KG_TOK_SIGN_MSG: + toktype2 = KG2_TOK_MIC_MSG; + break; + case KG_TOK_WRAP_MSG: + toktype2 = KG2_TOK_WRAP_MSG; + break; + case KG_TOK_DEL_CTX: + toktype2 = KG2_TOK_DEL_CTX; + break; + default: + toktype2 = toktype; + break; + } + else + toktype2 = toktype; + + return toktype2; +} + +krb5_boolean kg_integ_only_iov(gss_iov_buffer_desc *iov, int iov_count) +{ + int i; + krb5_boolean has_conf_data = FALSE; + + assert(iov != GSS_C_NO_IOV_BUFFER); + + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA) { + has_conf_data = TRUE; + break; + } + } + + return (has_conf_data == FALSE); +} + +krb5_error_code kg_allocate_iov(gss_iov_buffer_t iov, size_t size) +{ + assert(iov != GSS_C_NO_IOV_BUFFER); + assert(iov->type & GSS_IOV_BUFFER_FLAG_ALLOCATE); + + iov->buffer.length = size; + iov->buffer.value = xmalloc(size); + if (iov->buffer.value == NULL) { + iov->buffer.length = 0; + return ENOMEM; + } + + iov->type |= GSS_IOV_BUFFER_FLAG_ALLOCATED; + + return 0; +} diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index 3469e63edd..d5d7ffa57d 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -44,7 +44,8 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf) plain[5] = direction; plain[6] = direction; plain[7] = direction; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC ) { + if (key->enctype == ENCTYPE_ARCFOUR_HMAC || + key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { /* Yes, Microsoft used big-endian sequence number.*/ plain[0] = (seqnum>>24) & 0xff; plain[1] = (seqnum>>16) & 0xff; @@ -76,7 +77,8 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_error_code code; unsigned char plain[8]; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC) { + if (key->enctype == ENCTYPE_ARCFOUR_HMAC || + key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { code = kg_arcfour_docrypt (key, 0, cksum, 8, buf, 8, @@ -93,7 +95,8 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) return((krb5_error_code) KG_BAD_SEQ); *direction = plain[4]; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC) { + if (key->enctype == ENCTYPE_ARCFOUR_HMAC || + key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24)); } else { *seqnum = ((plain[0]) | diff --git a/src/lib/gssapi/krb5/verify.c b/src/lib/gssapi/krb5/verify.c index 4906ef38a1..31e8ff2961 100644 --- a/src/lib/gssapi/krb5/verify.c +++ b/src/lib/gssapi/krb5/verify.c @@ -27,21 +27,6 @@ * $Id$ */ -OM_uint32 -krb5_gss_verify(minor_status, context_handle, - message_buffer, token_buffer, - qop_state) - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t message_buffer; - gss_buffer_t token_buffer; - int *qop_state; -{ - return(kg_unseal(minor_status, context_handle, - token_buffer, message_buffer, - NULL, qop_state, KG_TOK_SIGN_MSG)); -} - /* V2 interface */ OM_uint32 krb5_gss_verify_mic(minor_status, context_handle, @@ -54,12 +39,27 @@ krb5_gss_verify_mic(minor_status, context_handle, gss_qop_t *qop_state; { OM_uint32 rstat; - int qstate; rstat = kg_unseal(minor_status, context_handle, token_buffer, message_buffer, - NULL, &qstate, KG_TOK_MIC_MSG); - if (!rstat && qop_state) - *qop_state = (gss_qop_t) qstate; + NULL, qop_state, KG_TOK_MIC_MSG); return(rstat); } + +#if 0 +OM_uint32 +krb5_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) +{ + OM_uint32 major_status; + + major_status = kg_unseal_iov(minor_status, context_handle, + NULL, qop_state, + iov, iov_count, KG_TOK_WRAP_MSG); + + return major_status; +} +#endif diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index f240047103..59e8761873 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -111,9 +111,15 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, /* No pseudo-ASN.1 wrapper overhead, so no sequence length and OID. */ OM_uint32 sz = req_output_size; + /* Token header: 16 octets. */ if (conf_req_flag) { - while (sz > 0 && krb5_encrypt_size(sz, ctx->enc->enctype) + 16 > req_output_size) + krb5_enctype enctype; + + enctype = ctx->have_acceptor_subkey ? ctx->acceptor_subkey->enctype + : ctx->subkey->enctype; + + while (sz > 0 && krb5_encrypt_size(sz, enctype) + 16 > req_output_size) sz--; /* Allow for encrypted copy of header. */ if (sz > 16) @@ -129,11 +135,24 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, sz = 0; #endif } else { + krb5_cksumtype cksumtype; + krb5_error_code err; + size_t cksumsize; + + cksumtype = ctx->have_acceptor_subkey ? ctx->acceptor_subkey_cksumtype + : ctx->cksumtype; + + err = krb5_c_checksum_length(ctx->k5_context, cksumtype, &cksumsize); + if (err) { + *minor_status = err; + return GSS_S_FAILURE; + } + /* Allow for token header and checksum. */ - if (sz < 16 + ctx->cksum_size) + if (sz < 16 + cksumsize) sz = 0; else - sz -= (16 + ctx->cksum_size); + sz -= (16 + cksumsize); } *max_input_size = sz; diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports index 2d6199cde4..524533843f 100644 --- a/src/lib/gssapi/libgssapi_krb5.exports +++ b/src/lib/gssapi/libgssapi_krb5.exports @@ -1,3 +1,4 @@ +GSS_C_INQ_SSPI_SESSION_KEY GSS_C_NT_ANONYMOUS GSS_C_NT_EXPORT_NAME GSS_C_NT_HOSTBASED_SERVICE @@ -8,36 +9,46 @@ GSS_C_NT_USER_NAME GSS_KRB5_NT_PRINCIPAL_NAME gss_accept_sec_context gss_acquire_cred +gss_add_buffer_set_member gss_add_cred gss_add_oid_set_member gss_canonicalize_name gss_compare_name +gss_complete_auth_token gss_context_time +gss_create_empty_buffer_set gss_create_empty_oid_set gss_delete_sec_context gss_display_name gss_display_status gss_duplicate_name gss_export_name +gss_export_name_object gss_export_sec_context gss_get_mic gss_import_name +gss_import_name_object gss_import_sec_context gss_indicate_mechs gss_init_sec_context gss_inquire_context gss_inquire_cred gss_inquire_cred_by_mech +gss_inquire_cred_by_oid gss_inquire_mechs_for_name gss_inquire_names_for_mech +gss_inquire_sec_context_by_oid gss_krb5_ccache_name gss_krb5_copy_ccache gss_krb5_export_lucid_sec_context gss_krb5_get_tkt_flags gss_krb5_free_lucid_sec_context gss_krb5_set_allowable_enctypes +gss_krb5_set_cred_rcache gss_krb5int_make_seal_token_v3 gss_krb5int_unseal_token_v3 +gsskrb5_extract_authtime_from_sec_context +gsskrb5_extract_authz_data_from_sec_context gss_mech_krb5 gss_mech_krb5_old gss_mech_set_krb5 @@ -53,21 +64,31 @@ gss_nt_string_uid_name gss_nt_user_name gss_oid_to_str gss_process_context_token +gss_release_buffer_set gss_release_buffer gss_release_cred +gss_release_iov_buffer gss_release_name gss_release_oid gss_release_oid_set gss_seal +gss_set_sec_context_option gss_sign gss_str_to_oid gss_test_oid_set_member gss_unseal gss_unwrap +gss_unwrap_aead +gss_unwrap_iov gss_verify gss_verify_mic gss_wrap +gss_wrap_aead +gss_wrap_iov +gss_wrap_iov_length gss_wrap_size_limit +gssspi_set_cred_option +gssspi_mech_invoke krb5_gss_dbg_client_expcreds krb5_gss_register_acceptor_identity krb5_gss_use_kdc_context diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in index 53852f0cd8..bbaab80afd 100644 --- a/src/lib/gssapi/mechglue/Makefile.in +++ b/src/lib/gssapi/mechglue/Makefile.in @@ -2,8 +2,8 @@ thisconfigdir=../../.. myfulldir=lib/gssapi/mechglue mydir=lib/gssapi/mechglue BUILDTOP=$(REL)..$(S)..$(S).. -LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/.. -I../generic -I$(srcdir)/../generic -DEFS= +LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/.. -I../generic -I$(srcdir)/../generic -I../krb5 -I$(srcdir)/../krb5 -I../spnego -I$(srcdir)/../spnego +DEFS=-D_GSS_STATIC_LINK=1 ##DOSBUILDTOP = ..\..\.. ##DOS##PREFIXDIR=mechglue @@ -14,8 +14,10 @@ DEFS= SRCS = \ $(srcdir)/g_accept_sec_context.c \ $(srcdir)/g_acquire_cred.c \ + $(srcdir)/g_buffer_set.c \ $(srcdir)/g_canon_name.c \ $(srcdir)/g_compare_name.c \ + $(srcdir)/g_complete_auth_token.c \ $(srcdir)/g_context_time.c \ $(srcdir)/g_delete_sec_context.c \ $(srcdir)/g_dsp_name.c \ @@ -23,14 +25,19 @@ SRCS = \ $(srcdir)/g_dup_name.c \ $(srcdir)/g_exp_sec_context.c \ $(srcdir)/g_export_name.c \ + $(srcdir)/g_export_name_object.c \ $(srcdir)/g_glue.c \ $(srcdir)/g_imp_name.c \ + $(srcdir)/g_imp_name_object.c \ $(srcdir)/g_imp_sec_context.c \ $(srcdir)/g_init_sec_context.c \ $(srcdir)/g_initialize.c \ $(srcdir)/g_inq_context.c \ + $(srcdir)/g_inq_context_oid.c \ $(srcdir)/g_inq_cred.c \ + $(srcdir)/g_inq_cred_oid.c \ $(srcdir)/g_inq_names.c \ + $(srcdir)/g_mech_invoke.c \ $(srcdir)/g_mechname.c \ $(srcdir)/g_oid_ops.c \ $(srcdir)/g_process_context.c \ @@ -39,17 +46,24 @@ SRCS = \ $(srcdir)/g_rel_name.c \ $(srcdir)/g_rel_oid_set.c \ $(srcdir)/g_seal.c \ + $(srcdir)/g_set_context_option.c \ + $(srcdir)/g_set_cred_option.c \ $(srcdir)/g_sign.c \ $(srcdir)/g_store_cred.c \ $(srcdir)/g_unseal.c \ + $(srcdir)/g_unwrap_aead.c \ + $(srcdir)/g_unwrap_iov.c \ $(srcdir)/g_verify.c \ - $(srcdir)/oid_ops.c + $(srcdir)/g_wrap_aead.c \ + $(srcdir)/g_wrap_iov.c OBJS = \ $(OUTPRE)g_accept_sec_context.$(OBJEXT) \ $(OUTPRE)g_acquire_cred.$(OBJEXT) \ + $(OUTPRE)g_buffer_set.$(OBJEXT) \ $(OUTPRE)g_canon_name.$(OBJEXT) \ $(OUTPRE)g_compare_name.$(OBJEXT) \ + $(OUTPRE)g_complete_auth_token.$(OBJEXT) \ $(OUTPRE)g_context_time.$(OBJEXT) \ $(OUTPRE)g_delete_sec_context.$(OBJEXT) \ $(OUTPRE)g_dsp_name.$(OBJEXT) \ @@ -57,14 +71,19 @@ OBJS = \ $(OUTPRE)g_dup_name.$(OBJEXT) \ $(OUTPRE)g_exp_sec_context.$(OBJEXT) \ $(OUTPRE)g_export_name.$(OBJEXT) \ + $(OUTPRE)g_export_name_object.$(OBJEXT) \ $(OUTPRE)g_glue.$(OBJEXT) \ $(OUTPRE)g_imp_name.$(OBJEXT) \ + $(OUTPRE)g_imp_name_object.$(OBJEXT) \ $(OUTPRE)g_imp_sec_context.$(OBJEXT) \ $(OUTPRE)g_init_sec_context.$(OBJEXT) \ $(OUTPRE)g_initialize.$(OBJEXT) \ $(OUTPRE)g_inq_context.$(OBJEXT) \ + $(OUTPRE)g_inq_context_oid.$(OBJEXT) \ $(OUTPRE)g_inq_cred.$(OBJEXT) \ + $(OUTPRE)g_inq_cred_oid.$(OBJEXT) \ $(OUTPRE)g_inq_names.$(OBJEXT) \ + $(OUTPRE)g_mech_invoke.$(OBJEXT) \ $(OUTPRE)g_mechname.$(OBJEXT) \ $(OUTPRE)g_oid_ops.$(OBJEXT) \ $(OUTPRE)g_process_context.$(OBJEXT) \ @@ -73,17 +92,24 @@ OBJS = \ $(OUTPRE)g_rel_name.$(OBJEXT) \ $(OUTPRE)g_rel_oid_set.$(OBJEXT) \ $(OUTPRE)g_seal.$(OBJEXT) \ + $(OUTPRE)g_set_context_option.$(OBJEXT) \ + $(OUTPRE)g_set_cred_option.$(OBJEXT) \ $(OUTPRE)g_sign.$(OBJEXT) \ $(OUTPRE)g_store_cred.$(OBJEXT) \ $(OUTPRE)g_unseal.$(OBJEXT) \ + $(OUTPRE)g_unwrap_aead.$(OBJEXT) \ + $(OUTPRE)g_unwrap_iov.$(OBJEXT) \ $(OUTPRE)g_verify.$(OBJEXT) \ - $(OUTPRE)oid_ops.$(OBJEXT) + $(OUTPRE)g_wrap_aead.$(OBJEXT) \ + $(OUTPRE)g_wrap_iov.$(OBJEXT) STLIBOBJS = \ g_accept_sec_context.o \ g_acquire_cred.o \ + g_buffer_set.o \ g_canon_name.o \ g_compare_name.o \ + g_complete_auth_token.o \ g_context_time.o \ g_delete_sec_context.o \ g_dsp_name.o \ @@ -91,14 +117,19 @@ STLIBOBJS = \ g_dup_name.o \ g_exp_sec_context.o \ g_export_name.o \ + g_export_name_object.o \ g_glue.o \ g_imp_name.o \ + g_imp_name_object.o \ g_imp_sec_context.o \ g_init_sec_context.o \ g_initialize.o \ g_inq_context.o \ + g_inq_context_oid.o \ g_inq_cred.o \ + g_inq_cred_oid.o \ g_inq_names.o \ + g_mech_invoke.o \ g_mechname.o \ g_oid_ops.o \ g_process_context.o \ @@ -107,11 +138,16 @@ STLIBOBJS = \ g_rel_name.o \ g_rel_oid_set.o \ g_seal.o \ + g_set_context_option.o \ + g_set_cred_option.o \ g_sign.o \ g_store_cred.o \ g_unseal.o \ + g_unwrap_aead.o \ + g_unwrap_iov.o \ g_verify.o \ - oid_ops.o + g_wrap_aead.o \ + g_wrap_iov.o EHDRDIR= $(BUILDTOP)$(S)include$(S)gssapi EXPORTED_HEADERS = mechglue.h @@ -141,195 +177,357 @@ includes:: # g_accept_sec_context.so g_accept_sec_context.po $(OUTPRE)g_accept_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_accept_sec_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_accept_sec_context.c \ + mechglue.h mglueP.h g_acquire_cred.so g_acquire_cred.po $(OUTPRE)g_acquire_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_acquire_cred.c mechglue.h \ + mglueP.h +g_buffer_set.so g_buffer_set.po $(OUTPRE)g_buffer_set.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_acquire_cred.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_buffer_set.c mechglue.h \ + mglueP.h g_canon_name.so g_canon_name.po $(OUTPRE)g_canon_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_canon_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_canon_name.c mechglue.h \ + mglueP.h g_compare_name.so g_compare_name.po $(OUTPRE)g_compare_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_compare_name.c mechglue.h \ + mglueP.h +g_complete_auth_token.so g_complete_auth_token.po $(OUTPRE)g_complete_auth_token.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_compare_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_complete_auth_token.c \ + mechglue.h mglueP.h g_context_time.so g_context_time.po $(OUTPRE)g_context_time.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_context_time.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_context_time.c mechglue.h \ + mglueP.h g_delete_sec_context.so g_delete_sec_context.po $(OUTPRE)g_delete_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_delete_sec_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_delete_sec_context.c \ + mechglue.h mglueP.h g_dsp_name.so g_dsp_name.po $(OUTPRE)g_dsp_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_dsp_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_dsp_name.c mechglue.h \ + mglueP.h g_dsp_status.so g_dsp_status.po $(OUTPRE)g_dsp_status.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_dsp_status.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_dsp_status.c mechglue.h \ + mglueP.h g_dup_name.so g_dup_name.po $(OUTPRE)g_dup_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_dup_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_dup_name.c mechglue.h \ + mglueP.h g_exp_sec_context.so g_exp_sec_context.po $(OUTPRE)g_exp_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_exp_sec_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_exp_sec_context.c \ + mechglue.h mglueP.h g_export_name.so g_export_name.po $(OUTPRE)g_export_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_export_name.c mechglue.h mglueP.h -g_glue.so g_glue.po $(OUTPRE)g_glue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(COM_ERR_DEPS) \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_export_name.c mechglue.h \ + mglueP.h +g_export_name_object.so g_export_name_object.po $(OUTPRE)g_export_name_object.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h $(srcdir)/../spnego/gssapiP_spnego.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_export_name_object.c \ + mechglue.h mglueP.h +g_glue.so g_glue.po $(OUTPRE)g_glue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ ../generic/gssapi_err_generic.h g_glue.c mechglue.h \ mglueP.h g_imp_name.so g_imp_name.po $(OUTPRE)g_imp_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_imp_name.c mechglue.h \ + mglueP.h +g_imp_name_object.so g_imp_name_object.po $(OUTPRE)g_imp_name_object.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_imp_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_imp_name_object.c \ + mechglue.h mglueP.h g_imp_sec_context.so g_imp_sec_context.po $(OUTPRE)g_imp_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_imp_sec_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_imp_sec_context.c \ + mechglue.h mglueP.h g_init_sec_context.so g_init_sec_context.po $(OUTPRE)g_init_sec_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_init_sec_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_init_sec_context.c \ + mechglue.h mglueP.h g_initialize.so g_initialize.po $(OUTPRE)g_initialize.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/gssapi.h $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ - $(srcdir)/../gss_libinit.h ../generic/gssapi_err_generic.h \ - g_initialize.c mechglue.h mglueP.h + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + $(srcdir)/../krb5/gssapiP_krb5.h $(srcdir)/../spnego/gssapiP_spnego.h \ + ../generic/gssapi_err_generic.h ../krb5/gssapi_err_krb5.h \ + ../krb5/gssapi_krb5.h g_initialize.c mechglue.h mglueP.h g_inq_context.so g_inq_context.po $(OUTPRE)g_inq_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_inq_context.c mechglue.h \ + mglueP.h +g_inq_context_oid.so g_inq_context_oid.po $(OUTPRE)g_inq_context_oid.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_inq_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_inq_context_oid.c \ + mechglue.h mglueP.h g_inq_cred.so g_inq_cred.po $(OUTPRE)g_inq_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_inq_cred.c mechglue.h \ + mglueP.h +g_inq_cred_oid.so g_inq_cred_oid.po $(OUTPRE)g_inq_cred_oid.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_inq_cred.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_inq_cred_oid.c mechglue.h \ + mglueP.h g_inq_names.so g_inq_names.po $(OUTPRE)g_inq_names.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_inq_names.c mechglue.h \ + mglueP.h +g_mech_invoke.so g_mech_invoke.po $(OUTPRE)g_mech_invoke.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_inq_names.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_mech_invoke.c mechglue.h \ + mglueP.h g_mechname.so g_mechname.po $(OUTPRE)g_mechname.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_mechname.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_mechname.c mechglue.h \ + mglueP.h g_oid_ops.so g_oid_ops.po $(OUTPRE)g_oid_ops.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_oid_ops.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_oid_ops.c mechglue.h \ + mglueP.h g_process_context.so g_process_context.po $(OUTPRE)g_process_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_process_context.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_process_context.c \ + mechglue.h mglueP.h g_rel_buffer.so g_rel_buffer.po $(OUTPRE)g_rel_buffer.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_rel_buffer.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_rel_buffer.c mechglue.h \ + mglueP.h g_rel_cred.so g_rel_cred.po $(OUTPRE)g_rel_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_rel_cred.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_rel_cred.c mechglue.h \ + mglueP.h g_rel_name.so g_rel_name.po $(OUTPRE)g_rel_name.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_rel_name.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_rel_name.c mechglue.h \ + mglueP.h g_rel_oid_set.so g_rel_oid_set.po $(OUTPRE)g_rel_oid_set.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_rel_oid_set.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_rel_oid_set.c mechglue.h \ + mglueP.h g_seal.so g_seal.po $(OUTPRE)g_seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(COM_ERR_DEPS) \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_seal.c mechglue.h \ + mglueP.h +g_set_context_option.so g_set_context_option.po $(OUTPRE)g_set_context_option.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_seal.c mechglue.h mglueP.h -g_sign.so g_sign.po $(OUTPRE)g_sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(COM_ERR_DEPS) \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_set_context_option.c \ + mechglue.h mglueP.h +g_set_cred_option.so g_set_cred_option.po $(OUTPRE)g_set_cred_option.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_sign.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_set_cred_option.c \ + mechglue.h mglueP.h +g_sign.so g_sign.po $(OUTPRE)g_sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_sign.c mechglue.h \ + mglueP.h g_store_cred.so g_store_cred.po $(OUTPRE)g_store_cred.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_store_cred.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_store_cred.c mechglue.h \ + mglueP.h g_unseal.so g_unseal.po $(OUTPRE)g_unseal.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_unseal.c mechglue.h \ + mglueP.h +g_unwrap_aead.so g_unwrap_aead.po $(OUTPRE)g_unwrap_aead.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_unseal.c mechglue.h mglueP.h + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_unwrap_aead.c mechglue.h \ + mglueP.h +g_unwrap_iov.so g_unwrap_iov.po $(OUTPRE)g_unwrap_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_unwrap_iov.c mechglue.h \ + mglueP.h g_verify.so g_verify.po $(OUTPRE)g_verify.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - g_verify.c mechglue.h mglueP.h -oid_ops.so oid_ops.po $(OUTPRE)oid_ops.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ - $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_verify.c mechglue.h \ + mglueP.h +g_wrap_aead.so g_wrap_aead.po $(OUTPRE)g_wrap_aead.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ - $(srcdir)/../generic/gssapi_generic.h ../generic/gssapi_err_generic.h \ - mechglue.h mglueP.h oid_ops.c + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_wrap_aead.c mechglue.h \ + mglueP.h +g_wrap_iov.so g_wrap_iov.po $(OUTPRE)g_wrap_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ + ../generic/gssapi_err_generic.h g_wrap_iov.c mechglue.h \ + mglueP.h diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c index 9527895eee..fa703d34d2 100644 --- a/src/lib/gssapi/mechglue/g_accept_sec_context.c +++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c @@ -146,7 +146,7 @@ gss_cred_id_t * d_cred; if(*context_handle == GSS_C_NO_CONTEXT) { - if (GSS_EMPTY_BUFFER(input_token_buffer)) + if (input_token_buffer == GSS_C_NO_BUFFER) return (GSS_S_CALL_INACCESSIBLE_READ); /* Get the token mech type */ @@ -193,9 +193,7 @@ gss_cred_id_t * d_cred; mech = gssint_get_mechanism (token_mech_type); if (mech && mech->gss_accept_sec_context) { - status = mech->gss_accept_sec_context( - mech->context, - minor_status, + status = mech->gss_accept_sec_context(minor_status, &union_ctx_id->internal_ctx_id, input_cred_handle, input_token_buffer, @@ -236,7 +234,6 @@ gss_cred_id_t * d_cred; output_token); if (internal_name != GSS_C_NO_NAME) mech->gss_release_name( - mech->context, &temp_minor_status, &internal_name); return (temp_status); @@ -288,8 +285,7 @@ gss_cred_id_t * d_cred; d_u_cred->loopback = d_u_cred; if (mech->gss_inquire_cred) { - status = mech->gss_inquire_cred(mech->context, - minor_status, + status = mech->gss_inquire_cred(minor_status, tmp_d_cred, &internal_name, &d_u_cred->auxinfo.time_rec, diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c index f2e8cd1b78..fada9e8872 100644 --- a/src/lib/gssapi/mechglue/g_acquire_cred.c +++ b/src/lib/gssapi/mechglue/g_acquire_cred.c @@ -381,8 +381,8 @@ gss_add_cred(minor_status, input_cred_handle, internal_name = union_name->mech_name; else { if (gssint_import_internal_name(minor_status, - &mech->mech_type, union_name, - &allocated_name) != GSS_S_COMPLETE) + &mech->mech_type, union_name, + &allocated_name) != GSS_S_COMPLETE) return (GSS_S_BAD_NAME); internal_name = allocated_name; } @@ -397,8 +397,10 @@ gss_add_cred(minor_status, input_cred_handle, else if (cred_usage == GSS_C_BOTH) time_req = (acceptor_time_req > initiator_time_req) ? acceptor_time_req : initiator_time_req; + else + time_req = 0; - status = mech->gss_acquire_cred(mech->context, minor_status, + status = mech->gss_acquire_cred(minor_status, internal_name, time_req, GSS_C_NULL_OID_SET, cred_usage, &cred, NULL, &time_rec); @@ -421,7 +423,6 @@ gss_add_cred(minor_status, input_cred_handle, if (internal_name == NULL) { if (mech->gss_inquire_cred == NULL || ((status = mech->gss_inquire_cred( - mech->context, &temp_minor_status, cred, &allocated_name, NULL, NULL, NULL)) != GSS_S_COMPLETE)) @@ -430,8 +431,7 @@ gss_add_cred(minor_status, input_cred_handle, } if (internal_name != GSS_C_NO_NAME) { - status = mech->gss_display_name(mech->context, - &temp_minor_status, internal_name, + status = mech->gss_display_name(&temp_minor_status, internal_name, &union_cred->auxinfo.name, &union_cred->auxinfo.name_type); @@ -519,8 +519,7 @@ errout: free(new_cred_array); if (cred != NULL && mech->gss_release_cred) - mech->gss_release_cred(mech->context, - &temp_minor_status, &cred); + mech->gss_release_cred(&temp_minor_status, &cred); if (allocated_name) (void) gssint_release_internal_name(&temp_minor_status, diff --git a/src/lib/gssapi/mechglue/g_buffer_set.c b/src/lib/gssapi/mechglue/g_buffer_set.c new file mode 100644 index 0000000000..1b2621c6b7 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_buffer_set.c @@ -0,0 +1,57 @@ +/* + * 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 "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV gss_create_empty_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + return generic_gss_create_empty_buffer_set(minor_status, 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) +{ + return generic_gss_add_buffer_set_member(minor_status, + member_buffer, + buffer_set); +} + +OM_uint32 KRB5_CALLCONV gss_release_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + return generic_gss_release_buffer_set(minor_status, buffer_set); +} + diff --git a/src/lib/gssapi/mechglue/g_compare_name.c b/src/lib/gssapi/mechglue/g_compare_name.c index 40f4648efd..153e9b615c 100644 --- a/src/lib/gssapi/mechglue/g_compare_name.c +++ b/src/lib/gssapi/mechglue/g_compare_name.c @@ -72,7 +72,7 @@ int * name_equal; { OM_uint32 major_status, temp_minor; gss_union_name_t union_name1, union_name2; - gss_mechanism mech; + gss_mechanism mech = NULL; gss_name_t internal_name; major_status = val_comp_name_args(minor_status, @@ -114,7 +114,11 @@ int * name_equal; if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0)) /* should never happen */ return (GSS_S_BAD_NAME); - major_status = mech->gss_compare_name(mech->context, minor_status, + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_compare_name) + return (GSS_S_UNAVAILABLE); + major_status = mech->gss_compare_name(minor_status, union_name1->mech_name, union_name2->mech_name, name_equal); @@ -190,7 +194,11 @@ int * name_equal; if (major_status != GSS_S_COMPLETE) return (GSS_S_COMPLETE); /* return complete, but not equal */ - major_status = mech->gss_compare_name(mech->context, minor_status, + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_compare_name) + return (GSS_S_UNAVAILABLE); + major_status = mech->gss_compare_name(minor_status, union_name1->mech_name, internal_name, name_equal); if (major_status != GSS_S_COMPLETE) diff --git a/src/lib/gssapi/mechglue/g_complete_auth_token.c b/src/lib/gssapi/mechglue/g_complete_auth_token.c new file mode 100644 index 0000000000..9181551301 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_complete_auth_token.c @@ -0,0 +1,70 @@ +/* #ident "@(#)gss_seal.c 1.10 95/08/07 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_complete_auth_token + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +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) +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech != NULL) { + if (mech->gss_complete_auth_token != NULL) { + status = mech->gss_complete_auth_token(minor_status, + ctx->internal_ctx_id, + input_message_buffer); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_COMPLETE; + } else + status = GSS_S_BAD_MECH; + + return status; +} diff --git a/src/lib/gssapi/mechglue/g_context_time.c b/src/lib/gssapi/mechglue/g_context_time.c index 866405729b..4293b078eb 100644 --- a/src/lib/gssapi/mechglue/g_context_time.c +++ b/src/lib/gssapi/mechglue/g_context_time.c @@ -64,7 +64,6 @@ OM_uint32 * time_rec; if (mech->gss_context_time) { status = mech->gss_context_time( - mech->context, minor_status, ctx->internal_ctx_id, time_rec); diff --git a/src/lib/gssapi/mechglue/g_delete_sec_context.c b/src/lib/gssapi/mechglue/g_delete_sec_context.c index fdaf2c310d..2fcd3c2d10 100644 --- a/src/lib/gssapi/mechglue/g_delete_sec_context.c +++ b/src/lib/gssapi/mechglue/g_delete_sec_context.c @@ -73,7 +73,6 @@ gss_buffer_t output_token; { OM_uint32 status; gss_union_ctx_id_t ctx; - gss_mechanism mech; status = val_del_sec_ctx_args(minor_status, context_handle, output_token); if (status != GSS_S_COMPLETE) @@ -87,29 +86,19 @@ gss_buffer_t output_token; ctx = (gss_union_ctx_id_t) *context_handle; if (GSSINT_CHK_LOOP(ctx)) return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); - mech = gssint_get_mechanism (ctx->mech_type); - - if (mech) { - - if (mech->gss_delete_sec_context) { - status = mech->gss_delete_sec_context( - mech->context, - minor_status, - &ctx->internal_ctx_id, - output_token); - if (status != GSS_S_COMPLETE) - map_error(minor_status, mech); - } else - status = GSS_S_UNAVAILABLE; - - /* now free up the space for the union context structure */ - free(ctx->mech_type->elements); - free(ctx->mech_type); - free(*context_handle); - *context_handle = NULL; - - return(status); - } + + status = gssint_delete_internal_sec_context(minor_status, + ctx->mech_type, + &ctx->internal_ctx_id, + output_token); + if (status) + return status; + + /* now free up the space for the union context structure */ + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(*context_handle); + *context_handle = GSS_C_NO_CONTEXT; - return (GSS_S_BAD_MECH); + return (GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/mechglue/g_dsp_status.c b/src/lib/gssapi/mechglue/g_dsp_status.c index cb779aa909..49b79e15d8 100644 --- a/src/lib/gssapi/mechglue/g_dsp_status.c +++ b/src/lib/gssapi/mechglue/g_dsp_status.c @@ -121,7 +121,7 @@ gss_buffer_t status_string; if (mech && mech->gss_display_status) { OM_uint32 r; - r = mech->gss_display_status(mech->context, minor_status, + r = mech->gss_display_status(minor_status, status_value, status_type, mech_type, message_context, status_string); /* How's this for weird? If we get an error returning the diff --git a/src/lib/gssapi/mechglue/g_exp_sec_context.c b/src/lib/gssapi/mechglue/g_exp_sec_context.c index cf9905f830..f2ee5a5b75 100644 --- a/src/lib/gssapi/mechglue/g_exp_sec_context.c +++ b/src/lib/gssapi/mechglue/g_exp_sec_context.c @@ -101,7 +101,7 @@ gss_buffer_t interprocess_token; if (!mech->gss_export_sec_context) return (GSS_S_UNAVAILABLE); - status = mech->gss_export_sec_context(mech->context, minor_status, + status = mech->gss_export_sec_context(minor_status, &ctx->internal_ctx_id, &token); if (status != GSS_S_COMPLETE) { map_error(minor_status, mech); diff --git a/src/lib/gssapi/mechglue/g_export_name.c b/src/lib/gssapi/mechglue/g_export_name.c index c845f8caf7..d9545b798b 100644 --- a/src/lib/gssapi/mechglue/g_export_name.c +++ b/src/lib/gssapi/mechglue/g_export_name.c @@ -56,3 +56,4 @@ gss_buffer_t exported_name; return gssint_export_internal_name(minor_status, union_name->mech_type, union_name->mech_name, exported_name); } + diff --git a/src/lib/gssapi/mechglue/g_export_name_object.c b/src/lib/gssapi/mechglue/g_export_name_object.c new file mode 100644 index 0000000000..4005070438 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_export_name_object.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1996,1997, by Sun Microsystems, Inc. + * All rights reserved. + */ + +/* #pragma ident "@(#)g_export_name.c 1.11 00/07/17 SMI" */ + +/* + * glue routine gss_export_name_object_object_object_object + * + * Will either call the mechanism defined gss_export_name, or if one is + * not defined will call a generic_gss_export_name routine. + */ + +#include <mglueP.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV +gss_export_name_object(minor_status, + input_name, + desired_name_type, + output_name) +OM_uint32 * minor_status; +const gss_name_t input_name; +gss_OID desired_name_type; +void ** output_name; +{ + gss_union_name_t union_name; + gss_mechanism mech; + OM_uint32 major_status; + + if (minor_status != NULL) + *minor_status = 0; + + if (output_name != NULL) + *output_name = NULL; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (input_name == NULL) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME; + + if (desired_name_type == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAMETYPE; + + if (output_name == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + union_name = (gss_union_name_t)input_name; + + if (union_name->mech_type == GSS_C_NO_OID) + return GSS_S_NAME_NOT_MN; + + mech = gssint_get_mechanism(union_name->mech_type); + if (mech == NULL) + return GSS_S_BAD_MECH; + + if (mech->gss_export_name_object == NULL) + return GSS_S_UNAVAILABLE; + + major_status = mech->gss_export_name_object(minor_status, + input_name, + desired_name_type, + output_name); + if (major_status != GSS_S_COMPLETE) + map_error(minor_status, mech); + + return major_status; +} diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c index a347906562..8b4070eb4f 100644 --- a/src/lib/gssapi/mechglue/g_glue.c +++ b/src/lib/gssapi/mechglue/g_glue.c @@ -29,7 +29,6 @@ #endif #include <string.h> #include <errno.h> -#include "../spnego/gssapiP_spnego.h" #define MSO_BIT (8*(sizeof (int) - 1)) /* Most significant octet bit */ @@ -52,7 +51,7 @@ gssint_get_der_length(unsigned char **buf, unsigned int buf_len, unsigned int *b /* p points to the beginning of the buffer */ unsigned char *p = *buf; int length, new_length; - int octets; + unsigned int octets; if (buf_len < 1) return (-1); @@ -185,7 +184,7 @@ gssint_put_der_length(unsigned int length, unsigned char **buf, unsigned int max * */ -OM_uint32 gssint_get_mech_type(OID, token) +OM_uint32 gssint_get_mech_type_oid(OID, token) gss_OID OID; gss_buffer_t token; { @@ -247,6 +246,43 @@ OM_uint32 gssint_get_mech_type(OID, token) return (GSS_S_COMPLETE); } +/* + * The following mechanisms do not always identify themselves + * per the GSS-API specification, when interoperating with MS + * peers. We include the OIDs here so we do not have to ilnk + * with the mechanism. + */ +static gss_OID_desc gss_ntlm_mechanism_oid_desc = + {10, (void *)"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"}; +static gss_OID_desc gss_spnego_mechanism_oid_desc = + {6, (void *)"\x2b\x06\x01\x05\x05\x02"}; +static gss_OID_desc gss_krb5_mechanism_oid_desc = + {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; + +#define NTLMSSP_SIGNATURE "NTLMSSP" + +OM_uint32 gssint_get_mech_type(OID, token) + gss_OID OID; + gss_buffer_t token; +{ + /* Check for interoperability exceptions */ + if (token->length >= sizeof(NTLMSSP_SIGNATURE) && + memcmp(token->value, NTLMSSP_SIGNATURE, + sizeof(NTLMSSP_SIGNATURE)) == 0) { + *OID = gss_ntlm_mechanism_oid_desc; + } else if (token->length != 0 && + ((char *)token->value)[0] == 0x6E) { + /* Could be a raw AP-REQ (check for APPLICATION tag) */ + *OID = gss_krb5_mechanism_oid_desc; + } else if (token->length == 0) { + *OID = gss_spnego_mechanism_oid_desc; + } else { + return gssint_get_mech_type_oid(OID, token); + } + + return (GSS_S_COMPLETE); +} + /* * Internal routines to get and release an internal mechanism name @@ -268,7 +304,6 @@ gss_name_t *internal_name; if (mech) { if (mech->gss_import_name) { status = mech->gss_import_name ( - mech->context, minor_status, union_name->external_name, union_name->name_type, @@ -307,8 +342,7 @@ OM_uint32 gssint_export_internal_name(minor_status, mech_type, return (GSS_S_BAD_MECH); if (mech->gss_export_name) { - status = mech->gss_export_name(mech->context, - minor_status, + status = mech->gss_export_name(minor_status, internal_name, name_buf); if (status != GSS_S_COMPLETE) @@ -343,8 +377,7 @@ OM_uint32 gssint_export_internal_name(minor_status, mech_type, * mechanisms also, so that factoring name export/import out of * the mech and into libgss pays off. */ - if ((status = mech->gss_display_name(mech->context, - minor_status, + if ((status = mech->gss_display_name(minor_status, internal_name, &dispName, &nameOid)) @@ -422,7 +455,6 @@ gss_OID *name_type; if (mech) { if (mech->gss_display_name) { status = mech->gss_display_name ( - mech->context, minor_status, internal_name, external_name, @@ -450,7 +482,6 @@ gss_name_t *internal_name; if (mech) { if (mech->gss_release_name) { status = mech->gss_release_name ( - mech->context, minor_status, internal_name); if (status != GSS_S_COMPLETE) @@ -464,6 +495,32 @@ gss_name_t *internal_name; return (GSS_S_BAD_MECH); } +OM_uint32 gssint_delete_internal_sec_context (minor_status, + mech_type, + internal_ctx, + output_token) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_ctx_id_t *internal_ctx; +gss_buffer_t output_token; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = gssint_get_mechanism (mech_type); + if (mech) { + if (mech->gss_delete_sec_context) + status = mech->gss_delete_sec_context (minor_status, + internal_ctx, + output_token); + else + status = GSS_S_UNAVAILABLE; + + return (status); + } + + return (GSS_S_BAD_MECH); +} /* * This function converts an internal gssapi name to a union gssapi @@ -502,10 +559,11 @@ OM_uint32 gssint_convert_name_to_union_name(minor_status, mech, union_name->external_name = (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); if (!union_name->external_name) { + major_status = GSS_S_FAILURE; goto allocation_failure; } - major_status = mech->gss_display_name(mech->context, minor_status, + major_status = mech->gss_display_name(minor_status, internal_name, union_name->external_name, &union_name->name_type); @@ -551,16 +609,20 @@ gssint_get_mechanism_cred(union_cred, mech_type) gss_OID mech_type; { int i; - + if (union_cred == GSS_C_NO_CREDENTIAL) return GSS_C_NO_CREDENTIAL; - + + /* SPNEGO mechanism will again call into GSSAPI */ + if (g_OID_equal(&gss_spnego_mechanism_oid_desc, mech_type)) + return (gss_cred_id_t)union_cred; + for (i=0; i < union_cred->count; i++) { if (g_OID_equal(mech_type, &union_cred->mechs_array[i])) return union_cred->cred_array[i]; /* for SPNEGO, check the next-lower set of creds */ - if (g_OID_equal(gss_mech_spnego, &union_cred->mechs_array[i])) { + if (g_OID_equal(&gss_spnego_mechanism_oid_desc, &union_cred->mechs_array[i])) { gss_union_cred_t candidate_cred; gss_cred_id_t sub_cred; @@ -617,3 +679,4 @@ gssint_create_copy_buffer(srcBuf, destBuf, addNullChar) return (GSS_S_COMPLETE); } /* ****** gssint_create_copy_buffer ****** */ + diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c index bb7db31954..c4767bf3e9 100644 --- a/src/lib/gssapi/mechglue/g_imp_name.c +++ b/src/lib/gssapi/mechglue/g_imp_name.c @@ -252,7 +252,7 @@ importExportName(minor, unionName) * have created it. */ if (mech->gss_export_name) { - major = mech->gss_import_name(mech->context, minor, + major = mech->gss_import_name(minor, &expName, (gss_OID)GSS_C_NT_EXPORT_NAME, &unionName->mech_name); if (major != GSS_S_COMPLETE) @@ -350,7 +350,7 @@ importExportName(minor, unionName) */ expName.length = nameLen; expName.value = nameLen ? (void *)buf : NULL; - major = mech->gss_import_name(mech->context, minor, &expName, + major = mech->gss_import_name(minor, &expName, GSS_C_NULL_OID, &unionName->mech_name); if (major != GSS_S_COMPLETE) { map_error(minor, mech); @@ -363,3 +363,4 @@ importExportName(minor, unionName) } return major; } /* importExportName */ + diff --git a/src/lib/gssapi/mechglue/g_imp_name_object.c b/src/lib/gssapi/mechglue/g_imp_name_object.c new file mode 100644 index 0000000000..83f327bd70 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_imp_name_object.c @@ -0,0 +1,124 @@ +/* #pragma ident "@(#)g_imp_name.c 1.26 04/02/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 gss_import_name_object + * + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +static OM_uint32 +val_imp_name_object_args( + OM_uint32 *minor_status, + void *input_name, + gss_OID input_name_type, + gss_name_t *output_name) +{ + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (output_name == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (input_name_type == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAMETYPE; + + if (input_name == NULL) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME; + + return GSS_S_COMPLETE; +} + +OM_uint32 KRB5_CALLCONV +gss_import_name_object(minor_status, + input_name, + input_name_type, + output_name) +OM_uint32 * minor_status; +void * input_name; +gss_OID input_name_type; +gss_name_t * output_name; +{ + gss_union_name_t union_name = NULL; + gss_mechanism mech = NULL; + gss_name_t internal_name = GSS_C_NO_NAME; + OM_uint32 tmp, major_status = GSS_S_FAILURE; + gss_OID_set mechlist = GSS_C_NO_OID_SET; + size_t i; + + major_status = val_imp_name_object_args(minor_status, + input_name, + input_name_type, + output_name); + if (major_status != GSS_S_COMPLETE) + return major_status; + + major_status = gss_indicate_mechs(minor_status, &mechlist); + if (major_status != GSS_S_COMPLETE) + return major_status; + + major_status = GSS_S_BAD_NAMETYPE; + + for (i = 0; i < mechlist->count; i++) { + mech = gssint_get_mechanism(&mechlist->elements[i]); + if (mech == NULL || mech->gss_import_name_object == NULL) + continue; + + major_status = mech->gss_import_name_object(minor_status, + input_name, + input_name_type, + &internal_name); + if (major_status != GSS_S_BAD_NAMETYPE) + break; + } + + if (major_status == GSS_S_COMPLETE) { + assert(internal_name != GSS_C_NO_NAME); + + major_status = gssint_convert_name_to_union_name(minor_status, + mech, + internal_name, + &union_name); + if (major_status != GSS_S_COMPLETE) { + if (mech->gss_release_name != NULL) + mech->gss_release_name(&tmp, &internal_name); + } else + *output_name = (gss_name_t)union_name; + } else + map_error(minor_status, mech); + + generic_gss_release_oid_set(&tmp, &mechlist); + + return major_status; +} + diff --git a/src/lib/gssapi/mechglue/g_imp_sec_context.c b/src/lib/gssapi/mechglue/g_imp_sec_context.c index 2b7aacf102..7aa1165b0f 100644 --- a/src/lib/gssapi/mechglue/g_imp_sec_context.c +++ b/src/lib/gssapi/mechglue/g_imp_sec_context.c @@ -143,7 +143,7 @@ gss_ctx_id_t * context_handle; goto error_out; } - status = mech->gss_import_sec_context(mech->context, minor_status, + status = mech->gss_import_sec_context(minor_status, &token, &ctx->internal_ctx_id); if (status == GSS_S_COMPLETE) { diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c index b51fb8951d..10c8bf9712 100644 --- a/src/lib/gssapi/mechglue/g_init_sec_context.c +++ b/src/lib/gssapi/mechglue/g_init_sec_context.c @@ -209,7 +209,6 @@ OM_uint32 * time_rec; */ status = mech->gss_init_sec_context( - mech->context, minor_status, input_cred_handle, &union_ctx_id->internal_ctx_id, diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c index f2f12266be..e762341c5d 100644 --- a/src/lib/gssapi/mechglue/g_initialize.c +++ b/src/lib/gssapi/mechglue/g_initialize.c @@ -27,10 +27,15 @@ */ #include "mglueP.h" -#include "gss_libinit.h" #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif #include <stdio.h> #include <string.h> @@ -40,16 +45,27 @@ #define M_DEFAULT "default" #include "k5-thread.h" +#include "k5-plugin.h" +#include "osconf.h" +#ifdef _GSS_STATIC_LINK +#include "gssapiP_krb5.h" +#include "gssapiP_spnego.h" +#endif + +#define MECH_SYM "gss_mech_initialize" + +#ifndef MECH_CONF +#define MECH_CONF "/etc/gss/mech" +#endif /* Local functions */ static gss_mech_info searchMechList(const gss_OID); +static void loadConfigFile(const char *); static void updateMechList(void); static void freeMechList(void); -static void register_mech(gss_mechanism, const char *, void *); static OM_uint32 build_mechSet(void); static void free_mechSet(void); -static void init_hardcoded(void); /* * list of mechanism libraries and their entry points. @@ -58,28 +74,67 @@ static void init_hardcoded(void); static gss_mech_info g_mechList = NULL; static gss_mech_info g_mechListTail = NULL; static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER; +static time_t g_confFileModTime = (time_t)0; +static time_t g_mechSetTime = (time_t)0; static gss_OID_set_desc g_mechSet = { 0, NULL }; static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER; +MAKE_INIT_FUNCTION(gssint_mechglue_init); +MAKE_FINI_FUNCTION(gssint_mechglue_fini); + int gssint_mechglue_init(void) { int err; +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_mechglue_init\n"); +#endif + + add_error_table(&et_ggss_error_table); + err = k5_mutex_finish_init(&g_mechSetLock); - return k5_mutex_finish_init(&g_mechListLock); + err = k5_mutex_finish_init(&g_mechListLock); + +#ifdef _GSS_STATIC_LINK + err = gss_krb5int_lib_init(); + err = gss_spnegoint_lib_init(); +#endif + + return err; } void gssint_mechglue_fini(void) { + if (!INITIALIZER_RAN(gssint_mechglue_init) || PROGRAM_EXITING()) { +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_mechglue_fini: skipping\n"); +#endif + return; + } + +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_mechglue_fini\n"); +#endif +#ifdef _GSS_STATIC_LINK + gss_spnegoint_lib_fini(); + gss_krb5int_lib_fini(); +#endif k5_mutex_destroy(&g_mechSetLock); k5_mutex_destroy(&g_mechListLock); free_mechSet(); freeMechList(); + remove_error_table(&et_ggss_error_table); + gssint_mecherrmap_destroy(); } +int +gssint_mechglue_initialize_library(void) +{ + return CALL_INIT_FUNCTION(gssint_mechglue_init); +} /* * function used to reclaim the memory used by a gss_OID structure. @@ -93,13 +148,12 @@ gss_OID *oid; OM_uint32 major; gss_mech_info aMech; - if (gssint_initialize_library()) - return GSS_S_FAILURE; - if (minor_status == NULL) return (GSS_S_CALL_INACCESSIBLE_WRITE); - *minor_status = 0; + *minor_status = gssint_mechglue_initialize_library(); + if (*minor_status != 0) + return (GSS_S_FAILURE); *minor_status = k5_mutex_lock(&g_mechListLock); if (*minor_status) @@ -116,7 +170,6 @@ gss_OID *oid; */ if (aMech->mech && aMech->mech->gss_internal_release_oid) { major = aMech->mech->gss_internal_release_oid( - aMech->mech->context, minor_status, oid); if (major == GSS_S_COMPLETE) { k5_mutex_unlock(&g_mechListLock); @@ -146,6 +199,8 @@ gss_indicate_mechs(minorStatus, mechSet) OM_uint32 *minorStatus; gss_OID_set *mechSet; { + char *fileName; + struct stat fileInfo; unsigned int i, j; gss_OID curItem; @@ -161,9 +216,20 @@ gss_OID_set *mechSet; if (minorStatus == NULL || mechSet == NULL) return (GSS_S_CALL_INACCESSIBLE_WRITE); - if (gssint_initialize_library()) - return GSS_S_FAILURE; + *minorStatus = gssint_mechglue_initialize_library(); + if (*minorStatus != 0) + return (GSS_S_FAILURE); + + fileName = MECH_CONF; + /* + * If we have already computed the mechanisms supported and if it + * is still valid; make a copy and return to caller, + * otherwise build it first. + */ + if ((stat(fileName, &fileInfo) == 0 && + fileInfo.st_mtime > g_mechSetTime)) { + } /* if g_mechSet is out of date or not initialized */ if (build_mechSet()) return GSS_S_FAILURE; @@ -247,7 +313,8 @@ static OM_uint32 build_mechSet(void) { gss_mech_info mList; - int i, count; + size_t i; + size_t count; gss_OID curItem; /* @@ -260,6 +327,20 @@ build_mechSet(void) if (k5_mutex_lock(&g_mechListLock) != 0) return GSS_S_FAILURE; +#if 0 + /* + * this checks for the case when we need to re-construct the + * g_mechSet structure, but the mechanism list is upto date + * (because it has been read by someone calling + * gssint_get_mechanism) + */ + if (fileInfo.st_mtime > g_confFileModTime) + { + g_confFileModTime = fileInfo.st_mtime; + loadConfigFile(fileName); + } +#endif + updateMechList(); /* @@ -323,6 +404,9 @@ build_mechSet(void) } } +#if 0 + g_mechSetTime = fileInfo.st_mtime; +#endif (void) k5_mutex_unlock(&g_mechSetLock); (void) k5_mutex_unlock(&g_mechListLock); @@ -344,6 +428,9 @@ const gss_OID oid; gss_mech_info aMech; char *modOptions = NULL; + if (gssint_mechglue_initialize_library() != 0) + return (NULL); + /* make sure we have fresh data */ if (k5_mutex_lock(&g_mechListLock) != 0) return NULL; @@ -375,6 +462,9 @@ gssint_mech_to_oid(const char *mechStr, gss_OID* oid) *oid = GSS_C_NULL_OID; + if (gssint_mechglue_initialize_library() != 0) + return (GSS_S_FAILURE); + if ((mechStr == NULL) || (strlen(mechStr) == 0) || (strcasecmp(mechStr, M_DEFAULT) == 0)) return (GSS_S_COMPLETE); @@ -413,6 +503,9 @@ gssint_oid_to_mech(const gss_OID oid) if (oid == GSS_C_NULL_OID) return (M_DEFAULT); + if (gssint_mechglue_initialize_library() != 0) + return (NULL); + /* ensure we have fresh data */ if (k5_mutex_lock(&g_mechListLock) != 0) return NULL; @@ -437,11 +530,12 @@ gssint_get_mechanisms(char *mechArray[], int arrayLen) gss_mech_info aMech; int i; - if (gssint_initialize_library()) - return GSS_S_FAILURE; if (mechArray == NULL || arrayLen < 1) return (GSS_S_CALL_INACCESSIBLE_WRITE); + if (gssint_mechglue_initialize_library() != 0) + return (GSS_S_FAILURE); + /* ensure we have fresh data */ if (k5_mutex_lock(&g_mechListLock) != 0) return GSS_S_FAILURE; @@ -463,7 +557,6 @@ gssint_get_mechanisms(char *mechArray[], int arrayLen) return (GSS_S_COMPLETE); } /* gss_get_mechanisms */ - /* * determines if the mechList needs to be updated from file * and performs the update. @@ -472,56 +565,128 @@ gssint_get_mechanisms(char *mechArray[], int arrayLen) static void updateMechList(void) { - + char *fileName; + struct stat fileInfo; + + fileName = MECH_CONF; + + /* check if mechList needs updating */ + if (stat(fileName, &fileInfo) == 0 && + (fileInfo.st_mtime > g_confFileModTime)) { + loadConfigFile(fileName); + g_confFileModTime = fileInfo.st_mtime; + } +#if 0 init_hardcoded(); - +#endif } /* updateMechList */ +#ifdef _GSS_STATIC_LINK static void -freeMechList(void) +releaseMechInfo(gss_mech_info *pCf) { - gss_mech_info cf, next_cf; + gss_mech_info cf; + OM_uint32 minor_status; - for (cf = g_mechList; cf != NULL; cf = next_cf) { - next_cf = cf->next; + if (*pCf == NULL) { + return; + } + + cf = *pCf; + + if (cf->kmodName != NULL) + free(cf->kmodName); + if (cf->uLibName != NULL) free(cf->uLibName); + if (cf->mechNameStr != NULL) free(cf->mechNameStr); - free(cf); + if (cf->optionStr != NULL) + free(cf->optionStr); + if (cf->mech_type != GSS_C_NO_OID && + cf->mech_type != &cf->mech->mech_type) + generic_gss_release_oid(&minor_status, &cf->mech_type); + if (cf->mech != NULL) { + memset(cf->mech, 0, sizeof(*cf->mech)); + free(cf->mech); } + if (cf->dl_handle != NULL) + krb5int_close_plugin(cf->dl_handle); + + memset(cf, 0, sizeof(*cf)); + free(cf); + + *pCf = NULL; } /* * Register a mechanism. Called with g_mechListLock held. */ -static void -register_mech(gss_mechanism mech, const char *namestr, void *dl_handle) +int +gssint_register_mechinfo(gss_mech_info template) { gss_mech_info cf, new_cf; - new_cf = malloc(sizeof(*new_cf)); - if (new_cf == NULL) - return; + new_cf = calloc(1, sizeof(*new_cf)); + if (new_cf == NULL) { + return ENOMEM; + } - memset(new_cf, 0, sizeof(*new_cf)); - new_cf->kmodName = NULL; - new_cf->uLibName = strdup(namestr); - new_cf->mechNameStr = strdup(mech->mechNameStr); - new_cf->mech_type = &mech->mech_type; - new_cf->mech = mech; + new_cf->dl_handle = template->dl_handle; + /* copy mech so we can rewrite canonical mechanism OID */ + new_cf->mech = (gss_mechanism)calloc(1, sizeof(struct gss_config)); + if (new_cf->mech == NULL) { + releaseMechInfo(&new_cf); + return ENOMEM; + } + memcpy(new_cf->mech, template->mech, sizeof(struct gss_config)); + if (template->mech_type != NULL) + new_cf->mech->mech_type = *(template->mech_type); + new_cf->mech_type = &new_cf->mech->mech_type; + new_cf->priority = template->priority; + new_cf->freeMech = 1; new_cf->next = NULL; + if (template->kmodName != NULL) { + new_cf->kmodName = strdup(template->kmodName); + if (new_cf->kmodName == NULL) { + releaseMechInfo(&new_cf); + return ENOMEM; + } + } + if (template->uLibName != NULL) { + new_cf->uLibName = strdup(template->uLibName); + if (new_cf->uLibName == NULL) { + releaseMechInfo(&new_cf); + return ENOMEM; + } + } + if (template->mechNameStr != NULL) { + new_cf->mechNameStr = strdup(template->mechNameStr); + if (new_cf->mechNameStr == NULL) { + releaseMechInfo(&new_cf); + return ENOMEM; + } + } + if (template->optionStr != NULL) { + new_cf->optionStr = strdup(template->optionStr); + if (new_cf->optionStr == NULL) { + releaseMechInfo(&new_cf); + return ENOMEM; + } + } if (g_mechList == NULL) { g_mechList = new_cf; g_mechListTail = new_cf; - return; - } else if (mech->priority < g_mechList->mech->priority) { + return 0; + } else if (new_cf->priority < g_mechList->priority) { new_cf->next = g_mechList; g_mechList = new_cf; - return; + return 0; } + for (cf = g_mechList; cf != NULL; cf = cf->next) { if (cf->next == NULL || - mech->priority < cf->next->mech->priority) { + new_cf->priority < cf->next->priority) { new_cf->next = cf->next; cf->next = new_cf; if (g_mechListTail == cf) { @@ -530,36 +695,113 @@ register_mech(gss_mechanism mech, const char *namestr, void *dl_handle) break; } } + + return 0; +} +#endif /* _GSS_STATIC_LINK */ + +#define GSS_ADD_DYNAMIC_METHOD(_dl, _mech, _symbol) \ + do { \ + struct errinfo errinfo; \ + \ + memset(&errinfo, 0, sizeof(errinfo)); \ + if (krb5int_get_plugin_func(_dl, \ + #_symbol, \ + (void (**)())&(_mech)->_symbol, \ + &errinfo) || errinfo.code) \ + (_mech)->_symbol = NULL; \ + } while (0) + +static gss_mechanism +build_dynamicMech(void *dl, const gss_OID mech_type) +{ + gss_mechanism mech; + + mech = (gss_mechanism)calloc(1, sizeof(*mech)); + if (mech == NULL) { + return NULL; + } + + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_acquire_cred); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_release_cred); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_init_sec_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_accept_sec_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_process_context_token); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_delete_sec_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_context_time); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_get_mic); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_verify_mic); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_unwrap); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_display_status); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_indicate_mechs); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_compare_name); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_display_name); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_import_name); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_release_name); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_cred); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_add_cred); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_sec_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_import_sec_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_cred_by_mech); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_names_for_mech); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_context); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_internal_release_oid); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap_size_limit); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_store_cred); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_import_name_object); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name_object); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_sec_context_by_oid); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_cred_by_oid); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_set_sec_context_option); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_set_cred_option); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_mech_invoke); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap_aead); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_unwrap_aead); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap_iov); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_unwrap_iov); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap_iov_length); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_complete_auth_token); + + assert(mech_type != GSS_C_NO_OID); + + mech->mech_type = *(mech_type); + + return mech; } -/* - * Initialize the hardcoded mechanisms. This function is called with - * g_mechListLock held. - */ static void -init_hardcoded(void) +freeMechList(void) { - gss_mechanism *cflist; - static int inited; - - if (inited) - return; + gss_mech_info cf, next_cf; + OM_uint32 minor; - cflist = krb5_gss_get_mech_configs(); - if (cflist == NULL) - return; - for ( ; *cflist != NULL; cflist++) { - register_mech(*cflist, "<builtin krb5>", NULL); - } - cflist = spnego_gss_get_mech_configs(); - if (cflist == NULL) - return; - for ( ; *cflist != NULL; cflist++) { - register_mech(*cflist, "<builtin spnego>", NULL); + for (cf = g_mechList; cf != NULL; cf = next_cf) { + next_cf = cf->next; + if (cf->kmodName != NULL) + free(cf->kmodName); + if (cf->uLibName != NULL) + free(cf->uLibName); + if (cf->mechNameStr != NULL) + free(cf->mechNameStr); + if (cf->optionStr != NULL) + free(cf->optionStr); + if (cf->mech_type != &cf->mech->mech_type) + generic_gss_release_oid(&minor, &cf->mech_type); + if (cf->mech != NULL && cf->freeMech) + free(cf->mech); + if (cf->mech_ext != NULL && cf->freeMech) + free(cf->mech_ext); + if (cf->dl_handle != NULL) + (void) krb5int_close_plugin(cf->dl_handle); + free(cf); } - inited = 1; } +/* + * Register a mechanism. Called with g_mechListLock held. + */ /* * given the mechanism type, return the mechanism structure @@ -569,12 +811,16 @@ init_hardcoded(void) * module if it has not been already loaded. */ gss_mechanism -gssint_get_mechanism(gss_OID oid) +gssint_get_mechanism(oid) +const gss_OID oid; { gss_mech_info aMech; + gss_mechanism (*sym)(const gss_OID); + struct plugin_file_handle *dl; + struct errinfo errinfo; - if (gssint_initialize_library()) - return NULL; + if (gssint_mechglue_initialize_library() != 0) + return (NULL); if (k5_mutex_lock(&g_mechListLock) != 0) return NULL; @@ -602,11 +848,102 @@ gssint_get_mechanism(gss_OID oid) if (aMech->mech) { (void) k5_mutex_unlock(&g_mechListLock); return (aMech->mech); + } + + memset(&errinfo, 0, sizeof(errinfo)); + + if (krb5int_open_plugin(aMech->uLibName, &dl, &errinfo) != 0 || + errinfo.code != 0) { +#if 0 + (void) syslog(LOG_INFO, "libgss dlopen(%s): %s\n", + aMech->uLibName, dlerror()); +#endif + (void) k5_mutex_unlock(&g_mechListLock); + return ((gss_mechanism)NULL); + } + + if (krb5int_get_plugin_func(dl, MECH_SYM, (void (**)())&sym, + &errinfo) == 0) { + /* Call the symbol to get the mechanism table */ + aMech->mech = (*sym)(aMech->mech_type); } else { - return NULL; + /* Try dynamic dispatch table */ + aMech->mech = build_dynamicMech(dl, aMech->mech_type); + aMech->freeMech = 1; } + if (aMech->mech == NULL) { + (void) krb5int_close_plugin(dl); +#if 0 + (void) syslog(LOG_INFO, "unable to initialize mechanism" + " library [%s]\n", aMech->uLibName); +#endif + (void) k5_mutex_unlock(&g_mechListLock); + return ((gss_mechanism)NULL); + } + + aMech->dl_handle = dl; + + (void) k5_mutex_unlock(&g_mechListLock); + return (aMech->mech); } /* gssint_get_mechanism */ +gss_mechanism_ext +gssint_get_mechanism_ext(oid) +const gss_OID oid; +{ + gss_mech_info aMech; + gss_mechanism_ext mech_ext; + + if (gssint_mechglue_initialize_library() != 0) + return (NULL); + + /* check if the mechanism is already loaded */ + if ((aMech = searchMechList(oid)) != NULL && aMech->mech_ext != NULL) + return (aMech->mech_ext); + + if (gssint_get_mechanism(oid) == NULL) + return (NULL); + + if (aMech->dl_handle == NULL) + return (NULL); + + /* Load the gss_config_ext struct for this mech */ + + mech_ext = (gss_mechanism_ext)malloc(sizeof (struct gss_config_ext)); + + if (mech_ext == NULL) + return (NULL); + +#if 0 + /* + * dlsym() the mech's 'method' functions for the extended APIs + * + * NOTE: Until the void *context argument is removed from the + * SPI method functions' signatures it will be necessary to have + * different function pointer typedefs and function names for + * the SPI methods than for the API. When this argument is + * removed it will be possible to rename gss_*_sfct to gss_*_fct + * and and gssspi_* to gss_*. + */ + mech_ext->gss_acquire_cred_with_password = + (gss_acquire_cred_with_password_sfct)dlsym(aMech->dl_handle, + "gssspi_acquire_cred_with_password"); +#endif + + /* Set aMech->mech_ext */ + (void) k5_mutex_lock(&g_mechListLock); + + if (aMech->mech_ext == NULL) + aMech->mech_ext = mech_ext; + else + free(mech_ext); /* we raced and lost; don't leak */ + + (void) k5_mutex_unlock(&g_mechListLock); + + return (aMech->mech_ext); + +} /* gssint_get_mechanism_ext */ + /* * this routine is used for searching the list of mechanism data. @@ -631,3 +968,235 @@ const gss_OID oid; /* none found */ return ((gss_mech_info) NULL); } /* searchMechList */ + + +/* + * loads the configuration file + * this is called while having a mutex lock on the mechanism list + * entries for libraries that have been loaded can't be modified + * mechNameStr and mech_type fields are not updated during updates + */ +static void loadConfigFile(fileName) +const char *fileName; +{ + char buffer[BUFSIZ], *oidStr, *oid, *sharedLib, *kernMod, *endp; + char *modOptions; + char sharedPath[sizeof (MECH_LIB_PREFIX) + BUFSIZ]; + char *tmpStr; + FILE *confFile; + gss_OID mechOid; + gss_mech_info aMech, tmp; + OM_uint32 minor; + gss_buffer_desc oidBuf; + + if ((confFile = fopen(fileName, "r")) == NULL) { + return; + } + + (void) memset(buffer, 0, sizeof (buffer)); + while (fgets(buffer, BUFSIZ, confFile) != NULL) { + + /* ignore lines beginning with # */ + if (*buffer == '#') + continue; + + /* + * find the first white-space character after + * the mechanism name + */ + oidStr = buffer; + for (oid = buffer; *oid && !isspace(*oid); oid++); + + /* Now find the first non-white-space character */ + if (*oid) { + *oid = '\0'; + oid++; + while (*oid && isspace(*oid)) + oid++; + } + + /* + * If that's all, then this is a corrupt entry. Skip it. + */ + if (! *oid) + continue; + + /* Find the end of the oid and make sure it is NULL-ended */ + for (endp = oid; *endp && !isspace(*endp); endp++) + ; + + if (*endp) { + *endp = '\0'; + } + + /* + * check if an entry for this oid already exists + * if it does, and the library is already loaded then + * we can't modify it, so skip it + */ + oidBuf.value = (void *)oid; + oidBuf.length = strlen(oid); + if (generic_gss_str_to_oid(&minor, &oidBuf, &mechOid) + != GSS_S_COMPLETE) { +#if 0 + (void) syslog(LOG_INFO, "invalid mechanism oid" + " [%s] in configuration file", oid); +#endif + continue; + } + + aMech = searchMechList(mechOid); + if (aMech && aMech->mech) { + generic_gss_release_oid(&minor, &mechOid); + continue; + } + + /* Find the start of the shared lib name */ + for (sharedLib = endp+1; *sharedLib && isspace(*sharedLib); + sharedLib++) + ; + + /* + * If that's all, then this is a corrupt entry. Skip it. + */ + if (! *sharedLib) { + generic_gss_release_oid(&minor, &mechOid); + continue; + } + + /* + * Find the end of the shared lib name and make sure it is + * NULL-terminated. + */ + for (endp = sharedLib; *endp && !isspace(*endp); endp++) + ; + + if (*endp) { + *endp = '\0'; + } + + /* Find the start of the optional kernel module lib name */ + for (kernMod = endp+1; *kernMod && isspace(*kernMod); + kernMod++) + ; + + /* + * If this item starts with a bracket "[", then + * it is not a kernel module, but is a list of + * options for the user module to parse later. + */ + if (*kernMod && *kernMod != '[') { + /* + * Find the end of the shared lib name and make sure + * it is NULL-terminated. + */ + for (endp = kernMod; *endp && !isspace(*endp); endp++) + ; + + if (*endp) { + *endp = '\0'; + } + } else + kernMod = NULL; + + /* Find the start of the optional module options list */ + for (modOptions = endp+1; *modOptions && isspace(*modOptions); + modOptions++); + + if (*modOptions == '[') { + /* move past the opening bracket */ + for (modOptions = modOptions+1; + *modOptions && isspace(*modOptions); + modOptions++); + + /* Find the closing bracket */ + for (endp = modOptions; + *endp && *endp != ']'; endp++); + + if (endp) + *endp = '\0'; + + } else { + modOptions = NULL; + } + + snprintf(sharedPath, sizeof(sharedPath), "%s%s", MECH_LIB_PREFIX, sharedLib); + + /* + * are we creating a new mechanism entry or + * just modifying existing (non loaded) mechanism entry + */ + if (aMech) { + /* + * delete any old values and set new + * mechNameStr and mech_type are not modified + */ + if (aMech->kmodName) { + free(aMech->kmodName); + aMech->kmodName = NULL; + } + + if (aMech->optionStr) { + free(aMech->optionStr); + aMech->optionStr = NULL; + } + + if ((tmpStr = strdup(sharedPath)) != NULL) { + if (aMech->uLibName) + free(aMech->uLibName); + aMech->uLibName = tmpStr; + } + + if (kernMod) /* this is an optional parameter */ + aMech->kmodName = strdup(kernMod); + + if (modOptions) /* optional module options */ + aMech->optionStr = strdup(modOptions); + + /* the oid is already set */ + generic_gss_release_oid(&minor, &mechOid); + continue; + } + + /* adding a new entry */ + aMech = calloc(1, sizeof (struct gss_mech_config)); + if (aMech == NULL) { + generic_gss_release_oid(&minor, &mechOid); + continue; + } + aMech->mech_type = mechOid; + aMech->uLibName = strdup(sharedPath); + aMech->mechNameStr = strdup(oidStr); + aMech->freeMech = 0; + + /* check if any memory allocations failed - bad news */ + if (aMech->uLibName == NULL || aMech->mechNameStr == NULL) { + if (aMech->uLibName) + free(aMech->uLibName); + if (aMech->mechNameStr) + free(aMech->mechNameStr); + generic_gss_release_oid(&minor, &mechOid); + free(aMech); + continue; + } + if (kernMod) /* this is an optional parameter */ + aMech->kmodName = strdup(kernMod); + + if (modOptions) + aMech->optionStr = strdup(modOptions); + /* + * add the new entry to the end of the list - make sure + * that only complete entries are added because other + * threads might currently be searching the list. + */ + tmp = g_mechListTail; + g_mechListTail = aMech; + + if (tmp != NULL) + tmp->next = aMech; + + if (g_mechList == NULL) + g_mechList = aMech; + } /* while */ + (void) fclose(confFile); +} /* loadConfigFile */ diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c index 201c8bb4a7..013b1768b7 100644 --- a/src/lib/gssapi/mechglue/g_inq_context.c +++ b/src/lib/gssapi/mechglue/g_inq_context.c @@ -111,7 +111,6 @@ gss_inquire_context( } status = mech->gss_inquire_context( - mech->context, minor_status, ctx->internal_ctx_id, (src_name ? &localSourceName : NULL), @@ -135,8 +134,7 @@ gss_inquire_context( if (status != GSS_S_COMPLETE) { if (localTargName) - mech->gss_release_name(mech->context, - &temp_minor, &localTargName); + mech->gss_release_name(&temp_minor, &localTargName); return (status); } diff --git a/src/lib/gssapi/mechglue/g_inq_context_oid.c b/src/lib/gssapi/mechglue/g_inq_context_oid.c new file mode 100644 index 0000000000..50bfcb561d --- /dev/null +++ b/src/lib/gssapi/mechglue/g_inq_context_oid.c @@ -0,0 +1,72 @@ +/* + * 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. + * + */ + +/* + * glue routine for gss_inquire_sec_context_by_oid + */ + +#include "mglueP.h" + +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 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech != NULL) { + if (mech->gss_inquire_sec_context_by_oid != NULL) { + status = mech->gss_inquire_sec_context_by_oid(minor_status, + ctx->internal_ctx_id, + desired_object, + data_set); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_BAD_MECH; + + return status; + } + + return GSS_S_NO_CONTEXT; +} + diff --git a/src/lib/gssapi/mechglue/g_inq_cred.c b/src/lib/gssapi/mechglue/g_inq_cred.c index 2413abca23..a144243990 100644 --- a/src/lib/gssapi/mechglue/g_inq_cred.c +++ b/src/lib/gssapi/mechglue/g_inq_cred.c @@ -86,7 +86,7 @@ gss_OID_set * mechanisms; if (!mech->gss_inquire_cred) return (GSS_S_UNAVAILABLE); - status = mech->gss_inquire_cred(mech->context, minor_status, + status = mech->gss_inquire_cred(minor_status, GSS_C_NO_CREDENTIAL, name ? &internal_name : NULL, lifetime, cred_usage, mechanisms); @@ -143,7 +143,9 @@ gss_OID_set * mechanisms; */ if(name != NULL) { - if ((gss_import_name(&temp_minor_status, + if (union_cred->auxinfo.name.length == 0) { + *name = GSS_C_NO_NAME; + } else if ((gss_import_name(&temp_minor_status, &union_cred->auxinfo.name, union_cred->auxinfo.name_type, name) != GSS_S_COMPLETE) || @@ -246,7 +248,7 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, return (GSS_S_DEFECTIVE_CREDENTIAL); #endif - status = mech->gss_inquire_cred_by_mech(mech->context, minor_status, + status = mech->gss_inquire_cred_by_mech(minor_status, mech_cred, mech_type, name ? &internal_name : NULL, initiator_lifetime, diff --git a/src/lib/gssapi/mechglue/g_inq_cred_oid.c b/src/lib/gssapi/mechglue/g_inq_cred_oid.c new file mode 100644 index 0000000000..34056f6bde --- /dev/null +++ b/src/lib/gssapi/mechglue/g_inq_cred_oid.c @@ -0,0 +1,133 @@ +/* + * 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. + * + */ + +/* + * glue routine for gss_inquire_cred_by_oid + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <time.h> + +static OM_uint32 append_to_buffer_set(OM_uint32 *minor_status, + gss_buffer_set_t *dst, + const gss_buffer_set_t src) +{ + size_t i; + OM_uint32 status; + + if (src == GSS_C_NO_BUFFER_SET) + return GSS_S_COMPLETE; + + if (*dst == GSS_C_NO_BUFFER_SET) { + status = gss_create_empty_buffer_set(minor_status, dst); + if (status != GSS_S_COMPLETE) + return status; + } + + status = GSS_S_COMPLETE; + + for (i = 0; i < src->count; i++) { + status = gss_add_buffer_set_member(minor_status, + &src->elements[i], + dst); + if (status != GSS_S_COMPLETE) + break; + } + + return status; +} + +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) +{ + gss_union_cred_t union_cred; + gss_mechanism mech; + int i; + gss_buffer_set_t union_set = GSS_C_NO_BUFFER_SET; + gss_buffer_set_t ret_set = GSS_C_NO_BUFFER_SET; + OM_uint32 status, minor; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED; + + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + + union_cred = (gss_union_cred_t) cred_handle; + + status = gss_create_empty_buffer_set(minor_status, &ret_set); + if (status != GSS_S_COMPLETE) { + return status; + } + + status = GSS_S_BAD_MECH; + + for (i = 0; i < union_cred->count; i++) { + mech = gssint_get_mechanism(&union_cred->mechs_array[i]); + if (mech == NULL) + continue; + + if (mech->gss_inquire_cred_by_oid == NULL) + continue; + + status = (mech->gss_inquire_cred_by_oid)(minor_status, + union_cred->cred_array[i], + desired_object, + &ret_set); + if (status != GSS_S_COMPLETE) { + map_error(minor_status, mech); + continue; + } + + if (union_cred->count == 1) { + union_set = ret_set; + break; + } + + status = append_to_buffer_set(minor_status, &union_set, ret_set); + gss_release_buffer_set(&minor, &ret_set); + if (status != GSS_S_COMPLETE) + break; + } + + if (status != GSS_S_COMPLETE) + gss_release_buffer_set(&minor, &union_set); + + *data_set = union_set; + + return status; +} + diff --git a/src/lib/gssapi/mechglue/g_inq_names.c b/src/lib/gssapi/mechglue/g_inq_names.c index 6142d86bac..597ab9919b 100644 --- a/src/lib/gssapi/mechglue/g_inq_names.c +++ b/src/lib/gssapi/mechglue/g_inq_names.c @@ -69,7 +69,6 @@ gss_OID_set * name_types; if (mech->gss_inquire_names_for_mech) { status = mech->gss_inquire_names_for_mech( - mech->context, minor_status, mechanism, name_types); diff --git a/src/lib/gssapi/mechglue/g_mech_invoke.c b/src/lib/gssapi/mechglue/g_mech_invoke.c new file mode 100644 index 0000000000..d753347d15 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_mech_invoke.c @@ -0,0 +1,70 @@ +/* + * 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. + * + */ + +/* + * glue routine for gssspi_mech_invoke + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +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) +{ + OM_uint32 status; + gss_mechanism mech; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = gssint_get_mechanism (desired_mech); + if (mech == NULL || mech->gssspi_mech_invoke == NULL) { + return GSS_S_BAD_MECH; + } + + status = mech->gssspi_mech_invoke(minor_status, + desired_mech, + desired_object, + value); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + + return status; +} + diff --git a/src/lib/gssapi/mechglue/g_oid_ops.c b/src/lib/gssapi/mechglue/g_oid_ops.c index 261d699f8f..bd195239c8 100644 --- a/src/lib/gssapi/mechglue/g_oid_ops.c +++ b/src/lib/gssapi/mechglue/g_oid_ops.c @@ -100,3 +100,12 @@ gss_str_to_oid(minor_status, oid_str, oid) return status; } +OM_uint32 KRB5_CALLCONV +gssint_copy_oid_set( + OM_uint32 *minor_status, + const gss_OID_set_desc * const oidset, + gss_OID_set *new_oidset) +{ + return generic_gss_copy_oid_set(minor_status, oidset, new_oidset); +} + diff --git a/src/lib/gssapi/mechglue/g_process_context.c b/src/lib/gssapi/mechglue/g_process_context.c index 5172c4cb57..9ed350c023 100644 --- a/src/lib/gssapi/mechglue/g_process_context.c +++ b/src/lib/gssapi/mechglue/g_process_context.c @@ -67,7 +67,6 @@ gss_buffer_t token_buffer; if (mech->gss_process_context_token) { status = mech->gss_process_context_token( - mech->context, minor_status, ctx->internal_ctx_id, token_buffer); diff --git a/src/lib/gssapi/mechglue/g_rel_cred.c b/src/lib/gssapi/mechglue/g_rel_cred.c index 02e9152626..df208a0dff 100644 --- a/src/lib/gssapi/mechglue/g_rel_cred.c +++ b/src/lib/gssapi/mechglue/g_rel_cred.c @@ -78,7 +78,7 @@ gss_cred_id_t * cred_handle; if (mech) { if (mech->gss_release_cred) { temp_status = mech->gss_release_cred - (mech->context, + ( minor_status, &union_cred->cred_array[j]); diff --git a/src/lib/gssapi/mechglue/g_rel_name.c b/src/lib/gssapi/mechglue/g_rel_name.c index a6615b7075..84d1af839c 100644 --- a/src/lib/gssapi/mechglue/g_rel_name.c +++ b/src/lib/gssapi/mechglue/g_rel_name.c @@ -48,7 +48,7 @@ gss_name_t * input_name; *minor_status = 0; /* if input_name is NULL, return error */ - if (input_name == 0) + if (input_name == NULL) return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME); if (*input_name == GSS_C_NO_NAME) @@ -65,16 +65,19 @@ gss_name_t * input_name; *input_name = 0; *minor_status = 0; - if (union_name->name_type) - gss_release_oid(minor_status, &union_name->name_type); - - free(union_name->external_name->value); - free(union_name->external_name); + if (union_name->name_type != GSS_C_NO_OID) + gss_release_oid(minor_status, &union_name->name_type); + + if (union_name->external_name != GSS_C_NO_BUFFER) { + if (union_name->external_name->value != NULL) + free(union_name->external_name->value); + free(union_name->external_name); + } if (union_name->mech_type) { - gssint_release_internal_name(minor_status, union_name->mech_type, - &union_name->mech_name); - gss_release_oid(minor_status, &union_name->mech_type); + gssint_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + gss_release_oid(minor_status, &union_name->mech_type); } free(union_name); diff --git a/src/lib/gssapi/mechglue/g_rel_oid_set.c b/src/lib/gssapi/mechglue/g_rel_oid_set.c index f55c907ec4..84c6ce6c96 100644 --- a/src/lib/gssapi/mechglue/g_rel_oid_set.c +++ b/src/lib/gssapi/mechglue/g_rel_oid_set.c @@ -39,25 +39,5 @@ gss_release_oid_set (minor_status, OM_uint32 * minor_status; gss_OID_set * set; { - OM_uint32 i; - gss_OID oid; - 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++) { - oid = &(*set)->elements[i]; - free(oid->elements); - } - free((*set)->elements); - free(*set); - - *set = GSS_C_NULL_OID_SET; - - return(GSS_S_COMPLETE); + return generic_gss_release_oid_set(minor_status, set); } diff --git a/src/lib/gssapi/mechglue/g_seal.c b/src/lib/gssapi/mechglue/g_seal.c index 95c9b45a01..9faa5ddb0b 100644 --- a/src/lib/gssapi/mechglue/g_seal.c +++ b/src/lib/gssapi/mechglue/g_seal.c @@ -23,17 +23,17 @@ */ /* - * glue routine for gss_seal + * glue routine for gss_wrap */ #include "mglueP.h" static OM_uint32 -val_seal_args( +val_wrap_args( OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, - int qop_req, + gss_qop_t qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer) @@ -66,9 +66,8 @@ val_seal_args( return (GSS_S_COMPLETE); } - OM_uint32 KRB5_CALLCONV -gss_seal (minor_status, +gss_wrap (minor_status, context_handle, conf_req_flag, qop_req, @@ -79,7 +78,7 @@ gss_seal (minor_status, OM_uint32 * minor_status; gss_ctx_id_t context_handle; int conf_req_flag; -int qop_req; +gss_qop_t qop_req; gss_buffer_t input_message_buffer; int * conf_state; gss_buffer_t output_message_buffer; @@ -90,7 +89,7 @@ gss_buffer_t output_message_buffer; gss_union_ctx_id_t ctx; gss_mechanism mech; - status = val_seal_args(minor_status, context_handle, + status = val_wrap_args(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer); @@ -106,9 +105,8 @@ gss_buffer_t output_message_buffer; mech = gssint_get_mechanism (ctx->mech_type); if (mech) { - if (mech->gss_seal) { - status = mech->gss_seal( - mech->context, + if (mech->gss_wrap) { + status = mech->gss_wrap( minor_status, ctx->internal_ctx_id, conf_req_flag, @@ -118,9 +116,20 @@ gss_buffer_t output_message_buffer; output_message_buffer); if (status != GSS_S_COMPLETE) map_error(minor_status, mech); + } else if (mech->gss_wrap_aead || + (mech->gss_wrap_iov && mech->gss_wrap_iov_length)) { + status = gssint_wrap_aead(mech, + minor_status, + ctx, + conf_req_flag, + (gss_qop_t)qop_req, + GSS_C_NO_BUFFER, + input_message_buffer, + conf_state, + output_message_buffer); } else status = GSS_S_UNAVAILABLE; - + return(status); } /* EXPORT DELETE END */ @@ -129,7 +138,7 @@ gss_buffer_t output_message_buffer; } OM_uint32 KRB5_CALLCONV -gss_wrap (minor_status, +gss_seal (minor_status, context_handle, conf_req_flag, qop_req, @@ -140,19 +149,74 @@ gss_wrap (minor_status, OM_uint32 * minor_status; gss_ctx_id_t context_handle; int conf_req_flag; -gss_qop_t qop_req; +int qop_req; gss_buffer_t input_message_buffer; int * conf_state; gss_buffer_t output_message_buffer; { - return gss_seal(minor_status, (gss_ctx_id_t)context_handle, - conf_req_flag, (int) qop_req, - (gss_buffer_t)input_message_buffer, conf_state, + return gss_wrap(minor_status, context_handle, + conf_req_flag, (gss_qop_t) qop_req, + input_message_buffer, conf_state, output_message_buffer); } /* + * It is only possible to implement gss_wrap_size_limit() on top + * of gss_wrap_iov_length() for mechanisms that do not use any + * padding and have fixed length headers/trailers. + */ +static OM_uint32 +gssint_wrap_size_limit_iov_shim(gss_mechanism mech, + 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) +{ + gss_iov_buffer_desc iov[4]; + OM_uint32 status; + OM_uint32 ohlen; + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[0].buffer.value = NULL; + iov[0].buffer.length = 0; + + iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[1].buffer.length = req_output_size; + iov[1].buffer.value = NULL; + + iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING; + iov[2].buffer.value = NULL; + iov[2].buffer.length = 0; + + iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER; + iov[3].buffer.value = NULL; + iov[3].buffer.length = 0; + + assert(mech->gss_wrap_iov_length); + + status = mech->gss_wrap_iov_length(minor_status, context_handle, + conf_req_flag, qop_req, + NULL, iov, + sizeof(iov)/sizeof(iov[0])); + if (status != GSS_S_COMPLETE) { + map_error(minor_status, mech); + return status; + } + + ohlen = iov[0].buffer.length + iov[3].buffer.length; + + if (iov[2].buffer.length == 0 && ohlen < req_output_size) + *max_input_size = req_output_size - ohlen; + else + *max_input_size = 0; + + return GSS_S_COMPLETE; +} + +/* * New for V2 */ OM_uint32 KRB5_CALLCONV @@ -190,13 +254,18 @@ gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, if (!mech) return (GSS_S_BAD_MECH); - if (!mech->gss_wrap_size_limit) - return (GSS_S_UNAVAILABLE); - - major_status = mech->gss_wrap_size_limit(mech->context, minor_status, - ctx->internal_ctx_id, - conf_req_flag, qop_req, - req_output_size, max_input_size); + if (mech->gss_wrap_size_limit) + major_status = mech->gss_wrap_size_limit(minor_status, + ctx->internal_ctx_id, + conf_req_flag, qop_req, + req_output_size, max_input_size); + else if (mech->gss_wrap_iov_length) + major_status = gssint_wrap_size_limit_iov_shim(mech, minor_status, + ctx->internal_ctx_id, + conf_req_flag, qop_req, + req_output_size, max_input_size); + else + major_status = GSS_S_UNAVAILABLE; if (major_status != GSS_S_COMPLETE) map_error(minor_status, mech); return major_status; diff --git a/src/lib/gssapi/mechglue/g_set_context_option.c b/src/lib/gssapi/mechglue/g_set_context_option.c new file mode 100644 index 0000000000..17d9e3bace --- /dev/null +++ b/src/lib/gssapi/mechglue/g_set_context_option.c @@ -0,0 +1,110 @@ +/* + * 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. + * + */ + +/* + * glue routine for gss_set_sec_context_option + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV +gss_set_sec_context_option (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + OM_uint32 status, minor; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + gss_ctx_id_t internal_ctx = GSS_C_NO_CONTEXT; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (context_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) *context_handle; + if (ctx == NULL) { + mech = gssint_get_mechanism (GSS_C_NO_OID); + } else { + mech = gssint_get_mechanism (ctx->mech_type); + } + + if (mech == NULL || mech->gss_set_sec_context_option == NULL) { + return GSS_S_BAD_MECH; + } + + status = mech->gss_set_sec_context_option(minor_status, + ctx ? &internal_ctx : + &ctx->internal_ctx_id, + desired_object, + value); + if (status == GSS_S_COMPLETE) { + if (ctx == NULL && internal_ctx != GSS_C_NO_CONTEXT) { + /* Allocate a union context handle to wrap new context */ + ctx = (gss_union_ctx_id_t)malloc(sizeof(*ctx)); + if (ctx == NULL) { + *minor_status = ENOMEM; + gssint_delete_internal_sec_context(&minor, + ctx->mech_type, + &internal_ctx, + GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + status = generic_gss_copy_oid(minor_status, + &mech->mech_type, + &ctx->mech_type); + if (status != GSS_S_COMPLETE) { + gssint_delete_internal_sec_context(&minor, + ctx->mech_type, + &internal_ctx, + GSS_C_NO_BUFFER); + free(ctx); + return status; + } + + ctx->internal_ctx_id = internal_ctx; + *context_handle = (gss_ctx_id_t)ctx; + } + } else + map_error(minor_status, mech); + + return status; +} + diff --git a/src/lib/gssapi/mechglue/g_set_cred_option.c b/src/lib/gssapi/mechglue/g_set_cred_option.c new file mode 100644 index 0000000000..84d18cdf81 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_set_cred_option.c @@ -0,0 +1,81 @@ +/* + * 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. + * + */ + +/* + * glue routine for gssspi_set_cred_option + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <time.h> + +OM_uint32 KRB5_CALLCONV +gssspi_set_cred_option(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + gss_union_cred_t union_cred; + gss_mechanism mech; + int i; + OM_uint32 status; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED; + + *minor_status = 0; + + union_cred = (gss_union_cred_t) cred_handle; + + status = GSS_S_BAD_MECH; + + for (i = 0; i < union_cred->count; i++) { + mech = gssint_get_mechanism(&union_cred->mechs_array[i]); + if (mech == NULL) + continue; + + if (mech->gssspi_set_cred_option == NULL) + continue; + + status = (mech->gssspi_set_cred_option)(minor_status, + union_cred->cred_array[i], + desired_object, + value); + if (status != GSS_S_COMPLETE) { + map_error(minor_status, mech); + break; + } + } + + return status; +} + diff --git a/src/lib/gssapi/mechglue/g_sign.c b/src/lib/gssapi/mechglue/g_sign.c index d297ee1ca3..eec0f49b49 100644 --- a/src/lib/gssapi/mechglue/g_sign.c +++ b/src/lib/gssapi/mechglue/g_sign.c @@ -23,16 +23,16 @@ */ /* - * glue routine gss_sign + * glue routine gss_get_mic */ #include "mglueP.h" static OM_uint32 -val_sign_args( +val_get_mic_args( OM_uint32 *minor_status, gss_ctx_id_t context_handle, - int qop_req, + gss_qop_t qop_req, gss_buffer_t message_buffer, gss_buffer_t msg_token) { @@ -66,15 +66,15 @@ val_sign_args( OM_uint32 KRB5_CALLCONV -gss_sign (minor_status, - context_handle, - qop_req, - message_buffer, - msg_token) +gss_get_mic (minor_status, + context_handle, + qop_req, + message_buffer, + msg_token) OM_uint32 * minor_status; gss_ctx_id_t context_handle; -int qop_req; +gss_qop_t qop_req; gss_buffer_t message_buffer; gss_buffer_t msg_token; @@ -83,8 +83,8 @@ gss_buffer_t msg_token; gss_union_ctx_id_t ctx; gss_mechanism mech; - status = val_sign_args(minor_status, context_handle, - qop_req, message_buffer, msg_token); + status = val_get_mic_args(minor_status, context_handle, + qop_req, message_buffer, msg_token); if (status != GSS_S_COMPLETE) return (status); @@ -97,9 +97,8 @@ gss_buffer_t msg_token; mech = gssint_get_mechanism (ctx->mech_type); if (mech) { - if (mech->gss_sign) { - status = mech->gss_sign( - mech->context, + if (mech->gss_get_mic) { + status = mech->gss_get_mic( minor_status, ctx->internal_ctx_id, qop_req, @@ -117,7 +116,7 @@ gss_buffer_t msg_token; } OM_uint32 KRB5_CALLCONV -gss_get_mic (minor_status, +gss_sign (minor_status, context_handle, qop_req, message_buffer, @@ -125,12 +124,12 @@ gss_get_mic (minor_status, OM_uint32 * minor_status; gss_ctx_id_t context_handle; -gss_qop_t qop_req; +int qop_req; gss_buffer_t message_buffer; gss_buffer_t msg_token; { - return (gss_sign(minor_status, context_handle, (int) qop_req, - message_buffer, msg_token)); + return (gss_get_mic(minor_status, context_handle, (gss_qop_t) qop_req, + message_buffer, msg_token)); } diff --git a/src/lib/gssapi/mechglue/g_store_cred.c b/src/lib/gssapi/mechglue/g_store_cred.c index d9a7d9adcf..1d438c4b92 100644 --- a/src/lib/gssapi/mechglue/g_store_cred.c +++ b/src/lib/gssapi/mechglue/g_store_cred.c @@ -111,7 +111,7 @@ gss_cred_usage_t *cred_usage_stored; if (mech_cred == GSS_C_NO_CREDENTIAL) return (GSS_S_NO_CRED); - major_status = mech->gss_store_cred(mech->context, + major_status = mech->gss_store_cred( minor_status, (gss_cred_id_t)mech_cred, cred_usage, @@ -143,7 +143,7 @@ gss_cred_usage_t *cred_usage_stored; if (mech_cred == GSS_C_NO_CREDENTIAL) continue; /* can't happen, but safe to ignore */ - major_status = mech->gss_store_cred(mech->context, + major_status = mech->gss_store_cred( minor_status, (gss_cred_id_t)mech_cred, cred_usage, diff --git a/src/lib/gssapi/mechglue/g_unseal.c b/src/lib/gssapi/mechglue/g_unseal.c index be7a8de90b..c6b33506be 100644 --- a/src/lib/gssapi/mechglue/g_unseal.c +++ b/src/lib/gssapi/mechglue/g_unseal.c @@ -23,13 +23,13 @@ */ /* - * glue routine gss_unseal + * glue routine gss_unwrap */ #include "mglueP.h" OM_uint32 KRB5_CALLCONV -gss_unseal (minor_status, +gss_unwrap (minor_status, context_handle, input_message_buffer, output_message_buffer, @@ -41,7 +41,7 @@ gss_ctx_id_t context_handle; gss_buffer_t input_message_buffer; gss_buffer_t output_message_buffer; int * conf_state; -int * qop_state; +gss_qop_t * qop_state; { /* EXPORT DELETE START */ @@ -75,15 +75,12 @@ int * qop_state; * select the approprate underlying mechanism routine and * call it. */ - ctx = (gss_union_ctx_id_t) context_handle; mech = gssint_get_mechanism (ctx->mech_type); if (mech) { - if (mech->gss_unseal) { - status = mech->gss_unseal( - mech->context, - minor_status, + if (mech->gss_unwrap) { + status = mech->gss_unwrap(minor_status, ctx->internal_ctx_id, input_message_buffer, output_message_buffer, @@ -91,6 +88,15 @@ int * qop_state; qop_state); if (status != GSS_S_COMPLETE) map_error(minor_status, mech); + } else if (mech->gss_unwrap_aead || mech->gss_unwrap_iov) { + status = gssint_unwrap_aead(mech, + minor_status, + ctx, + input_message_buffer, + GSS_C_NO_BUFFER, + output_message_buffer, + conf_state, + (gss_qop_t *)qop_state); } else status = GSS_S_UNAVAILABLE; @@ -103,7 +109,7 @@ int * qop_state; } OM_uint32 KRB5_CALLCONV -gss_unwrap (minor_status, +gss_unseal (minor_status, context_handle, input_message_buffer, output_message_buffer, @@ -115,10 +121,10 @@ 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; +int * qop_state; { - return (gss_unseal(minor_status, (gss_ctx_id_t)context_handle, - (gss_buffer_t)input_message_buffer, - output_message_buffer, conf_state, (int *) qop_state)); + return (gss_unwrap(minor_status, context_handle, + input_message_buffer, + output_message_buffer, conf_state, (gss_qop_t *) qop_state)); } diff --git a/src/lib/gssapi/mechglue/g_unwrap_aead.c b/src/lib/gssapi/mechglue/g_unwrap_aead.c new file mode 100644 index 0000000000..7dcc27701f --- /dev/null +++ b/src/lib/gssapi/mechglue/g_unwrap_aead.c @@ -0,0 +1,198 @@ +/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 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_unwrap_aead + */ + +#include "mglueP.h" + +static OM_uint32 +val_unwrap_aead_args( + 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) +{ + + /* Initialize outputs. */ + + if (minor_status != NULL) + *minor_status = 0; + + /* Validate arguments. */ + + if (minor_status == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (context_handle == GSS_C_NO_CONTEXT) + return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); + + if (input_message_buffer == GSS_C_NO_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (output_payload_buffer == GSS_C_NO_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + return (GSS_S_COMPLETE); +} + +static OM_uint32 +gssint_unwrap_aead_iov_shim(gss_mechanism mech, + 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) +{ + OM_uint32 status; + gss_iov_buffer_desc iov[3]; + int i = 0; + + iov[i].type = GSS_IOV_BUFFER_TYPE_STREAM; + iov[i].buffer = *input_message_buffer; + i++; + + if (input_assoc_buffer != NULL) { + iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[i].buffer = *input_assoc_buffer; + i++; + } + + iov[i].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; + iov[i].buffer.value = NULL; + iov[i].buffer.length = 0; + i++; + + assert(mech->gss_unwrap_iov); + + status = mech->gss_unwrap_iov(minor_status, context_handle, conf_state, + qop_state, iov, i); + if (status == GSS_S_COMPLETE) { + *output_payload_buffer = iov[i - 1].buffer; + } else { + OM_uint32 minor; + + map_error(minor_status, mech); + + if (iov[i - 1].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { + gss_release_buffer(&minor, &iov[i - 1].buffer); + iov[i - 1].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); + } + } + + return status; +} + +OM_uint32 +gssint_unwrap_aead (gss_mechanism mech, + OM_uint32 *minor_status, + gss_union_ctx_id_t ctx, + 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) +{ + OM_uint32 status; + + assert(mech != NULL); + assert(ctx != NULL); + + /* EXPORT DELETE START */ + + if (mech->gss_unwrap_aead) { + status = mech->gss_unwrap_aead(minor_status, + ctx->internal_ctx_id, + input_message_buffer, + input_assoc_buffer, + output_payload_buffer, + conf_state, + qop_state); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else if (mech->gss_unwrap_iov) { + status = gssint_unwrap_aead_iov_shim(mech, + minor_status, + ctx->internal_ctx_id, + input_message_buffer, + input_assoc_buffer, + output_payload_buffer, + conf_state, + qop_state); + } else + status = GSS_S_UNAVAILABLE; + /* EXPORT DELETE END */ + + return (status); +} + +OM_uint32 KRB5_CALLCONV +gss_unwrap_aead (minor_status, + context_handle, + input_message_buffer, + input_assoc_buffer, + output_payload_buffer, + conf_state, + qop_state) +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; +{ + + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + status = val_unwrap_aead_args(minor_status, context_handle, + input_message_buffer, input_assoc_buffer, + output_payload_buffer, + conf_state, qop_state); + if (status != GSS_S_COMPLETE) + return (status); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (!mech) + return (GSS_S_BAD_MECH); + + return gssint_unwrap_aead(mech, minor_status, context_handle, + input_message_buffer, input_assoc_buffer, + output_payload_buffer, conf_state, qop_state); +} + diff --git a/src/lib/gssapi/mechglue/g_unwrap_iov.c b/src/lib/gssapi/mechglue/g_unwrap_iov.c new file mode 100644 index 0000000000..ebef1a70a3 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_unwrap_iov.c @@ -0,0 +1,114 @@ +/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 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_unwrap_iov + */ + +#include "mglueP.h" + +static OM_uint32 +val_unwrap_iov_args( + 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) +{ + + /* Initialize outputs. */ + + if (minor_status != NULL) + *minor_status = 0; + + /* Validate arguments. */ + + if (minor_status == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (context_handle == GSS_C_NO_CONTEXT) + return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); + + if (iov == GSS_C_NO_IOV_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_READ); + + return (GSS_S_COMPLETE); +} + + +OM_uint32 KRB5_CALLCONV +gss_unwrap_iov (minor_status, + context_handle, + conf_state, + qop_state, + iov, + iov_count) +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; +{ + /* EXPORT DELETE START */ + + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + status = val_unwrap_iov_args(minor_status, context_handle, + conf_state, qop_state, iov, iov_count); + if (status != GSS_S_COMPLETE) + return (status); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_unwrap_iov) { + status = mech->gss_unwrap_iov( + minor_status, + ctx->internal_ctx_id, + conf_state, + qop_state, + iov, + iov_count); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_UNAVAILABLE; + + return(status); + } + /* EXPORT DELETE END */ + + return (GSS_S_BAD_MECH); +} + diff --git a/src/lib/gssapi/mechglue/g_userok.c b/src/lib/gssapi/mechglue/g_userok.c new file mode 100644 index 0000000000..90fa90335e --- /dev/null +++ b/src/lib/gssapi/mechglue/g_userok.c @@ -0,0 +1,114 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* #pragma ident "@(#)g_userok.c 1.1 04/03/25 SMI" */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <mglueP.h> +#include <gssapi/gssapi.h> + + +static OM_uint32 +compare_names(OM_uint32 *minor, + const gss_OID mech_type, + const gss_name_t name, + const char *user, + int *user_ok) +{ + + OM_uint32 status, tmpMinor; + gss_name_t imported_name; + gss_name_t canon_name; + gss_buffer_desc gss_user; + int match = 0; + + *user_ok = 0; + + gss_user.value = (void *)user; + if (!gss_user.value || !name || !mech_type) + return (GSS_S_BAD_NAME); + gss_user.length = strlen(gss_user.value); + + status = gss_import_name(minor, + &gss_user, + GSS_C_NT_USER_NAME, + &imported_name); + if (status != GSS_S_COMPLETE) { + goto out; + } + + status = gss_canonicalize_name(minor, + imported_name, + mech_type, + &canon_name); + if (status != GSS_S_COMPLETE) { + (void) gss_release_name(&tmpMinor, &imported_name); + goto out; + } + + status = gss_compare_name(minor, + canon_name, + name, + &match); + (void) gss_release_name(&tmpMinor, &canon_name); + (void) gss_release_name(&tmpMinor, &imported_name); + if (status == GSS_S_COMPLETE) { + if (match) + *user_ok = 1; /* remote user is a-ok */ + } + +out: + return (status); +} + + +OM_uint32 +gssint_userok(OM_uint32 *minor, + const gss_name_t name, + const char *user, + int *user_ok) + +{ + gss_mechanism mech; + gss_union_name_t intName; + gss_name_t mechName = NULL; + OM_uint32 major; + + if (minor == NULL || user_ok == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (name == NULL || user == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + *user_ok = 0; + *minor = GSS_S_COMPLETE; + + intName = (gss_union_name_t)name; + + mech = gssint_get_mechanism(intName->mech_type); + if (mech == NULL) + return (GSS_S_UNAVAILABLE); + + /* may need to import the name if this is not MN */ + if (intName->mech_type == NULL) { + return (GSS_S_FAILURE); + } else + mechName = intName->mech_name; + + if (mech->gssint_userok) { + major = mech->gssint_userok(minor, mechName, + user, user_ok); + if (major != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + major = compare_names(minor, intName->mech_type, + name, user, user_ok); + + return (major); +} /* gss_userok */ + diff --git a/src/lib/gssapi/mechglue/g_verify.c b/src/lib/gssapi/mechglue/g_verify.c index a6ca923a40..da3279cc78 100644 --- a/src/lib/gssapi/mechglue/g_verify.c +++ b/src/lib/gssapi/mechglue/g_verify.c @@ -23,23 +23,23 @@ */ /* - * glue routine for gss_verify + * glue routine for gss_verify_mic */ #include "mglueP.h" OM_uint32 KRB5_CALLCONV -gss_verify (minor_status, - context_handle, - message_buffer, - token_buffer, - qop_state) +gss_verify_mic (minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state) OM_uint32 * minor_status; gss_ctx_id_t context_handle; gss_buffer_t message_buffer; gss_buffer_t token_buffer; -int * qop_state; +gss_qop_t * qop_state; { OM_uint32 status; @@ -68,14 +68,13 @@ int * qop_state; mech = gssint_get_mechanism (ctx->mech_type); if (mech) { - if (mech->gss_verify) { - status = mech->gss_verify( - mech->context, - minor_status, - ctx->internal_ctx_id, - message_buffer, - token_buffer, - qop_state); + if (mech->gss_verify_mic) { + status = mech->gss_verify_mic( + minor_status, + ctx->internal_ctx_id, + message_buffer, + token_buffer, + qop_state); if (status != GSS_S_COMPLETE) map_error(minor_status, mech); } else @@ -88,7 +87,7 @@ int * qop_state; } OM_uint32 KRB5_CALLCONV -gss_verify_mic (minor_status, +gss_verify (minor_status, context_handle, message_buffer, token_buffer, @@ -98,9 +97,10 @@ OM_uint32 * minor_status; gss_ctx_id_t context_handle; gss_buffer_t message_buffer; gss_buffer_t token_buffer; -gss_qop_t * qop_state; +int * qop_state; { - return (gss_verify(minor_status, context_handle, - message_buffer, token_buffer, (int *) qop_state)); + return (gss_verify_mic(minor_status, context_handle, + message_buffer, token_buffer, + (gss_qop_t *) qop_state)); } diff --git a/src/lib/gssapi/mechglue/g_wrap_aead.c b/src/lib/gssapi/mechglue/g_wrap_aead.c new file mode 100644 index 0000000000..ff170e237c --- /dev/null +++ b/src/lib/gssapi/mechglue/g_wrap_aead.c @@ -0,0 +1,267 @@ +/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 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_wrap_aead + */ + +#include "mglueP.h" + +static OM_uint32 +val_wrap_aead_args( + 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) +{ + + /* Initialize outputs. */ + + if (minor_status != NULL) + *minor_status = 0; + + /* Validate arguments. */ + + if (minor_status == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (context_handle == GSS_C_NO_CONTEXT) + return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); + + if (input_payload_buffer == GSS_C_NO_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (output_message_buffer == GSS_C_NO_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + return (GSS_S_COMPLETE); +} + +static OM_uint32 +gssint_wrap_aead_iov_shim(gss_mechanism mech, + 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) +{ + gss_iov_buffer_desc iov[5]; + OM_uint32 status; + size_t offset; + int i = 0, iov_count; + + /* HEADER | SIGN_ONLY_DATA | DATA | PADDING | TRAILER */ + + iov[i].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[i].buffer.value = NULL; + iov[i].buffer.length = 0; + i++; + + if (input_assoc_buffer != GSS_C_NO_BUFFER) { + iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[i].buffer = *input_assoc_buffer; + i++; + } + + iov[i].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[i].buffer = *input_payload_buffer; + i++; + + iov[i].type = GSS_IOV_BUFFER_TYPE_PADDING; + iov[i].buffer.value = NULL; + iov[i].buffer.length = 0; + i++; + + iov[i].type = GSS_IOV_BUFFER_TYPE_TRAILER; + iov[i].buffer.value = NULL; + iov[i].buffer.length = 0; + i++; + + iov_count = i; + + assert(mech->gss_wrap_iov_length); + + status = mech->gss_wrap_iov_length(minor_status, context_handle, + conf_req_flag, qop_req, + NULL, iov, iov_count); + if (status != GSS_S_COMPLETE) { + map_error(minor_status, mech); + return status; + } + + /* Format output token (does not include associated data) */ + for (i = 0, output_message_buffer->length = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + continue; + + output_message_buffer->length += iov[i].buffer.length; + } + + output_message_buffer->value = malloc(output_message_buffer->length); + if (output_message_buffer->value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + i = 0, offset = 0; + + /* HEADER */ + iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; + offset += iov[i].buffer.length; + i++; + + /* SIGN_ONLY_DATA */ + if (input_assoc_buffer != GSS_C_NO_BUFFER) + i++; + + /* DATA */ + iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; + offset += iov[i].buffer.length; + + memcpy(iov[i].buffer.value, input_payload_buffer->value, iov[i].buffer.length); + i++; + + /* PADDING */ + iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; + offset += iov[i].buffer.length; + i++; + + /* TRAILER */ + iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; + offset += iov[i].buffer.length; + i++; + + assert(offset == output_message_buffer->length); + + assert(mech->gss_wrap_iov); + + status = mech->gss_wrap_iov(minor_status, context_handle, + conf_req_flag, qop_req, + conf_state, iov, iov_count); + if (status != GSS_S_COMPLETE) { + OM_uint32 minor; + + map_error(minor_status, mech); + gss_release_buffer(&minor, output_message_buffer); + } + + return status; +} + +OM_uint32 +gssint_wrap_aead (gss_mechanism mech, + OM_uint32 *minor_status, + gss_union_ctx_id_t ctx, + 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) +{ + /* EXPORT DELETE START */ + OM_uint32 status; + + assert(ctx != NULL); + assert(mech != NULL); + + if (mech->gss_wrap_aead) { + status = mech->gss_wrap_aead(minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + input_assoc_buffer, + input_payload_buffer, + conf_state, + output_message_buffer); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else if (mech->gss_wrap_iov && mech->gss_wrap_iov_length) { + status = gssint_wrap_aead_iov_shim(mech, + minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + input_assoc_buffer, + input_payload_buffer, + conf_state, + output_message_buffer); + } else + status = GSS_S_UNAVAILABLE; + + /* EXPORT DELETE END */ + + return status; +} + +OM_uint32 KRB5_CALLCONV +gss_wrap_aead (minor_status, + context_handle, + conf_req_flag, + qop_req, + input_assoc_buffer, + input_payload_buffer, + conf_state, + output_message_buffer) +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 status; + gss_mechanism mech; + gss_union_ctx_id_t ctx; + + status = val_wrap_aead_args(minor_status, context_handle, + conf_req_flag, qop_req, + input_assoc_buffer, input_payload_buffer, + conf_state, output_message_buffer); + if (status != GSS_S_COMPLETE) + return (status); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + ctx = (gss_union_ctx_id_t)context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + + return gssint_wrap_aead(mech, minor_status, context_handle, + conf_req_flag, qop_req, + input_assoc_buffer, input_payload_buffer, + conf_state, output_message_buffer); +} diff --git a/src/lib/gssapi/mechglue/g_wrap_iov.c b/src/lib/gssapi/mechglue/g_wrap_iov.c new file mode 100644 index 0000000000..8d054b259a --- /dev/null +++ b/src/lib/gssapi/mechglue/g_wrap_iov.c @@ -0,0 +1,207 @@ +/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 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_wrap_iov + */ + +#include "mglueP.h" + +static OM_uint32 +val_wrap_iov_args( + 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) +{ + + /* Initialize outputs. */ + + if (minor_status != NULL) + *minor_status = 0; + + /* Validate arguments. */ + + if (minor_status == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (context_handle == GSS_C_NO_CONTEXT) + return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); + + if (iov == GSS_C_NO_IOV_BUFFER) + return (GSS_S_CALL_INACCESSIBLE_READ); + + return (GSS_S_COMPLETE); +} + + +OM_uint32 KRB5_CALLCONV +gss_wrap_iov (minor_status, + context_handle, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count) +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; +{ + /* EXPORT DELETE START */ + + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + status = val_wrap_iov_args(minor_status, context_handle, + conf_req_flag, qop_req, + conf_state, iov, iov_count); + if (status != GSS_S_COMPLETE) + return (status); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_wrap_iov) { + status = mech->gss_wrap_iov( + minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_UNAVAILABLE; + + return(status); + } + /* EXPORT DELETE END */ + + return (GSS_S_BAD_MECH); +} + +OM_uint32 KRB5_CALLCONV +gss_wrap_iov_length (minor_status, + context_handle, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count) +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; +{ + /* EXPORT DELETE START */ + + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + status = val_wrap_iov_args(minor_status, context_handle, + conf_req_flag, qop_req, + conf_state, iov, iov_count); + if (status != GSS_S_COMPLETE) + return (status); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_wrap_iov_length) { + status = mech->gss_wrap_iov_length( + minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_UNAVAILABLE; + + return(status); + } + /* EXPORT DELETE END */ + + return (GSS_S_BAD_MECH); +} + +OM_uint32 KRB5_CALLCONV +gss_release_iov_buffer (minor_status, + iov, + iov_count) +OM_uint32 * minor_status; +gss_iov_buffer_desc * iov; +int iov_count; +{ + OM_uint32 status = GSS_S_COMPLETE; + int i; + + if (minor_status) + *minor_status = 0; + + if (iov == GSS_C_NO_IOV_BUFFER) + return GSS_S_COMPLETE; + + for (i = 0; i < iov_count; i++) { + if (iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { + status = gss_release_buffer(minor_status, &iov[i].buffer); + if (status != GSS_S_COMPLETE) + break; + + iov[i].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); + } + } + + return status; +} + diff --git a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c new file mode 100644 index 0000000000..c310f1630e --- /dev/null +++ b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c @@ -0,0 +1,67 @@ +/* #pragma ident "@(#)gssd_pname_to_uid.c 1.18 04/02/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 routines that test the mech id either passed in to + * gss_init_sec_contex() or gss_accept_sec_context() or within the glue + * routine supported version of the security context and then call + * the appropriate underlying mechanism library procedure. + * + */ + +#include "mglueP.h" + +int gssd_pname_to_uid(pname, name_type, mech_type, uid) + +char * pname; +gss_OID name_type; +gss_OID mech_type; +uid_t * uid; +{ + int status; + gss_mechanism mech; + + /* + * find the appropriate mechanism specific pname_to_uid procedure and + * call it. + */ + + mech = gssint_get_mechanism (mech_type); + + if (mech) { + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->pname_to_uid) { + status = mech->pname_to_uid(pname, name_type, mech_type, uid); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_BAD_MECH; + } else + status = GSS_S_BAD_MECH; + + return(status); +} + diff --git a/src/lib/gssapi/mechglue/mech.conf b/src/lib/gssapi/mechglue/mech.conf deleted file mode 100644 index 5257a01a27..0000000000 --- a/src/lib/gssapi/mechglue/mech.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# -# GSSAPI Mechanism Definitions -# -# library function -/opt/SUNWgss/lib/mech_krb5.so krb5_gss_initialize -#mech_krb5.so krb5_gss_initialize diff --git a/src/lib/gssapi/mechglue/mechglue.h b/src/lib/gssapi/mechglue/mechglue.h index 4f4cd481cb..7f3334aec2 100644 --- a/src/lib/gssapi/mechglue/mechglue.h +++ b/src/lib/gssapi/mechglue/mechglue.h @@ -35,4 +35,8 @@ /* GSSAPI Extension functions -- these functions aren't */ /* in the GSSAPI, but they are provided in this library */ +#include <gssapi/gssapi_ext.h> + +void KRB5_CALLCONV gss_initialize(void); + #endif /* _GSS_MECHGLUE_H */ diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index 1f14ee2178..52195f2931 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -20,9 +20,6 @@ do { \ (o1)->length = (o2)->length; \ } while (0) -#define GSS_EMPTY_BUFFER(buf) ((buf) == NULL ||\ - (buf)->value == NULL || (buf)->length == 0) - /* * Array of context IDs typed by mechanism OID */ @@ -78,7 +75,20 @@ typedef struct gss_cred_id_struct { gss_cred_id_t *cred_array; gss_union_cred_auxinfo auxinfo; } gss_union_cred_desc, *gss_union_cred_t; - + +typedef OM_uint32 (*gss_acquire_cred_with_password_sfct)( + void *, /* context */ + 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 */ + int, /* cred_usage */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 * /* time_rec */ + /* */); + /* * Rudimentary pointer validation macro to check whether the * "loopback" field of an opaque struct points back to itself. This @@ -91,7 +101,10 @@ typedef struct gss_cred_id_struct { /********************************************************/ /* The Mechanism Dispatch Table -- a mechanism needs to */ /* define one of these and provide a function to return */ -/* it to initialize the GSSAPI library */ +/* it to initialize the GSSAPI library */ +int gssint_mechglue_initialize_library(void); + +OM_uint32 gssint_get_mech_type_oid(gss_OID OID, gss_buffer_t token); /* * This is the definition of the mechs_array struct, which is used to @@ -105,13 +118,10 @@ typedef struct gss_cred_id_struct { */ typedef struct gss_config { - OM_uint32 priority; - char * mechNameStr; gss_OID_desc mech_type; void * context; OM_uint32 (*gss_acquire_cred) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_name_t, /* desired_name */ OM_uint32, /* time_req */ @@ -123,13 +133,11 @@ typedef struct gss_config { ); OM_uint32 (*gss_release_cred) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_cred_id_t* /* cred_handle */ ); OM_uint32 (*gss_init_sec_context) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_cred_id_t, /* claimant_cred_handle */ gss_ctx_id_t*, /* context_handle */ @@ -146,7 +154,6 @@ typedef struct gss_config { ); OM_uint32 (*gss_accept_sec_context) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_cred_id_t, /* verifier_cred_handle */ @@ -161,67 +168,59 @@ typedef struct gss_config { ); OM_uint32 (*gss_process_context_token) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t /* token_buffer */ ); OM_uint32 (*gss_delete_sec_context) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_buffer_t /* output_token */ ); OM_uint32 (*gss_context_time) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ OM_uint32* /* time_rec */ ); - OM_uint32 (*gss_sign) + OM_uint32 (*gss_get_mic) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ - int, /* qop_req */ + gss_qop_t, /* qop_req */ gss_buffer_t, /* message_buffer */ gss_buffer_t /* message_token */ ); - OM_uint32 (*gss_verify) + OM_uint32 (*gss_verify_mic) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* message_buffer */ gss_buffer_t, /* token_buffer */ - int* /* qop_state */ + gss_qop_t* /* qop_state */ ); - OM_uint32 (*gss_seal) + OM_uint32 (*gss_wrap) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ - int, /* qop_req */ + gss_qop_t, /* qop_req */ gss_buffer_t, /* input_message_buffer */ int*, /* conf_state */ gss_buffer_t /* output_message_buffer */ ); - OM_uint32 (*gss_unseal) + OM_uint32 (*gss_unwrap) ( - void*, /* context */ 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 */ + gss_qop_t* /* qop_state */ ); OM_uint32 (*gss_display_status) ( - void*, /* context */ OM_uint32*, /* minor_status */ OM_uint32, /* status_value */ int, /* status_type */ @@ -231,13 +230,11 @@ typedef struct gss_config { ); OM_uint32 (*gss_indicate_mechs) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_OID_set* /* mech_set */ ); OM_uint32 (*gss_compare_name) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_name_t, /* name1 */ gss_name_t, /* name2 */ @@ -245,7 +242,6 @@ typedef struct gss_config { ); OM_uint32 (*gss_display_name) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_name_t, /* input_name */ gss_buffer_t, /* output_name_buffer */ @@ -253,7 +249,6 @@ typedef struct gss_config { ); OM_uint32 (*gss_import_name) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_buffer_t, /* input_name_buffer */ gss_OID, /* input_name_type */ @@ -261,13 +256,11 @@ typedef struct gss_config { ); OM_uint32 (*gss_release_name) ( - void*, /* context */ OM_uint32*, /* minor_status */ gss_name_t* /* input_name */ ); OM_uint32 (*gss_inquire_cred) ( - void*, /* context */ OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_name_t *, /* name */ @@ -277,7 +270,6 @@ typedef struct gss_config { ); OM_uint32 (*gss_add_cred) ( - void*, /* context */ OM_uint32 *, /* minor_status */ gss_cred_id_t, /* input_cred_handle */ gss_name_t, /* desired_name */ @@ -292,21 +284,18 @@ typedef struct gss_config { ); OM_uint32 (*gss_export_sec_context) ( - void*, /* context */ OM_uint32 *, /* minor_status */ gss_ctx_id_t *, /* context_handle */ gss_buffer_t /* interprocess_token */ ); OM_uint32 (*gss_import_sec_context) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_buffer_t, /* interprocess_token */ gss_ctx_id_t * /* context_handle */ ); OM_uint32 (*gss_inquire_cred_by_mech) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_OID, /* mech_type */ @@ -317,14 +306,12 @@ typedef struct gss_config { ); OM_uint32 (*gss_inquire_names_for_mech) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_OID, /* mechanism */ gss_OID_set * /* name_types */ ); OM_uint32 (*gss_inquire_context) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_name_t *, /* src_name */ @@ -332,18 +319,16 @@ typedef struct gss_config { OM_uint32 *, /* lifetime_rec */ gss_OID *, /* mech_type */ OM_uint32 *, /* ctx_flags */ - int *, /* locally_initiated */ + int *, /* locally_initiated */ int * /* open */ ); OM_uint32 (*gss_internal_release_oid) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_OID * /* OID */ ); OM_uint32 (*gss_wrap_size_limit) ( - void *, /* context */ OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ @@ -351,16 +336,30 @@ typedef struct gss_config { OM_uint32, /* req_output_size */ OM_uint32 * /* max_input_size */ ); +#if 0 + int (*pname_to_uid) + ( + char *, /* pname */ + gss_OID, /* name type */ + gss_OID, /* mech type */ + uid_t * /* uid */ + ); + OM_uint32 (*gssint_userok) + ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* pname */ + const char *, /* local user */ + int * /* user ok? */ + /* */); +#endif OM_uint32 (*gss_export_name) ( - void *, /* context */ OM_uint32 *, /* minor_status */ const gss_name_t, /* input_name */ gss_buffer_t /* exported_name */ /* */); OM_uint32 (*gss_store_cred) ( - void *, /* context */ OM_uint32 *, /* minor_status */ const gss_cred_id_t, /* input_cred */ gss_cred_usage_t, /* cred_usage */ @@ -370,8 +369,132 @@ typedef struct gss_config { gss_OID_set *, /* elements_stored */ gss_cred_usage_t * /* cred_usage_stored */ /* */); + + OM_uint32 (*gss_import_name_object) + ( + OM_uint32 *, /* minor_status */ + void *, /* input_name */ + gss_OID, /* input_name_type */ + gss_name_t * /* output_name */ + /* */); + + OM_uint32 (*gss_export_name_object) + ( + OM_uint32 *, /* minor_status */ + gss_name_t, /* input_name */ + gss_OID, /* desired_name_type */ + void ** /* output_name */ + /* */); + + /* GGF extensions */ + + OM_uint32 (*gss_inquire_sec_context_by_oid) + ( + OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_OID, /* OID */ + gss_buffer_set_t * /* data_set */ + ); + OM_uint32 (*gss_inquire_cred_by_oid) + ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + const gss_OID, /* OID */ + gss_buffer_set_t * /* data_set */ + ); + OM_uint32 (*gss_set_sec_context_option) + ( + OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + const gss_OID, /* OID */ + const gss_buffer_t /* value */ + ); + OM_uint32 (*gssspi_set_cred_option) + ( + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + const gss_OID, /* OID */ + const gss_buffer_t /* value */ + ); + OM_uint32 (*gssspi_mech_invoke) + ( + OM_uint32*, /* minor_status */ + const gss_OID, /* mech OID */ + const gss_OID, /* OID */ + gss_buffer_t /* value */ + ); + + /* AEAD extensions */ + OM_uint32 (*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 (*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 */ + OM_uint32 (*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 */ + /* */); + + OM_uint32 (*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 */ + /* */); + + OM_uint32 (*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 */ + /* */); + + OM_uint32 (*gss_complete_auth_token) + ( + OM_uint32*, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* input_message_buffer */ + ); + } *gss_mechanism; +/* This structure MUST NOT be used by any code outside libgss */ +typedef struct gss_config_ext { + gss_acquire_cred_with_password_sfct gss_acquire_cred_with_password; +} *gss_mechanism_ext; + /* * In the user space we use a wrapper structure to encompass the * mechanism entry points. The wrapper contain the mechanism @@ -387,21 +510,22 @@ typedef struct gss_mech_config { void *dl_handle; /* RTLD object handle for the mech */ gss_OID mech_type; /* mechanism oid */ gss_mechanism mech; /* mechanism initialization struct */ + gss_mechanism_ext mech_ext; /* extensions */ + int priority; /* mechanism preference order */ + int freeMech; /* free mech table */ struct gss_mech_config *next; /* next element in the list */ } *gss_mech_info; -/* Mechanisms defined within our library */ - -extern gss_mechanism *krb5_gss_get_mech_configs(void); -extern gss_mechanism *spnego_gss_get_mech_configs(void); - /********************************************************/ /* Internal mechglue routines */ +#if 0 int gssint_mechglue_init(void); void gssint_mechglue_fini(void); +#endif gss_mechanism gssint_get_mechanism (gss_OID); +gss_mechanism_ext gssint_get_mechanism_ext(const gss_OID); OM_uint32 gssint_get_mech_type (gss_OID, gss_buffer_t); char *gssint_get_kmodName(const gss_OID); char *gssint_get_modOptions(const gss_OID); @@ -412,6 +536,11 @@ OM_uint32 gssint_export_internal_name(OM_uint32 *, const gss_OID, OM_uint32 gssint_display_internal_name (OM_uint32 *, gss_OID, gss_name_t, gss_buffer_t, gss_OID *); OM_uint32 gssint_release_internal_name (OM_uint32 *, gss_OID, gss_name_t *); +OM_uint32 gssint_delete_internal_sec_context (OM_uint32 *, gss_OID, + gss_ctx_id_t *, gss_buffer_t); +#ifdef _GSS_STATIC_LINK +int gssint_register_mechinfo(gss_mech_info template); +#endif OM_uint32 gssint_convert_name_to_union_name (OM_uint32 *, /* minor_status */ @@ -466,6 +595,14 @@ gssint_get_mechanisms( ); OM_uint32 +gssint_userok( + OM_uint32 *, /* minor */ + const gss_name_t, /* name */ + const char *, /* user */ + int * /* user_ok */ +); + +OM_uint32 gss_store_cred( OM_uint32 *, /* minor_status */ const gss_cred_id_t, /* input_cred_handle */ @@ -494,6 +631,27 @@ gssint_put_der_length( unsigned int /* max_len */ ); +OM_uint32 +gssint_wrap_aead (gss_mechanism, /* mech */ + OM_uint32 *, /* minor_status */ + gss_union_ctx_id_t, /* ctx */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req_flag */ + gss_buffer_t, /* input_assoc_buffer */ + gss_buffer_t, /* input_payload_buffer */ + int *, /* conf_state */ + gss_buffer_t); /* output_message_buffer */ +OM_uint32 +gssint_unwrap_aead (gss_mechanism, /* mech */ + OM_uint32 *, /* minor_status */ + gss_union_ctx_id_t, /* ctx */ + 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 */ + + /* Use this to map an error code that was returned from a mech operation; the mech will be asked to produce the associated error messages. diff --git a/src/lib/gssapi/spnego/Makefile.in b/src/lib/gssapi/spnego/Makefile.in index fae08ab366..7d71f8b278 100644 --- a/src/lib/gssapi/spnego/Makefile.in +++ b/src/lib/gssapi/spnego/Makefile.in @@ -3,6 +3,7 @@ myfulldir=lib/gssapi/spnego mydir=lib/gssapi/spnego BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/.. -I../generic -I$(srcdir)/../generic -I../mechglue -I$(srcdir)/../mechglue +DEFS=-D_GSS_STATIC_LINK=1 ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=spnego @@ -30,14 +31,15 @@ clean-unix:: clean-libobjs # spnego_mech.so spnego_mech.po $(OUTPRE)spnego_mech.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \ - $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ - $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ - $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ - $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ - $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ - $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ - $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \ + $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../generic/gssapiP_generic.h \ + $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \ $(srcdir)/../mechglue/mechglue.h $(srcdir)/../mechglue/mglueP.h \ ../generic/gssapi_err_generic.h gssapiP_spnego.h spnego_mech.c diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h index 53464dc877..e1f3987cd2 100644 --- a/src/lib/gssapi/spnego/gssapiP_spnego.h +++ b/src/lib/gssapi/spnego/gssapiP_spnego.h @@ -39,6 +39,7 @@ extern "C" { #define ENUMERATED 0x0a #define ENUMERATION_LENGTH 1 #define HEADER_ID 0x60 +#define GENERAL_STRING 0x1b /* * SPNEGO specific error codes (minor status codes) @@ -123,7 +124,6 @@ extern const gss_OID_set_desc * const gss_mech_set_spnego; OM_uint32 spnego_gss_acquire_cred ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ gss_name_t, /* desired_name */ OM_uint32, /* time_req */ @@ -136,7 +136,6 @@ OM_uint32 spnego_gss_acquire_cred OM_uint32 spnego_gss_release_cred ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ /* CSTYLED */ gss_cred_id_t * /* cred_handle */ @@ -144,7 +143,6 @@ OM_uint32 spnego_gss_release_cred OM_uint32 spnego_gss_init_sec_context ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ gss_cred_id_t, /* claimant_cred_handle */ gss_ctx_id_t *, /* context_handle */ @@ -163,7 +161,6 @@ OM_uint32 spnego_gss_init_sec_context #ifndef LEAN_CLIENT OM_uint32 spnego_gss_accept_sec_context ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ gss_ctx_id_t *, /* context_handle */ gss_cred_id_t, /* verifier_cred_handle */ @@ -179,9 +176,16 @@ OM_uint32 spnego_gss_accept_sec_context ); #endif /* LEAN_CLIENT */ +OM_uint32 spnego_gss_compare_name +( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* name1 */ + const gss_name_t, /* name2 */ + int * /* name_equal */ +); + OM_uint32 spnego_gss_display_name ( - void *, OM_uint32 *, /* minor_status */ gss_name_t, /* input_name */ gss_buffer_t, /* output_name_buffer */ @@ -190,7 +194,6 @@ OM_uint32 spnego_gss_display_name OM_uint32 spnego_gss_display_status ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ OM_uint32, /* status_value */ int, /* status_type */ @@ -201,7 +204,6 @@ OM_uint32 spnego_gss_display_status OM_uint32 spnego_gss_import_name ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ gss_buffer_t, /* input_name_buffer */ gss_OID, /* input_name_type */ @@ -211,7 +213,6 @@ OM_uint32 spnego_gss_import_name OM_uint32 spnego_gss_release_name ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ /* CSTYLED */ gss_name_t * /* input_name */ @@ -219,30 +220,27 @@ OM_uint32 spnego_gss_release_name OM_uint32 spnego_gss_inquire_names_for_mech ( - void *, /* spnego context */ OM_uint32 *, /* minor_status */ gss_OID, /* mechanism */ gss_OID_set * /* name_types */ ); -OM_uint32 spnego_gss_unseal +OM_uint32 spnego_gss_unwrap ( - void *context, 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 + gss_qop_t *qop_state ); -OM_uint32 spnego_gss_seal +OM_uint32 spnego_gss_wrap ( - void *context, OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, - int qop_req, + gss_qop_t qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer @@ -250,7 +248,6 @@ OM_uint32 spnego_gss_seal OM_uint32 spnego_gss_process_context_token ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t token_buffer @@ -258,7 +255,6 @@ OM_uint32 spnego_gss_process_context_token OM_uint32 spnego_gss_delete_sec_context ( - void *context, OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t output_token @@ -266,7 +262,6 @@ OM_uint32 spnego_gss_delete_sec_context OM_uint32 spnego_gss_context_time ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, OM_uint32 *time_rec @@ -274,7 +269,6 @@ OM_uint32 spnego_gss_context_time #ifndef LEAN_CLIENT OM_uint32 spnego_gss_export_sec_context ( - void *context, OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token @@ -282,7 +276,6 @@ OM_uint32 spnego_gss_export_sec_context OM_uint32 spnego_gss_import_sec_context ( - void *context, OM_uint32 *minor_status, const gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle @@ -291,7 +284,6 @@ OM_uint32 spnego_gss_import_sec_context OM_uint32 spnego_gss_inquire_context ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, gss_name_t *src_name, @@ -305,7 +297,6 @@ OM_uint32 spnego_gss_inquire_context OM_uint32 spnego_gss_wrap_size_limit ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, @@ -314,24 +305,110 @@ OM_uint32 spnego_gss_wrap_size_limit OM_uint32 *max_input_size ); -OM_uint32 spnego_gss_sign +OM_uint32 spnego_gss_get_mic ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, - int qop_req, + gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token ); -OM_uint32 spnego_gss_verify +OM_uint32 spnego_gss_verify_mic ( - void *context, OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t msg_buffer, const gss_buffer_t token_buffer, - int *qop_state + gss_qop_t *qop_state +); + +OM_uint32 +spnego_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 +spnego_gss_set_sec_context_option +( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value +); + +#ifdef _GSS_STATIC_LINK +int gss_spnegoint_lib_init(void); +void gss_spnegoint_lib_fini(void); +#else +gss_mechanism KRB5_CALLCONV gss_mech_initialize(void); +#endif /* _GSS_STATIC_LINK */ + +OM_uint32 spnego_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 spnego_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 +); + +OM_uint32 spnego_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 +); + +OM_uint32 spnego_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 +); + +OM_uint32 spnego_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 +); + +OM_uint32 +spnego_gss_complete_auth_token +( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer ); #ifdef __cplusplus diff --git a/src/lib/gssapi/spnego/mech_spnego.exports b/src/lib/gssapi/spnego/mech_spnego.exports new file mode 100644 index 0000000000..9d570e5c05 --- /dev/null +++ b/src/lib/gssapi/spnego/mech_spnego.exports @@ -0,0 +1 @@ +gss_mech_initialize diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index f3cb5919b4..44aea26436 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -32,9 +32,37 @@ * peers using the GSS-API. * */ - +/* + * Copyright (c) 2006-2008, Novell, Inc. + * 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. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 OWNER 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. + */ /* #pragma ident "@(#)spnego_mech.c 1.7 04/09/28 SMI" */ +#include <sys/param.h> +#include <unistd.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> @@ -135,7 +163,9 @@ static int g_get_tag_and_length(unsigned char **, int, unsigned int, unsigned int *); static int -make_spnego_tokenInit_msg(spnego_gss_ctx_id_t, gss_buffer_t, +make_spnego_tokenInit_msg(spnego_gss_ctx_id_t, + int, + gss_buffer_t, OM_uint32, gss_buffer_t, send_token_flag, gss_buffer_t); static int @@ -165,6 +195,12 @@ static const gss_OID_set_desc spnego_oidsets[] = { }; const gss_OID_set_desc * const gss_mech_set_spnego = spnego_oidsets+0; +static int make_NegHints(OM_uint32 *, gss_cred_id_t, gss_buffer_t *); +static int put_neg_hints(unsigned char **, gss_buffer_t, unsigned int); +static OM_uint32 +acc_ctx_hints(OM_uint32 *, gss_ctx_id_t *, gss_cred_id_t, + gss_buffer_t *, OM_uint32 *, send_token_flag *); + /* * The Mech OID for SPNEGO: * { iso(1) org(3) dod(6) internet(1) security(5) @@ -172,7 +208,6 @@ const gss_OID_set_desc * const gss_mech_set_spnego = spnego_oidsets+0; */ static struct gss_config spnego_mechanism = { - 400, "spnego", {SPNEGO_OID_LENGTH, SPNEGO_OID}, NULL, spnego_gss_acquire_cred, @@ -186,13 +221,13 @@ static struct gss_config spnego_mechanism = NULL, /* gss_process_context_token */ spnego_gss_delete_sec_context, /* gss_delete_sec_context */ spnego_gss_context_time, /* gss_context_time */ - spnego_gss_sign, /* gss_sign */ - spnego_gss_verify, /* gss_verify */ - spnego_gss_seal, /* gss_seal */ - spnego_gss_unseal, /* gss_unseal */ + spnego_gss_get_mic, /* gss_get_mic */ + spnego_gss_verify_mic, /* gss_verify_mic */ + spnego_gss_wrap, /* gss_wrap */ + spnego_gss_unwrap, /* gss_unwrap */ spnego_gss_display_status, NULL, /* gss_indicate_mechs */ - NULL, /* gss_compare_name */ + spnego_gss_compare_name, spnego_gss_display_name, spnego_gss_import_name, spnego_gss_release_name, @@ -212,24 +247,63 @@ static struct gss_config spnego_mechanism = spnego_gss_wrap_size_limit, /* gss_wrap_size_limit */ NULL, /* gss_export_name */ NULL, /* gss_store_cred */ + NULL, /* gss_import_name_object */ + NULL, /* gss_export_name_object */ + spnego_gss_inquire_sec_context_by_oid, /* gss_inquire_sec_context_by_oid */ + NULL, /* gss_inquire_cred_by_oid */ + spnego_gss_set_sec_context_option, /* gss_set_sec_context_option */ + NULL, /* gssspi_set_cred_option */ + NULL, /* gssspi_mech_invoke */ + spnego_gss_wrap_aead, + spnego_gss_unwrap_aead, + spnego_gss_wrap_iov, + spnego_gss_unwrap_iov, + spnego_gss_wrap_iov_length, + spnego_gss_complete_auth_token }; -static gss_mechanism spnego_mech_configs[] = { - &spnego_mechanism, NULL -}; +#ifdef _GSS_STATIC_LINK +#include "mglueP.h" + +static int gss_spnegomechglue_init(void) +{ + struct gss_mech_config mech_spnego; -#define gssint_get_mech_configs spnego_gss_get_mech_configs + memset(&mech_spnego, 0, sizeof(mech_spnego)); + mech_spnego.mech = &spnego_mechanism; + mech_spnego.mechNameStr = "spnego"; + mech_spnego.mech_type = GSS_C_NO_OID; -gss_mechanism * -gssint_get_mech_configs(void) + return gssint_register_mechinfo(&mech_spnego); +} +#else +gss_mechanism KRB5_CALLCONV +gss_mech_initialize(void) +{ + return (&spnego_mechanism); +} + +MAKE_INIT_FUNCTION(gss_krb5int_lib_init); +MAKE_FINI_FUNCTION(gss_krb5int_lib_fini); +int gss_krb5int_lib_init(void) +#endif /* _GSS_STATIC_LINK */ + +int gss_spnegoint_lib_init(void) +{ +#ifdef _GSS_STATIC_LINK + return gss_spnegomechglue_init(); +#else + return 0; +#endif +} + +void gss_spnegoint_lib_fini(void) { - return spnego_mech_configs; } /*ARGSUSED*/ OM_uint32 -spnego_gss_acquire_cred(void *ctx, - OM_uint32 *minor_status, +spnego_gss_acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name, OM_uint32 time_req, gss_OID_set desired_mechs, @@ -282,8 +356,7 @@ spnego_gss_acquire_cred(void *ctx, /*ARGSUSED*/ OM_uint32 -spnego_gss_release_cred(void *ctx, - OM_uint32 *minor_status, +spnego_gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) { OM_uint32 status; @@ -570,10 +643,15 @@ init_ctx_cont(OM_uint32 *minor_status, gss_ctx_id_t *ctx, gss_buffer_t buf, * mech not finished and mech token missing */ ret = GSS_S_DEFECTIVE_TOKEN; - } else { + } else if (sc->mic_reqd && + (sc->ctx_flags & GSS_C_INTEG_FLAG)) { *negState = ACCEPT_INCOMPLETE; *tokflag = CONT_TOKEN_SEND; ret = GSS_S_CONTINUE_NEEDED; + } else { + *negState = ACCEPT_COMPLETE; + *tokflag = NO_TOKEN_SEND; + ret = GSS_S_COMPLETE; } cleanup: if (supportedMech != GSS_C_NO_OID) @@ -745,6 +823,7 @@ init_ctx_call_init(OM_uint32 *minor_status, * generated/handled. */ if (*send_token == CONT_TOKEN_SEND && + mechtok_out->length == 0 && (!sc->mic_reqd || !(sc->ctx_flags & GSS_C_INTEG_FLAG))) { @@ -771,7 +850,7 @@ init_ctx_call_init(OM_uint32 *minor_status, /*ARGSUSED*/ OM_uint32 -spnego_gss_init_sec_context(void *ct, +spnego_gss_init_sec_context( OM_uint32 *minor_status, gss_cred_id_t claimant_cred_handle, gss_ctx_id_t *context_handle, @@ -858,11 +937,11 @@ spnego_gss_init_sec_context(void *ct, cleanup: if (send_token == INIT_TOKEN_SEND) { if (make_spnego_tokenInit_msg(spnego_ctx, + 0, mechListMIC_out, req_flags, &mechtok_out, send_token, output_token) < 0) { - ret = GSS_S_FAILURE; } } else if (send_token != NO_TOKEN_SEND) { @@ -882,6 +961,8 @@ cleanup: *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle; if (actual_mech != NULL) *actual_mech = spnego_ctx->actual_mech; + if (ret_flags != NULL) + *ret_flags = spnego_ctx->ctx_flags; release_spnego_ctx(&spnego_ctx); } else if (ret != GSS_S_CONTINUE_NEEDED) { if (spnego_ctx != NULL) { @@ -910,6 +991,265 @@ cleanup: return ret; } /* init_sec_context */ +/* We don't want to import KRB5 headers here */ +static const gss_OID_desc gss_mech_krb5_oid = + { 9, "\052\206\110\206\367\022\001\002\002" }; +static const gss_OID_desc gss_mech_krb5_wrong_oid = + { 9, "\052\206\110\202\367\022\001\002\002" }; + +/* + * verify that the input token length is not 0. If it is, just return. + * If the token length is greater than 0, der encode as a sequence + * and place in buf_out, advancing buf_out. + */ + +static int +put_neg_hints(unsigned char **buf_out, gss_buffer_t input_token, + unsigned int buflen) +{ + int ret; + + /* if token length is 0, we do not want to send */ + if (input_token->length == 0) + return (0); + + if (input_token->length > buflen) + return (-1); + + *(*buf_out)++ = SEQUENCE; + if ((ret = gssint_put_der_length(input_token->length, buf_out, + input_token->length))) + return (ret); + TWRITE_STR(*buf_out, input_token->value, input_token->length); + return (0); +} + +/* + * NegHints ::= SEQUENCE { + * hintName [0] GeneralString OPTIONAL, + * hintAddress [1] OCTET STRING OPTIONAL + * } + */ + +#define HOST_PREFIX "host@" +#define HOST_PREFIX_LEN (sizeof(HOST_PREFIX) - 1) + +static int +make_NegHints(OM_uint32 *minor_status, + gss_cred_id_t cred, gss_buffer_t *outbuf) +{ + gss_buffer_desc hintNameBuf; + gss_name_t hintName = GSS_C_NO_NAME; + gss_name_t hintKerberosName; + gss_OID hintNameType; + OM_uint32 major_status; + OM_uint32 minor; + unsigned int tlen = 0; + unsigned int hintNameSize = 0; + unsigned int negHintsSize = 0; + unsigned char *ptr; + unsigned char *t; + + *outbuf = GSS_C_NO_BUFFER; + + if (cred != GSS_C_NO_CREDENTIAL) { + major_status = gss_inquire_cred(minor_status, + cred, + &hintName, + NULL, + NULL, + NULL); + if (major_status != GSS_S_COMPLETE) + return (major_status); + } + + if (hintName == GSS_C_NO_NAME) { + krb5_error_code code; + krb5int_access kaccess; + char hostname[HOST_PREFIX_LEN + MAXHOSTNAMELEN + 1] = HOST_PREFIX; + + code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION); + if (code != 0) { + *minor_status = code; + return (GSS_S_FAILURE); + } + + /* this breaks mutual authentication but Samba relies on it */ + code = (*kaccess.clean_hostname)(NULL, NULL, + &hostname[HOST_PREFIX_LEN], + MAXHOSTNAMELEN); + if (code != 0) { + *minor_status = code; + return (GSS_S_FAILURE); + } + + hintNameBuf.value = hostname; + hintNameBuf.length = strlen(hostname); + + major_status = gss_import_name(minor_status, + &hintNameBuf, + GSS_C_NT_HOSTBASED_SERVICE, + &hintName); + if (major_status != GSS_S_COMPLETE) { + return (major_status); + } + } + + hintNameBuf.value = NULL; + hintNameBuf.length = 0; + + major_status = gss_canonicalize_name(minor_status, + hintName, + (gss_OID)&gss_mech_krb5_oid, + &hintKerberosName); + if (major_status != GSS_S_COMPLETE) { + gss_release_name(&minor, &hintName); + return (major_status); + } + gss_release_name(&minor, &hintName); + + major_status = gss_display_name(minor_status, + hintKerberosName, + &hintNameBuf, + &hintNameType); + if (major_status != GSS_S_COMPLETE) { + gss_release_name(&minor, &hintName); + return (major_status); + } + gss_release_name(&minor, &hintKerberosName); + + /* + * Now encode the name hint into a NegHints ASN.1 type + */ + major_status = GSS_S_FAILURE; + + /* Length of DER encoded GeneralString */ + tlen = 1 + gssint_der_length_size(hintNameBuf.length) + + hintNameBuf.length; + hintNameSize = tlen; + + /* Length of DER encoded hintName */ + tlen += 1 + gssint_der_length_size(hintNameSize); + negHintsSize = tlen; + + t = (unsigned char *)malloc(tlen); + if (t == NULL) { + *minor_status = ENOMEM; + goto errout; + } + + ptr = t; + + *ptr++ = CONTEXT | 0x00; /* hintName identifier */ + if (gssint_put_der_length(hintNameSize, + &ptr, tlen - (int)(ptr-t))) + goto errout; + + *ptr++ = GENERAL_STRING; + if (gssint_put_der_length(hintNameBuf.length, + &ptr, tlen - (int)(ptr-t))) + goto errout; + + memcpy(ptr, hintNameBuf.value, hintNameBuf.length); + ptr += hintNameBuf.length; + + *outbuf = (gss_buffer_t)malloc(sizeof(gss_buffer_desc)); + if (*outbuf == NULL) { + *minor_status = ENOMEM; + goto errout; + } + (*outbuf)->value = (void *)t; + (*outbuf)->length = ptr - t; + + t = NULL; /* don't free */ + + *minor_status = 0; + major_status = GSS_S_COMPLETE; + +errout: + if (t != NULL) { + free(t); + } + + gss_release_buffer(&minor, &hintNameBuf); + + return (major_status); +} + +static OM_uint32 +acc_ctx_hints(OM_uint32 *minor_status, + gss_ctx_id_t *ctx, + gss_cred_id_t cred, + gss_buffer_t *mechListMIC, + OM_uint32 *negState, + send_token_flag *return_token) +{ + OM_uint32 tmpmin, ret; + gss_OID_set supported_mechSet; + spnego_gss_ctx_id_t sc = NULL; + + *mechListMIC = GSS_C_NO_BUFFER; + supported_mechSet = GSS_C_NO_OID_SET; + *return_token = ERROR_TOKEN_SEND; + *negState = REJECT; + *minor_status = 0; + + *ctx = GSS_C_NO_CONTEXT; + ret = GSS_S_DEFECTIVE_TOKEN; + + if (cred != GSS_C_NO_CREDENTIAL) { + ret = gss_inquire_cred(minor_status, cred, NULL, NULL, + NULL, &supported_mechSet); + if (ret != GSS_S_COMPLETE) { + *return_token = NO_TOKEN_SEND; + goto cleanup; + } + } else { + ret = get_available_mechs(minor_status, GSS_C_NO_NAME, + GSS_C_ACCEPT, NULL, + &supported_mechSet); + if (ret != GSS_S_COMPLETE) { + *return_token = NO_TOKEN_SEND; + goto cleanup; + } + } + + ret = make_NegHints(minor_status, cred, mechListMIC); + if (ret != GSS_S_COMPLETE) { + *return_token = NO_TOKEN_SEND; + goto cleanup; + } + + /* + * Select the best match between the list of mechs + * that the initiator requested and the list that + * the acceptor will support. + */ + sc = create_spnego_ctx(); + if (sc == NULL) { + ret = GSS_S_FAILURE; + *return_token = NO_TOKEN_SEND; + goto cleanup; + } + if (put_mech_set(supported_mechSet, &sc->DER_mechTypes) < 0) { + ret = GSS_S_FAILURE; + *return_token = NO_TOKEN_SEND; + goto cleanup; + } + sc->internal_mech = GSS_C_NO_OID; + + *negState = ACCEPT_INCOMPLETE; + *return_token = INIT_TOKEN_SEND; + sc->firstpass = 1; + *ctx = (gss_ctx_id_t)sc; + ret = GSS_S_COMPLETE; + +cleanup: + gss_release_oid_set(&tmpmin, &supported_mechSet); + + return ret; +} + /* * Set negState to REJECT if the token is defective, else * ACCEPT_INCOMPLETE or REQUEST_MIC, depending on whether initiator's @@ -932,6 +1272,7 @@ acc_ctx_new(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc = NULL; *ctx = GSS_C_NO_CONTEXT; + ret = GSS_S_DEFECTIVE_TOKEN; der_mechTypes.length = 0; der_mechTypes.value = NULL; @@ -976,7 +1317,12 @@ acc_ctx_new(OM_uint32 *minor_status, ret = GSS_S_BAD_MECH; goto cleanup; } - sc = create_spnego_ctx(); + sc = (spnego_gss_ctx_id_t)*ctx; + if (sc != NULL) { + gss_release_buffer(&tmpmin, &sc->DER_mechTypes); + assert(mech_wanted != GSS_C_NO_OID); + } else + sc = create_spnego_ctx(); if (sc == NULL) { ret = GSS_S_FAILURE; *return_token = NO_TOKEN_SEND; @@ -1101,7 +1447,7 @@ acc_ctx_vfy_oid(OM_uint32 *minor_status, *tokflag = ERROR_TOKEN_SEND; return GSS_S_BAD_MECH; } - ret = mech->gss_indicate_mechs(NULL, minor_status, &mech_set); + ret = mech->gss_indicate_mechs(minor_status, &mech_set); if (ret != GSS_S_COMPLETE) { *tokflag = NO_TOKEN_SEND; map_error(minor_status, mech); @@ -1138,18 +1484,20 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, OM_uint32 ret; gss_OID_desc mechoid; - /* - * mechoid is an alias; don't free it. - */ - ret = gssint_get_mech_type(&mechoid, mechtok_in); - if (ret != GSS_S_COMPLETE) { - *tokflag = NO_TOKEN_SEND; - return ret; + if (sc->ctx_handle == GSS_C_NO_CONTEXT) { + /* + * mechoid is an alias; don't free it. + */ + ret = gssint_get_mech_type(&mechoid, mechtok_in); + if (ret != GSS_S_COMPLETE) { + *tokflag = NO_TOKEN_SEND; + return ret; + } + ret = acc_ctx_vfy_oid(minor_status, sc, &mechoid, + negState, tokflag); + if (ret != GSS_S_COMPLETE) + return ret; } - ret = acc_ctx_vfy_oid(minor_status, sc, &mechoid, - negState, tokflag); - if (ret != GSS_S_COMPLETE) - return ret; ret = gss_accept_sec_context(minor_status, &sc->ctx_handle, @@ -1196,7 +1544,7 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, /*ARGSUSED*/ OM_uint32 -spnego_gss_accept_sec_context(void *ct, +spnego_gss_accept_sec_context( OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_cred_id_t verifier_cred_handle, @@ -1209,12 +1557,13 @@ spnego_gss_accept_sec_context(void *ct, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle) { - OM_uint32 ret, tmpret, tmpmin, negState; + OM_uint32 ret, tmpmin, negState; send_token_flag return_token; gss_buffer_t mechtok_in, mic_in, mic_out; gss_buffer_desc mechtok_out = GSS_C_EMPTY_BUFFER; spnego_gss_ctx_id_t sc = NULL; OM_uint32 mechstat = GSS_S_FAILURE; + int sendTokenInit = 0; mechtok_in = mic_in = mic_out = GSS_C_NO_BUFFER; @@ -1233,7 +1582,8 @@ spnego_gss_accept_sec_context(void *ct, if (input_token == GSS_C_NO_BUFFER) return GSS_S_CALL_INACCESSIBLE_READ; - if (*context_handle == GSS_C_NO_CONTEXT) { + sc = (spnego_gss_ctx_id_t)*context_handle; + if (sc == NULL || sc->internal_mech == GSS_C_NO_OID) { if (src_name != NULL) *src_name = GSS_C_NO_NAME; if (mech_type != NULL) @@ -1244,14 +1594,27 @@ spnego_gss_accept_sec_context(void *ct, *ret_flags = 0; if (delegated_cred_handle != NULL) *delegated_cred_handle = GSS_C_NO_CREDENTIAL; - /* Can set negState to REQUEST_MIC */ - ret = acc_ctx_new(minor_status, input_token, - context_handle, verifier_cred_handle, - &mechtok_in, &mic_in, - &negState, &return_token); - if (ret != GSS_S_COMPLETE) - goto cleanup; - ret = GSS_S_CONTINUE_NEEDED; + if (input_token->length == 0) { + sendTokenInit = 1; + ret = acc_ctx_hints(minor_status, + context_handle, + verifier_cred_handle, + &mic_out, + &negState, + &return_token); + if (ret != GSS_S_COMPLETE) + goto cleanup; + ret = GSS_S_CONTINUE_NEEDED; + } else { + /* Can set negState to REQUEST_MIC */ + ret = acc_ctx_new(minor_status, input_token, + context_handle, verifier_cred_handle, + &mechtok_in, &mic_in, + &negState, &return_token); + if (ret != GSS_S_COMPLETE) + goto cleanup; + ret = GSS_S_CONTINUE_NEEDED; + } } else { /* Can set negState to ACCEPT_INCOMPLETE */ ret = acc_ctx_cont(minor_status, input_token, @@ -1290,13 +1653,27 @@ spnego_gss_accept_sec_context(void *ct, } cleanup: if (return_token != NO_TOKEN_SEND && return_token != CHECK_MIC) { - tmpret = make_spnego_tokenTarg_msg(negState, sc->internal_mech, - &mechtok_out, mic_out, - return_token, - output_token); - if (tmpret != GSS_S_COMPLETE) { - ret = tmpret; + /* For acceptor-sends-first send a tokenInit */ + int tmpret; + + assert(sc != NULL); + + if (sendTokenInit) { + tmpret = make_spnego_tokenInit_msg(sc, + 1, + mic_out, + 0, + GSS_C_NO_BUFFER, + return_token, + output_token); + } else { + tmpret = make_spnego_tokenTarg_msg(negState, sc->internal_mech, + &mechtok_out, mic_out, + return_token, + output_token); } + if (tmpret < 0) + ret = GSS_S_FAILURE; } if (ret == GSS_S_COMPLETE) { *context_handle = (gss_ctx_id_t)sc->ctx_handle; @@ -1326,7 +1703,7 @@ cleanup: /*ARGSUSED*/ OM_uint32 -spnego_gss_display_status(void *ctx, +spnego_gss_display_status( OM_uint32 *minor_status, OM_uint32 status_value, int status_type, @@ -1371,7 +1748,7 @@ spnego_gss_display_status(void *ctx, /*ARGSUSED*/ OM_uint32 -spnego_gss_import_name(void *ctx, +spnego_gss_import_name( OM_uint32 *minor_status, gss_buffer_t input_name_buffer, gss_OID input_name_type, @@ -1390,7 +1767,7 @@ spnego_gss_import_name(void *ctx, /*ARGSUSED*/ OM_uint32 -spnego_gss_release_name(void *ctx, +spnego_gss_release_name( OM_uint32 *minor_status, gss_name_t *input_name) { @@ -1406,7 +1783,25 @@ spnego_gss_release_name(void *ctx, /*ARGSUSED*/ OM_uint32 -spnego_gss_display_name(void *ctx, +spnego_gss_compare_name( + OM_uint32 *minor_status, + const gss_name_t name1, + const gss_name_t name2, + int *name_equal) +{ + OM_uint32 status = GSS_S_COMPLETE; + dsyslog("Entering compare_name\n"); + + status = gss_compare_name(minor_status, name1, name2, name_equal); + + dsyslog("Leaving compare_name\n"); + return (status); +} + +/*ARGSUSED*/ +/*ARGSUSED*/ +OM_uint32 +spnego_gss_display_name( OM_uint32 *minor_status, gss_name_t input_name, gss_buffer_t output_name_buffer, @@ -1425,7 +1820,7 @@ spnego_gss_display_name(void *ctx, /*ARGSUSED*/ OM_uint32 -spnego_gss_inquire_names_for_mech(void *ctx, +spnego_gss_inquire_names_for_mech( OM_uint32 *minor_status, gss_OID mechanism, gss_OID_set *name_types) @@ -1468,16 +1863,16 @@ spnego_gss_inquire_names_for_mech(void *ctx, } OM_uint32 -spnego_gss_unseal(void *context, +spnego_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, - int *qop_state) + gss_qop_t *qop_state) { OM_uint32 ret; - ret = gss_unseal(minor_status, + ret = gss_unwrap(minor_status, context_handle, input_message_buffer, output_message_buffer, @@ -1488,17 +1883,17 @@ spnego_gss_unseal(void *context, } OM_uint32 -spnego_gss_seal(void *context, +spnego_gss_wrap( OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, - int qop_req, + gss_qop_t qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer) { OM_uint32 ret; - ret = gss_seal(minor_status, + ret = gss_wrap(minor_status, context_handle, conf_req_flag, qop_req, @@ -1510,7 +1905,7 @@ spnego_gss_seal(void *context, } OM_uint32 -spnego_gss_process_context_token(void *context, +spnego_gss_process_context_token( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t token_buffer) @@ -1524,7 +1919,7 @@ spnego_gss_process_context_token(void *context, } OM_uint32 -spnego_gss_delete_sec_context(void *context, +spnego_gss_delete_sec_context( OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t output_token) @@ -1552,7 +1947,7 @@ spnego_gss_delete_sec_context(void *context, } OM_uint32 -spnego_gss_context_time(void *context, +spnego_gss_context_time( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, OM_uint32 *time_rec) @@ -1565,7 +1960,7 @@ spnego_gss_context_time(void *context, } #ifndef LEAN_CLIENT OM_uint32 -spnego_gss_export_sec_context(void *context, +spnego_gss_export_sec_context( OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token) @@ -1578,7 +1973,7 @@ spnego_gss_export_sec_context(void *context, } OM_uint32 -spnego_gss_import_sec_context(void *context, +spnego_gss_import_sec_context( OM_uint32 *minor_status, const gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle) @@ -1592,7 +1987,7 @@ spnego_gss_import_sec_context(void *context, #endif /* LEAN_CLIENT */ OM_uint32 -spnego_gss_inquire_context(void *context, +spnego_gss_inquire_context( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, gss_name_t *src_name, @@ -1619,7 +2014,7 @@ spnego_gss_inquire_context(void *context, } OM_uint32 -spnego_gss_wrap_size_limit(void *context, +spnego_gss_wrap_size_limit( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, @@ -1638,15 +2033,15 @@ spnego_gss_wrap_size_limit(void *context, } OM_uint32 -spnego_gss_sign(void *context, +spnego_gss_get_mic( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, - int qop_req, + gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token) { OM_uint32 ret; - ret = gss_sign(minor_status, + ret = gss_get_mic(minor_status, context_handle, qop_req, message_buffer, @@ -1655,19 +2050,164 @@ spnego_gss_sign(void *context, } OM_uint32 -spnego_gss_verify(void *context, +spnego_gss_verify_mic( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t msg_buffer, const gss_buffer_t token_buffer, - int *qop_state) + gss_qop_t *qop_state) { OM_uint32 ret; ret = gss_verify_mic(minor_status, context_handle, msg_buffer, token_buffer, - (gss_qop_t *)qop_state); /* XXX */ + qop_state); + return (ret); +} + +OM_uint32 +spnego_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 ret; + ret = gss_inquire_sec_context_by_oid(minor_status, + context_handle, + desired_object, + data_set); + return (ret); +} + +OM_uint32 +spnego_gss_set_sec_context_option( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + OM_uint32 ret; + ret = gss_set_sec_context_option(minor_status, + context_handle, + desired_object, + value); + return (ret); +} + +OM_uint32 +spnego_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 ret; + ret = gss_wrap_aead(minor_status, + context_handle, + conf_req_flag, + qop_req, + input_assoc_buffer, + input_payload_buffer, + conf_state, + output_message_buffer); + + return (ret); +} + +OM_uint32 +spnego_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) +{ + OM_uint32 ret; + ret = gss_unwrap_aead(minor_status, + context_handle, + input_message_buffer, + input_assoc_buffer, + output_payload_buffer, + conf_state, + qop_state); + return (ret); +} + +OM_uint32 +spnego_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) +{ + OM_uint32 ret; + ret = gss_wrap_iov(minor_status, + context_handle, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count); + return (ret); +} + +OM_uint32 +spnego_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) +{ + OM_uint32 ret; + ret = gss_unwrap_iov(minor_status, + context_handle, + conf_state, + qop_state, + iov, + iov_count); + return (ret); +} + +OM_uint32 +spnego_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) +{ + OM_uint32 ret; + ret = gss_wrap_iov_length(minor_status, + context_handle, + conf_req_flag, + qop_req, + conf_state, + iov, + iov_count); + return (ret); +} + + +OM_uint32 +spnego_gss_complete_auth_token( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer) +{ + OM_uint32 ret; + ret = gss_complete_auth_token(minor_status, + context_handle, + input_message_buffer); return (ret); } @@ -2237,8 +2777,14 @@ negotiate_mech_type(OM_uint32 *minor_status, unsigned int i; for (i = 0; i < mechset->count; i++) { - gss_test_oid_set_member(minor_status, &mechset->elements[i], - supported_mechSet, &present); + gss_OID mech_oid = &mechset->elements[i]; + + /* Accept wrong mechanism OID from MS clients */ + if (mech_oid->length == gss_mech_krb5_wrong_oid.length && + memcmp(mech_oid->elements, gss_mech_krb5_wrong_oid.elements, mech_oid->length) == 0) + mech_oid = (gss_OID)&gss_mech_krb5_oid;; + + gss_test_oid_set_member(minor_status, mech_oid, supported_mechSet, &present); if (!present) continue; @@ -2298,6 +2844,7 @@ make_err_msg(char *name) */ static int make_spnego_tokenInit_msg(spnego_gss_ctx_id_t spnego_ctx, + int negHintsCompat, gss_buffer_t mechListMIC, OM_uint32 req_flags, gss_buffer_t data, send_token_flag sendtoken, gss_buffer_t outbuf) @@ -2405,7 +2952,7 @@ make_spnego_tokenInit_msg(spnego_gss_ctx_id_t spnego_ctx, tlen - (int)(ptr-t)))) goto errout; - *ptr++ = CONTEXT; /* MechTypeList identifier */ + *ptr++ = CONTEXT | 0x00; /* MechTypeList identifier */ if ((ret = gssint_put_der_length(spnego_ctx->DER_mechTypes.length, &ptr, tlen - (int)(ptr-t)))) goto errout; @@ -2433,7 +2980,12 @@ make_spnego_tokenInit_msg(spnego_gss_ctx_id_t spnego_ctx, &ptr, tlen - (int)(ptr - t)))) goto errout; - if ((ret = put_input_token(&ptr, mechListMIC, + if (negHintsCompat) { + ret = put_neg_hints(&ptr, mechListMIC, + tlen - (int)(ptr - t)); + if (ret) + goto errout; + } else if ((ret = put_input_token(&ptr, mechListMIC, tlen - (int)(ptr - t)))) goto errout; } @@ -2716,7 +3268,7 @@ g_get_tag_and_length(unsigned char **buf, int tag, unsigned char *ptr = *buf; int ret = -1; /* pessimists, assume failure ! */ unsigned int encoded_len; - int tmplen = 0; + unsigned int tmplen = 0; *outlen = 0; if (buflen > 1 && *ptr == tag) { |