diff options
| author | Sam Hartman <hartmans@mit.edu> | 2009-01-03 23:19:42 +0000 |
|---|---|---|
| committer | Sam Hartman <hartmans@mit.edu> | 2009-01-03 23:19:42 +0000 |
| commit | 0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d (patch) | |
| tree | 2049c9c2cb135fe36b14c0a171711259258d18ec /src/lib/gssapi/krb5 | |
| parent | ff0a6514c9f4230938c29922d69cbd4e83691adf (diff) | |
| download | krb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.tar.gz krb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.tar.xz krb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.zip | |
Merge mskrb-integ onto trunk
The mskrb-integ branch includes support for the following projects:
Projects/Aliases
* Projects/PAC and principal APIs
* Projects/AEAD encryption API
* Projects/GSSAPI DCE
* Projects/RFC 3244
In addition, it includes support for enctype negotiation, and a variety of GSS-API extensions.
In the KDC it includes support for protocol transition, constrained delegation
and a new authorization data interface.
The old authorization data interface is also supported.
This commit merges the mskrb-integ branch on to the trunk.
Additional review and testing is required.
Merge commit 'mskrb-integ' into trunk
ticket: new
status: open
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21690 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi/krb5')
39 files changed, 5097 insertions, 2038 deletions
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; |
