diff options
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 |
