diff options
| author | Marc Horowitz <marc@mit.edu> | 1996-07-22 20:49:46 +0000 |
|---|---|---|
| committer | Marc Horowitz <marc@mit.edu> | 1996-07-22 20:49:46 +0000 |
| commit | edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1 (patch) | |
| tree | 6c2974a97b448c040fa4a31708ec5e02f187526c /src/lib/gssapi | |
| parent | 013bb1391582ed9e653ae706e398ddb8d08cfcc9 (diff) | |
| download | krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.gz krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.xz krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.zip | |
this commit includes all the changes on the OV_9510_INTEGRATION and
OV_MERGE branches. This includes, but is not limited to, the new openvision
admin system, and major changes to gssapi to add functionality, and bring
the implementation in line with rfc1964. before committing, the
code was built and tested for netbsd and solaris.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8774 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
62 files changed, 2957 insertions, 1126 deletions
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog index 0ad7c89bd..036bd4693 100644 --- a/src/lib/gssapi/ChangeLog +++ b/src/lib/gssapi/ChangeLog @@ -12,6 +12,11 @@ Mon May 6 21:33:25 1996 Ezra Peisach <epeisach@kangaroo.mit.edu> * Makefile.in (clean-unix): Remove libgssapi_krb5.stamp. +Wed Apr 17 21:48:15 1996 Marc Horowitz <marc@mit.edu> + + * Makefile.in, configure.in: Nothing in mechglue is used anymore, + for now. + Tue Feb 27 22:10:48 1996 Theodore Y. Ts'o <tytso@dcl> * Makefile.in (all-windows, clean-windows): Add mechglue to the diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in index c27788dc2..b874a951c 100644 --- a/src/lib/gssapi/Makefile.in +++ b/src/lib/gssapi/Makefile.in @@ -10,8 +10,8 @@ KRB5_VER=@KRB5_SH_VERS@ DEPLIBS=$(TOPLIBD)/libcrypto.$(SHEXT).$(CRYPTO_VER) \ $(TOPLIBD)/libcom_err.$(SHEXT).$(COMERR_VER) \ $(TOPLIBD)/libkrb5.$(SHEXT).$(KRB5_VER) -LIB_SUBDIRS= generic krb5 mechglue -LIBDONE= generic/DONE krb5/DONE mechglue/DONE +LIB_SUBDIRS= generic krb5 +LIBDONE= generic/DONE krb5/DONE # mechglue/DONE LIBUPDATE= $(BUILDTOP)/util/libupdate SHLIB_LIBS=-lkrb5 -lcrypto -lcom_err @@ -51,9 +51,9 @@ all-windows:: cd ..\krb5 @echo Making in gssapi\krb5 -$(MAKE) -$(MFLAGS) - cd ..\mechglue - @echo Making in gssapi\mechglue - -$(MAKE) -$(MFLAGS) +# cd ..\mechglue +# @echo Making in gssapi\mechglue +# -$(MAKE) -$(MFLAGS) cd .. clean-windows:: @@ -63,9 +63,9 @@ clean-windows:: cd ..\krb5 @echo Making clean in gssapi\krb5 -$(MAKE) -$(MFLAGS) clean - cd ..\mechglue - @echo Making clean in gssapi\mechglue - -$(MAKE) -$(MFLAGS) clean +# cd ..\mechglue +# @echo Making clean in gssapi\mechglue +# -$(MAKE) -$(MFLAGS) clean cd .. @echo Making clean in gssapi diff --git a/src/lib/gssapi/configure.in b/src/lib/gssapi/configure.in index ee150e11f..164582c64 100644 --- a/src/lib/gssapi/configure.in +++ b/src/lib/gssapi/configure.in @@ -1,6 +1,7 @@ AC_INIT(configure.in) CONFIG_RULES -CONFIG_DIRS(generic krb5 mechglue) +CONFIG_DIRS(generic krb5) +dnl CONFIG_DIRS(generic krb5 mechglue) AC_PROG_ARCHIVE AC_PROG_ARCHIVE_ADD AC_PROG_RANLIB diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog index d43459914..a3b2a1411 100644 --- a/src/lib/gssapi/generic/ChangeLog +++ b/src/lib/gssapi/generic/ChangeLog @@ -28,6 +28,26 @@ Wed Jun 12 00:46:41 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> all uses of INTERFACE in favor of KRB5_CALLCONV and KRB5_DLLIMP. +Sun Apr 21 03:07:02 1996 Marc Horowitz <marc@mit.edu> + + * gssapi_generic.c, release_buffer.c, release_oid_set.c: added + files which should have been added before, but either I or commit + was confused. + +Wed Apr 17 20:59:23 1996 Marc Horowitz <marc@mit.edu> + + * oid_ops.c: moved from mechglue + + * util_canonhost.c (g_canonicalize_host): cast the return value of + malloc() + + * gssapiP_generic.h: Added prototypes for oid_ops.c + + * gssapi.h: Make the types of OM_uint32 constants portable, + fix some minor compile-time nits + + * Makefile.in: change the list of files which need to be built + Tue Apr 2 15:31:25 1996 Theodore Y. Ts'o <tytso@dcl> * Makefile.in (SRCS): Inlined list of source files for SRCS and diff --git a/src/lib/gssapi/generic/Makefile.in b/src/lib/gssapi/generic/Makefile.in index 9c90244f2..c9e940962 100644 --- a/src/lib/gssapi/generic/Makefile.in +++ b/src/lib/gssapi/generic/Makefile.in @@ -39,28 +39,40 @@ gssapi_err_generic.c: gssapi_err_generic.et #endif SRCS = \ - $(srcdir)/disp_major_status.c \ $(srcdir)/disp_com_err_status.c \ + $(srcdir)/disp_major_status.c \ + $(srcdir)/gssapi_generic.c \ + $(srcdir)/oid_ops.c \ + $(srcdir)/release_buffer.c \ + $(srcdir)/release_oid_set.c \ $(srcdir)/util_buffer.c \ $(srcdir)/util_canonhost.c \ $(srcdir)/util_dup.c \ $(srcdir)/util_oid.c \ + $(srcdir)/util_ordering.c \ + $(srcdir)/util_set.c \ $(srcdir)/util_token.c \ - $(srcdir)/utl_nohash_validate.c \ + $(srcdir)/util_validate.c \ gssapi_err_generic.c OBJS = \ - disp_major_status.$(OBJEXT) \ disp_com_err_status.$(OBJEXT) \ + disp_major_status.$(OBJEXT) \ + gssapi_generic.$(OBJEXT) \ + oid_ops.$(OBJEXT) \ + release_buffer.$(OBJEXT) \ + release_oid_set.$(OBJEXT) \ util_buffer.$(OBJEXT) \ util_canonhost.$(OBJEXT) \ util_dup.$(OBJEXT) \ util_oid.$(OBJEXT) \ + util_ordering.$(OBJEXT) \ + util_set.$(OBJEXT) \ util_token.$(OBJEXT) \ - utl_nohash_validate.$(OBJEXT) \ + util_validate.$(OBJEXT) \ gssapi_err_generic.$(OBJEXT) -EHDRDIR= $(BUILDTOP)$(S)include$(S)gssapi +EHDRDIR= $(BUILDTOP)/include/gssapi EXPORTED_HEADERS= gssapi.h gssapi_generic.h HDRS= $(ETHDRS) @@ -89,8 +101,8 @@ clean-windows:: # Krb5InstallHeaders($(EXPORTED_HEADERS), $(KRB5_INCDIR)/krb5) install:: @set -x; for f in $(EXPORTED_HEADERS) ; \ - do $(INSTALL_DATA) $(srcdir)$(S)$$f \ - $(DESTDIR)$(KRB5_INCDIR)$(S)gssapi$(S)$$f ; \ + do $(INSTALL_DATA) $(srcdir)/$$f \ + $(DESTDIR)$(KRB5_INCDIR)/gssapi/$$f ; \ done depend:: $(ETSRCS) diff --git a/src/lib/gssapi/generic/disp_com_err_status.c b/src/lib/gssapi/generic/disp_com_err_status.c index 79b5fbbe2..c4db91375 100644 --- a/src/lib/gssapi/generic/disp_com_err_status.c +++ b/src/lib/gssapi/generic/disp_com_err_status.c @@ -20,6 +20,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_generic.h" #include "com_err.h" diff --git a/src/lib/gssapi/generic/disp_major_status.c b/src/lib/gssapi/generic/disp_major_status.c index ad0b17f20..4dd91d25f 100644 --- a/src/lib/gssapi/generic/disp_major_status.c +++ b/src/lib/gssapi/generic/disp_major_status.c @@ -23,6 +23,10 @@ #include "gssapiP_generic.h" #include <string.h> +/* + * $Id$ + */ + /* This code has knowledge of the min and max errors of each type within the gssapi major status */ diff --git a/src/lib/gssapi/generic/gssapi.h b/src/lib/gssapi/generic/gssapi.h index 2b2e6002b..28cc4ca41 100644 --- a/src/lib/gssapi/generic/gssapi.h +++ b/src/lib/gssapi/generic/gssapi.h @@ -131,14 +131,6 @@ typedef unsigned int uid_t; #endif #endif -#ifndef NPROTOTYPE -#if defined(__ultrix) && !defined (__GNUC__) -#define NPROTOTYPE(x) () -#else -#define NPROTOTYPE(x) PROTOTYPE(x) -#endif -#endif - /* * First, include stddef.h to get size_t defined. */ @@ -161,8 +153,13 @@ typedef unsigned int uid_t; #endif /* HAVE_XOM_H */ /* + * $Id$ + */ + +/* * First, define the three platform-dependent pointer types. */ + typedef void FAR * gss_name_t; typedef void FAR * gss_cred_id_t; typedef void FAR * gss_ctx_id_t; @@ -305,7 +302,7 @@ typedef int gss_cred_usage_t; * Expiration time of 2^32-1 seconds means infinite lifetime for a * credential or security context */ -#define GSS_C_INDEFINITE 0xffffffffl +#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful) /* Major status codes */ @@ -318,9 +315,9 @@ typedef int gss_cred_usage_t; #define GSS_C_CALLING_ERROR_OFFSET 24 #define GSS_C_ROUTINE_ERROR_OFFSET 16 #define GSS_C_SUPPLEMENTARY_OFFSET 0 -#define GSS_C_CALLING_ERROR_MASK 0377l -#define GSS_C_ROUTINE_ERROR_MASK 0377l -#define GSS_C_SUPPLEMENTARY_MASK 0177777l +#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul) +#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul) +#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul) /* * The macros that test status codes for error conditions. Note that the @@ -345,43 +342,51 @@ typedef int gss_cred_usage_t; * Calling errors: */ #define GSS_S_CALL_INACCESSIBLE_READ \ - (1l << GSS_C_CALLING_ERROR_OFFSET) + (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET) #define GSS_S_CALL_INACCESSIBLE_WRITE \ - (2l << GSS_C_CALLING_ERROR_OFFSET) + (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET) #define GSS_S_CALL_BAD_STRUCTURE \ - (3l << GSS_C_CALLING_ERROR_OFFSET) + (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET) /* * Routine errors: */ -#define GSS_S_BAD_MECH (1l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_NAME (2l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_NAMETYPE (3l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_BINDINGS (4l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_STATUS (5l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_SIG (6l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_NO_CRED (7l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_NO_CONTEXT (8l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_DEFECTIVE_TOKEN (9l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_DEFECTIVE_CREDENTIAL (10l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_CREDENTIALS_EXPIRED (11l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_CONTEXT_EXPIRED (12l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_FAILURE (13l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_QOP (14l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_UNAUTHORIZED (15l << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_UNAVAILABLE (16l << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_CREDENTIAL \ + (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CREDENTIALS_EXPIRED \ + (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CONTEXT_EXPIRED \ + (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET) /* * XXX new functions. Check to get official error number assigments? */ -#define GSS_S_DUPLICATE_ELEMENT (17l << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DUPLICATE_ELEMENT \ + (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET) /* * Supplementary info bits: */ -#define GSS_S_CONTINUE_NEEDED (1l << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) -#define GSS_S_DUPLICATE_TOKEN (1l << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) -#define GSS_S_OLD_TOKEN (1l << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) -#define GSS_S_UNSEQ_TOKEN (1l << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) +#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) +#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) +#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) +#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) +/* + * XXX not in the cbindings yet. remove this comment when it is + */ +#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) /* diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h index a882f6139..e0bb28d44 100644 --- a/src/lib/gssapi/generic/gssapiP_generic.h +++ b/src/lib/gssapi/generic/gssapiP_generic.h @@ -23,7 +23,10 @@ #ifndef _GSSAPIP_GENERIC_H_ #define _GSSAPIP_GENERIC_H_ -#include "k5-int.h" +/* + * $Id$ + */ + #include "gssapi.h" #include "gssapi_err_generic.h" @@ -86,6 +89,14 @@ /** helper functions **/ +typedef struct _g_set *g_set; + +int g_set_init PROTOTYPE((g_set *s)); +int g_set_destroy PROTOTYPE((g_set *s)); +int g_set_entry_add PROTOTYPE((g_set *s, void *key, void *value)); +int g_set_entry_delete PROTOTYPE((g_set *s, void *key)); +int g_set_entry_get PROTOTYPE((g_set *s, void *key, void **value)); + int g_save_name PROTOTYPE((void **vdb, gss_name_t *name)); int g_save_cred_id PROTOTYPE((void **vdb, gss_cred_id_t *cred)); int g_save_ctx_id PROTOTYPE((void **vdb, gss_ctx_id_t *ctx)); @@ -119,8 +130,64 @@ OM_uint32 g_display_com_err_status PROTOTYPE((OM_uint32 *minor_status, OM_uint32 status_value, gss_buffer_t status_string)); -char * g_canonicalize_host PROTOTYPE((char *hostname)); - -char * g_strdup PROTOTYPE((char *str)); +OM_uint32 g_order_init PROTOTYPE((void **queue, unsigned int seqnum, + int do_replay, int do_sequence)); + +OM_uint32 g_order_check PROTOTYPE((void **queue, unsigned int seqnum)); + +void g_order_free PROTOTYPE((void **queue)); + +char *g_canonicalize_host PROTOTYPE((char *hostname)); +char *g_local_host_name PROTOTYPE((void)); + +char *g_strdup PROTOTYPE((char *str)); + +/** declarations of internal name mechanism functions **/ + +OM_uint32 generic_gss_release_buffer +PROTOTYPE((OM_uint32*, /* minor_status */ + gss_buffer_t /* buffer */ + )); + +OM_uint32 generic_gss_release_oid_set +PROTOTYPE((OM_uint32*, /* minor_status */ + gss_OID_set* /* set */ + )); + +OM_uint32 generic_gss_copy_oid +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_OID * /* new_oid */ + )); + +OM_uint32 generic_gss_create_empty_oid_set +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + )); + +OM_uint32 generic_gss_add_oid_set_member +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_OID, /* member_oid */ + gss_OID_set * /* oid_set */ + )); + +OM_uint32 generic_gss_test_oid_set_member +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_OID, /* member */ + gss_OID_set, /* set */ + int * /* present */ + )); + +OM_uint32 generic_gss_oid_to_str +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_buffer_t /* oid_str */ + )); + +OM_uint32 generic_gss_str_to_oid +PROTOTYPE( (OM_uint32 *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID * /* oid */ + )); #endif /* _GSSAPIP_GENERIC_H_ */ diff --git a/src/lib/gssapi/generic/gssapi_err_generic.et b/src/lib/gssapi/generic/gssapi_err_generic.et index 91d958d12..ddeed4227 100644 --- a/src/lib/gssapi/generic/gssapi_err_generic.et +++ b/src/lib/gssapi/generic/gssapi_err_generic.et @@ -20,6 +20,10 @@ # PERFORMANCE OF THIS SOFTWARE. # +# +# $Id$ +# + error_table ggss error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string" @@ -31,5 +35,9 @@ error_code G_BAD_MSG_CTX, "Message context invalid" error_code G_WRONG_SIZE, "Buffer is the wrong size" error_code G_BAD_USAGE, "Credential usage type is unknown" error_code G_UNKNOWN_QOP, "Unknown quality of protection specified" +error_code G_NO_HOSTNAME, "Local host name could not be determined" error_code G_BAD_HOSTNAME, "Hostname in SERVICE-NAME string could not be canonicalized" +error_code G_WRONG_MECH, "Mechanism is incorrect" +error_code G_BAD_TOK_HEADER, "Token header is malformed or corrupt" +error_code G_BAD_DIRECTION, "Packet was replayed in wrong direction" end diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c new file mode 100644 index 000000000..7072329b7 --- /dev/null +++ b/src/lib/gssapi/generic/gssapi_generic.c @@ -0,0 +1,59 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_generic.h" + +/* + * See krb5/gssapi_krb5.c for a description of the algorithm for + * encoding an object identifier. + */ + +/* + * The OID of user_name is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) user_name(1) = 1.2.840.113554.1.2.1.1 + * machine_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) machine_uid_name(2) = 1.2.840.113554.1.2.1.2 + * string_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) string_uid_name(3) = 1.2.840.113554.1.2.1.3 + * service_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4) = 1.2.840.113554.1.2.1.4 + */ + +static gss_OID_desc oids[] = { + {10, "\052\206\110\206\367\022\001\002\001\001"}, + {10, "\052\206\110\206\367\022\001\002\001\002"}, + {10, "\052\206\110\206\367\022\001\002\001\003"}, + {10, "\052\206\110\206\367\022\001\002\001\004"}, +}; + +gss_OID gss_nt_user_name = oids+0; +gss_OID gss_nt_machine_uid_name = oids+1; +gss_OID gss_nt_string_uid_name = oids+2; +gss_OID gss_nt_service_name = oids+3; diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h index fe2282796..88c054788 100644 --- a/src/lib/gssapi/generic/gssapi_generic.h +++ b/src/lib/gssapi/generic/gssapi_generic.h @@ -23,6 +23,10 @@ #ifndef _GSSAPI_GENERIC_H_ #define _GSSAPI_GENERIC_H_ +/* + * $Id$ + */ + #if defined(__MWERKS__) || defined(applec) || defined(THINK_C) #include <gssapi.h> #else diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c new file mode 100644 index 000000000..38d73f429 --- /dev/null +++ b/src/lib/gssapi/generic/oid_ops.c @@ -0,0 +1,385 @@ +/* + * lib/gssapi/generic/oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. 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. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include "gssapiP_generic.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <ctype.h> + +#if 0 +OM_uint32 +generic_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + *minor_status = 0; + + if (*oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); + + /* + * The V2 API says the following! + * + * gss_release_oid[()] will recognize any of the GSSAPI's own OID values, + * and will silently ignore attempts to free these OIDs; for other OIDs + * it will call the C free() routine for both the OID data and the + * descriptor. This allows applications to freely mix their own heap- + * allocated OID values with OIDs returned by GSS-API. + */ + if ((*oid != gss_nt_user_name) && + (*oid != gss_nt_machine_uid_name) && + (*oid != gss_nt_string_uid_name) && + (*oid != gss_nt_service_name)) { + free((*oid)->elements); + free(*oid); + } + *oid = GSS_C_NO_OID; + return(GSS_S_COMPLETE); +} +#endif + +OM_uint32 +generic_gss_copy_oid(minor_status, oid, new_oid) + OM_uint32 *minor_status; + gss_OID oid, *new_oid; +{ + gss_OID p; + + p = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!p) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + p->length = oid->length; + p->elements = malloc(p->length); + if (!p->elements) { + free(p); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(p->elements, oid->elements, p->length); + *new_oid = p; + return(GSS_S_COMPLETE); +} + + +OM_uint32 +generic_gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) { + memset(*oid_set, 0, sizeof(gss_OID_set_desc)); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } +} + +OM_uint32 +generic_gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + gss_OID elist; + gss_OID lastel; + + elist = (*oid_set)->elements; + /* Get an enlarged copy of the array */ + if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * + sizeof(gss_OID_desc)))) { + /* Copy in the old junk */ + if (elist) + memcpy((*oid_set)->elements, + elist, + ((*oid_set)->count * sizeof(gss_OID_desc))); + + /* Duplicate the input element */ + lastel = &(*oid_set)->elements[(*oid_set)->count]; + if ((lastel->elements = + (void *) malloc((size_t) member_oid->length))) { + /* Success - copy elements */ + memcpy(lastel->elements, member_oid->elements, + (size_t) member_oid->length); + /* Set length */ + lastel->length = member_oid->length; + + /* Update count */ + (*oid_set)->count++; + if (elist) + free(elist); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else + free((*oid_set)->elements); + } + /* Failure - restore old contents of list */ + (*oid_set)->elements = elist; + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + size_t i; + int result; + + result = 0; + for (i=0; i<set->count; i++) { + if ((set->elements[i].length == member->length) && + !memcmp(set->elements[i].elements, + member->elements, + (size_t) member->length)) { + result = 1; + break; + } + } + *present = result; + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +/* + * OID<->string routines. These are uuuuugly. + */ +OM_uint32 +generic_gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + char numstr[128]; + unsigned long number; + int numshift; + size_t string_length; + size_t i; + unsigned char *cp; + char *bp; + + /* Decoded according to krb5/gssapi_krb5.c */ + + /* First determine the size of the string */ + string_length = 0; + number = 0; + numshift = 0; + cp = (unsigned char *) oid->elements; + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + string_length += strlen(numstr); + sprintf(numstr, "%ld ", number%40); + string_length += strlen(numstr); + for (i=1; i<oid->length; i++) { + if ( (size_t) (numshift+7) < (sizeof(unsigned long)*8)) { + number = (number << 7) | (cp[i] & 0x7f); + numshift += 7; + } + else { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + string_length += strlen(numstr); + number = 0; + numshift = 0; + } + } + /* + * If we get here, we've calculated the length of "n n n ... n ". Add 4 + * here for "{ " and "}\0". + */ + string_length += 4; + if ((bp = (char *) malloc(string_length))) { + strcpy(bp, "{ "); + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + strcat(bp, numstr); + sprintf(numstr, "%ld ", number%40); + strcat(bp, numstr); + number = 0; + cp = (unsigned char *) oid->elements; + for (i=1; i<oid->length; i++) { + number = (number << 7) | (cp[i] & 0x7f); + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + strcat(bp, numstr); + number = 0; + } + } + strcat(bp, "}"); + oid_str->length = strlen(bp)+1; + oid_str->value = (void *) bp; + *minor_status = 0; + return(GSS_S_COMPLETE); + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + char *cp, *bp, *startp; + int brace; + long numbuf; + long onumbuf; + OM_uint32 nbytes; + int index; + unsigned char *op; + + brace = 0; + bp = (char *) oid_str->value; + cp = bp; + /* Skip over leading space */ + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (*bp == '{') { + brace = 1; + bp++; + } + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + startp = bp; + nbytes = 0; + + /* + * The first two numbers are chewed up by the first octet. + */ + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + nbytes++; + while (isdigit(*bp)) { + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + } + if (brace && (*bp != '}')) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + + /* + * Phew! We've come this far, so the syntax is good. + */ + if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) { + if (((*oid)->elements = (void *) malloc((size_t) nbytes))) { + (*oid)->length = nbytes; + op = (unsigned char *) (*oid)->elements; + bp = startp; + sscanf(bp, "%ld", &numbuf); + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + onumbuf = 40*numbuf; + sscanf(bp, "%ld", &numbuf); + onumbuf += numbuf; + *op = (unsigned char) onumbuf; + op++; + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + while (isdigit(*bp)) { + sscanf(bp, "%ld", &numbuf); + nbytes = 0; + /* Have to fill in the bytes msb-first */ + onumbuf = numbuf; + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + numbuf = onumbuf; + op += nbytes; + index = -1; + while (numbuf) { + op[index] = (unsigned char) numbuf & 0x7f; + if (index != -1) + op[index] |= 0x80; + index--; + numbuf >>= 7; + } + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + } + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + free(*oid); + *oid = GSS_C_NO_OID; + } + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + diff --git a/src/lib/gssapi/generic/release_buffer.c b/src/lib/gssapi/generic/release_buffer.c new file mode 100644 index 000000000..d367ef31e --- /dev/null +++ b/src/lib/gssapi/generic/release_buffer.c @@ -0,0 +1,58 @@ +/* #ident "@(#)g_rel_buffer.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_buffer + */ + +#include "gssapiP_generic.h" + +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 INTERFACE +generic_gss_release_buffer (minor_status, + buffer) + OM_uint32 * minor_status; + gss_buffer_t buffer; +{ + if (minor_status) + *minor_status = 0; + + /* if buffer is NULL, return */ + + if (buffer == GSS_C_NO_BUFFER) + return(GSS_S_COMPLETE); + + if ((buffer->length) && + (buffer->value)) { + free(buffer->value); + buffer->length = 0; + buffer->value = NULL; + } + + return (GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/generic/release_oid_set.c b/src/lib/gssapi/generic/release_oid_set.c new file mode 100644 index 000000000..01e814bcb --- /dev/null +++ b/src/lib/gssapi/generic/release_oid_set.c @@ -0,0 +1,62 @@ +/* #ident "@(#)gss_release_oid_set.c 1.12 95/08/23 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_oid_set + */ + +#include "gssapiP_generic.h" + +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 INTERFACE +generic_gss_release_oid_set (minor_status, + set) + OM_uint32 * minor_status; + gss_OID_set * set; +{ + size_t i; + gss_OID oid; + if (minor_status) + *minor_status = 0; + + if (set == NULL) + return(GSS_S_COMPLETE); + + if (*set == GSS_C_NULL_OID_SET) + return(GSS_S_COMPLETE); + + for (i=0; i<(*set)->count; i++) + free((*set)->elements[i].elements); + + free((*set)->elements); + free(*set); + + *set = GSS_C_NULL_OID_SET; + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/generic/util_buffer.c b/src/lib/gssapi/generic/util_buffer.c index cf144495f..e715834d9 100644 --- a/src/lib/gssapi/generic/util_buffer.c +++ b/src/lib/gssapi/generic/util_buffer.c @@ -20,6 +20,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_generic.h" #include <string.h> diff --git a/src/lib/gssapi/generic/util_canonhost.c b/src/lib/gssapi/generic/util_canonhost.c index 896b950b1..900834f40 100644 --- a/src/lib/gssapi/generic/util_canonhost.c +++ b/src/lib/gssapi/generic/util_canonhost.c @@ -20,10 +20,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + /* This file could be OS specific */ -#define NEED_SOCKETS + #include "gssapiP_generic.h" +#include "port-sockets.h" + #ifndef _MACINTOSH #include <sys/types.h> #endif @@ -41,7 +47,7 @@ g_canonicalize_host(hostname) if ((hent = gethostbyname(hostname)) == NULL) return(NULL); - if (! (haddr = xmalloc(hent->h_length))) { + if (! (haddr = (char *) xmalloc(hent->h_length))) { return(NULL); } @@ -53,7 +59,7 @@ g_canonicalize_host(hostname) xfree(haddr); - if ((canon = xmalloc(strlen(hent->h_name)+1)) == NULL) + if ((canon = (char *) xmalloc(strlen(hent->h_name)+1)) == NULL) return(NULL); strcpy(canon, hent->h_name); diff --git a/src/lib/gssapi/generic/util_dup.c b/src/lib/gssapi/generic/util_dup.c index 6b19092db..d601ceef2 100644 --- a/src/lib/gssapi/generic/util_dup.c +++ b/src/lib/gssapi/generic/util_dup.c @@ -20,6 +20,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_generic.h" #include <string.h> diff --git a/src/lib/gssapi/generic/util_oid.c b/src/lib/gssapi/generic/util_oid.c index 91bb544ed..8843a7ff6 100644 --- a/src/lib/gssapi/generic/util_oid.c +++ b/src/lib/gssapi/generic/util_oid.c @@ -22,6 +22,10 @@ #include "gssapiP_generic.h" +/* + * $Id$ + */ + int g_copy_OID_set(in, out) const gss_OID_set_desc * const in; diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c index e440d907a..027d2a765 100644 --- a/src/lib/gssapi/generic/util_token.c +++ b/src/lib/gssapi/generic/util_token.c @@ -23,11 +23,9 @@ #include "gssapiP_generic.h" #include <memory.h> -#if (SIZEOF_INT == 2) -#define VALID_INT_BITS 0x7fff -#elif (SIZEOF_INT == 4) -#define VALID_INT_BITS 0x7fffffff -#endif +/* + * $Id$ + */ /* XXXX this code currently makes the assumption that a mech oid will never be longer than 127 bytes. This assumption is not inherent in @@ -153,58 +151,68 @@ void g_make_token_header(mech, body_size, buf, tok_type) *(*buf)++ = (unsigned char) (tok_type&0xff); } -/* given a buffer containing a token, reads and verifies the token, - leaving buf advanced past the token header, and setting body_size - to the number of remaining bytes */ - -int g_verify_token_header(mech, body_size, buf, tok_type, toksize) +/* + * Given a buffer containing a token, reads and verifies the token, + * leaving buf advanced past the token header, and setting body_size + * to the number of remaining bytes. Returns 0 on success, + * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the + * mechanism in the token does not match the mech argument. buf and + * *body_size are left unmodified on error. + */ +int g_verify_token_header(mech, body_size, buf_in, tok_type, toksize) gss_OID mech; int *body_size; - unsigned char **buf; + unsigned char **buf_in; int tok_type; int toksize; { + char *buf = *buf_in; int seqsize; gss_OID_desc toid; + int ret = 0; if ((toksize-=1) < 0) - return(0); - if (*(*buf)++ != 0x60) - return(0); + return(G_BAD_TOK_HEADER); + if (*buf++ != 0x60) + return(G_BAD_TOK_HEADER); - if ((seqsize = der_read_length(buf, &toksize)) < 0) - return(0); + if ((seqsize = der_read_length(&buf, &toksize)) < 0) + return(G_BAD_TOK_HEADER); if (seqsize != toksize) - return(0); + return(G_BAD_TOK_HEADER); if ((toksize-=1) < 0) - return(0); - if (*(*buf)++ != 0x06) - return(0); + return(G_BAD_TOK_HEADER); + if (*buf++ != 0x06) + return(G_BAD_TOK_HEADER); if ((toksize-=1) < 0) - return(0); - toid.length = *(*buf)++; - - if ((toid.length & VALID_INT_BITS) != toid.length) /* Overflow??? */ - return(0); - if ((toksize-= (int) toid.length) < 0) - return(0); - toid.elements = *buf; - (*buf)+=toid.length; - - if (! g_OID_equal(&toid, mech)) - return(0); + return(G_BAD_TOK_HEADER); + toid.length = *buf++; + + if ((toksize-=toid.length) < 0) + return(G_BAD_TOK_HEADER); + toid.elements = buf; + buf+=toid.length; + + if (! g_OID_equal(&toid, mech)) + ret = G_WRONG_MECH; + /* G_WRONG_MECH is not returned immediately because it's more important + to return G_BAD_TOK_HEADER if the token header is in fact bad */ + if ((toksize-=2) < 0) - return(0); + return(G_BAD_TOK_HEADER); - if ((*(*buf)++ != ((tok_type>>8)&0xff)) || - (*(*buf)++ != (tok_type&0xff))) - return(0); + if ((*buf++ != ((tok_type>>8)&0xff)) || + (*buf++ != (tok_type&0xff))) + return(G_BAD_TOK_HEADER); - *body_size = toksize; + if (!ret) { + *buf_in = buf; + *body_size = toksize; + } - return(1); + return(ret); } diff --git a/src/lib/gssapi/generic/util_validate.c b/src/lib/gssapi/generic/util_validate.c index 72631341b..63f552859 100644 --- a/src/lib/gssapi/generic/util_validate.c +++ b/src/lib/gssapi/generic/util_validate.c @@ -21,6 +21,10 @@ */ /* + * $Id$ + */ + +/* * functions to validate name, credential, and context handles */ @@ -30,24 +34,31 @@ #include <sys/file.h> #include <fcntl.h> #include <limits.h> +#ifdef HAVE_BSD_DB #include <db.h> -#define V_NAME 1 -#define V_CRED_ID 2 -#define V_CTX_ID 3 +static const int one = 1; +static const DBT dbtone = { (void *) &one, sizeof(one) }; typedef struct _vkey { int type; void *ptr; } vkey; +#endif -static const int one = 1; -static const DBT dbtone = { (void *) &one, sizeof(one) }; +#define V_NAME 1 +#define V_CRED_ID 2 +#define V_CTX_ID 3 /* All these functions return 0 on failure, and non-zero on success */ -static int g_save(DB **vdb, int type, void *ptr) +static int g_save(db, type, ptr) + void **db; + int type; + void *ptr; { +#ifdef HAVE_BSD_DB + DB **vdb = (DB **) db; vkey vk; DBT key; @@ -61,10 +72,24 @@ static int g_save(DB **vdb, int type, void *ptr) key.size = sizeof(vk); return((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0); +#else + g_set *gs = (g_set *) db; + + if (!*gs) + if (g_set_init(gs)) + return(0); + + return(g_set_entry_add(gs, ptr, (void *) type) == 0); +#endif } -static int g_validate(DB **vdb, int type, void *ptr) +static int g_validate(db, type, ptr) + void **db; + int type; + void *ptr; { +#ifdef HAVE_BSD_DB + DB **vdb = (DB **) db; vkey vk; DBT key, value; @@ -82,10 +107,27 @@ static int g_validate(DB **vdb, int type, void *ptr) return((value.size == sizeof(one)) && (*((int *) value.data) == one)); +#else + g_set *gs = (g_set *) db; + void *value; + + if (!*gs) + return(0); + + if (g_set_entry_get(gs, ptr, (void **) &value)) + return(0); + + return(((int) value) == type); +#endif } -static int g_delete(DB **vdb, int type, void *ptr) +static int g_delete(db, type, ptr) + void **db; + int type; + void *ptr; { +#ifdef HAVE_BSD_DB + DB **vdb = (DB **) db; vkey vk; DBT key; @@ -99,52 +141,81 @@ static int g_delete(DB **vdb, int type, void *ptr) key.size = sizeof(vk); return((*((*vdb)->del))(*vdb, &key, 0) == 0); +#else + g_set *gs = (g_set *) db; + + if (!*gs) + return(0); + + if (g_set_entry_delete(gs, ptr)) + return(0); + + return(1); +#endif } /* functions for each type */ /* save */ -int g_save_name(void **vdb, gss_name_t *name) +int g_save_name(vdb, name) + void **vdb; + gss_name_t *name; { - return(g_save((DB **) vdb, V_NAME, (void *) name)); + return(g_save(vdb, V_NAME, (void *) name)); } -int g_save_cred_id(void **vdb, gss_cred_id_t *cred) +int g_save_cred_id(vdb, cred) + void **vdb; + gss_cred_id_t *cred; { - return(g_save((DB **) vdb, V_CRED_ID, (void *) cred)); + return(g_save(vdb, V_CRED_ID, (void *) cred)); } -int g_save_ctx_id(void **vdb, gss_ctx_id_t *ctx) +int g_save_ctx_id(vdb, ctx) + void **vdb; + gss_ctx_id_t *ctx; { - return(g_save((DB **) vdb, V_CTX_ID, (void *) ctx)); + return(g_save(vdb, V_CTX_ID, (void *) ctx)); } /* validate */ -int g_validate_name(void **vdb, gss_name_t *name) +int g_validate_name(vdb, name) + void **vdb; + gss_name_t *name; { - return(g_validate((DB **) vdb, V_NAME, (void *) name)); + return(g_validate(vdb, V_NAME, (void *) name)); } -int g_validate_cred_id(void **vdb, gss_cred_id_t *cred) +int g_validate_cred_id(vdb, cred) + void **vdb; + gss_cred_id_t *cred; { - return(g_validate((DB **) vdb, V_CRED_ID, (void *) cred)); + return(g_validate(vdb, V_CRED_ID, (void *) cred)); } -int g_validate_ctx_id(void **vdb, gss_ctx_id_t *ctx) +int g_validate_ctx_id(vdb, ctx) + void **vdb; + gss_ctx_id_t *ctx; { - return(g_validate((DB **) vdb, V_CTX_ID, (void *) ctx)); + return(g_validate(vdb, V_CTX_ID, (void *) ctx)); } /* delete */ -int g_delete_name(void **vdb, gss_name_t *name) +int g_delete_name(vdb, name) + void **vdb; + gss_name_t *name; { - return(g_delete((DB **) vdb, V_NAME, (void *) name)); + return(g_delete(vdb, V_NAME, (void *) name)); } -int g_delete_cred_id(void **vdb, gss_cred_id_t *cred) +int g_delete_cred_id(vdb, cred) + void **vdb; + gss_cred_id_t *cred; { - return(g_delete((DB **) vdb, V_CRED_ID, (void *) cred)); + return(g_delete(vdb, V_CRED_ID, (void *) cred)); } -int g_delete_ctx_id(void **vdb, gss_ctx_id_t *ctx) +int g_delete_ctx_id(vdb, ctx) + void **vdb; + gss_ctx_id_t *ctx; { - return(g_delete((DB **) vdb, V_CTX_ID, (void *) ctx)); + return(g_delete(vdb, V_CTX_ID, (void *) ctx)); } diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index 73a09c111..a996733e6 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,43 @@ +Thu Jul 18 19:48:48 1996 Marc Horowitz <marc@mit.edu> + + * init_sec_context.c (krb5_gss_init_sec_context), + accept_sec_context.c (krb5_gss_accept_sec_context): ifdef'd out + reference to 3des. + +Fri Jul 5 15:27:29 1996 Marc Horowitz <marc@mit.edu> + + * gssapi_krb5.h: Add declarations for _old mech set, and _both + mech set + +Thu Jun 20 23:15:57 1996 Marc Horowitz <marc@mit.edu> + + * ser_sctx.c (kg_oid_size, kg_ctx_size): pull the oid-related code + out of kg_ctx_size into kg_oid_size. + + * k5unseal.c (kg_unseal), k5seal.c (make_seal_token): == cannot be + used to compare oid's. The g_OID_equal macro must be used. + + * init_sec_context.c (make_ap_req, krb5_gss_init_sec_context): - + gss_init_sec_context should use the mech set in the credential. + If the default mech is requested, but the old mech oid was + explicitly passed to gss_acquire_cred, then the context should be + the old mech, otherwise, the new mech. If a mech was requested + explicitly, then the code should insure that the credential is + compatible. + + * acquire_cred.c (krb5_gss_acquire_cred), gssapiP_krb5.h (struct + _krb5_gss_cred_it_rec), gssapi_krb5.c (gss_mech_set_krb5*), + inq_cred.c (krb5_gss_inquire_cred): gss_acquire_cred needs to be + able to deal with both mech oid's. It should return in + actual_mechs the intersection of the set passed in and the + {old,new} mechs, or if the default was requested, it should return + both mech oid's. This state should be stored in the credential + handle, and regurgitated by gss_inquire_cred. + + * accept_sec_context.c (krb5_gss_accept_sec_context): make sure + that the oid in the token is compatible with the mechanisms + specified by the credential. + Thu Jun 13 22:11:30 1996 Tom Yu <tlyu@voltage-multiplier.mit.edu> * configure.in: remove ref to ET_RULES @@ -29,6 +69,63 @@ Tue May 14 04:42:11 1996 Theodore Y. Ts'o <tytso@mit.edu> krb5_auth_con_setcksumtype to use krb5_auth_con_set_req_cksumtype by default instead. +Sun May 12 00:54:35 1996 Marc Horowitz <marc@mit.edu> + + * util_crypt.c (kg_encrypt): It used to be that krb5_encrypt could + be used to encrypt in place. That's broken now. This would need + to be fixed in several places in the crypto layer, and it's not + clear what the right thing is, so it's worked around here in the + interests of portability and reliablility, at the expense of a + malloc/memcpy/free. + + * Makefile.in, configure.in: gssapi_krb5.h should be installed + inside the tree. This is really only half the work, as it should + be installed outside of the tree, too. + +Sat Apr 20 00:02:51 1996 Marc Horowitz <marc@mit.edu> + + * accept_sec_context.c, export_sec_context.c, gssapiP_krb5.h, + import_sec_context.c, init_sec_context.c, k5seal.c, k5unseal.c, + ser_sctx.c, wrap_size_limit.c: Implemented triple-des changes + based on Richard's patches. + +Wed Apr 17 21:08:59 1996 Marc Horowitz <marc@mit.edu> + + * accept_sec_context.c (krb5_gss_set_backward_mode): removed + + * krb5_gss_glue.c, wrap_size_limit.c: added + + * import_sec_context.c: intern the newly created context id so + that the validation functions will accept it. + + * Makefile.in (CFLAGS): Don't need md5 header files anymore. + (OBJS, SRCS): Change the list of files to build. + + * export_sec_context.c, import_sec_context.c, gssapiP_krb5.h, + ser_sctx.c: don't use the serialization abstraction, since it + doesn't add anything, and is internal to kerberos. Instead, make + the {de,}serialization functions internal gssapi functions, and + call those directly. + + * accept_sec_context.c, acquire_cred.c, context_time.c, + delete_sec_context.c, disp_name.c, disp_status.c, + export_sec_context.c, gssapi_krb5.c (kg_get_context), + import_name.c, import_sec_context.c, indicate_mechs.c, + init_sec_context.c, inq_context.c, inq_cred.c, inq_names.c, + process_context_token.c, rel_cred.c, rel_name.c, seal.c, sign.c, + unseal.c, verify.c: + Don't pass in the context from the caller. Instead, call + kg_get_context() to find out the kerberos library context. Also, + random minor compile-time fixes. + + * accept_sec_context.c, gssapi_krb5.c (kg_get_defcred), + gssapiP_krb5.h, init_sec_context.c, k5seal.c, k5unseal.c, + util_cksum.c (kg_checksum_channel_bindings), util_seqnum.c + (kg_make_seq_num, kg_get_seq_num), util_seed.c (kg_make_seed), + util_crypt.c (kg_encrypt, kg_decrypt): + pass the context to the kg_* functions which need it instead of + determining it directly. + Fri Apr 12 21:47:46 1996 Richard Basch <basch@lehman.com> * k5seal.c k5unseal.c: diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in index d5061fa14..4a18efeea 100644 --- a/src/lib/gssapi/krb5/Makefile.in +++ b/src/lib/gssapi/krb5/Makefile.in @@ -1,4 +1,4 @@ -CFLAGS = $(CCOPTS) $(DEFS) -I. -I$(srcdir) -I../generic -I$(srcdir)/../generic -I$(srcdir)/../../crypto/md5 -DUSE_AUTOCONF_H +CFLAGS = $(CCOPTS) $(DEFS) -I. -I$(srcdir) -I../generic -I$(srcdir)/../generic -DUSE_AUTOCONF_H ##DOSBUILDTOP = ..\..\.. ##DOSLIBNAME=..\gssapi.$(LIBEXT) @@ -50,12 +50,10 @@ SRCS = \ $(srcdir)/inq_names.c \ $(srcdir)/k5seal.c \ $(srcdir)/k5unseal.c \ - $(srcdir)/k5mech.c \ - $(srcdir)/pname_to_uid.c \ + $(srcdir)/krb5_gss_glue.c \ $(srcdir)/process_context_token.c \ $(srcdir)/rel_cred.c \ $(srcdir)/rel_name.c \ - $(srcdir)/rel_oid.c \ $(srcdir)/seal.c \ $(srcdir)/ser_sctx.c \ $(srcdir)/sign.c \ @@ -65,8 +63,13 @@ SRCS = \ $(srcdir)/util_seed.c \ $(srcdir)/util_seqnum.c \ $(srcdir)/verify.c \ + $(srcdir)/wrap_size_limit.c \ gssapi_err_krb5.c +# $(srcdir)/pname_to_uid.c \ +# $(srcdir)/k5mech.c \ +# $(srcdir)/rel_oid.c + OBJS = \ accept_sec_context.$(OBJEXT) \ acquire_cred.$(OBJEXT) \ @@ -87,12 +90,10 @@ OBJS = \ inq_names.$(OBJEXT) \ k5seal.$(OBJEXT) \ k5unseal.$(OBJEXT) \ - k5mech.$(OBJEXT) \ - pname_to_uid.$(OBJEXT) \ + krb5_gss_glue.$(OBJEXT) \ process_context_token.$(OBJEXT) \ rel_cred.$(OBJEXT) \ rel_name.$(OBJEXT) \ - rel_oid.$(OBJEXT) \ seal.$(OBJEXT) \ ser_sctx.$(OBJEXT) \ sign.$(OBJEXT) \ @@ -102,15 +103,23 @@ OBJS = \ util_seed.$(OBJEXT) \ util_seqnum.$(OBJEXT) \ verify.$(OBJEXT) \ + wrap_size_limit.$(OBJEXT) \ gssapi_err_krb5.$(OBJEXT) +# k5mech.$(OBJEXT) \ +# pname_to_uid.$(OBJEXT) \ +# rel_oid.$(OBJEXT) + HDRS= $(ETHDRS) EHDRDIR=$(TOP)/include/gssapi +EXPORTED_HEADERS= gssapi_krb5.h all-unix:: $(SRCS) $(HDRS) includes $(OBJS) all-mac:: $(SRCS) $(HDRS) includes $(OBJS) all-windows:: $(SRCS) $(HDRS) includes $(OBJS) + if not exist $(EHDRDIR)\nul mkdir $(EHDRDIR) + copy gssapi_krb5.h $(EHDRDIR) clean-unix:: $(RM) $(ETHDRS) $(ETSRCS) shared/* @@ -119,6 +128,14 @@ clean-mac:: $(RM) $(ETHDRS) $(ETSRCS) shared/* clean-windows:: + $(RM) $(EHDRDIR)\gssapi_krb5.h + if exist $(EHDRDIR)\nul rmdir $(EHDRDIR) + +install:: + @set -x; for f in $(EXPORTED_HEADERS) ; \ + do $(INSTALL_DATA) $(srcdir)/$$f \ + $(DESTDIR)$(KRB5_INCDIR)/gssapi/$$f ; \ + done depend:: $(ETSRCS) diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 79d41b71d..09ed41247 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -21,9 +21,40 @@ */ #include "gssapiP_krb5.h" -#include "rsa-md5.h" #include <memory.h> +/* + * $Id$ + */ + +#if 0 + +/* XXXX This widen/narrow stuff is bletcherous, but it seems to be + necessary. Perhaps there is a "better" way, but I don't know what it + is */ + +#include <krb5/widen.h> +static krb5_error_code +rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, + krb5_kvno kvno, krb5_keyblock **keyblock) +#include <krb5/narrow.h> +{ + krb5_error_code code; + krb5_keytab_entry ktentry; + + if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno, + &ktentry)) + return(code); + + code = krb5_copy_keyblock(&ktentry.key, keyblock); + + (void) krb5_kt_free_entry(&ktentry); + + return(code); +} + +#endif + /* Decode, decrypt and store the forwarded creds in the local ccache. */ static krb5_error_code rd_and_store_for_creds(context, auth_context, inbuf) @@ -56,12 +87,11 @@ cleanup: } OM_uint32 -krb5_gss_accept_sec_context(ct, minor_status, context_handle, +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) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_cred_id_t verifier_cred_handle; @@ -74,7 +104,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, OM_uint32 *time_rec; gss_cred_id_t *delegated_cred_handle; { - krb5_context context = ct; + krb5_context context; unsigned char *ptr, *ptr2; char *sptr; long tmp; @@ -89,14 +119,20 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, krb5_principal name; int gss_flags; krb5_gss_ctx_id_rec *ctx; + krb5_enctype enctype; krb5_timestamp now; gss_buffer_desc token; + int err; krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; int option_id; krb5_data option; krb5_auth_context auth_context_cred = NULL; + const gss_OID_desc *mech_used = NULL; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); /* set up returns to be freeable */ @@ -141,14 +177,43 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, return(GSS_S_NO_CRED); } - /* verify the token's integrity, and leave the token in ap_req */ + /* verify the token's integrity, and leave the token in ap_req. + figure out which mech oid was used, and save it */ ptr = (unsigned char *) input_token->value; - if (! g_verify_token_header((gss_OID) gss_mech_krb5, &(ap_req.length), - &ptr, KG_TOK_CTX_AP_REQ, input_token->length)) { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); + if (err = g_verify_token_header((gss_OID) gss_mech_krb5, &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length)) { + /* + * Previous versions of this library used the old mech_id + * and some broken behavior (wrong IV on checksum + * encryption). We support the old mech_id for + * compatibility, and use it to decide when to use the + * old behavior. + */ + if (err != G_WRONG_MECH || + (err = g_verify_token_header((gss_OID) gss_mech_krb5_old, + &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length))) { + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); + } else { + if (! cred->prerfc_mech) { + *minor_status = G_WRONG_MECH; + return(GSS_S_DEFECTIVE_TOKEN); + } + + mech_used = gss_mech_krb5_old; + } + } else { + if (! cred->rfc_mech) { + *minor_status = G_WRONG_MECH; + return(GSS_S_DEFECTIVE_TOKEN); + } + + mech_used = gss_mech_krb5; } sptr = (char *) ptr; @@ -180,6 +245,17 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, krb5_auth_con_getauthenticator(context, auth_context, &authdat); +#if 0 + /* make sure the necessary parts of the authdat are present */ + + if ((authdat->authenticator->subkey == NULL) || + (authdat->ticket->enc_part2 == NULL)) { + krb5_free_tkt_authent(authdat); + *minor_status = KG_NO_SUBKEY; + return(GSS_S_FAILURE); + } +#endif + /* verify that the checksum is correct */ /* @@ -210,13 +286,13 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, TREAD_INT(ptr, tmp, bigend); - if (tmp != RSA_MD5_CKSUM_LENGTH) { + if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { ptr = (unsigned char *) authdat->checksum->contents; bigend = 1; TREAD_INT(ptr, tmp, bigend); - if (tmp != RSA_MD5_CKSUM_LENGTH) { + if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { xfree(md5.contents); krb5_free_authenticator(context, authdat); *minor_status = KG_BAD_LENGTH; @@ -226,7 +302,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, /* at this point, bigend is set according to the initiator's byte order */ - if ((code = kg_checksum_channel_bindings(input_chan_bindings, &md5, + if ((code = kg_checksum_channel_bindings(context, input_chan_bindings, &md5, bigend))) { krb5_free_authenticator(context, authdat); *minor_status = code; @@ -289,21 +365,13 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, break; - default : + /* default: */ + /* unknown options aren't an error */ - /* any other options are unrecognized. return - generic GSS_C_FAILURE error with a minor status - of KRB5_PARSE_MALFORMED (XXX this is probably - not the right error, since it is used for - string parsing errors not token parsing errors.) */ - - *minor_status = KRB5_PARSE_MALFORMED; - return(GSS_S_FAILURE); } /* switch */ } /* while */ } /* if */ - /* create the ctx struct and start filling it in */ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) @@ -313,6 +381,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, } memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); + ctx->mech_used = mech_used; ctx->auth_context = auth_context; ctx->initiate = 0; ctx->gss_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | @@ -345,20 +414,42 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, return(GSS_S_FAILURE); } + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; +#if 0 + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; +#endif + default: + return GSS_S_FAILURE; + } + /* fill in the encryption descriptors */ - krb5_use_enctype(context, &ctx->enc.eblock, ENCTYPE_DES_CBC_RAW); + krb5_use_enctype(context, &ctx->enc.eblock, enctype); ctx->enc.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) + + if (code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key)) return(code); for (i=0; i<ctx->enc.key->length; i++) /*SUPPRESS 113*/ ctx->enc.key->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, ENCTYPE_DES_CBC_RAW); + krb5_use_enctype(context, &ctx->seq.eblock, enctype); ctx->seq.processed = 0; if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) return(code); + ctx->endtime = ticket->enc_part2->times.endtime; ctx->flags = ticket->enc_part2->flags; @@ -366,6 +457,10 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, krb5_auth_con_getremoteseqnumber(context, auth_context, &ctx->seq_recv); + g_order_init(&(ctx->seqstate), ctx->seq_recv, + gss_flags & GSS_C_REPLAY_FLAG, + gss_flags & GSS_C_SEQUENCE_FLAG); + /* at this point, the entire context structure is filled in, so it can be released. */ @@ -375,23 +470,23 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, krb5_data ap_rep; unsigned char * ptr; if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); *minor_status = code; return(GSS_S_FAILURE); } krb5_auth_con_getlocalseqnumber(context, auth_context, &ctx->seq_send); - token.length = g_token_size((gss_OID) gss_mech_krb5, ap_rep.length); + token.length = g_token_size((gss_OID) mech_used, ap_rep.length); if ((token.value = (unsigned char *) xmalloc(token.length)) == NULL) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); - *minor_status = code; + *minor_status = ENOMEM; return(GSS_S_FAILURE); } ptr = token.value; - g_make_token_header((gss_OID) gss_mech_krb5, ap_rep.length, - &ptr, KG_TOK_CTX_AP_REP); + g_make_token_header((gss_OID) mech_used, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); TWRITE_STR(ptr, ap_rep.data, ap_rep.length); xfree(ap_rep.data); @@ -410,7 +505,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, if ((code = krb5_copy_principal(context, ctx->there, &name))) { if (token.value) xfree(token.value); - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); *minor_status = code; return(GSS_S_FAILURE); @@ -418,14 +513,14 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, } if (mech_type) - *mech_type = (gss_OID) gss_mech_krb5; + *mech_type = (gss_OID) mech_used; if (time_rec) { if ((code = krb5_timeofday(context, &now))) { if (src_name) krb5_free_principal(context, name); xfree(token.value); - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); *minor_status = code; return(GSS_S_FAILURE); @@ -434,7 +529,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, } if (ret_flags) - *ret_flags = ctx->gss_flags; + *ret_flags = KG_IMPLFLAGS(gss_flags); ctx->established = 1; @@ -445,7 +540,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, krb5_free_principal(context, name); if (token.value) xfree(token.value); - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); *minor_status = (OM_uint32) G_VALIDATE_FAILED; return(GSS_S_FAILURE); @@ -460,7 +555,7 @@ krb5_gss_accept_sec_context(ct, minor_status, context_handle, } if (token.value) xfree(token.value); - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); *minor_status = (OM_uint32) G_VALIDATE_FAILED; return(GSS_S_FAILURE); diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 526e6dddb..b2d6ce111 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -27,6 +27,10 @@ #include <strings.h> #endif +/* + * $Id$ + */ + /* get credentials corresponding to a key in the krb5 keytab. If the default name is requested, return the name in output_princ. If output_princ is non-NULL, the caller will use or free it, regardless @@ -35,14 +39,13 @@ */ static OM_uint32 -acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) - void *ctx; +acquire_accept_cred(context, minor_status, desired_name, output_princ, cred) + krb5_context context; OM_uint32 *minor_status; gss_name_t desired_name; krb5_principal *output_princ; krb5_gss_cred_id_rec *cred; { - krb5_context context = ctx; krb5_error_code code; krb5_principal princ; krb5_keytab kt; @@ -65,6 +68,7 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) if (desired_name == (gss_name_t) NULL) { if (code = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST, &princ)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -76,6 +80,7 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) /* iterate over the keytab searching for the principal */ if (code = krb5_kt_start_seq_get(context, kt, &cur)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -92,16 +97,19 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) if (code == KRB5_KT_END) { /* this means that the principal wasn't in the keytab */ (void)krb5_kt_end_seq_get(context, kt, &cur); + (void) krb5_kt_close(context, kt); *minor_status = KG_KEYTAB_NOMATCH; return(GSS_S_CRED_UNAVAIL); } else if (code) { /* this means some error occurred reading the keytab */ (void)krb5_kt_end_seq_get(context, kt, &cur); + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } else { /* this means that we found a matching entry */ if (code = krb5_kt_end_seq_get(context, kt, &cur)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -204,7 +212,6 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) if (got_endtime == 0) { cred->tgt_expire = creds.times.endtime; got_endtime = 1; - *minor_status = KG_TGT_MISSING; } krb5_free_cred_contents(context, &creds); } @@ -215,6 +222,12 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) (void)krb5_cc_close(context, ccache); *minor_status = code; return(GSS_S_FAILURE); + } else if (! got_endtime) { + /* this means the ccache was entirely empty */ + (void)krb5_cc_end_seq_get(context, ccache, &cur); + (void)krb5_cc_close(context, ccache); + *minor_status = KG_EMPTY_CCACHE; + return(GSS_S_FAILURE); } else { /* this means that we found an endtime to use. */ if (code = krb5_cc_end_seq_get(context, ccache, &cur)) { @@ -239,10 +252,9 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) /*ARGSUSED*/ OM_uint32 -krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, +krb5_gss_acquire_cred(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; @@ -252,13 +264,17 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, gss_OID_set *actual_mechs; OM_uint32 *time_rec; { - krb5_context context = ctx; + krb5_context context; size_t i; krb5_gss_cred_id_t cred; - gss_OID_set mechs; + gss_OID_set valid_mechs, ret_mechs; + int req_old, req_new; OM_uint32 ret; krb5_error_code code; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* make sure all outputs are valid */ *output_cred_handle = NULL; @@ -279,11 +295,26 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* verify that the requested mechanism set is the default, or contains krb5 */ - if (desired_mechs != GSS_C_NULL_OID_SET) { - for (i=0; i<desired_mechs->count; i++) + if (desired_mechs == GSS_C_NULL_OID_SET) { + valid_mechs = gss_mech_set_krb5_both; + } else { + req_old = 0; + req_new = 0; + + for (i=0; i<desired_mechs->count; i++) { + if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) + req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) - break; - if (i == desired_mechs->count) { + req_new++; + } + + if (req_old && req_new) { + valid_mechs = gss_mech_set_krb5_both; + } else if (req_old) { + valid_mechs = gss_mech_set_krb5_old; + } else if (req_new) { + valid_mechs = gss_mech_set_krb5; + } else { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -300,6 +331,9 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, cred->usage = cred_usage; cred->princ = NULL; + cred->actual_mechs = valid_mechs; + cred->prerfc_mech = req_old; + cred->rfc_mech = req_new; cred->keytab = NULL; cred->ccache = NULL; @@ -390,7 +424,7 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* create mechs */ if (actual_mechs) { - if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) { + if (! g_copy_OID_set(cred->actual_mechs, &ret_mechs)) { if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); if (cred->keytab) @@ -406,8 +440,8 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* intern the credential handle */ if (! kg_save_cred_id((gss_cred_id_t) cred)) { - free(mechs->elements); - free(mechs); + free(ret_mechs->elements); + free(ret_mechs); if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); if (cred->keytab) @@ -424,19 +458,18 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, *minor_status = 0; *output_cred_handle = (gss_cred_id_t) cred; if (actual_mechs) - *actual_mechs = mechs; + *actual_mechs = ret_mechs; return(GSS_S_COMPLETE); } /* V2 interface */ OM_uint32 -krb5_gss_add_cred(ctx, minor_status, input_cred_handle, +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) - void *ctx; OM_uint32 *minor_status; gss_cred_id_t input_cred_handle; gss_name_t desired_name; @@ -449,12 +482,19 @@ krb5_gss_add_cred(ctx, minor_status, input_cred_handle, OM_uint32 *initiator_time_rec; OM_uint32 *acceptor_time_rec; { - krb5_context context = ctx; /* - * This does not apply to our single-mechanism implementation. Until we - * come up with a better error code, return failure. + * This does not apply to our single-mechanism implementation. Decide + * if the correct error is BAD_MECH or DUPLICATE_ELEMENT. */ + + /* verify that the requested mechanism is the default, or + is krb5 */ + + if ((desired_mech != GSS_C_NULL_OID) && + (g_OID_equal(desired_mech, gss_mech_krb5))) + return(GSS_S_BAD_MECH); + *minor_status = 0; - return(GSS_S_FAILURE); + return(GSS_S_DUPLICATE_ELEMENT); } diff --git a/src/lib/gssapi/krb5/compare_name.c b/src/lib/gssapi/krb5/compare_name.c index 19b94f452..75a534220 100644 --- a/src/lib/gssapi/krb5/compare_name.c +++ b/src/lib/gssapi/krb5/compare_name.c @@ -20,17 +20,24 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_compare_name(ctx, minor_status, name1, name2, name_equal) - void *ctx; +krb5_gss_compare_name(minor_status, name1, name2, name_equal) OM_uint32 *minor_status; gss_name_t name1; gss_name_t name2; int *name_equal; { - krb5_context context = ctx; + krb5_context context; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (! kg_validate_name(name1)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); diff --git a/src/lib/gssapi/krb5/configure.in b/src/lib/gssapi/krb5/configure.in index d5fc0695f..a05531893 100644 --- a/src/lib/gssapi/krb5/configure.in +++ b/src/lib/gssapi/krb5/configure.in @@ -4,4 +4,5 @@ AC_PROG_AWK AC_CHECK_HEADERS(stdlib.h) V5_SHARED_LIB_OBJS SubdirLibraryRule([${OBJS}]) +CopySrcHeader(gssapi_krb5.h,[$](BUILDTOP)/include/gssapi) V5_AC_OUTPUT_MAKEFILE diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c index 3bc42e603..76f1489b7 100644 --- a/src/lib/gssapi/krb5/context_time.c +++ b/src/lib/gssapi/krb5/context_time.c @@ -22,19 +22,25 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_context_time(ct, minor_status, context_handle, time_rec) - void *ct; +krb5_gss_context_time(minor_status, context_handle, time_rec) OM_uint32 *minor_status; gss_ctx_id_t context_handle; OM_uint32 *time_rec; { - krb5_context context = ct; + krb5_context context; krb5_error_code code; krb5_gss_ctx_id_rec *ctx; krb5_timestamp now; krb5_deltat lifetime; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index fded9afa8..5b5ff74fa 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -22,16 +22,22 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_delete_sec_context(ct, minor_status, context_handle, output_token) - void *ct; +krb5_gss_delete_sec_context(minor_status, context_handle, output_token) OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_buffer_t output_token; { - krb5_context context = ct; + krb5_context context; krb5_gss_ctx_id_rec *ctx; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (output_token) { output_token->length = 0; output_token->value = NULL; @@ -71,6 +77,9 @@ krb5_gss_delete_sec_context(ct, minor_status, context_handle, output_token) ctx = (gss_ctx_id_t) *context_handle; + if (ctx->seqstate) + g_order_free(&(ctx->seqstate)); + if (ctx->enc.processed) krb5_finish_key(context, &ctx->enc.eblock); krb5_free_keyblock(context, ctx->enc.key); @@ -86,6 +95,8 @@ krb5_gss_delete_sec_context(ct, minor_status, context_handle, output_token) if (ctx->auth_context) krb5_auth_con_free(context, ctx->auth_context); + /* Zero out context */ + memset(ctx, 0, sizeof(*ctx)); xfree(ctx); /* zero the handle itself */ diff --git a/src/lib/gssapi/krb5/disp_name.c b/src/lib/gssapi/krb5/disp_name.c index a9cbcae06..77f520035 100644 --- a/src/lib/gssapi/krb5/disp_name.c +++ b/src/lib/gssapi/krb5/disp_name.c @@ -23,18 +23,20 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_display_name(ctx, minor_status, input_name, output_name_buffer, +krb5_gss_display_name(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; { - krb5_context context = ctx; + krb5_context context; krb5_error_code code; char *str; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + output_name_buffer->length = 0; output_name_buffer->value = NULL; diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c index 326d3fc7c..143f7a624 100644 --- a/src/lib/gssapi/krb5/disp_status.c +++ b/src/lib/gssapi/krb5/disp_status.c @@ -32,9 +32,8 @@ static int init_et = 0; /**/ OM_uint32 -krb5_gss_display_status(ctx, minor_status, status_value, status_type, +krb5_gss_display_status(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; @@ -42,10 +41,13 @@ krb5_gss_display_status(ctx, minor_status, status_value, status_type, OM_uint32 *message_context; gss_buffer_t status_string; { - krb5_context context = ctx; + krb5_context context; status_string->length = 0; status_string->value = NULL; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if ((mech_type != GSS_C_NULL_OID) && (! g_OID_equal(gss_mech_krb5, mech_type))) { *minor_status = 0; diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c index 180cc2ef5..fba8a684b 100644 --- a/src/lib/gssapi/krb5/export_sec_context.c +++ b/src/lib/gssapi/krb5/export_sec_context.c @@ -28,20 +28,21 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_export_sec_context(ct, - minor_status, context_handle, interprocess_token) - void *ct; +krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token) OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_buffer_t interprocess_token; { - krb5_context ser_ctx = ct; + krb5_context context; krb5_error_code kret; OM_uint32 retval; size_t bufsize, blen; - krb5_gss_ctx_id_t *ctx; + krb5_gss_ctx_id_t ctx; krb5_octet *obuffer, *obp; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* Assume a tragic failure */ obuffer = (krb5_octet *) NULL; retval = GSS_S_FAILURE; @@ -53,12 +54,12 @@ krb5_gss_export_sec_context(ct, goto error_out; } - ctx = (krb5_gss_ctx_id_t *) *context_handle; + ctx = (krb5_gss_ctx_id_t) *context_handle; /* Determine size needed for externalization of context */ bufsize = 0; - if ((kret = krb5_size_opaque(ser_ctx, KG_CONTEXT, (krb5_pointer) ctx, - &bufsize))) + if ((kret = kg_ctx_size(context, (krb5_pointer) ctx, + &bufsize))) goto error_out; /* Allocate the buffer */ @@ -70,8 +71,8 @@ krb5_gss_export_sec_context(ct, obp = obuffer; blen = bufsize; /* Externalize the context */ - if ((kret = krb5_externalize_opaque(ser_ctx, KG_CONTEXT, - (krb5_pointer)ctx, &obp, &blen))) + if ((kret = kg_ctx_externalize(context, + (krb5_pointer) ctx, &obp, &blen))) goto error_out; /* Success! Return the buffer */ @@ -81,23 +82,7 @@ krb5_gss_export_sec_context(ct, retval = GSS_S_COMPLETE; /* Now, clean up the context state */ - (void) kg_delete_ctx_id((gss_ctx_id_t) ctx); - if (ctx->enc.processed) - krb5_finish_key(ser_ctx, &ctx->enc.eblock); - krb5_free_keyblock(ser_ctx, ctx->enc.key); - if (ctx->seq.processed) - krb5_finish_key(ser_ctx, &ctx->seq.eblock); - krb5_free_keyblock(ser_ctx, ctx->seq.key); - krb5_free_principal(ser_ctx, ctx->here); - krb5_free_principal(ser_ctx, ctx->there); - krb5_free_keyblock(ser_ctx, ctx->subkey); - - if (ctx->auth_context) - krb5_auth_con_free(ser_ctx, ctx->auth_context); - - /* Zero out context */ - memset(ctx, 0, sizeof(*ctx)); - xfree(ctx); + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); *context_handle = GSS_C_NO_CONTEXT; return (GSS_S_COMPLETE); diff --git a/src/lib/gssapi/krb5/get_tkt_flags.c b/src/lib/gssapi/krb5/get_tkt_flags.c index 2e73cacfe..5dd91064f 100644 --- a/src/lib/gssapi/krb5/get_tkt_flags.c +++ b/src/lib/gssapi/krb5/get_tkt_flags.c @@ -22,6 +22,10 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 gss_krb5_get_tkt_flags(minor_status, context_handle, ticket_flags) OM_uint32 *minor_status; diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 53c4f4691..7ccc4b828 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -23,7 +23,11 @@ #ifndef _GSSAPIP_KRB5_H_ #define _GSSAPIP_KRB5_H_ -#include "k5-int.h" +/* + * $Id$ + */ + +#include <krb5.h> #include <memory.h> /* work around sunos braindamage */ @@ -34,12 +38,15 @@ #undef minor #endif -/* this must be after "krb5.h", since krb5 #defines xfree(), too */ #ifndef _MACINTOSH #include "../generic/gssapiP_generic.h" #else #include "gssapiP_generic.h" #endif + +/* The include of gssapi_krb5.h will dtrt with the above #defines in + * effect. + */ #include "gssapi_krb5.h" #include "gssapi_err_krb5.h" @@ -56,6 +63,10 @@ #define KG_TOK_WRAP_MSG 0x0201 #define KG_TOK_DEL_CTX 0x0102 +#define KG_IMPLFLAGS(x) (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | \ + ((x) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \ + GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))) + #define KRB5_GSS_FOR_CREDS_OPTION 1 /** internal types **/ @@ -66,6 +77,9 @@ typedef struct _krb5_gss_cred_id_rec { /* name/type of credential */ gss_cred_usage_t usage; krb5_principal princ; /* this is not interned as a gss_name_t */ + const gss_OID_set_desc *actual_mechs; + int prerfc_mech; /* these are a cache of the set above */ + int rfc_mech; /* keytab (accept) data */ krb5_keytab keytab; @@ -89,21 +103,24 @@ typedef struct _krb5_gss_ctx_id_rec { krb5_principal here; krb5_principal there; krb5_keyblock *subkey; + int signalg; + int cksum_size; + int sealalg; krb5_gss_enc_desc enc; krb5_gss_enc_desc seq; krb5_timestamp endtime; krb5_flags flags; krb5_int32 seq_send; krb5_int32 seq_recv; + void *seqstate; int established; int big_endian; krb5_auth_context auth_context; -} krb5_gss_ctx_id_rec, krb5_gss_ctx_id_t; + const gss_OID_desc *mech_used; +} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; extern void *kg_vdb; -extern krb5_context kg_context; - /* helper macros */ #define kg_save_name(name) g_save_name(&kg_vdb,name) @@ -127,16 +144,23 @@ OM_uint32 kg_get_defcred OM_uint32 kg_release_defcred PROTOTYPE((OM_uint32 *minor_status)); krb5_error_code kg_checksum_channel_bindings - PROTOTYPE((gss_channel_bindings_t cb, + PROTOTYPE((krb5_context context, gss_channel_bindings_t cb, krb5_checksum *cksum, int bigend)); -krb5_error_code kg_make_seq_num PROTOTYPE((krb5_gss_enc_desc *ed, +krb5_error_code kg_make_seq_num PROTOTYPE((krb5_context context, + krb5_gss_enc_desc *ed, int direction, krb5_int32 seqnum, unsigned char *cksum, unsigned char *buf)); -krb5_error_code kg_make_seed PROTOTYPE((krb5_keyblock *key, - unsigned char *seed)); +krb5_error_code kg_get_seq_num PROTOTYPE((krb5_context context, + krb5_gss_enc_desc *ed, + unsigned char *cksum, unsigned char *buf, int *direction, + krb5_int32 *seqnum)); + +krb5_error_code kg_make_seed PROTOTYPE((krb5_context context, + krb5_keyblock *key, + unsigned char *seed)); int kg_confounder_size PROTOTYPE((krb5_gss_enc_desc *ed)); @@ -145,10 +169,12 @@ krb5_error_code kg_make_confounder PROTOTYPE((krb5_gss_enc_desc *ed, int kg_encrypt_size PROTOTYPE((krb5_gss_enc_desc *ed, int n)); -krb5_error_code kg_encrypt PROTOTYPE((krb5_gss_enc_desc *ed, +krb5_error_code kg_encrypt PROTOTYPE((krb5_context context, + krb5_gss_enc_desc *ed, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); -krb5_error_code kg_decrypt PROTOTYPE((krb5_gss_enc_desc *ed, +krb5_error_code kg_decrypt PROTOTYPE((krb5_context context, + krb5_gss_enc_desc *ed, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); OM_uint32 kg_seal PROTOTYPE((krb5_context context, @@ -178,14 +204,27 @@ OM_uint32 kg_seal_size PROTOTYPE((krb5_context context, OM_uint32 output_size, OM_uint32 *input_size)); -krb5_error_code -kg_ser_context_init PROTOTYPE((krb5_context)); +krb5_error_code kg_ctx_size PROTOTYPE((krb5_context kcontext, + krb5_pointer arg, + size_t *sizep)); + +krb5_error_code kg_ctx_externalize PROTOTYPE((krb5_context kcontext, + krb5_pointer arg, + krb5_octet **buffer, + size_t *lenremain)); + +krb5_error_code kg_ctx_internalize PROTOTYPE((krb5_context kcontext, + krb5_pointer *argp, + krb5_octet **buffer, + size_t *lenremain)); +OM_uint32 kg_get_context PROTOTYPE((OM_uint32 *minor_status, + krb5_context *context)); + /** declarations of internal name mechanism functions **/ OM_uint32 krb5_gss_acquire_cred -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_name_t, /* desired_name */ OM_uint32, /* time_req */ gss_OID_set, /* desired_mechs */ @@ -196,14 +235,12 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_release_cred -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_cred_id_t* /* cred_handle */ )); OM_uint32 krb5_gss_init_sec_context -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_cred_id_t, /* claimant_cred_handle */ gss_ctx_id_t*, /* context_handle */ gss_name_t, /* target_name */ @@ -220,8 +257,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_accept_sec_context -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_cred_id_t, /* verifier_cred_handle */ gss_buffer_t, /* input_token_buffer */ @@ -236,29 +272,25 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_process_context_token -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t /* token_buffer */ )); OM_uint32 krb5_gss_delete_sec_context -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_buffer_t /* output_token */ )); OM_uint32 krb5_gss_context_time -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ OM_uint32* /* time_rec */ )); OM_uint32 krb5_gss_sign -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* qop_req */ gss_buffer_t, /* message_buffer */ @@ -266,8 +298,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_verify -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* message_buffer */ gss_buffer_t, /* token_buffer */ @@ -275,8 +306,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_seal -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ int, /* qop_req */ @@ -286,8 +316,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_unseal -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* input_message_buffer */ gss_buffer_t, /* output_message_buffer */ @@ -296,8 +325,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_display_status -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ OM_uint32, /* status_value */ int, /* status_type */ gss_OID, /* mech_type */ @@ -306,44 +334,38 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_indicate_mechs -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_OID_set* /* mech_set */ )); OM_uint32 krb5_gss_compare_name -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_name_t, /* name1 */ gss_name_t, /* name2 */ int* /* name_equal */ )); OM_uint32 krb5_gss_display_name -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_name_t, /* input_name */ gss_buffer_t, /* output_name_buffer */ gss_OID* /* output_name_type */ )); OM_uint32 krb5_gss_import_name -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_buffer_t, /* input_name_buffer */ gss_OID, /* input_name_type */ gss_name_t* /* output_name */ )); OM_uint32 krb5_gss_release_name -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_name_t* /* input_name */ )); OM_uint32 krb5_gss_inquire_cred -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_name_t *, /* name */ OM_uint32 *, /* lifetime */ @@ -352,8 +374,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_inquire_context -PROTOTYPE( (void *, - OM_uint32*, /* minor_status */ +PROTOTYPE( (OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_name_t*, /* initiator_name */ gss_name_t*, /* acceptor_name */ @@ -366,8 +387,7 @@ PROTOTYPE( (void *, /* New V2 entry points */ OM_uint32 krb5_gss_get_mic -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_qop_t, /* qop_req */ gss_buffer_t, /* message_buffer */ @@ -375,8 +395,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_verify_mic -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* message_buffer */ gss_buffer_t, /* message_token */ @@ -384,8 +403,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_wrap -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ @@ -395,8 +413,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_unwrap -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* input_message_buffer */ gss_buffer_t, /* output_message_buffer */ @@ -405,8 +422,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_wrap_size_limit -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ @@ -415,24 +431,21 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_import_name_object -PROTOTYPE( (krb5_context, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ void *, /* input_name */ gss_OID, /* input_name_type */ gss_name_t * /* output_name */ )); OM_uint32 krb5_gss_export_name_object -PROTOTYPE( (krb5_context, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_name_t, /* input_name */ gss_OID, /* desired_name_type */ void * * /* output_name */ )); OM_uint32 krb5_gss_add_cred -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_cred_id_t, /* input_cred_handle */ gss_name_t, /* desired_name */ gss_OID, /* desired_mech */ @@ -446,8 +459,7 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_inquire_cred_by_mech -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_OID, /* mech_type */ gss_name_t *, /* name */ @@ -457,38 +469,33 @@ PROTOTYPE( (void *, )); OM_uint32 krb5_gss_export_sec_context -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_ctx_id_t *, /* context_handle */ gss_buffer_t /* interprocess_token */ )); OM_uint32 krb5_gss_import_sec_context -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_buffer_t, /* interprocess_token */ gss_ctx_id_t * /* context_handle */ )); +#if 0 OM_uint32 krb5_gss_release_oid PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_OID * /* oid */ )); - +#endif OM_uint32 krb5_gss_internal_release_oid -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_OID * /* oid */ )); OM_uint32 krb5_gss_inquire_names_for_mech -PROTOTYPE( (void *, - OM_uint32 *, /* minor_status */ +PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_OID, /* mechanism */ gss_OID_set * /* name_types */ )); -OM_uint32 kg_get_context(); - #endif /* _GSSAPIP_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/gssapi_err_krb5.et b/src/lib/gssapi/krb5/gssapi_err_krb5.et index 0f26773b1..54a126518 100644 --- a/src/lib/gssapi/krb5/gssapi_err_krb5.et +++ b/src/lib/gssapi/krb5/gssapi_err_krb5.et @@ -33,4 +33,6 @@ error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context" error_code KG_CONTEXT, "Bad magic number for krb5_gss_ctx_id_t" error_code KG_CRED, "Bad magic number for krb5_gss_cred_id_t" error_code KG_ENC_DESC, "Bad magic number for krb5_gss_enc_desc" +error_code KG_BAD_SEQ, "Sequence number in token is corrupt" +error_code KG_EMPTY_CCACHE, "Credential cache is empty" end diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index e18455755..feec0bc71 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -20,50 +20,62 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_krb5.h" -/** exported constants defined in gssapi_krb5.h **/ +/** exported constants defined in gssapi_krb5{,_nx}.h **/ /* these are bogus, but will compile */ /* - * The OID of the krb5 mechanism, assigned by IETF, is: - * 1.3.5.1.5.2 + * The OID of the draft krb5 mechanism, assigned by IETF, is: + * iso(1) org(3) dod(5) internet(1) security(5) + * kerberosv5(2) = 1.3.5.1.5.2 * The OID of the krb5_name type is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) - * krb5(2) krb5_name(1) = 1.2.840.113554.2.1.2.1 + * krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1 * The OID of the krb5_principal type is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) - * krb5(2) krb5_principal(2) = 1.2.840.113554.2.1.2.2 + * krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2 + * The OID of the proposed standard krb5 mechanism is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) = 1.2.840.113554.1.2.2 + * */ /* * Encoding rules: The first two values are encoded in one byte as 40 * * value1 + value2. Subsequent values are encoded base 128, most - * significant digit first, with the high bit set on all octets except - * the last in each value's encoding. + * significant digit first, with the high bit (\200) set on all octets + * except the last in each value's encoding. */ static const gss_OID_desc oids[] = { - /* this OID is from Ted. It's not official yet, but it's close. */ + /* this is the unofficial, wrong OID */ {5, "\053\005\001\005\002"}, + /* this is the official, rfc-specified OID */ + {9, "\052\206\110\206\367\022\001\002\002"}, {10, "\052\206\110\206\367\022\001\002\002\001"}, {10, "\052\206\110\206\367\022\001\002\002\002"}, - {9, "\052\206\110\206\367\022\001\002\002"}, }; -const gss_OID_desc * const gss_mech_krb5 = oids+0; +const gss_OID_desc * const gss_mech_krb5_old = oids+0; +const gss_OID_desc * const gss_mech_krb5 = oids+1; const gss_OID_desc * const gss_nt_krb5_name = oids+1; -const gss_OID_desc * const gss_nt_krb5_principal = oids+2; -const gss_OID_desc * const gss_new_mech_krb5 = oids+3; +const gss_OID_desc * const gss_nt_krb5_principal = oids+3; static const gss_OID_set_desc oidsets[] = { - {1, (gss_OID) oids}, + {1, (gss_OID) oids+0}, + {1, (gss_OID) oids+1}, + {2, (gss_OID) oids+0}, }; -const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0; - -krb5_context kg_context; +const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+0; +const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+1; +const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; void *kg_vdb = NULL; @@ -83,10 +95,7 @@ kg_get_defcred(minor_status, cred) if (defcred == GSS_C_NO_CREDENTIAL) { OM_uint32 major; - if (!kg_context && kg_get_context()) - return GSS_S_FAILURE; - - if ((major = krb5_gss_acquire_cred(kg_context, minor_status, + if ((major = krb5_gss_acquire_cred(minor_status, (gss_name_t) NULL, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_INITIATE, &defcred, NULL, NULL)) && @@ -110,19 +119,24 @@ kg_release_defcred(minor_status) return(GSS_S_COMPLETE); } - if (!kg_context && kg_get_context()) - return GSS_S_FAILURE; - - return(krb5_gss_release_cred(kg_context, minor_status, &defcred)); + return(krb5_gss_release_cred(minor_status, &defcred)); } OM_uint32 -kg_get_context() +kg_get_context(minor_status, context) + OM_uint32 *minor_status; + krb5_context *context; { - if (kg_context) - return GSS_S_COMPLETE; - if (krb5_init_context(&kg_context)) - return GSS_S_FAILURE; - krb5_init_ets(kg_context); - return GSS_S_COMPLETE; + static krb5_context kg_context = NULL; + krb5_error_code code; + + if ((! kg_context) && + (code = krb5_init_context(&kg_context))) { + *minor_status = (OM_uint32) code; + return GSS_S_FAILURE; + } + + *context = kg_context; + *minor_status = 0; + return GSS_S_COMPLETE; } diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h index 450081d97..71182f22b 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.h +++ b/src/lib/gssapi/krb5/gssapi_krb5.h @@ -28,10 +28,13 @@ #else #include <gssapi_generic.h> #endif -#include "krb5.h" +#include <krb5.h> extern const gss_OID_desc * const gss_mech_krb5; +extern const gss_OID_desc * const gss_mech_krb5_old; extern const gss_OID_set_desc * const gss_mech_set_krb5; +extern const gss_OID_set_desc * const gss_mech_set_krb5_old; +extern const gss_OID_set_desc * const gss_mech_set_krb5_both; extern const gss_OID_desc * const gss_nt_krb5_name; extern const gss_OID_desc * const gss_nt_krb5_principal; @@ -49,4 +52,11 @@ OM_uint32 gss_krb5_get_tkt_flags krb5_flags *ticket_flags)); +/* this is for backward compatibility only. It is declared here for + completeness, but should not be used */ + +OM_uint32 krb5_gss_set_backward_mode + PROTOTYPE((OM_uint32 *minor_status, + int mode)); + #endif /* _GSSAPI_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c index ee44132ae..5c2c6f43a 100644 --- a/src/lib/gssapi/krb5/import_name.c +++ b/src/lib/gssapi/krb5/import_name.c @@ -20,7 +20,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_krb5.h" + #ifndef NO_PASSWORD #include <pwd.h> #endif @@ -39,21 +44,24 @@ */ OM_uint32 -krb5_gss_import_name(ctx, minor_status, input_name_buffer, +krb5_gss_import_name(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; { - krb5_context context = ctx; + krb5_context context; krb5_principal princ; krb5_error_code code; char *stringrep, *tmp; #ifndef NO_PASSWORD struct passwd *pw; #endif + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* set up default returns */ *output_name = NULL; @@ -75,13 +83,10 @@ krb5_gss_import_name(ctx, minor_status, input_name_buffer, tmp[input_name_buffer->length] = 0; service = tmp; - if ((host = strchr(tmp, '@')) == NULL) { - xfree(tmp); - *minor_status = (OM_uint32) G_BAD_SERVICE_NAME; - return(GSS_S_BAD_NAME); + if (host = strchr(tmp, '@')) { + *host = '\0'; + host++; } - *host = '\0'; - host++; code = krb5_sname_to_principal(context, host, service, KRB5_NT_SRV_HST, &princ); diff --git a/src/lib/gssapi/krb5/import_sec_context.c b/src/lib/gssapi/krb5/import_sec_context.c index d802ecdd0..c1d1bfa72 100644 --- a/src/lib/gssapi/krb5/import_sec_context.c +++ b/src/lib/gssapi/krb5/import_sec_context.c @@ -28,59 +28,46 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_import_sec_context(ct, - minor_status, interprocess_token, context_handle) - void *ct; +krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle) OM_uint32 *minor_status; gss_buffer_t interprocess_token; gss_ctx_id_t *context_handle; { - krb5_context ser_ctx = ct; + krb5_context context; krb5_error_code kret = 0; OM_uint32 retval; size_t blen; - krb5_gss_ctx_id_t *ctx; + krb5_gss_ctx_id_t ctx; krb5_octet *ibp; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* Assume a tragic failure */ - ctx = (krb5_gss_ctx_id_t *) NULL; + ctx = (krb5_gss_ctx_id_t) NULL; retval = GSS_S_FAILURE; *minor_status = 0; /* Internalize the context */ ibp = (krb5_octet *) interprocess_token->value; blen = (size_t) interprocess_token->length; - if ((kret = krb5_internalize_opaque(ser_ctx, KG_CONTEXT, - (krb5_pointer *) &ctx, - &ibp, &blen))) - goto error_out; - + if ((kret = kg_ctx_internalize(context, + (krb5_pointer *) &ctx, + &ibp, &blen))) { + *minor_status = (OM_uint32) kret; + return(GSS_S_FAILURE); + } - /* Make sure that everything is cool. */ - if (!kg_validate_ctx_id((gss_ctx_id_t) ctx)) - goto error_out; + /* intern the context handle */ + if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { + (void)krb5_gss_delete_sec_context(minor_status, + (gss_ctx_id_t *) &ctx, NULL); + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } *context_handle = (gss_ctx_id_t) ctx; + *minor_status = 0; return (GSS_S_COMPLETE); - -error_out: - if (ctx) { - (void) kg_delete_ctx_id((gss_ctx_id_t) ctx); - if (ctx->enc.processed) - krb5_finish_key(ser_ctx, &ctx->enc.eblock); - krb5_free_keyblock(ser_ctx, ctx->enc.key); - if (ctx->seq.processed) - krb5_finish_key(ser_ctx, &ctx->seq.eblock); - krb5_free_principal(ser_ctx, ctx->here); - krb5_free_principal(ser_ctx, ctx->there); - krb5_free_keyblock(ser_ctx, ctx->subkey); - - /* Zero out context */ - memset(ctx, 0, sizeof(*ctx)); - xfree(ctx); - } - if (*minor_status == 0) - *minor_status = (OM_uint32) kret; - return(retval); } diff --git a/src/lib/gssapi/krb5/indicate_mechs.c b/src/lib/gssapi/krb5/indicate_mechs.c index 0f78de219..bc53b4434 100644 --- a/src/lib/gssapi/krb5/indicate_mechs.c +++ b/src/lib/gssapi/krb5/indicate_mechs.c @@ -20,11 +20,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_indicate_mechs(ctx, minor_status, mech_set) - void *ctx; +krb5_gss_indicate_mechs(minor_status, mech_set) OM_uint32 *minor_status; gss_OID_set *mech_set; { diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 2b671680a..686384216 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -22,22 +22,25 @@ #include "gssapiP_krb5.h" #include <memory.h> -#include "k5-int.h" + +/* + * $Id$ + */ static krb5_error_code -make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, - do_mutual, flags, token) - void *ctx; +make_ap_req(context, auth_context, cred, server, endtime, chan_bindings, + req_flags, flags, mech_type, token) + krb5_context context; krb5_auth_context * auth_context; krb5_gss_cred_id_t cred; krb5_principal server; krb5_timestamp *endtime; gss_channel_bindings_t chan_bindings; - OM_uint32 do_mutual; + OM_uint32 req_flags; krb5_flags *flags; + gss_OID mech_type; gss_buffer_t token; { - krb5_context context = ctx; krb5_flags mk_req_flags = 0; krb5_error_code code; krb5_data checksum_data; @@ -46,19 +49,19 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, krb5_data ap_req; unsigned char *ptr; krb5_data credmsg; - unsigned char ckbuf[24]; /* see the token formats doc */ unsigned char *t; int tlen; krb5_int32 con_flags; ap_req.data = 0; checksum_data.data = 0; + credmsg.data = 0; /* build the checksum buffer */ /* compute the hash of the channel bindings */ - if ((code = kg_checksum_channel_bindings(chan_bindings, &md5, 0))) + if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0))) return(code); /* get an auth_context structure and fill in checksum type */ @@ -92,25 +95,31 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, return(KRB5KRB_ERR_FIELD_TOOLONG); } - /* now allocate a buffer to hold the checksum data and KRB_CRED msg - and write it */ + checksum_data.length = 28+credmsg.length; + } else { + checksum_data.length = 24; + } + + /* now allocate a buffer to hold the checksum data and + (maybe) KRB_CRED msg */ - if ((ptr = (unsigned char *) xmalloc(credmsg.length+28)) == NULL) { + if ((checksum_data.data = + (char *) xmalloc(checksum_data.length)) == NULL) { + if (credmsg.data) krb5_xfree(credmsg.data); - return(ENOMEM); - } + return(ENOMEM); + } - checksum_data.data = (char *) ptr; - checksum_data.length = credmsg.length+28; + ptr = checksum_data.data; - TWRITE_INT(ptr, md5.length, 0); - TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length); - TWRITE_INT(ptr, do_mutual?GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG - :GSS_C_DELEG_FLAG, 0); + TWRITE_INT(ptr, md5.length, 0); + TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length); + TWRITE_INT(ptr, KG_IMPLFLAGS(req_flags), 0); - /* done with this, free it */ - xfree(md5.contents); + /* done with this, free it */ + xfree(md5.contents); + if (credmsg.data) { TWRITE_INT16(ptr, KRB5_GSS_FOR_CREDS_OPTION, 0); TWRITE_INT16(ptr, credmsg.length, 0); TWRITE_STR(ptr, (unsigned char *) credmsg.data, credmsg.length); @@ -118,20 +127,6 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, /* free credmsg data */ krb5_xfree(credmsg.data); - - } else { - - ptr = ckbuf; - - TWRITE_INT(ptr, md5.length, 0); - TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length); - TWRITE_INT(ptr, do_mutual?GSS_C_MUTUAL_FLAG:0, 0); - - /* done with this, free it */ - xfree(md5.contents); - - checksum_data.data = (char *) ckbuf; - checksum_data.length = sizeof(ckbuf); } /* fill in the necessary fields in creds */ @@ -142,7 +137,7 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, goto cleanup; in_creds.times.endtime = *endtime; - in_creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; + /* * Get the credential..., I don't know in 0 is a good value for the * kdcoptions @@ -155,7 +150,7 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, mk_req_flags = AP_OPTS_USE_SUBKEY; - if (do_mutual) + if (req_flags & GSS_C_MUTUAL_FLAG) mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; if ((code = krb5_mk_req_extended(context, auth_context, mk_req_flags, @@ -169,7 +164,7 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, /* build up the token */ /* allocate space for the token */ - tlen = g_token_size((gss_OID) gss_mech_krb5, ap_req.length); + tlen = g_token_size((gss_OID) mech_type, ap_req.length); if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { code = ENOMEM; @@ -180,38 +175,38 @@ make_ap_req(ctx, auth_context, cred, server, endtime, chan_bindings, ptr = t; - g_make_token_header((gss_OID) gss_mech_krb5, ap_req.length, + g_make_token_header((gss_OID) mech_type, ap_req.length, &ptr, KG_TOK_CTX_AP_REQ); TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); /* pass it back */ + token->length = tlen; token->value = (void *) t; code = 0; cleanup: - if (checksum_data.data && checksum_data.data != (char *) ckbuf) - free(checksum_data.data); - krb5_free_cred_contents(context, &in_creds); - if (out_creds) - krb5_free_creds(context, out_creds); - if (ap_req.data) - xfree(ap_req.data); - if (code) - krb5_auth_con_free(context, *auth_context); - - return (code); + if (checksum_data.data) + free(checksum_data.data); + krb5_free_cred_contents(context, &in_creds); + if (out_creds) + krb5_free_creds(context, out_creds); + if (ap_req.data) + xfree(ap_req.data); + if (code) + krb5_auth_con_free(context, *auth_context); + + return (code); } OM_uint32 -krb5_gss_init_sec_context(ct, 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 *ct; +krb5_gss_init_sec_context(minor_status, claimant_cred_handle, + context_handle, target_name, mech_type, + req_flags, time_req, input_chan_bindings, + input_token, actual_mech_type, output_token, + ret_flags, time_rec) OM_uint32 *minor_status; gss_cred_id_t claimant_cred_handle; gss_ctx_id_t *context_handle; @@ -226,28 +221,25 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, OM_uint32 *ret_flags; OM_uint32 *time_rec; { - krb5_context context = ct; - krb5_gss_cred_id_t cred; - krb5_error_code code; - krb5_gss_ctx_id_rec *ctx; - krb5_timestamp now; - gss_buffer_desc token; - int i; + krb5_context context; + krb5_gss_cred_id_t cred; + krb5_error_code code; + krb5_gss_ctx_id_rec *ctx; + krb5_timestamp now; + krb5_enctype enctype; + gss_buffer_desc token; + int i; + int err; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); /* set up return values so they can be "freed" successfully */ output_token->length = 0; output_token->value = NULL; if (actual_mech_type) - *actual_mech_type = (gss_OID) gss_mech_krb5; - - /* verify the mech_type */ - - if ((mech_type != GSS_C_NULL_OID) && - (! g_OID_equal(mech_type, gss_mech_krb5))) { - *minor_status = 0; - return(GSS_S_BAD_MECH); - } + *actual_mech_type = NULL; /* verify the credential, or use the default */ /*SUPPRESS 29*/ @@ -267,6 +259,17 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, cred = (krb5_gss_cred_id_t) claimant_cred_handle; + /* verify the mech_type */ + + if (mech_type == GSS_C_NULL_OID) { + mech_type = cred->rfc_mech?gss_mech_krb5:gss_mech_krb5_old; + } else if ((g_OID_equal(mech_type, gss_mech_krb5) && !cred->rfc_mech) || + (g_OID_equal(mech_type, gss_mech_krb5_old) && + !cred->prerfc_mech)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + /* verify that the target_name is valid and usable */ if (! kg_validate_name(target_name)) { @@ -303,6 +306,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, /* fill in the ctx */ memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); + ctx->mech_used = mech_type; ctx->auth_context = NULL; ctx->initiate = 1; ctx->gss_flags = ((req_flags & (GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG)) | @@ -310,6 +314,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, ctx->flags = req_flags & GSS_C_DELEG_FLAG; ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ + ctx->seqstate = 0; if (time_req == 0 || time_req == GSS_C_INDEFINITE) { ctx->endtime = 0; @@ -338,8 +343,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, if ((code = make_ap_req(context, &(ctx->auth_context), cred, ctx->there, &ctx->endtime, input_chan_bindings, - ctx->gss_flags & GSS_C_MUTUAL_FLAG, &ctx->flags, - &token))) { + req_flags, &ctx->flags, mech_type, &token))) { krb5_free_principal(context, ctx->here); krb5_free_principal(context, ctx->there); xfree(ctx); @@ -354,9 +358,29 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, /* fill in the encryption descriptors */ + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; +#if 0 + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; +#endif + default: + return GSS_S_FAILURE; + } + /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ - krb5_use_enctype(context, &ctx->enc.eblock, ENCTYPE_DES_CBC_RAW); + krb5_use_enctype(context, &ctx->enc.eblock, enctype); ctx->enc.processed = 0; if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) return(code); @@ -364,7 +388,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, /*SUPPRESS 113*/ ctx->enc.key->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, ENCTYPE_DES_CBC_RAW); + krb5_use_enctype(context, &ctx->seq.eblock, enctype); ctx->seq.processed = 0; if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) return(code); @@ -390,7 +414,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, if (time_rec) { if ((code = krb5_timeofday(context, &now))) { xfree(token.value); - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t) ctx, NULL); *minor_status = code; return(GSS_S_FAILURE); @@ -405,7 +429,10 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, *output_token = token; if (ret_flags) - *ret_flags = ctx->gss_flags; + *ret_flags = KG_IMPLFLAGS(req_flags); + + if (actual_mech_type) + *actual_mech_type = mech_type; /* return successfully */ @@ -415,8 +442,11 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, return(GSS_S_CONTINUE_NEEDED); } else { ctx->seq_recv = ctx->seq_send; + g_order_init(&(ctx->seqstate), ctx->seq_recv, + req_flags & GSS_C_REPLAY_FLAG, + req_flags & GSS_C_SEQUENCE_FLAG); ctx->established = 1; - return(GSS_S_COMPLETE); + /* fall through to GSS_S_COMPLETE */ } } else { unsigned char *ptr; @@ -439,15 +469,16 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, if ((ctx->established) || (((gss_cred_id_t) cred) != claimant_cred_handle) || ((req_flags & GSS_C_MUTUAL_FLAG) == 0)) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + /* XXX this minor status is wrong if an arg was changed */ *minor_status = KG_CONTEXT_ESTABLISHED; return(GSS_S_FAILURE); } if (! krb5_principal_compare(context, ctx->there, (krb5_principal) target_name)) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); *minor_status = 0; return(GSS_S_BAD_NAME); @@ -456,7 +487,7 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, /* verify the token and leave the AP_REP message in ap_rep */ if (input_token == GSS_C_NO_BUFFER) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); *minor_status = 0; return(GSS_S_DEFECTIVE_TOKEN); @@ -464,10 +495,10 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, ptr = (unsigned char *) input_token->value; - if (! g_verify_token_header((gss_OID) gss_mech_krb5, &(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length)) { - *minor_status = 0; + if (err = g_verify_token_header((gss_OID) mech_type, &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length)) { + *minor_status = err; return(GSS_S_DEFECTIVE_TOKEN); } @@ -482,9 +513,9 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, * To be removed in 1999 -- proven */ krb5_auth_con_setuseruserkey(context,ctx->auth_context,ctx->subkey); - if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, - &ap_rep_data))) { - (void)krb5_gss_delete_sec_context(context, minor_status, + if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, + &ap_rep_data))) { + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); *minor_status = code; return(GSS_S_FAILURE); @@ -493,6 +524,9 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, /* store away the sequence number */ ctx->seq_recv = ap_rep_data->seq_number; + g_order_init(&(ctx->seqstate), ctx->seq_recv, + req_flags & GSS_C_REPLAY_FLAG, + req_flags & GSS_C_SEQUENCE_FLAG); /* free the ap_rep_data */ krb5_free_ap_rep_enc_part(context, ap_rep_data); @@ -504,20 +538,25 @@ krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, if (time_rec) { if ((code = krb5_timeofday(context, &now))) { - (void)krb5_gss_delete_sec_context(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t) ctx, NULL); *minor_status = code; return(GSS_S_FAILURE); - } + *time_rec = ctx->endtime - now; } if (ret_flags) - *ret_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_MUTUAL_FLAG; + *ret_flags = KG_IMPLFLAGS(req_flags); + + if (actual_mech_type) + *actual_mech_type = mech_type; /* success */ *minor_status = 0; - return(GSS_S_COMPLETE); + /* fall through to GSS_S_COMPLETE */ } + + return(GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c index c8499212f..5e5746344 100644 --- a/src/lib/gssapi/krb5/inq_context.c +++ b/src/lib/gssapi/krb5/inq_context.c @@ -23,10 +23,9 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_inquire_context(ct, minor_status, context_handle, initiator_name, +krb5_gss_inquire_context(minor_status, context_handle, initiator_name, acceptor_name, lifetime_rec, mech_type, ret_flags, locally_initiated, open) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_name_t *initiator_name; @@ -37,13 +36,16 @@ krb5_gss_inquire_context(ct, minor_status, context_handle, initiator_name, int *locally_initiated; int *open; { - krb5_context context = ct; + krb5_context context; krb5_error_code code; krb5_gss_ctx_id_rec *ctx; krb5_principal init, accept; krb5_timestamp now; krb5_deltat lifetime; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (initiator_name) *initiator_name = (gss_name_t) NULL; if (acceptor_name) @@ -116,7 +118,7 @@ krb5_gss_inquire_context(ct, minor_status, context_handle, initiator_name, *lifetime_rec = lifetime; if (mech_type) - *mech_type = (gss_OID) gss_mech_krb5; + *mech_type = (gss_OID) ctx->mech_used; if (ret_flags) *ret_flags = ctx->gss_flags; diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index e3e01bf4e..f9811c347 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -23,9 +23,8 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, +krb5_gss_inquire_cred(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; @@ -33,7 +32,7 @@ krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, gss_cred_usage_t *cred_usage; gss_OID_set *mechanisms; { - krb5_context context = ctx; + krb5_context context; krb5_gss_cred_id_t cred; krb5_error_code code; krb5_timestamp now; @@ -41,6 +40,9 @@ krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, krb5_principal ret_name; gss_OID_set mechs; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (name) *name = NULL; if (mechanisms) *mechanisms = NULL; @@ -82,7 +84,7 @@ krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, } if (mechanisms) - if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) { + if (! g_copy_OID_set(cred->actual_mechs, &mechs)) { krb5_free_principal(context, ret_name); *minor_status = ENOMEM; return(GSS_S_FAILURE); @@ -113,10 +115,9 @@ krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, /* V2 interface */ OM_uint32 -krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle, +krb5_gss_inquire_cred_by_mech(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; @@ -125,11 +126,14 @@ krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle, OM_uint32 *acceptor_lifetime; gss_cred_usage_t *cred_usage; { - krb5_context context = ctx; + krb5_context context; krb5_gss_cred_id_t cred; OM_uint32 lifetime; OM_uint32 mstat; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* * We only know how to handle our own creds. */ @@ -140,8 +144,7 @@ krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle, } cred = (krb5_gss_cred_id_t) cred_handle; - mstat = krb5_gss_inquire_cred(context, - minor_status, + mstat = krb5_gss_inquire_cred(minor_status, cred_handle, name, &lifetime, diff --git a/src/lib/gssapi/krb5/inq_names.c b/src/lib/gssapi/krb5/inq_names.c index fe61eb01a..948346dc6 100644 --- a/src/lib/gssapi/krb5/inq_names.c +++ b/src/lib/gssapi/krb5/inq_names.c @@ -28,19 +28,23 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_inquire_names_for_mech(context, minor_status, mechanism, name_types) - void *context; +krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) OM_uint32 *minor_status; gss_OID mechanism; gss_OID_set *name_types; { + krb5_context context; OM_uint32 major, minor; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* * We only know how to handle our own mechanism. */ if ((mechanism != GSS_C_NULL_OID) && - !g_OID_equal(gss_mech_krb5, mechanism)) { + !g_OID_equal(gss_mech_krb5, mechanism) && + !g_OID_equal(gss_mech_krb5_old, mechanism)) { *minor_status = 0; return(GSS_S_FAILURE); } diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index 4e5c78bd1..254d51680 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -21,11 +21,11 @@ */ #include "gssapiP_krb5.h" -#include "rsa-md5.h" static krb5_error_code make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, - encrypt, toktype, bigend) + signalg, cksum_size, sealalg, encrypt, toktype, + bigend, oid) krb5_context context; krb5_gss_enc_desc *enc_ed; krb5_gss_enc_desc *seq_ed; @@ -33,29 +33,36 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, int direction; gss_buffer_t text; gss_buffer_t token; + int signalg; + int cksum_size; + int sealalg; int encrypt; int toktype; int bigend; + gss_OID oid; { krb5_error_code code; - krb5_MD5_CTX md5; - krb5_checksum desmac; - krb5_octet cbc_checksum[KRB5_MIT_DES_KEYSIZE]; - int tmsglen, tlen; + char *data_ptr; + krb5_checksum md5cksum; + krb5_checksum cksum; + int conflen, tmsglen, tlen; unsigned char *t, *ptr; /* create the token buffer */ - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) { - if (bigend && !encrypt) + if (toktype == KG_TOK_SEAL_MSG) { + if (bigend && !encrypt) { tmsglen = text->length; - else - tmsglen = (kg_confounder_size(enc_ed)+text->length+8)&(~7); + } else { + conflen = kg_confounder_size(enc_ed); + /* XXX knows that des block size is 8 */ + tmsglen = (conflen+text->length+8)&(~7); + } } else { tmsglen = 0; } - tlen = g_token_size((gss_OID) gss_mech_krb5, 22+tmsglen); + tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); if ((t = (unsigned char *) xmalloc(tlen)) == NULL) return(ENOMEM); @@ -64,104 +71,192 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, ptr = t; - g_make_token_header((gss_OID) gss_mech_krb5, 22+tmsglen, &ptr, toktype); + g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); - /* for now, only generate DES integrity */ + /* 0..1 SIGN_ALG */ - ptr[0] = 0; + ptr[0] = signalg; ptr[1] = 0; + + /* 2..3 SEAL_ALG or Filler */ - /* SEAL_ALG, or filler */ - - if (((toktype == KG_TOK_SEAL_MSG) || - (toktype == KG_TOK_WRAP_MSG)) && encrypt) { - ptr[2] = 0; + if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { + ptr[2] = sealalg; ptr[3] = 0; } else { + /* No seal */ ptr[2] = 0xff; ptr[3] = 0xff; } - /* filler */ + /* 4..5 Filler */ ptr[4] = 0xff; ptr[5] = 0xff; /* pad the plaintext, encrypt if needed, and stick it in the token */ - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) { + /* initialize the the cksum and allocate the contents buffer */ + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); + if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { + return(ENOMEM); + } + + if (toktype == KG_TOK_SEAL_MSG) { unsigned char *plain; unsigned char pad; - if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - xfree(t); - return(ENOMEM); - } + if (!bigend || encrypt) { + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + xfree(md5cksum.contents); + xfree(t); + return(ENOMEM); + } - if (code = kg_make_confounder(enc_ed, plain)) { - xfree(plain); - xfree(t); - return(code); - } + if (code = kg_make_confounder(enc_ed, plain)) { + xfree(plain); + xfree(md5cksum.contents); + xfree(t); + return(code); + } - memcpy(plain+8, text->value, text->length); + memcpy(plain+conflen, text->value, text->length); - pad = 8-(text->length%8); + /* XXX 8 is DES cblock size */ + pad = 8-(text->length%8); - memset(plain+8+text->length, pad, pad); + memset(plain+conflen+text->length, pad, pad); + } else { + /* plain is never used in the bigend && !encrypt case */ + plain = NULL; + } if (encrypt) { - if (code = kg_encrypt(enc_ed, NULL, (krb5_pointer) plain, - (krb5_pointer) (ptr+22), tmsglen)) { - xfree(plain); + if (code = kg_encrypt(context, enc_ed, NULL, (krb5_pointer) plain, + (krb5_pointer) (ptr+cksum_size+14), tmsglen)) { + if (plain) + xfree(plain); + xfree(md5cksum.contents); xfree(t); return(code); } } else { if (bigend) - memcpy(ptr+22, text->value, text->length); + memcpy(ptr+14+cksum_size, text->value, text->length); else - memcpy(ptr+22, plain, tmsglen); + memcpy(ptr+14+cksum_size, plain, tmsglen); } /* compute the checksum */ - krb5_MD5Init(&md5); - krb5_MD5Update(&md5, (unsigned char *) ptr-2, 8); + /* 8 = head of token body as specified by mech spec */ + if (! (data_ptr = + (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { + if (plain) + xfree(plain); + xfree(md5cksum.contents); + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); if (bigend) - krb5_MD5Update(&md5, text->value, text->length); + (void) memcpy(data_ptr+8, text->value, text->length); else - krb5_MD5Update(&md5, plain, tmsglen); - krb5_MD5Final(&md5); + (void) memcpy(data_ptr+8, plain, tmsglen); + code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, + 8 + (bigend ? text->length : tmsglen), + 0, 0, &md5cksum); + xfree(data_ptr); + + if (code) { + if (plain) + xfree(plain); + xfree(md5cksum.contents); + xfree(t); + return(code); + memcpy(ptr+14+cksum_size, plain, tmsglen); + } - xfree(plain); + if (plain) + xfree(plain); } else { /* compute the checksum */ - krb5_MD5Init(&md5); - krb5_MD5Update(&md5, (unsigned char *) ptr-2, 8); - krb5_MD5Update(&md5, text->value, text->length); - krb5_MD5Final(&md5); + if (! (data_ptr = (char *) xmalloc(8 + text->length))) { + xfree(md5cksum.contents); + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, text->value, text->length); + code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, + 8 + text->length, + 0, 0, &md5cksum); + xfree(data_ptr); + if (code) { + xfree(md5cksum.contents); + xfree(t); + return(code); + } } - /* XXX this depends on the key being a single-des key, but that's - all that kerberos supports right now */ - - desmac.length = sizeof(cbc_checksum); - desmac.contents = cbc_checksum; - if (code = krb5_calculate_checksum(context, CKSUMTYPE_DESCBC, md5.digest, 16, - seq_ed->key->contents, - seq_ed->key->length, - &desmac)) { - xfree(t); - return(code); + switch(signalg) { + case 0: + case 3: + +#if 0 + /* XXX this depends on the key being a single-des key */ + + /* DES CBC doesn't use a zero IV like it should in some + krb5 implementations (beta5+). So we just do the + DES encryption the long way, and keep the last block + as the MAC */ + + /* initialize the the cksum and allocate the contents buffer */ + cksum.checksum_type = CKSUMTYPE_DESCBC; + cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); + if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) + return(ENOMEM); + + if (code = krb5_calculate_checksum(context, cksum.checksum_type, + md5cksum.contents, 16, + seq_ed->key->contents, + seq_ed->key->length, + &cksum)) { + xfree(cksum.contents); + xfree(md5cksum.contents); + xfree(t); + return(code); + } + + memcpy(ptr+14, cksum.contents, 8); + + xfree(cksum.contents); +#else + if (code = kg_encrypt(context, seq_ed, + (g_OID_equal(oid, gss_mech_krb5_old) ? + seq_ed->key->contents : NULL), + md5cksum.contents, md5cksum.contents, 16)) { + xfree(md5cksum.contents); + xfree(t); + return code; + } + + cksum.length = cksum_size; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + memcpy(ptr+14, cksum.contents, cksum.length); +#endif + + break; } - memcpy(ptr+14, desmac.contents, 8); + xfree(md5cksum.contents); /* create the seq_num */ - if (code = kg_make_seq_num(seq_ed, direction?0:0xff, *seqnum, + if (code = kg_make_seq_num(context, seq_ed, direction?0:0xff, *seqnum, ptr+14, ptr+6)) { xfree(t); return(code); @@ -227,60 +322,16 @@ kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, if (code = make_seal_token(context, &ctx->enc, &ctx->seq, &ctx->seq_send, ctx->initiate, input_message_buffer, output_message_buffer, - conf_req_flag, toktype, ctx->big_endian)) { + ctx->signalg, ctx->cksum_size, ctx->sealalg, + conf_req_flag, toktype, ctx->big_endian, + ctx->mech_used)) { *minor_status = code; return(GSS_S_FAILURE); } - if (((toktype == KG_TOK_SEAL_MSG) || - (toktype == KG_TOK_WRAP_MSG)) && conf_state) { + if ((toktype == KG_TOK_SEAL_MSG) && conf_state) *conf_state = conf_req_flag; - } *minor_status = 0; return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } - -OM_uint32 -kg_seal_size(context, minor_status, context_handle, conf_req_flag, qop_req, - output_size, input_size) - krb5_context context; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int conf_req_flag; - gss_qop_t qop_req; - OM_uint32 output_size; - OM_uint32 *input_size; -{ - krb5_gss_ctx_id_rec *ctx; - OM_uint32 cfsize; - OM_uint32 ohlen; - - /* only default qop is allowed */ - if (qop_req != GSS_C_QOP_DEFAULT) { - *minor_status = (OM_uint32) G_UNKNOWN_QOP; - return(GSS_S_FAILURE); - } - - /* validate the context handle */ - 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); - } - - /* Calculate the token size and subtract that from the output size */ - cfsize = (conf_req_flag) ? kg_confounder_size(&ctx->enc) : 0; - ohlen = g_token_size((gss_OID) gss_mech_krb5, (unsigned int) cfsize + 22); - - /* Cannot have trailer length that will cause us to pad over our length */ - *input_size = (output_size - ohlen) & (~7); - *minor_status = 0; - return(GSS_S_COMPLETE); -} - diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 1b4288c0c..70d2d4d7b 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -22,7 +22,10 @@ #include "gssapiP_krb5.h" #include <memory.h> -#include "rsa-md5.h" + +/* + * $Id$ + */ /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX conf_state is only valid if SEAL. @@ -44,19 +47,25 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, krb5_error_code code; int bodysize; int tmsglen; + int conflen; int signalg; int sealalg; gss_buffer_desc token; unsigned char *ptr; + krb5_checksum cksum; krb5_checksum desmac; - krb5_octet cbc_checksum[KRB5_MIT_DES_KEYSIZE]; - krb5_MD5_CTX md5; - unsigned char *cksum; + krb5_checksum md5cksum; + char *data_ptr; krb5_timestamp now; unsigned char *plain; + int cksum_len; int plainlen; + int err; + int direction; + krb5_int32 seqnum; + OM_uint32 retval; - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) { + if (toktype == KG_TOK_SEAL_MSG) { message_buffer->length = 0; message_buffer->value = NULL; } @@ -80,73 +89,109 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, ptr = (unsigned char *) input_token_buffer->value; - if (! g_verify_token_header((gss_OID) gss_mech_krb5, &bodysize, - &ptr, toktype, input_token_buffer->length)) { - *minor_status = 0; + if (err = g_verify_token_header((gss_OID) ctx->mech_used, &bodysize, + &ptr, toktype, + input_token_buffer->length)) { + *minor_status = err; return(GSS_S_DEFECTIVE_TOKEN); } - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) - tmsglen = bodysize-22; - /* get the sign and seal algorithms */ signalg = ptr[0] + (ptr[1]<<8); sealalg = ptr[2] + (ptr[3]<<8); - if (((signalg != 0) && (signalg != 1)) || - (((toktype != KG_TOK_SEAL_MSG) && - (toktype != KG_TOK_WRAP_MSG)) && (sealalg != 0xffff)) || - (((toktype == KG_TOK_SEAL_MSG) || - (toktype == KG_TOK_WRAP_MSG)) && - ((sealalg != 0xffff) && (sealalg != 0))) || - (ptr[4] != 0xff) || - (ptr[5] != 0xff)) { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); + /* Sanity checks */ + + if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } + if ((toktype != KG_TOK_SEAL_MSG) && + (sealalg != 0xffff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + /* in the current spec, there is only one valid seal algorithm per + key type, so a simple comparison is ok */ + + if ((toktype == KG_TOK_SEAL_MSG) && + !((sealalg == 0xffff) || + (sealalg == ctx->sealalg))) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + /* there are several mappings of seal algorithms to sign algorithms, + but few enough that we can try them all. */ + + if (((ctx->sealalg == 0) && + (signalg > 1)) || + ((ctx->sealalg == 1) && + (signalg != 3))) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + switch (signalg) { + case 0: + case 1: + cksum_len = 8; + break; + case 3: + cksum_len = 16; + break; + } + + if (toktype == KG_TOK_SEAL_MSG) + tmsglen = bodysize-(14+cksum_len); + /* get the token parameters */ /* decode the message, if SEAL */ - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) { - if (sealalg == 0) { + if (toktype == KG_TOK_SEAL_MSG) { + if (sealalg != 0xffff) { if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { *minor_status = ENOMEM; return(GSS_S_FAILURE); } - if (code = kg_decrypt(&ctx->enc, NULL, ptr+22, plain, tmsglen)) { + if (code = kg_decrypt(context, &ctx->enc, NULL, + ptr+14+cksum_len, plain, tmsglen)) { xfree(plain); *minor_status = code; return(GSS_S_FAILURE); } } else { - plain = ptr+22; + plain = ptr+14+cksum_len; } plainlen = tmsglen; - if (sealalg && ctx->big_endian) + if ((sealalg == 0xffff) && ctx->big_endian) { token.length = tmsglen; - else - token.length = tmsglen - 8 - plain[tmsglen-1]; + } else { + conflen = kg_confounder_size(&ctx->enc); + token.length = tmsglen - conflen - plain[tmsglen-1]; + } if (token.length) { - if ((token.value = xmalloc(token.length)) == NULL) { - if (sealalg == 0) + if ((token.value = (void *) xmalloc(token.length)) == NULL) { + if (sealalg != 0xffff) xfree(plain); *minor_status = ENOMEM; return(GSS_S_FAILURE); } - if (sealalg && ctx->big_endian) + if ((sealalg == 0xffff) && ctx->big_endian) memcpy(token.value, plain, token.length); else - memcpy(token.value, plain+8, token.length); + memcpy(token.value, plain+conflen, token.length); } - } else if ((toktype == KG_TOK_SIGN_MSG) || (toktype == KG_TOK_MIC_MSG)) { + } else if (toktype == KG_TOK_SIGN_MSG) { token = *message_buffer; plain = token.value; plainlen = token.length; @@ -159,81 +204,184 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, /* compute the checksum of the message */ - if (signalg == 0) { + /* initialize the the cksum and allocate the contents buffer */ + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); + if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { + if (sealalg != 0xffff) + xfree(plain); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + switch (signalg) { + case 0: + case 3: /* compute the checksum of the message */ - krb5_MD5Init(&md5); - krb5_MD5Update(&md5, (unsigned char *) ptr-2, 8); + /* 8 = bytes of token body to be checksummed according to spec */ + + if (! (data_ptr = (void *) + xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + (void) memcpy(data_ptr, ptr-2, 8); + if (ctx->big_endian) - krb5_MD5Update(&md5, token.value, token.length); + (void) memcpy(data_ptr+8, token.value, token.length); else - krb5_MD5Update(&md5, plain, plainlen); - krb5_MD5Final(&md5); - - if (sealalg == 0) - xfree(plain); + (void) memcpy(data_ptr+8, plain, plainlen); + + code = krb5_calculate_checksum(context, md5cksum.checksum_type, + data_ptr, 8 + + (ctx->big_endian ? token.length : + plainlen), 0, 0, &md5cksum); + xfree(data_ptr); + + if (code) { + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } +#if 0 /* XXX this depends on the key being a single-des key, but that's all that kerberos supports right now */ - desmac.length = sizeof(cbc_checksum); - desmac.contents = cbc_checksum; - if (code = krb5_calculate_checksum(context, CKSUMTYPE_DESCBC, md5.digest, - 16, ctx->seq.key->contents, + + /* initialize the the cksum and allocate the contents buffer */ + cksum.checksum_type = CKSUMTYPE_DESCBC; + cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); + if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) { + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + if (code = krb5_calculate_checksum(context, cksum.checksum_type, + md5cksum.contents, 16, + ctx->seq.key->contents, ctx->seq.key->length, - &desmac)) { - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) + &cksum)) { + xfree(cksum.contents); + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); *minor_status = code; return(GSS_S_FAILURE); } - cksum = desmac.contents; - } else { - if (! ctx->seed_init) { - if (code = kg_make_seed(ctx->subkey, ctx->seed)) { - if (sealalg == 0) + code = memcmp(cksum.contents, ptr+14, cksum.length); + + xfree(cksum.contents); +#else + if (code = kg_encrypt(context, &ctx->seq, + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? + ctx->seq.key->contents : NULL), + md5cksum.contents, md5cksum.contents, 16)) { + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return GSS_S_FAILURE; + } + + if (signalg == 0) + cksum.length = 8; + else + cksum.length = 16; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + code = memcmp(cksum.contents, ptr+14, cksum.length); +#endif + break; + + case 1: + if (!ctx->seed_init && + (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { + xfree(md5cksum.contents); + if (sealalg != 0xffff) xfree(plain); - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) + if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - ctx->seed_init = 1; + *minor_status = code; + return GSS_S_FAILURE; + } + + if (! (data_ptr = (void *) + xmalloc(sizeof(ctx->seed) + 8 + + (ctx->big_endian ? token.length : plainlen)))) { + xfree(md5cksum.contents); + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); } - - krb5_MD5Init(&md5); - krb5_MD5Update(&md5, ctx->seed, sizeof(ctx->seed)); - krb5_MD5Update(&md5, (unsigned char *) ptr-2, 8); + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); if (ctx->big_endian) - krb5_MD5Update(&md5, token.value, token.length); + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + token.value, token.length); else - krb5_MD5Update(&md5, plain, plainlen); - krb5_MD5Final(&md5); + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + plain, plainlen); + code = krb5_calculate_checksum(context, md5cksum.checksum_type, + data_ptr, 8 + sizeof(ctx->seed) + + (ctx->big_endian ? token.length : + plainlen), 0, 0, &md5cksum); + + xfree(data_ptr); + + if (code) { + xfree(md5cksum.contents); + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - if (sealalg == 0) - xfree(plain); + code = memcmp(md5cksum.contents, ptr+14, 8); - cksum = md5.digest; + default: + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); } - + + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); + /* compare the computed checksum against the transmitted checksum */ - if (memcmp(cksum, ptr+14, 8) != 0) { - if ((toktype == KG_TOK_SEAL_MSG) || (toktype == KG_TOK_WRAP_MSG)) + if (code) { + if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); *minor_status = 0; return(GSS_S_BAD_SIG); } + - /* XXX this is where the seq_num check would go */ - /* it got through unscathed. Make sure the context is unexpired */ - if ((toktype == KG_TOK_SEAL_MSG) || (toktype = KG_TOK_WRAP_MSG)) + if (toktype == KG_TOK_SEAL_MSG) *message_buffer = token; if (conf_state) - *conf_state = (sealalg == 0); + *conf_state = (sealalg != 0xffff); if (qop_state) *qop_state = GSS_C_QOP_DEFAULT; @@ -248,8 +396,28 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, return(GSS_S_CONTEXT_EXPIRED); } - /* success */ + /* do sequencing checks */ + + if (code = kg_get_seq_num(context, &(ctx->seq), ptr+14, ptr+6, &direction, + &seqnum)) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_BAD_SIG); + } + + if ((ctx->initiate && direction != 0xff) || + (!ctx->initiate && direction != 0)) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + retval = g_order_check(&(ctx->seqstate), seqnum); + + /* success or ordering violation */ *minor_status = 0; - return(GSS_S_COMPLETE); + return(retval); } diff --git a/src/lib/gssapi/krb5/krb5_gss_glue.c b/src/lib/gssapi/krb5/krb5_gss_glue.c new file mode 100644 index 000000000..f22e9d633 --- /dev/null +++ b/src/lib/gssapi/krb5/krb5_gss_glue.c @@ -0,0 +1,538 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_krb5.h" + +OM_uint32 INTERFACE +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; +{ + return(krb5_gss_accept_sec_context(minor_status, + context_handle, + verifier_cred_handle, + input_token, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle)); +} + +OM_uint32 INTERFACE +gss_acquire_cred(minor_status, desired_name, time_req, desired_mechs, + cred_usage, output_cred_handle, actual_mechs, time_rec) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +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) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_add_oid_set_member(minor_status, member_oid, oid_set) + 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)); +} + +OM_uint32 INTERFACE +gss_compare_name(minor_status, name1, name2, name_equal) + OM_uint32 *minor_status; + gss_name_t name1; + gss_name_t name2; + int *name_equal; +{ + return(krb5_gss_compare_name(minor_status, name1, + name2, name_equal)); +} + +OM_uint32 INTERFACE +gss_context_time(minor_status, context_handle, time_rec) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + return(generic_gss_create_empty_oid_set(minor_status, oid_set)); +} + +OM_uint32 INTERFACE +gss_delete_sec_context(minor_status, context_handle, output_token) + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_buffer_t output_token; +{ + return(krb5_gss_delete_sec_context(minor_status, + context_handle, output_token)); +} + +OM_uint32 INTERFACE +gss_display_name(minor_status, input_name, output_name_buffer, output_name_type) + OM_uint32 *minor_status; + gss_name_t input_name; + gss_buffer_t output_name_buffer; + gss_OID *output_name_type; +{ + return(krb5_gss_display_name(minor_status, input_name, + output_name_buffer, output_name_type)); +} + +OM_uint32 INTERFACE +gss_display_status(minor_status, status_value, status_type, + mech_type, message_context, status_string) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_export_sec_context(minor_status, context_handle, interprocess_token) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_get_mic(minor_status, context_handle, qop_req, + message_buffer, message_token) + 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)); +} + +OM_uint32 INTERFACE +gss_import_name(minor_status, input_name_buffer, input_name_type, output_name) + OM_uint32 *minor_status; + gss_buffer_t input_name_buffer; + gss_OID input_name_type; + gss_name_t *output_name; +{ + return(krb5_gss_import_name(minor_status, input_name_buffer, + input_name_type, output_name)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_import_sec_context(minor_status, interprocess_token, context_handle) + 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)); +} + +OM_uint32 INTERFACE +gss_indicate_mechs(minor_status, mech_set) + OM_uint32 *minor_status; + gss_OID_set *mech_set; +{ + return(krb5_gss_indicate_mechs(minor_status, mech_set)); +} + +OM_uint32 INTERFACE +gss_init_sec_context(minor_status, claimant_cred_handle, context_handle, + target_name, mech_type, req_flags, time_req, + input_chan_bindings, input_token, actual_mech_type, + output_token, ret_flags, time_rec) + OM_uint32 *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)); +} + +OM_uint32 INTERFACE +gss_inquire_context(minor_status, context_handle, initiator_name, acceptor_name, + lifetime_rec, mech_type, ret_flags, + locally_initiated, open) + 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; +{ + return(krb5_gss_inquire_context(minor_status, context_handle, + initiator_name, acceptor_name, lifetime_rec, + mech_type, ret_flags, locally_initiated, + open)); +} + +OM_uint32 INTERFACE +gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, + cred_usage, mechanisms) + 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; +{ + return(krb5_gss_inquire_cred(minor_status, cred_handle, + name, lifetime_ret, cred_usage, mechanisms)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, + initiator_lifetime, acceptor_lifetime, cred_usage) + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_inquire_names_for_mech(minor_status, mechanism, name_types) + OM_uint32 *minor_status; + gss_OID mechanism; + gss_OID_set *name_types; +{ + return(krb5_gss_inquire_names_for_mech(minor_status, + mechanism, + name_types)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + return(generic_gss_oid_to_str(minor_status, oid, oid_str)); +} + +OM_uint32 INTERFACE +gss_process_context_token(minor_status, context_handle, token_buffer) + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t token_buffer; +{ + return(krb5_gss_process_context_token(minor_status, + context_handle, token_buffer)); +} + +OM_uint32 INTERFACE +gss_release_cred(minor_status, cred_handle) + OM_uint32 *minor_status; + gss_cred_id_t *cred_handle; +{ + return(krb5_gss_release_cred(minor_status, cred_handle)); +} + +OM_uint32 INTERFACE +gss_release_name(minor_status, input_name) + OM_uint32 *minor_status; + gss_name_t *input_name; +{ + return(krb5_gss_release_name(minor_status, input_name)); +} + +OM_uint32 INTERFACE +gss_release_buffer(minor_status, buffer) + OM_uint32 *minor_status; + gss_buffer_t buffer; +{ + return(generic_gss_release_buffer(minor_status, + buffer)); +} + +#if 0 +/* V2 */ +OM_uint32 INTERFACE +gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + return(krb5_gss_release_oid(minor_status, oid)); +} +#endif + +OM_uint32 INTERFACE +gss_release_oid_set(minor_status, set) + OM_uint32* minor_status; + gss_OID_set *set; +{ + return(generic_gss_release_oid_set(minor_status, set)); +} + +/* V1 only */ +OM_uint32 INTERFACE +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(krb5_gss_seal(minor_status, context_handle, + conf_req_flag, qop_req, input_message_buffer, + conf_state, output_message_buffer)); +} + +OM_uint32 INTERFACE +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(krb5_gss_sign(minor_status, context_handle, + qop_req, message_buffer, message_token)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_verify_mic(minor_status, context_handle, + message_buffer, token_buffer, qop_state) + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t message_buffer; + gss_buffer_t token_buffer; + gss_qop_t *qop_state; +{ + return(krb5_gss_verify_mic(minor_status, context_handle, + message_buffer, token_buffer, qop_state)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_wrap(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; + 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)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + return(generic_gss_str_to_oid(minor_status, oid_str, oid)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_test_oid_set_member(minor_status, member, set, present) + 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)); +} + +/* V1 only */ +OM_uint32 INTERFACE +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(krb5_gss_unseal(minor_status, context_handle, + input_message_buffer, output_message_buffer, + conf_state, qop_state)); +} + +/* V2 */ +OM_uint32 INTERFACE +gss_unwrap(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; + gss_qop_t *qop_state; +{ + return(krb5_gss_unwrap(minor_status, context_handle, input_message_buffer, + output_message_buffer, conf_state, qop_state)); +} + +/* V1 only */ +OM_uint32 INTERFACE +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(krb5_gss_verify(minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state)); +} + +/* V2 interface */ +OM_uint32 INTERFACE +gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, + qop_req, req_output_size, max_input_size) + 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)); +} diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c index 80affbd27..4639108d5 100644 --- a/src/lib/gssapi/krb5/process_context_token.c +++ b/src/lib/gssapi/krb5/process_context_token.c @@ -22,18 +22,24 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_process_context_token(ct, minor_status, context_handle, +krb5_gss_process_context_token(minor_status, context_handle, token_buffer) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t token_buffer; { - krb5_context context = ct; + krb5_context context; krb5_gss_ctx_id_rec *ctx; OM_uint32 majerr; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; @@ -56,6 +62,6 @@ krb5_gss_process_context_token(ct, minor_status, context_handle, /* that's it. delete the context */ - return(krb5_gss_delete_sec_context(context, minor_status, &context_handle, + return(krb5_gss_delete_sec_context(minor_status, &context_handle, GSS_C_NO_BUFFER)); } diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c index 297699fe1..df301987b 100644 --- a/src/lib/gssapi/krb5/rel_cred.c +++ b/src/lib/gssapi/krb5/rel_cred.c @@ -23,15 +23,17 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_release_cred(ctx, minor_status, cred_handle) - void *ctx; +krb5_gss_release_cred(minor_status, cred_handle) OM_uint32 *minor_status; gss_cred_id_t *cred_handle; { - krb5_context context = ctx; + krb5_context context; krb5_gss_cred_id_t cred; krb5_error_code code1, code2; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (*cred_handle == GSS_C_NO_CREDENTIAL) return(kg_release_defcred(minor_status)); diff --git a/src/lib/gssapi/krb5/rel_name.c b/src/lib/gssapi/krb5/rel_name.c index 40ff0d2d3..56f56d060 100644 --- a/src/lib/gssapi/krb5/rel_name.c +++ b/src/lib/gssapi/krb5/rel_name.c @@ -23,13 +23,15 @@ #include "gssapiP_krb5.h" OM_uint32 -krb5_gss_release_name(ctx, minor_status, input_name) - void *ctx; +krb5_gss_release_name(minor_status, input_name) OM_uint32 *minor_status; gss_name_t *input_name; { - krb5_context context = ctx; + krb5_context context; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + if (! kg_validate_name(*input_name)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); diff --git a/src/lib/gssapi/krb5/rel_oid.c b/src/lib/gssapi/krb5/rel_oid.c index 32e697ace..d5ec7bcc7 100644 --- a/src/lib/gssapi/krb5/rel_oid.c +++ b/src/lib/gssapi/krb5/rel_oid.c @@ -73,6 +73,7 @@ krb5_gss_internal_release_oid(ct, minor_status, oid) */ if ((*oid != gss_mech_krb5) && + (*oid != gss_mech_krb5_old) && (*oid != gss_nt_krb5_name) && (*oid != gss_nt_krb5_principal)) { /* We don't know about this OID */ diff --git a/src/lib/gssapi/krb5/seal.c b/src/lib/gssapi/krb5/seal.c index ca52a60af..818de191f 100644 --- a/src/lib/gssapi/krb5/seal.c +++ b/src/lib/gssapi/krb5/seal.c @@ -22,11 +22,14 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_seal(ctx, minor_status, context_handle, conf_req_flag, +krb5_gss_seal(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; @@ -35,7 +38,11 @@ krb5_gss_seal(ctx, minor_status, context_handle, conf_req_flag, int *conf_state; gss_buffer_t output_message_buffer; { - krb5_context context = ctx; + krb5_context context; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + return(kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, KG_TOK_SEAL_MSG)); @@ -43,10 +50,9 @@ krb5_gss_seal(ctx, minor_status, context_handle, conf_req_flag, /* V2 interface */ OM_uint32 -krb5_gss_wrap(ctx, minor_status, context_handle, conf_req_flag, +krb5_gss_wrap(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; @@ -55,28 +61,13 @@ krb5_gss_wrap(ctx, minor_status, context_handle, conf_req_flag, int *conf_state; gss_buffer_t output_message_buffer; { - krb5_context context = ctx; + krb5_context context; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + return(kg_seal(context, minor_status, context_handle, conf_req_flag, (int) qop_req, input_message_buffer, conf_state, output_message_buffer, KG_TOK_WRAP_MSG)); } -/* V2 interface */ -OM_uint32 -krb5_gss_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; -{ - krb5_context context = ctx; - - /* XXX - should just put this in k5seal.c */ - return(kg_seal_size(context, minor_status, context_handle, conf_req_flag, - qop_req, req_output_size, max_input_size)); -} diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 5acfd5c67..2a8cd0dd0 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -28,264 +28,17 @@ #include "gssapiP_krb5.h" /* - * This module contains routines to [de]serialize krb5_gss_cred_id_t, + * This module contains routines to [de]serialize * krb5_gss_enc_desc and krb5_gss_ctx_id_t. + * XXX This whole serialization abstraction is unnecessary in a + * non-messaging environment, which krb5 is. Someday, this should + * all get redone without the extra level of indirection. I've done + * some of this work here, since adding new serializers is an internal + * krb5 interface, and I won't use those. There is some more + * deobfuscation (no longer anonymizing pointers, mostly) which could + * still be done. --marc */ - -/* Windows needs these prototypes since the structure they're assigned - * into is prototyped. - */ -static krb5_error_code kg_cred_size - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - size_t *sizep)); - -static krb5_error_code kg_cred_externalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - krb5_octet **buffer, - size_t *lenremain)); - -static krb5_error_code kg_cred_internalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer *argp, - krb5_octet **buffer, - size_t *lenremain)); - -static krb5_error_code kg_enc_desc_size - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - size_t *sizep)); - -static krb5_error_code kg_enc_desc_externalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - krb5_octet **buffer, - size_t *lenremain)); - -static krb5_error_code kg_enc_desc_internalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer *argp, - krb5_octet **buffer, - size_t *lenremain)); - -static krb5_error_code kg_ctx_size - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - size_t *sizep)); - -static krb5_error_code kg_ctx_externalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer arg, - krb5_octet **buffer, - size_t *lenremain)); - -static krb5_error_code kg_ctx_internalize - PROTOTYPE((krb5_context kcontext, - krb5_pointer *argp, - krb5_octet **buffer, - size_t *lenremain)); - -/* - * Determine the size required for this krb5_gss_cred_id_t. - */ -static krb5_error_code -kg_cred_size(kcontext, arg, sizep) - krb5_context kcontext; - krb5_pointer arg; - size_t *sizep; -{ - krb5_error_code kret; - krb5_gss_cred_id_t cred; - size_t required; - - /* - * krb5_gss_cred_id_t requires: - * krb5_int32 for KG_CRED - * krb5_int32 for usage. - * krb5_int32 for tgt_expire. - * krb5_int32 for trailer. - */ - kret = EINVAL; - if ((cred = (krb5_gss_cred_id_t) arg)) { - required = 4*sizeof(krb5_int32); - kret = 0; - if (cred->princ) - kret = krb5_size_opaque(kcontext, - KV5M_PRINCIPAL, - (krb5_pointer) cred->princ, - &required); - if (!kret && cred->keytab) - kret = krb5_size_opaque(kcontext, - KV5M_KEYTAB, - (krb5_pointer) cred->keytab, - &required); - - if (!kret && cred->ccache) - kret = krb5_size_opaque(kcontext, - KV5M_CCACHE, - (krb5_pointer) cred->ccache, - &required); - if (!kret) - *sizep += required; - } - return(kret); -} - -/* - * Externalize this krb5_gss_cred_id_t. - */ -static krb5_error_code -kg_cred_externalize(kcontext, arg, buffer, lenremain) - krb5_context kcontext; - krb5_pointer arg; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_cred_id_t cred; - size_t required; - krb5_octet *bp; - size_t remain; - - required = 0; - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - if ((cred = (krb5_gss_cred_id_t) arg)) { - kret = ENOMEM; - if (!kg_cred_size(kcontext, arg, &required) && - (required <= remain)) { - /* Our identifier */ - (void) krb5_ser_pack_int32(KG_CRED, &bp, &remain); - - /* Now static data */ - (void) krb5_ser_pack_int32((krb5_int32) cred->usage, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) cred->tgt_expire, - &bp, &remain); - - /* Now pack up dynamic data */ - if (cred->princ) - kret = krb5_externalize_opaque(kcontext, - KV5M_PRINCIPAL, - (krb5_pointer) cred->princ, - &bp, &remain); - else - kret = 0; - - if (!kret && cred->keytab) - kret = krb5_externalize_opaque(kcontext, - KV5M_KEYTAB, - (krb5_pointer) cred->keytab, - &bp, &remain); - - if (!kret && cred->ccache) - kret = krb5_externalize_opaque(kcontext, - KV5M_CCACHE, - (krb5_pointer) cred->ccache, - &bp, &remain); - - if (!kret) { - (void) krb5_ser_pack_int32(KG_CRED, &bp, &remain); - *buffer = bp; - *lenremain = remain; - } - } - } - return(kret); -} - -/* - * Internalize this krb5_gss_cred_id_t. - */ -static krb5_error_code -kg_cred_internalize(kcontext, argp, buffer, lenremain) - krb5_context kcontext; - krb5_pointer *argp; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_cred_id_t cred; - krb5_int32 ibuf; - krb5_octet *bp; - size_t remain; - - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - /* Read our magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - ibuf = 0; - if (ibuf == KG_CRED) { - kret = ENOMEM; - - /* Get a cred */ - if ((remain >= (2*sizeof(krb5_int32))) && - (cred = (krb5_gss_cred_id_t) - xmalloc(sizeof(krb5_gss_cred_id_rec)))) { - memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); - - /* Get the static data */ - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - cred->usage = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - cred->tgt_expire = (krb5_timestamp) ibuf; - - /* cred->princ */ - if ((kret = krb5_internalize_opaque(kcontext, - KV5M_PRINCIPAL, - (krb5_pointer *) &cred->princ, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - - /* cred->keytab */ - if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_KEYTAB, - (krb5_pointer *) &cred->keytab, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - - /* cred->ccache */ - if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_CCACHE, - (krb5_pointer *) &cred->ccache, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - - /* trailer */ - if (!kret && - !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && - (ibuf == KG_CRED)) { - *buffer = bp; - *lenremain = remain; - *argp = (krb5_pointer) cred; - } - else { - if (!kret && (ibuf != KG_CRED)) - kret = EINVAL; - if (cred->ccache) - krb5_cc_close(kcontext, cred->ccache); - if (cred->keytab) - krb5_kt_close(kcontext, cred->keytab); - if (cred->princ) - krb5_free_principal(kcontext, cred->princ); - xfree(cred); - } - } - } - return(kret); -} - /* * Determine the size required for this krb5_gss_enc_desc. */ @@ -332,7 +85,7 @@ kg_enc_desc_size(kcontext, arg, sizep) } return(kret); } - + /* * Externalize this krb5_gss_enc_desc. */ @@ -387,7 +140,7 @@ kg_enc_desc_externalize(kcontext, arg, buffer, lenremain) } return(kret); } - + /* * Internalize this krb5_gss_enc_desc. */ @@ -471,27 +224,88 @@ kg_enc_desc_internalize(kcontext, argp, buffer, lenremain) } return(kret); } - + +static krb5_error_code +kg_oid_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + gss_OID oid = (gss_OID) arg; + + (void) krb5_ser_pack_int32((krb5_int32) oid->length, + buffer, lenremain); + (void) krb5_ser_pack_bytes((krb5_octet *) oid->elements, + oid->length, buffer, lenremain); +} + +static krb5_error_code +kg_oid_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + gss_OID oid; + krb5_int32 ibuf; + + oid = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (oid == NULL) + return ENOMEM; + (void) krb5_ser_unpack_int32(&ibuf, buffer, lenremain); + oid->length = ibuf; + (void) krb5_ser_unpack_bytes((krb5_octet *) oid->elements, + oid->length, buffer, lenremain); + return 0; +} + +krb5_error_code +kg_oid_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + gss_OID oid; + size_t required; + + kret = EINVAL; + if ((oid = (gss_OID) arg)) { + required = sizeof(krb5_int32); + required += oid->length; + + kret = 0; + + *sizep += required; + } + + return(kret); +} + /* - * Determine the size required for this krb5_gss_ctx_id_t. + * Determine the size required for this krb5_gss_ctx_id_rec. */ -static krb5_error_code +krb5_error_code kg_ctx_size(kcontext, arg, sizep) krb5_context kcontext; krb5_pointer arg; size_t *sizep; { krb5_error_code kret; - krb5_gss_ctx_id_t *ctx; + krb5_gss_ctx_id_rec *ctx; size_t required; /* - * krb5_gss_ctx_id_t requires: + * krb5_gss_ctx_id_rec requires: * krb5_int32 for KG_CONTEXT * krb5_int32 for initiate. * krb5_int32 for mutual. * krb5_int32 for seed_init. * sizeof(seed) for seed + * krb5_int32 for signalg. + * krb5_int32 for cksum_size. + * krb5_int32 for sealalg. * krb5_int32 for endtime. * krb5_int32 for flags. * krb5_int32 for seq_send. @@ -501,8 +315,8 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for trailer. */ kret = EINVAL; - if ((ctx = (krb5_gss_ctx_id_t *) arg)) { - required = 11*sizeof(krb5_int32); + if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { + required = 14*sizeof(krb5_int32); required += sizeof(ctx->seed); kret = 0; @@ -525,33 +339,30 @@ kg_ctx_size(kcontext, arg, sizep) &required); if (!kret) - kret = krb5_size_opaque(kcontext, - KG_ENC_DESC, + kret = kg_enc_desc_size(kcontext, (krb5_pointer) &ctx->enc, &required); if (!kret) - kret = krb5_size_opaque(kcontext, - KG_ENC_DESC, + kret = kg_enc_desc_size(kcontext, (krb5_pointer) &ctx->seq, &required); - if (!kret && ctx->auth_context) - kret = krb5_size_opaque(kcontext, - KV5M_AUTH_CONTEXT, - (krb5_pointer) ctx->auth_context, - &required); + if (!kret) + kret = kg_oid_size(kcontext, + (krb5_pointer) ctx->mech_used, + &required); if (!kret) *sizep += required; } return(kret); } - + /* - * Externalize this krb5_gss_ctx_id_t. + * Externalize this krb5_gss_ctx_id_ret. */ -static krb5_error_code +krb5_error_code kg_ctx_externalize(kcontext, arg, buffer, lenremain) krb5_context kcontext; krb5_pointer arg; @@ -559,7 +370,7 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) size_t *lenremain; { krb5_error_code kret; - krb5_gss_ctx_id_t *ctx; + krb5_gss_ctx_id_rec *ctx; size_t required; krb5_octet *bp; size_t remain; @@ -568,7 +379,7 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) bp = *buffer; remain = *lenremain; kret = EINVAL; - if ((ctx = (krb5_gss_ctx_id_t *) arg)) { + if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { kret = ENOMEM; if (!kg_ctx_size(kcontext, arg, &required) && (required <= remain)) { @@ -585,6 +396,12 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed, sizeof(ctx->seed), &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->signalg, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->cksum_size, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->sealalg, + &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->endtime, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->flags, @@ -601,6 +418,10 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) /* Now dynamic data */ kret = 0; + if (!kret && ctx->mech_used) + kret = kg_oid_externalize(kcontext, ctx->mech_used, + &bp, &remain); + if (!kret && ctx->here) kret = krb5_externalize_opaque(kcontext, KV5M_PRINCIPAL, @@ -620,23 +441,15 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); if (!kret) - kret = krb5_externalize_opaque(kcontext, - KG_ENC_DESC, + kret = kg_enc_desc_externalize(kcontext, (krb5_pointer) &ctx->enc, &bp, &remain); if (!kret) - kret = krb5_externalize_opaque(kcontext, - KG_ENC_DESC, + kret = kg_enc_desc_externalize(kcontext, (krb5_pointer) &ctx->seq, &bp, &remain); - if (!kret && ctx->auth_context) - kret = krb5_externalize_opaque(kcontext, - KV5M_AUTH_CONTEXT, - (krb5_pointer)ctx->auth_context, - &bp, &remain); - if (!kret) { (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); *buffer = bp; @@ -646,11 +459,11 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) } return(kret); } - + /* * Internalize this krb5_gss_ctx_id_t. */ -static krb5_error_code +krb5_error_code kg_ctx_internalize(kcontext, argp, buffer, lenremain) krb5_context kcontext; krb5_pointer *argp; @@ -658,7 +471,7 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) size_t *lenremain; { krb5_error_code kret; - krb5_gss_ctx_id_t *ctx; + krb5_gss_ctx_id_rec *ctx; krb5_int32 ibuf; krb5_octet *bp; size_t remain; @@ -675,9 +488,9 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) /* Get a context */ if ((remain >= ((10*sizeof(krb5_int32))+sizeof(ctx->seed))) && - (ctx = (krb5_gss_ctx_id_t *) - xmalloc(sizeof(krb5_gss_ctx_id_t)))) { - memset(ctx, 0, sizeof(krb5_gss_ctx_id_t)); + (ctx = (krb5_gss_ctx_id_rec *) + xmalloc(sizeof(krb5_gss_ctx_id_rec)))) { + memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); /* Get static data */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); @@ -690,9 +503,15 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) sizeof(ctx->seed), &bp, &remain); (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->signalg = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->cksum_size = (int) ibuf; + (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; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->flags = (krb5_timestamp) ibuf; + ctx->flags = (krb5_flags) ibuf; (void) krb5_ser_unpack_int32(&ctx->seq_send, &bp, &remain); (void) krb5_ser_unpack_int32(&ctx->seq_recv, &bp, &remain); (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); @@ -700,6 +519,11 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->big_endian = (int) ibuf; + if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, + &remain))) { + if (kret == EINVAL) + kret = 0; + } /* Now get substructure data */ if ((kret = krb5_internalize_opaque(kcontext, KV5M_PRINCIPAL, @@ -725,8 +549,7 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) kret = 0; } if (!kret) { - if ((kret = krb5_internalize_opaque(kcontext, - KG_ENC_DESC, + if ((kret = kg_enc_desc_internalize(kcontext, (krb5_pointer *) &edp, &bp, &remain))) { if (kret == EINVAL) @@ -738,8 +561,7 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) } } if (!kret) { - if ((kret = krb5_internalize_opaque(kcontext, - KG_ENC_DESC, + if ((kret = kg_enc_desc_internalize(kcontext, (krb5_pointer *) &edp, &bp, &remain))) { if (kret == EINVAL) @@ -750,15 +572,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) xfree(edp); } } - if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_AUTH_CONTEXT, - (krb5_pointer *) - &ctx->auth_context, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } /* Get trailer */ if (!kret && @@ -771,8 +584,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) else { if (!kret && (ibuf != KG_CONTEXT)) kret = EINVAL; - if (ctx->auth_context) - krb5_auth_con_free(kcontext, ctx->auth_context); if (ctx->seq.eblock.key) krb5_free_keyblock(kcontext, ctx->seq.eblock.key); if (ctx->seq.eblock.priv && ctx->seq.eblock.priv_size) @@ -797,36 +608,3 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) } return(kret); } - -static const krb5_ser_entry kg_cred_ser_entry = { - KG_CRED, /* Type */ - kg_cred_size, /* Sizer routine */ - kg_cred_externalize, /* Externalize routine */ - kg_cred_internalize /* Internalize routine */ -}; -static const krb5_ser_entry kg_enc_desc_ser_entry = { - KG_ENC_DESC, /* Type */ - kg_enc_desc_size, /* Sizer routine */ - kg_enc_desc_externalize, /* Externalize routine */ - kg_enc_desc_internalize /* Internalize routine */ -}; -static const krb5_ser_entry kg_ctx_ser_entry = { - KG_CONTEXT, /* Type */ - kg_ctx_size, /* Sizer routine */ - kg_ctx_externalize, /* Externalize routine */ - kg_ctx_internalize /* Internalize routine */ -}; - -krb5_error_code -kg_ser_context_init(kcontext) - krb5_context kcontext; -{ - krb5_error_code kret; - - kret = krb5_register_serializer(kcontext, &kg_cred_ser_entry); - if (!kret) - kret = krb5_register_serializer(kcontext, &kg_enc_desc_ser_entry); - if (!kret) - kret = krb5_register_serializer(kcontext, &kg_ctx_ser_entry); - return(kret); -} diff --git a/src/lib/gssapi/krb5/sign.c b/src/lib/gssapi/krb5/sign.c index c3b6ebf4b..0177f40d4 100644 --- a/src/lib/gssapi/krb5/sign.c +++ b/src/lib/gssapi/krb5/sign.c @@ -22,19 +22,25 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_sign(ctx, minor_status, context_handle, +krb5_gss_sign(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; { - krb5_context context = ctx; + krb5_context context; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + return(kg_seal(context, minor_status, context_handle, 0, qop_req, message_buffer, NULL, message_token, KG_TOK_SIGN_MSG)); @@ -42,17 +48,19 @@ krb5_gss_sign(ctx, minor_status, context_handle, /* V2 interface */ OM_uint32 -krb5_gss_get_mic(ctx, minor_status, context_handle, qop_req, +krb5_gss_get_mic(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; { - krb5_context context = ctx; + krb5_context context; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + return(kg_seal(context, minor_status, context_handle, 0, (int) qop_req, message_buffer, NULL, message_token, KG_TOK_MIC_MSG)); diff --git a/src/lib/gssapi/krb5/unseal.c b/src/lib/gssapi/krb5/unseal.c index da71fa4f4..546521e1b 100644 --- a/src/lib/gssapi/krb5/unseal.c +++ b/src/lib/gssapi/krb5/unseal.c @@ -22,11 +22,14 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_unseal(ctx, minor_status, context_handle, +krb5_gss_unseal(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; @@ -34,7 +37,11 @@ krb5_gss_unseal(ctx, minor_status, context_handle, int *conf_state; int *qop_state; { - krb5_context context = ctx; + krb5_context context; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + return(kg_unseal(context, minor_status, context_handle, input_message_buffer, output_message_buffer, conf_state, qop_state, KG_TOK_SEAL_MSG)); @@ -42,10 +49,9 @@ krb5_gss_unseal(ctx, minor_status, context_handle, /* V2 interface */ OM_uint32 -krb5_gss_unwrap(ctx, minor_status, context_handle, +krb5_gss_unwrap(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; @@ -53,10 +59,13 @@ krb5_gss_unwrap(ctx, minor_status, context_handle, int *conf_state; gss_qop_t *qop_state; { - krb5_context context = ctx; + krb5_context context; OM_uint32 rstat; int qstate; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + rstat = kg_unseal(context, minor_status, context_handle, input_message_buffer, output_message_buffer, conf_state, &qstate, KG_TOK_WRAP_MSG); diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index 0b46d0e5e..ee3e1aafa 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -20,11 +20,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * $Id$ + */ + #include "gssapiP_krb5.h" #include <memory.h> krb5_error_code -kg_checksum_channel_bindings(cb, cksum, bigend) +kg_checksum_channel_bindings(context, cb, cksum, bigend) + krb5_context context; gss_channel_bindings_t cb; krb5_checksum *cksum; int bigend; @@ -33,20 +38,18 @@ kg_checksum_channel_bindings(cb, cksum, bigend) char *buf, *ptr; krb5_error_code code; - if (!kg_context && (code=kg_get_context())) - return code; - + /* initialize the the cksum and allocate the contents buffer */ + cksum->checksum_type = CKSUMTYPE_RSA_MD5; + cksum->length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); + if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { + free(buf); + return(ENOMEM); + } + /* generate a buffer full of zeros if no cb specified */ if (cb == GSS_C_NO_CHANNEL_BINDINGS) { - /* allocate the cksum contents buffer */ - if ((cksum->contents = (krb5_octet *) - xmalloc(krb5_checksum_size(context, CKSUMTYPE_RSA_MD5))) == NULL) - return(ENOMEM); - - cksum->checksum_type = CKSUMTYPE_RSA_MD5; - memset(cksum->contents, '\0', - (cksum->length = krb5_checksum_size(kg_context, CKSUMTYPE_RSA_MD5))); + memset(cksum->contents, '\0', cksum->length); return(0); } @@ -60,13 +63,6 @@ kg_checksum_channel_bindings(cb, cksum, bigend) if ((buf = (char *) xmalloc(len)) == NULL) return(ENOMEM); - /* allocate the cksum contents buffer */ - cksum->length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { - free(buf); - return(ENOMEM); - } - /* helper macros. This code currently depends on a long being 32 bits, and htonl dtrt. */ @@ -80,7 +76,7 @@ kg_checksum_channel_bindings(cb, cksum, bigend) /* checksum the data */ - if (code = krb5_calculate_checksum(kg_context, CKSUMTYPE_RSA_MD5, + if (code = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5, buf, len, NULL, 0, cksum)) { xfree(cksum->contents); xfree(buf); diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 89028270e..bf49de41d 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -23,6 +23,10 @@ #include "gssapiP_krb5.h" #include <memory.h> +/* + * $Id$ + */ + static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; int @@ -39,7 +43,7 @@ kg_make_confounder(ed, buf) krb5_gss_enc_desc *ed; unsigned char *buf; { - return(krb5_random_confounder( ed->eblock.crypto_entry->block_length, buf)); + return(krb5_random_confounder(ed->eblock.crypto_entry->block_length, buf)); } int @@ -51,7 +55,8 @@ kg_encrypt_size(ed, n) } krb5_error_code -kg_encrypt(ed, iv, in, out, length) +kg_encrypt(context, ed, iv, in, out, length) + krb5_context context; krb5_gss_enc_desc *ed; krb5_pointer iv; krb5_pointer in; @@ -59,18 +64,29 @@ kg_encrypt(ed, iv, in, out, length) int length; { krb5_error_code code; + krb5_pointer tmp; - if (!kg_context && (code=kg_get_context())) - return code; - if (! ed->processed) { - if (code = krb5_process_key(kg_context, &ed->eblock, ed->key)) + if (code = krb5_process_key(context, &ed->eblock, ed->key)) return(code); ed->processed = 1; } - if (code = krb5_encrypt(kg_context, in, out, length, &ed->eblock, - iv?iv:(krb5_pointer)zeros)) + /* this is lame. the krb5 encryption interfaces no longer allow + you to encrypt in place. perhaps this should be fixed, but + dealing here is easier for now --marc */ + + if ((tmp = (krb5_pointer) xmalloc(length)) == NULL) + return(ENOMEM); + + memcpy(tmp, in, length); + + code = krb5_encrypt(context, tmp, out, length, &ed->eblock, + iv?iv:(krb5_pointer)zeros); + + xfree(tmp); + + if (code) return(code); return(0); @@ -79,7 +95,8 @@ kg_encrypt(ed, iv, in, out, length) /* length is the length of the cleartext. */ krb5_error_code -kg_decrypt(ed, iv, in, out, length) +kg_decrypt(context, ed, iv, in, out, length) + krb5_context context; krb5_gss_enc_desc *ed; krb5_pointer iv; krb5_pointer in; @@ -90,11 +107,8 @@ kg_decrypt(ed, iv, in, out, length) int elen; char *buf; - if (!kg_context && (code=kg_get_context())) - return code; - if (! ed->processed) { - if (code = krb5_process_key(kg_context, &ed->eblock, ed->key)) + if (code = krb5_process_key(context, &ed->eblock, ed->key)) return(code); ed->processed = 1; } @@ -103,7 +117,7 @@ kg_decrypt(ed, iv, in, out, length) if ((buf = (char *) xmalloc(elen)) == NULL) return(ENOMEM); - if (code = krb5_decrypt(kg_context, in, buf, elen, &ed->eblock, + if (code = krb5_decrypt(context, in, buf, elen, &ed->eblock, iv?iv:(krb5_pointer)zeros)) { xfree(buf); return(code); diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c index ed60922d5..14f365245 100644 --- a/src/lib/gssapi/krb5/util_seed.c +++ b/src/lib/gssapi/krb5/util_seed.c @@ -23,10 +23,15 @@ #include "gssapiP_krb5.h" #include <memory.h> +/* + * $Id$ + */ + static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; krb5_error_code -kg_make_seed(key, seed) +kg_make_seed(context, key, seed) + krb5_context context; krb5_keyblock *key; unsigned char *seed; { @@ -34,10 +39,7 @@ kg_make_seed(key, seed) krb5_gss_enc_desc ed; int i; - if (!kg_context && (code=kg_get_context())) - return code; - - if (code = krb5_copy_keyblock(kg_context, key, &ed.key)) + if (code = krb5_copy_keyblock(context, key, &ed.key)) return(code); /* reverse the key bytes, as per spec */ @@ -45,13 +47,13 @@ kg_make_seed(key, seed) for (i=0; i<ed.key->length; i++) ed.key->contents[i] = key->contents[key->length - 1 - i]; - krb5_use_enctype(kg_context, &ed.eblock, ENCTYPE_DES_CBC_RAW); + krb5_use_enctype(context, &ed.eblock, ENCTYPE_DES_CBC_RAW); ed.processed = 0; - code = kg_encrypt(&ed, NULL, zeros, seed, 16); + code = kg_encrypt(context, &ed, NULL, zeros, seed, 16); - krb5_finish_key(kg_context, &ed.eblock); - krb5_free_keyblock(kg_context, ed.key); + krb5_finish_key(context, &ed.eblock); + krb5_free_keyblock(context, ed.key); return(code); } diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index 67bcda6db..ed9293f77 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -22,8 +22,13 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + krb5_error_code -kg_make_seq_num(ed, direction, seqnum, cksum, buf) +kg_make_seq_num(context, ed, direction, seqnum, cksum, buf) + krb5_context context; krb5_gss_enc_desc *ed; int direction; krb5_int32 seqnum; @@ -42,5 +47,34 @@ kg_make_seq_num(ed, direction, seqnum, cksum, buf) plain[6] = direction; plain[7] = direction; - return(kg_encrypt(ed, cksum, plain, buf, 8)); + return(kg_encrypt(context, ed, cksum, plain, buf, 8)); +} + +krb5_error_code kg_get_seq_num(context, ed, cksum, buf, direction, seqnum) + krb5_context context; + krb5_gss_enc_desc *ed; + unsigned char *cksum; + unsigned char *buf; + int *direction; + krb5_int32 *seqnum; +{ + krb5_error_code code; + unsigned char plain[8]; + + if (code = kg_decrypt(context, ed, cksum, buf, plain, 8)) + return(code); + + if ((plain[4] != plain[5]) || + (plain[4] != plain[6]) || + (plain[4] != plain[7])) + return((krb5_error_code) KG_BAD_SEQ); + + *direction = plain[4]; + + *seqnum = ((plain[0]) | + (plain[1]<<8) | + (plain[2]<<16) | + (plain[3]<<24)); + + return(0); } diff --git a/src/lib/gssapi/krb5/verify.c b/src/lib/gssapi/krb5/verify.c index 33ee8fb8c..0e7305640 100644 --- a/src/lib/gssapi/krb5/verify.c +++ b/src/lib/gssapi/krb5/verify.c @@ -22,39 +22,50 @@ #include "gssapiP_krb5.h" +/* + * $Id$ + */ + OM_uint32 -krb5_gss_verify(ctx, minor_status, context_handle, +krb5_gss_verify(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; { - krb5_context context = ctx; - return(kg_unseal(context, minor_status, context_handle, - token_buffer, message_buffer, - NULL, qop_state, KG_TOK_SIGN_MSG)); + krb5_context context; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + + + return(kg_unseal(context, minor_status, context_handle, + token_buffer, message_buffer, + NULL, qop_state, KG_TOK_SIGN_MSG)); } /* V2 interface */ OM_uint32 -krb5_gss_verify_mic(ctx, minor_status, context_handle, +krb5_gss_verify_mic(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; { - krb5_context context = ctx; + krb5_context context; OM_uint32 rstat; int qstate; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + + rstat = kg_unseal(context, minor_status, context_handle, token_buffer, message_buffer, NULL, &qstate, KG_TOK_MIC_MSG); diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c new file mode 100644 index 000000000..8c47d0fa6 --- /dev/null +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -0,0 +1,75 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gssapiP_krb5.h" + +/* + * $Id$ + */ + +/* V2 interface */ +OM_uint32 +krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, + qop_req, req_output_size, max_input_size) + 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; +{ + krb5_context context; + krb5_gss_ctx_id_rec *ctx; + OM_uint32 cfsize; + OM_uint32 ohlen; + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + + /* only default qop is allowed */ + if (qop_req != GSS_C_QOP_DEFAULT) { + *minor_status = (OM_uint32) G_UNKNOWN_QOP; + return(GSS_S_FAILURE); + } + + /* validate the context handle */ + 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); + } + + /* Calculate the token size and subtract that from the output size */ + cfsize = (conf_req_flag) ? kg_confounder_size(&ctx->enc) : 0; + ohlen = g_token_size((gss_OID) ctx->mech_used, + (unsigned int) cfsize + ctx->cksum_size + 14); + + /* Cannot have trailer length that will cause us to pad over our length */ + *max_input_size = (req_output_size - ohlen) & (~7); + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index e82cfbba0..22b8c5bdb 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -74,6 +74,17 @@ typedef struct gss_union_cred_t { /* define one of these and provide a function to return */ /* it to initialize the GSSAPI library */ +/* ultrix cc doesn't understand prototypes in structures. + we could autoconf test for this --marc */ + +#ifndef NPROTOTYPE +#if defined(__ultrix) && !defined (__GNUC__) +#define NPROTOTYPE(x) () +#else +#define NPROTOTYPE(x) PROTOTYPE(x) +#endif +#endif + /* * This is the definition of the mechs_array struct, which is used to * define the mechs array table. This table is used to indirectly |
