From 870d5a01e997b76cae1ad120c6c003edddab5205 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Sat, 18 Dec 1993 03:14:21 +0000 Subject: [PATCH] As submitted by Openvision Technologies: To: tytso@MIT.EDU Subject: gssapi Date: Fri, 17 Dec 1993 17:55:06 -0500 From: Marc Horowitz This is named in my RCS tree as MIT931217. The copyright notice included is (hopefully) final. Good luck! Marc git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@3205 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/Makefile | 31 ++ src/lib/gssapi/generic/Makefile | 74 +++ .../gssapi/generic/display_com_err_status.c | 68 +++ src/lib/gssapi/generic/display_major_status.c | 304 ++++++++++++ src/lib/gssapi/generic/gssapi.h | 404 ++++++++++++++++ src/lib/gssapi/generic/gssapiP_generic.h | 123 +++++ src/lib/gssapi/generic/gssapi_generic.c | 39 ++ src/lib/gssapi/generic/gssapi_generic.h | 37 ++ src/lib/gssapi/generic/gssapi_generic_err.et | 38 ++ src/lib/gssapi/generic/release_buffer.c | 42 ++ src/lib/gssapi/generic/release_oid_set.c | 44 ++ src/lib/gssapi/generic/util_buffer.c | 46 ++ src/lib/gssapi/generic/util_canonhost.c | 53 +++ src/lib/gssapi/generic/util_dup.c | 40 ++ src/lib/gssapi/generic/util_oid.c | 54 +++ src/lib/gssapi/generic/util_token.c | 183 ++++++++ src/lib/gssapi/generic/util_validate.c | 153 ++++++ src/lib/gssapi/krb5/Makefile | 98 ++++ src/lib/gssapi/krb5/accept_sec_context.c | 441 ++++++++++++++++++ src/lib/gssapi/krb5/acquire_cred.c | 418 +++++++++++++++++ src/lib/gssapi/krb5/compare_name.c | 49 ++ src/lib/gssapi/krb5/context_time.c | 66 +++ src/lib/gssapi/krb5/delete_sec_context.c | 92 ++++ src/lib/gssapi/krb5/display_name.c | 64 +++ src/lib/gssapi/krb5/display_status.c | 76 +++ src/lib/gssapi/krb5/get_tkt_flags.c | 54 +++ src/lib/gssapi/krb5/gssapiP_krb5.h | 322 +++++++++++++ src/lib/gssapi/krb5/gssapi_krb5.c | 90 ++++ src/lib/gssapi/krb5/gssapi_krb5.h | 44 ++ src/lib/gssapi/krb5/gssapi_krb5_err.et | 38 ++ src/lib/gssapi/krb5/import_name.c | 146 ++++++ src/lib/gssapi/krb5/indicate_mechs.c | 36 ++ src/lib/gssapi/krb5/init_sec_context.c | 417 +++++++++++++++++ src/lib/gssapi/krb5/inquire_context.c | 125 +++++ src/lib/gssapi/krb5/inquire_cred.c | 108 +++++ src/lib/gssapi/krb5/k5seal.c | 224 +++++++++ src/lib/gssapi/krb5/k5unseal.c | 236 ++++++++++ src/lib/gssapi/krb5/krb5_gss_glue.c | 304 ++++++++++++ src/lib/gssapi/krb5/process_context_token.c | 61 +++ src/lib/gssapi/krb5/release_cred.c | 69 +++ src/lib/gssapi/krb5/release_name.c | 46 ++ src/lib/gssapi/krb5/seal.c | 41 ++ src/lib/gssapi/krb5/sign.c | 39 ++ src/lib/gssapi/krb5/unseal.c | 40 ++ src/lib/gssapi/krb5/util_cksum.c | 93 ++++ src/lib/gssapi/krb5/util_crypt.c | 97 ++++ src/lib/gssapi/krb5/util_seed.c | 56 +++ src/lib/gssapi/krb5/util_seqnum.c | 46 ++ src/lib/gssapi/krb5/verify.c | 39 ++ 49 files changed, 5808 insertions(+) create mode 100644 src/lib/gssapi/Makefile create mode 100644 src/lib/gssapi/generic/Makefile create mode 100644 src/lib/gssapi/generic/display_com_err_status.c create mode 100644 src/lib/gssapi/generic/display_major_status.c create mode 100644 src/lib/gssapi/generic/gssapi.h create mode 100644 src/lib/gssapi/generic/gssapiP_generic.h create mode 100644 src/lib/gssapi/generic/gssapi_generic.c create mode 100644 src/lib/gssapi/generic/gssapi_generic.h create mode 100644 src/lib/gssapi/generic/gssapi_generic_err.et create mode 100644 src/lib/gssapi/generic/release_buffer.c create mode 100644 src/lib/gssapi/generic/release_oid_set.c create mode 100644 src/lib/gssapi/generic/util_buffer.c create mode 100644 src/lib/gssapi/generic/util_canonhost.c create mode 100644 src/lib/gssapi/generic/util_dup.c create mode 100644 src/lib/gssapi/generic/util_oid.c create mode 100644 src/lib/gssapi/generic/util_token.c create mode 100644 src/lib/gssapi/generic/util_validate.c create mode 100644 src/lib/gssapi/krb5/Makefile create mode 100644 src/lib/gssapi/krb5/accept_sec_context.c create mode 100644 src/lib/gssapi/krb5/acquire_cred.c create mode 100644 src/lib/gssapi/krb5/compare_name.c create mode 100644 src/lib/gssapi/krb5/context_time.c create mode 100644 src/lib/gssapi/krb5/delete_sec_context.c create mode 100644 src/lib/gssapi/krb5/display_name.c create mode 100644 src/lib/gssapi/krb5/display_status.c create mode 100644 src/lib/gssapi/krb5/get_tkt_flags.c create mode 100644 src/lib/gssapi/krb5/gssapiP_krb5.h create mode 100644 src/lib/gssapi/krb5/gssapi_krb5.c create mode 100644 src/lib/gssapi/krb5/gssapi_krb5.h create mode 100644 src/lib/gssapi/krb5/gssapi_krb5_err.et create mode 100644 src/lib/gssapi/krb5/import_name.c create mode 100644 src/lib/gssapi/krb5/indicate_mechs.c create mode 100644 src/lib/gssapi/krb5/init_sec_context.c create mode 100644 src/lib/gssapi/krb5/inquire_context.c create mode 100644 src/lib/gssapi/krb5/inquire_cred.c create mode 100644 src/lib/gssapi/krb5/k5seal.c create mode 100644 src/lib/gssapi/krb5/k5unseal.c create mode 100644 src/lib/gssapi/krb5/krb5_gss_glue.c create mode 100644 src/lib/gssapi/krb5/process_context_token.c create mode 100644 src/lib/gssapi/krb5/release_cred.c create mode 100644 src/lib/gssapi/krb5/release_name.c create mode 100644 src/lib/gssapi/krb5/seal.c create mode 100644 src/lib/gssapi/krb5/sign.c create mode 100644 src/lib/gssapi/krb5/unseal.c create mode 100644 src/lib/gssapi/krb5/util_cksum.c create mode 100644 src/lib/gssapi/krb5/util_crypt.c create mode 100644 src/lib/gssapi/krb5/util_seed.c create mode 100644 src/lib/gssapi/krb5/util_seqnum.c create mode 100644 src/lib/gssapi/krb5/verify.c diff --git a/src/lib/gssapi/Makefile b/src/lib/gssapi/Makefile new file mode 100644 index 000000000..0ace19c8e --- /dev/null +++ b/src/lib/gssapi/Makefile @@ -0,0 +1,31 @@ +# +# 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$ + +TOP = ../.. +include $(TOP)/config.mk/template + +all:: + +SUBDIRS = generic krb5 trust unit-test +expand SubdirTarget diff --git a/src/lib/gssapi/generic/Makefile b/src/lib/gssapi/generic/Makefile new file mode 100644 index 000000000..6fa6194d2 --- /dev/null +++ b/src/lib/gssapi/generic/Makefile @@ -0,0 +1,74 @@ +# +# 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$ + +TOP = ../../.. +include $(TOP)/config.mk/template + +CCSRCS = \ + display_major_status.c \ + display_com_err_status.c \ + gssapi_generic.c \ + release_buffer.c \ + release_oid_set.c \ + util_buffer.c \ + util_canonhost.c \ + util_dup.c \ + util_oid.c \ + util_token.c \ + util_validate.c +CCOBJS = $(addsuffix .o,$(basename $(CCSRCS))) + +ETSRCS = gssapi_generic_err.et +ETCS = $(addsuffix .c,$(basename $(ETSRCS))) +ETHS = $(addsuffix .h,$(basename $(ETSRCS))) +ETOBJS = $(addsuffix .o,$(basename $(ETSRCS))) + +OBJS = $(CCOBJS) + +CFLAGS := -I. $(CFLAGS) + +all:: + +all:: $(ETCS) $(ETHS) + +listobjs: + @echo $(CCOBJS) $(ETOBJS) + +SRCS = $(CCSRCS) +DEPENDS = $(ETHS) +expand Depend + +ETABLES = $(ETSRCS) +expand ErrorTables + +stage:: $(CCOBJS) $(ETOBJS) + +all:: $(CCOBJS) $(ETOBJS) + +SRCS = $(CCSRCS) +expand Saber + +HDRS = gssapi.h gssapi_generic.h +HDRS_DIR = gssapi +expand InstallIncludes diff --git a/src/lib/gssapi/generic/display_com_err_status.c b/src/lib/gssapi/generic/display_com_err_status.c new file mode 100644 index 000000000..0a36f91b4 --- /dev/null +++ b/src/lib/gssapi/generic/display_com_err_status.c @@ -0,0 +1,68 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_generic.h" +#include + +/* XXXX internationalization!! */ + +/**/ + +static int init_et = 0; +static const char * const no_error = "No error"; + +/**/ + +/* if status_type == GSS_C_GSS_CODE, return up to three error messages, + for routine errors, call error, and status, in that order. + message_context == 0 : print the routine error + message_context == 1 : print the calling error + message_context > 2 : print supplementary info bit (message_context-2) + if status_type == GSS_C_MECH_CODE, return the output from error_message() + */ + +OM_uint32 +g_display_com_err_status(OM_uint32 *minor_status, + OM_uint32 status_value, + gss_buffer_t status_string) +{ + status_string->length = 0; + status_string->value = NULL; + + if (!init_et) { + initialize_ggss_error_table(); + init_et = 1; + } + + if (! g_make_string_buffer(((status_value == 0)?no_error: + error_message(status_value)), + status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/generic/display_major_status.c b/src/lib/gssapi/generic/display_major_status.c new file mode 100644 index 000000000..0216cf116 --- /dev/null +++ b/src/lib/gssapi/generic/display_major_status.c @@ -0,0 +1,304 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gssapiP_generic.h" + +/* + * $Id$ + */ + +/* This code has knowledge of the min and max errors of each type + within the gssapi major status */ + +#define GSS_ERROR_STR(value, array, select, min, max, num) \ + (((select(value) < (min)) || (select(value) > (max))) ? NULL : \ + (array)[num(value)]) + +/**/ + +static const char * const calling_error_string[] = { + NULL, + "A required input parameter could not be read", + "A required input parameter could not be written", + "A parameter was malformed", +}; + +static const char * const calling_error = "calling error"; + +#define GSS_CALLING_ERROR_STR(x) \ + GSS_ERROR_STR((x), calling_error_string, GSS_CALLING_ERROR, \ + GSS_S_CALL_INACCESSIBLE_READ, GSS_S_CALL_BAD_STRUCTURE, \ + GSS_CALLING_ERROR_FIELD) + +/**/ + +static const char * const routine_error_string[] = { + NULL, + "An unsupported mechanism was requested", + "An invalid name was supplied", + "A supplied name was of an unsupported type", + "Incorrect channel bindings were supplied", + "An invalid status code was supplied", + "A token had an invalid signature", + "No credentials were supplied", + "No context has been established", + "A token was invalid", + "A credential was invalid", + "The referenced credentials have expired", + "The context has expired", + "Miscellaneous failure", +}; + +static const char * const routine_error = "routine error"; + +#define GSS_ROUTINE_ERROR_STR(x) \ + GSS_ERROR_STR((x), routine_error_string, GSS_ROUTINE_ERROR, \ + GSS_S_BAD_MECH, GSS_S_FAILURE, \ + GSS_ROUTINE_ERROR_FIELD) + +/**/ + +/* this becomes overly gross after about 4 strings */ + +static const char * const sinfo_string[] = { + "The routine must be called again to complete its function", + "The token was a duplicate of an earlier token", + "The token's validity period has expired", + "A later token has already been processed", +}; + +static const char * const sinfo_code = "supplementary info code"; + +#define LSBGET(x) ((((x)^((x)-1))+1)>>1) +#define LSBMASK(n) ((1<<(n))^((1<<(n))-1)) + +#define GSS_SINFO_STR(x) \ + ((((1<<(x)) < GSS_S_CONTINUE_NEEDED) || ((1<<(x)) > GSS_S_UNSEQ_TOKEN)) ? \ + /**/NULL:sinfo_string[(x)]) + +/**/ + +static const char * const no_error = "No error"; +static const char * const unknown_error = "Unknown %s (field = %d)"; + +/**/ + +int display_unknown(const char *kind, OM_uint32 value, + gss_buffer_t buffer) +{ + int len; + char *str; + + if ((str = + (char *) xmalloc(len = strlen(unknown_error)+strlen(kind)+7)) == NULL) + return(0); + + sprintf(str, unknown_error, kind, value); + + buffer->length = len; + buffer->value = str; + + return(1); +} + +/* code should be set to the calling error field */ + +static OM_uint32 + display_calling(OM_uint32 *minor_status, + OM_uint32 code, + gss_buffer_t status_string) +{ + const char *str; + + if (str = GSS_CALLING_ERROR_STR(code)) { + if (! g_make_string_buffer(str, status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } else { + if (! display_unknown(calling_error, GSS_CALLING_ERROR_FIELD(code), + status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +/* code should be set to the routine error field */ + +static OM_uint32 + display_routine(OM_uint32 *minor_status, + OM_uint32 code, + gss_buffer_t status_string) +{ + const char *str; + + if (str = GSS_ROUTINE_ERROR_STR(code)) { + if (! g_make_string_buffer(str, status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } else { + if (! display_unknown(routine_error, GSS_ROUTINE_ERROR_FIELD(code), + status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +/* code should be set to the bit offset (log_2) of a supplementary info bit */ + +static OM_uint32 + display_bit(OM_uint32 *minor_status, + OM_uint32 code, + gss_buffer_t status_string) +{ + const char *str; + + if (str = GSS_SINFO_STR(code)) { + if (! g_make_string_buffer(str, status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } else { + if (! display_unknown(sinfo_code, 1< 2 : print supplementary info bit (message_context-2) + */ + +OM_uint32 +g_display_major_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int *message_context, + gss_buffer_t status_string) +{ + OM_uint32 ret, tmp; + int bit; + + /*** deal with no error at all specially */ + + if (status_value == 0) { + if (! g_make_string_buffer(no_error, status_string)) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + *message_context = 0; + *minor_status = 0; + return(GSS_S_COMPLETE); + } + + /*** do routine error */ + + if (*message_context == 0) { + if (tmp = GSS_ROUTINE_ERROR(status_value)) { + status_value -= tmp; + if (ret = display_routine(minor_status, tmp, status_string)) + return(ret); + *minor_status = 0; + if (status_value) { + (*message_context)++; + return(GSS_S_CONTINUE_NEEDED); + } else { + *message_context = 0; + return(GSS_S_COMPLETE); + } + } else { + (*message_context)++; + } + } else { + status_value -= GSS_ROUTINE_ERROR(status_value); + } + + /*** do calling error */ + + if (*message_context == 1) { + if (tmp = GSS_CALLING_ERROR(status_value)) { + status_value -= tmp; + if (ret = display_calling(minor_status, tmp, status_string)) + return(ret); + *minor_status = 0; + if (status_value) { + (*message_context)++; + return(GSS_S_CONTINUE_NEEDED); + } else { + *message_context = 0; + return(GSS_S_COMPLETE); + } + } else { + (*message_context)++; + } + } else { + status_value -= GSS_CALLING_ERROR(status_value); + } + + /*** do sinfo bits (*message_context == 2 + number of bits done) */ + + tmp = GSS_SUPPLEMENTARY_INFO_FIELD(status_value); + /* mask off the bits which have been done */ + if (*message_context > 2) { + tmp &= ~LSBMASK(*message_context-3); + status_value &= ~LSBMASK(*message_context-3); + } + + if (!tmp) { + /* bogon input - there should be something left */ + *minor_status = G_BAD_MSG_CTX; + return(GSS_S_FAILURE); + } + + /* compute the bit offset */ + /*SUPPRESS 570*/ + for (bit=0; (1< +#include + +/* + * $Id$ + */ + +/* + * First, define the platform-dependent types. + */ +typedef unsigned int OM_uint32; +typedef void * gss_name_t; +typedef void * gss_cred_id_t; +typedef void * gss_ctx_id_t; + +/* + * Note that a platform supporting the xom.h X/Open header file + * may make use of that header for the definitions of OM_uint32 + * and the structure to which gss_OID_desc equates. + */ + +typedef struct gss_OID_desc_struct { + OM_uint32 length; + void *elements; +} gss_OID_desc, *gss_OID; + +typedef const gss_OID_desc * const const_gss_OID; + +typedef struct gss_OID_set_desc_struct { + int count; + gss_OID elements; +} gss_OID_set_desc, *gss_OID_set; + +typedef struct gss_buffer_desc_struct { + size_t length; + void *value; +} gss_buffer_desc, *gss_buffer_t; + +typedef struct gss_channel_bindings_struct { + OM_uint32 initiator_addrtype; + gss_buffer_desc initiator_address; + OM_uint32 acceptor_addrtype; + gss_buffer_desc acceptor_address; + gss_buffer_desc application_data; +} *gss_channel_bindings_t; + + +/* + * Six independent flags each of which indicates that a context + * supports a specific service option. + */ +#define GSS_C_DELEG_FLAG 1 +#define GSS_C_MUTUAL_FLAG 2 +#define GSS_C_REPLAY_FLAG 4 +#define GSS_C_SEQUENCE_FLAG 8 +#define GSS_C_CONF_FLAG 16 +#define GSS_C_INTEG_FLAG 32 + + +/* + * Credential usage options + */ +#define GSS_C_BOTH 0 +#define GSS_C_INITIATE 1 +#define GSS_C_ACCEPT 2 + +/* + * Status code types for gss_display_status + */ +#define GSS_C_GSS_CODE 1 +#define GSS_C_MECH_CODE 2 + +/* + * The constant definitions for channel-bindings address families + */ +#define GSS_C_AF_UNSPEC 0 +#define GSS_C_AF_LOCAL 1 +#define GSS_C_AF_INET 2 +#define GSS_C_AF_IMPLINK 3 +#define GSS_C_AF_PUP 4 +#define GSS_C_AF_CHAOS 5 +#define GSS_C_AF_NS 6 +#define GSS_C_AF_NBS 7 +#define GSS_C_AF_ECMA 8 +#define GSS_C_AF_DATAKIT 9 +#define GSS_C_AF_CCITT 10 +#define GSS_C_AF_SNA 11 +#define GSS_C_AF_DECnet 12 +#define GSS_C_AF_DLI 13 +#define GSS_C_AF_LAT 14 +#define GSS_C_AF_HYLINK 15 +#define GSS_C_AF_APPLETALK 16 +#define GSS_C_AF_BSC 17 +#define GSS_C_AF_DSS 18 +#define GSS_C_AF_OSI 19 +#define GSS_C_AF_X25 21 + +#define GSS_C_AF_NULLADDR 255 + +#define GSS_C_NO_BUFFER ((gss_buffer_t) 0) +#define GSS_C_NULL_OID ((gss_OID) 0) +#define GSS_C_NULL_OID_SET ((gss_OID_set) 0) +#define GSS_C_NO_NAME ((gss_name_t) 0) +#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0) +#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0) +#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0) +#define GSS_C_EMPTY_BUFFER {0, NULL} + +/* + * Define the default Quality of Protection for per-message + * services. Note that an implementation that offers multiple + * levels of QOP may either reserve a value (for example zero, + * as assumed here) to mean "default protection", or alternatively + * may simply equate GSS_C_QOP_DEFAULT to a specific explicit QOP + * value. + */ +#define GSS_C_QOP_DEFAULT 0 + +/* + * Expiration time of 2^32-1 seconds means infinite lifetime for a + * credential or security context + */ +#define GSS_C_INDEFINITE 0xffffffffu + + +/* Major status codes */ + +#define GSS_S_COMPLETE 0 + +/* + * Some "helper" definitions to make the status code macros obvious. + */ +#define GSS_C_CALLING_ERROR_OFFSET 24 +#define GSS_C_ROUTINE_ERROR_OFFSET 16 +#define GSS_C_SUPPLEMENTARY_OFFSET 0 +#define GSS_C_CALLING_ERROR_MASK 0377 +#define GSS_C_ROUTINE_ERROR_MASK 0377 +#define GSS_C_SUPPLEMENTARY_MASK 0177777 + +/* + * The macros that test status codes for error conditions + */ +#define GSS_CALLING_ERROR(x) \ + ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) +#define GSS_ROUTINE_ERROR(x) \ + ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) +#define GSS_SUPPLEMENTARY_INFO(x) \ + ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) +#define GSS_ERROR(x) \ + ((GSS_CALLING_ERROR(x) != 0) || (GSS_ROUTINE_ERROR(x) != 0)) + +/* XXXX these are not part of the GSSAPI C bindings! (but should be) */ + +#define GSS_CALLING_ERROR_FIELD(x) \ + (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK) +#define GSS_ROUTINE_ERROR_FIELD(x) \ + (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) +#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \ + (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK) + +/* + * Now the actual status code definitions + */ + +/* + * Calling errors: + */ +#define GSS_S_CALL_INACCESSIBLE_READ \ + (1 << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_INACCESSIBLE_WRITE \ + (2 << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_BAD_STRUCTURE \ + (3 << GSS_C_CALLING_ERROR_OFFSET) + +/* + * Routine errors: + */ +#define GSS_S_BAD_MECH (1 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAME (2 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAMETYPE (3 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_BINDINGS (4 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_STATUS (5 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_SIG (6 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CRED (7 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CONTEXT (8 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_TOKEN (9 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_CREDENTIAL (10 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CREDENTIALS_EXPIRED (11 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CONTEXT_EXPIRED (12 << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_FAILURE (13 << GSS_C_ROUTINE_ERROR_OFFSET) +/* XXXX This is a necessary evil until the spec is fixed */ +#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE + +/* + * Supplementary info bits: + */ +#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) +#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) +#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) +#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) + + +/* + * Finally, function prototypes for the GSSAPI routines. + */ + +OM_uint32 gss_acquire_cred + (OM_uint32*, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + int, /* cred_usage */ + gss_cred_id_t*, /* output_cred_handle */ + gss_OID_set*, /* actual_mechs */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 gss_release_cred + (OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + +OM_uint32 gss_init_sec_context + (OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + const_gss_OID, /* mech_type */ + int, /* 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 */ + int*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 gss_accept_sec_context + (OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_cred_id_t, /* verifier_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, + /* input_chan_bindings */ + gss_name_t*, /* src_name */ + gss_OID*, /* mech_type */ + gss_buffer_t, /* output_token */ + int*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + +OM_uint32 gss_process_context_token + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + +OM_uint32 gss_delete_sec_context + (OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + +OM_uint32 gss_context_time + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 gss_sign + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +OM_uint32 gss_verify + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + +OM_uint32 gss_seal + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +OM_uint32 gss_unseal + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int* /* qop_state */ + ); + +OM_uint32 gss_display_status + (OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + const_gss_OID, /* mech_type */ + int*, /* message_context */ + gss_buffer_t /* status_string */ + ); + +OM_uint32 gss_indicate_mechs + (OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + +OM_uint32 gss_compare_name + (OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + +OM_uint32 gss_display_name + (OM_uint32*, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID* /* output_name_type */ + ); + +OM_uint32 gss_import_name + (OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + const_gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + +OM_uint32 gss_release_name + (OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + +OM_uint32 gss_release_buffer + (OM_uint32*, /* minor_status */ + gss_buffer_t /* buffer */ + ); + +OM_uint32 gss_release_oid_set + (OM_uint32*, /* minor_status */ + gss_OID_set* /* set */ + ); + +OM_uint32 gss_inquire_cred + (OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + int *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + +OM_uint32 gss_inquire_context + (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 */ + int*, /* ret_flags */ + int* /* locally_initiated */ + ); + + +#endif /* _GSSAPI_H_ */ diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h new file mode 100644 index 000000000..5d8275568 --- /dev/null +++ b/src/lib/gssapi/generic/gssapiP_generic.h @@ -0,0 +1,123 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GSSAPIP_GENERIC_H_ +#define _GSSAPIP_GENERIC_H_ + +/* + * $Id$ + */ + +#include "gssapi.h" + +#include "gssapi_generic_err.h" +#include + +/** helper macros **/ + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(o1)->length) == 0)) + +#define TWRITE_INT(ptr, tmp, num) \ + (tmp) = htonl(num); \ + memcpy(ptr, (char *) &(tmp), sizeof(tmp)); \ + (ptr) += sizeof(tmp); + +#define TREAD_INT(ptr, num) \ + memcpy((char *) &(num), (char *) (ptr), sizeof(num)); \ + (num) = ntohl(num); \ + (ptr) += sizeof(num); + +#define TWRITE_STR(ptr, str, len) \ + memcpy((ptr), (char *) (str), (len)); \ + (ptr) += (len); + +#define TREAD_STR(ptr, str, len) \ + (str) = (ptr); \ + (ptr) += (len); + +#define TWRITE_BUF(ptr, tmp, buf) \ + TWRITE_INT((ptr), (tmp), (buf).length); \ + TWRITE_STR((ptr), (buf).value, (buf).length); + +/** malloc wrappers; these may actually do something later */ + +#define xmalloc(n) malloc(n) +#define xrealloc(p,n) realloc(p,n) +#ifdef xfree +#undef xfree +#endif +#define xfree(p) free(p) + +/** helper functions **/ + +int g_save_name(void **vdb, gss_name_t *name); +int g_save_cred_id(void **vdb, gss_cred_id_t *cred); +int g_save_ctx_id(void **vdb, gss_ctx_id_t *ctx); + +int g_validate_name(void **vdb, gss_name_t *name); +int g_validate_cred_id(void **vdb, gss_cred_id_t *cred); +int g_validate_ctx_id(void **vdb, gss_ctx_id_t *ctx); + +int g_delete_name(void **vdb, gss_name_t *name); +int g_delete_cred_id(void **vdb, gss_cred_id_t *cred); +int g_delete_ctx_id(void **vdb, gss_ctx_id_t *ctx); + +int g_make_string_buffer(const char *str, gss_buffer_t buffer); + +int g_copy_OID_set(const gss_OID_set_desc * const in, gss_OID_set *out); + +int g_token_size(const_gss_OID mech, unsigned int body_size); + +void g_make_token_header(const_gss_OID mech, int body_size, + unsigned char **buf, int tok_type); + +int g_verify_token_header(const_gss_OID mech, int *body_size, + unsigned char **buf, int tok_type, int toksize); + +OM_uint32 g_display_major_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int *message_context, + gss_buffer_t status_string); + +OM_uint32 g_display_com_err_status(OM_uint32 *minor_status, + OM_uint32 status_value, + gss_buffer_t status_string); + +char *g_canonicalize_host(char *hostname); + +char *g_strdup(char *str); + +/** declarations of internal name mechanism functions **/ + +OM_uint32 generic_gss_release_buffer + (OM_uint32*, /* minor_status */ + gss_buffer_t /* buffer */ + ); + +OM_uint32 generic_gss_release_oid_set + (OM_uint32*, /* minor_status */ + gss_OID_set* /* set */ + ); + +#endif /* _GSSAPIP_GENERIC_H_ */ diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c new file mode 100644 index 000000000..26d7eebf6 --- /dev/null +++ b/src/lib/gssapi/generic/gssapi_generic.c @@ -0,0 +1,39 @@ +/* + * 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" + +static const gss_OID_desc oids[] = { + {2, "\001\001"}, + {2, "\001\002"}, + {2, "\001\003"}, + {2, "\001\004"}, +}; + +const_gss_OID gss_nt_user_name = oids+0; +const_gss_OID gss_nt_machine_uid_name = oids+1; +const_gss_OID gss_nt_string_uid_name = oids+2; +const_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 new file mode 100644 index 000000000..8d934dda5 --- /dev/null +++ b/src/lib/gssapi/generic/gssapi_generic.h @@ -0,0 +1,37 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GSSAPI_GENERIC_H_ +#define _GSSAPI_GENERIC_H_ + +/* + * $Id$ + */ + +#include + +extern const gss_OID_desc * const gss_nt_user_name; +extern const gss_OID_desc * const gss_nt_machine_uid_name; +extern const gss_OID_desc * const gss_nt_string_uid_name; +extern const gss_OID_desc * const gss_nt_service_name; + +#endif /* _GSSAPI_GENERIC_H_ */ diff --git a/src/lib/gssapi/generic/gssapi_generic_err.et b/src/lib/gssapi/generic/gssapi_generic_err.et new file mode 100644 index 000000000..fed788c29 --- /dev/null +++ b/src/lib/gssapi/generic/gssapi_generic_err.et @@ -0,0 +1,38 @@ +# +# Copyright 1993 by OpenVision Technologies, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software +# and its documentation for any purpose is hereby granted without fee, +# provided that the above copyright notice appears in all copies and +# that both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of OpenVision not be used +# in advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. OpenVision makes no +# representations about the suitability of this software for any +# purpose. It is provided "as is" without express or implied warranty. +# +# OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# + +# +# $Id$ +# + +error_table ggss + +error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string" +error_code G_BAD_STRING_UID, "STRING-UID-NAME contains nondigits" +error_code G_NOUSER, "UID does not resolve to username" +error_code G_VALIDATE_FAILED, "Validation error" +error_code G_BUFFER_ALLOC, "Couldn't allocate gss_buffer_t data" +error_code G_BAD_MSG_CTX, "Message context invalid" +error_code G_WRONG_SIZE, "Buffer is the wrong size" +error_code G_BAD_USAGE, "Credential usage type is unknown" +error_code G_UNKNOWN_QOP, "Unknown quality of protection specified" +end diff --git a/src/lib/gssapi/generic/release_buffer.c b/src/lib/gssapi/generic/release_buffer.c new file mode 100644 index 000000000..ecb8eab08 --- /dev/null +++ b/src/lib/gssapi/generic/release_buffer.c @@ -0,0 +1,42 @@ +/* + * 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" + +OM_uint32 +generic_gss_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + if ((buffer->length) && + (buffer->value)) { + xfree(buffer->value); + buffer->length = 0; + buffer->value = NULL; + } + + *minor_status = 0; + 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..e821e6eec --- /dev/null +++ b/src/lib/gssapi/generic/release_oid_set.c @@ -0,0 +1,44 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gssapiP_generic.h" + +/* + * $Id$ + */ + +OM_uint32 +generic_gss_release_oid_set(OM_uint32 *minor_status, + gss_OID_set *set) +{ + *minor_status = 0; + + if (*set == GSS_C_NULL_OID_SET) + return(GSS_S_COMPLETE); + + xfree((*set)->elements); + xfree(*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 new file mode 100644 index 000000000..63c10522e --- /dev/null +++ b/src/lib/gssapi/generic/util_buffer.c @@ -0,0 +1,46 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_generic.h" +#include + +/* return nonzero on success, 0 on failure + make sure that buffer is consistent (release'able) when this + function exits, no matter what the exit value */ + +int g_make_string_buffer(const char *str, gss_buffer_t buffer) +{ + buffer->length = strlen(str)+1; + + if ((buffer->value = (void *) xmalloc(buffer->length)) == NULL) { + buffer->length = 0; + return(0); + } + + strcpy(buffer->value, str); + + return(1); +} diff --git a/src/lib/gssapi/generic/util_canonhost.c b/src/lib/gssapi/generic/util_canonhost.c new file mode 100644 index 000000000..8fb7a03fe --- /dev/null +++ b/src/lib/gssapi/generic/util_canonhost.c @@ -0,0 +1,53 @@ +/* + * 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$ + */ + +/* This file could be OS specific */ + +#include +#include +#include +#include + +#include "gssapiP_generic.h" + +char *g_canonicalize_host(char *hostname) +{ + struct hostent *hent; + char *canon, *str; + + if ((hent = gethostbyname(hostname)) == NULL) + return(NULL); + + if ((canon = xmalloc(strlen(hent->h_name)+1)) == NULL) + return(NULL); + + strcpy(canon, hent->h_name); + + for (str = canon; *str; str++) + if (isupper(*str)) *str = tolower(*str); + + return(canon); +} diff --git a/src/lib/gssapi/generic/util_dup.c b/src/lib/gssapi/generic/util_dup.c new file mode 100644 index 000000000..4da654719 --- /dev/null +++ b/src/lib/gssapi/generic/util_dup.c @@ -0,0 +1,40 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_generic.h" +#include + +char *g_strdup(char *str) +{ + char *ret; + + if ((ret = (char *) xmalloc(strlen(str)+1)) == NULL) + return(NULL); + + strcpy(ret, str); + + return(ret); +} diff --git a/src/lib/gssapi/generic/util_oid.c b/src/lib/gssapi/generic/util_oid.c new file mode 100644 index 000000000..40f730a36 --- /dev/null +++ b/src/lib/gssapi/generic/util_oid.c @@ -0,0 +1,54 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gssapiP_generic.h" + +/* + * $Id$ + */ + +int +g_copy_OID_set(const gss_OID_set_desc * const in, gss_OID_set *out) +{ + gss_OID_set copy; + int i; + + *out = NULL; + + if ((copy = + (gss_OID_set_desc *) xmalloc(sizeof(gss_OID_set_desc))) == NULL) + return(0); + + copy->count = in->count; + + if ((copy->elements = + (gss_OID_desc *) xmalloc(sizeof(gss_OID_desc)*copy->count)) == NULL) { + xfree(copy); + return(0); + } + + for (i=0; icount; i++) + copy->elements[i] = in->elements[i]; + + *out = copy; + return(1); +} diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c new file mode 100644 index 000000000..3fad4b9e5 --- /dev/null +++ b/src/lib/gssapi/generic/util_token.c @@ -0,0 +1,183 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gssapiP_generic.h" +#include + +/* + * $Id$ + */ + +/* XXXX this code currently makes the assumption that a mech oid will + never be longer than 127 bytes. This assumption is not inherent in + the interfaces, so the code can be fixed if the OSI namespace + balloons unexpectedly. */ + +/* Each token looks like this: + +0x60 tag for APPLICATION 0, SEQUENCE + (constructed, definite-length) + possible multiple bytes, need to parse/generate + 0x06 tag for OBJECT IDENTIFIER + compile-time constant string (assume 1 byte) + compile-time constant string + the ANY containing the application token + bytes 0,1 are the token type + bytes 2,n are the token data + +For the purposes of this abstraction, the token "header" consists of +the sequence tag and length octets, the mech OID DER encoding, and the +first two inner bytes, which indicate the token type. The token +"body" consists of everything else. + +*/ + +static int der_length_size(int length) +{ + if (length < (1<<7)) + return(1); + else if (length < (1<<8)) + return(2); + else if (length < (1<<16)) + return(3); + else if (length < (1<<24)) + return(4); + else + return(5); +} + +static void der_write_length(unsigned char **buf, int length) +{ + if (length < (1<<7)) { + *(*buf)++ = (unsigned char) length; + } else { + *(*buf)++ = (unsigned char) (der_length_size(length)+127); + if (length >= (1<<24)) + *(*buf)++ = (unsigned char) (length>>24); + if (length >= (1<<16)) + *(*buf)++ = (unsigned char) ((length>>16)&0xff); + if (length >= (1<<8)) + *(*buf)++ = (unsigned char) ((length>>8)&0xff); + *(*buf)++ = (unsigned char) (length&0xff); + } +} + +/* returns decoded length, or < 0 on failure. Advances buf and + decrements bufsize */ + +static int der_read_length(unsigned char **buf, int *bufsize) +{ + unsigned char sf; + int ret; + + if (*bufsize < 1) + return(-1); + sf = *(*buf)++; + (*bufsize)--; + if (sf & 0x80) { + if ((sf &= 0x7f) > ((*bufsize)-1)) + return(-1); + ret = 0; + for (; sf; sf--) { + ret = (ret<<8) + (*(*buf)++); + (*bufsize)--; + } + } else { + ret = sf; + } + + return(ret); +} + +/* returns the length of a token, given the mech oid and the body size */ + +int g_token_size(const_gss_OID mech, unsigned int body_size) +{ + /* set body_size to sequence contents size */ + body_size += 4 + mech->length; + return(1 + der_length_size(body_size) + body_size); +} + +/* fills in a buffer with the token header. The buffer is assumed to + be the right size. buf is advanced past the token header */ + +void g_make_token_header(const_gss_OID mech, int body_size, + unsigned char **buf, int tok_type) +{ + *(*buf)++ = 0x60; + der_write_length(buf, 4 + mech->length + body_size); + *(*buf)++ = 0x06; + *(*buf)++ = (unsigned char) mech->length; + TWRITE_STR(*buf, mech->elements, mech->length); + *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff); + *(*buf)++ = (unsigned char) (tok_type&0xff); +} + +/* given a buffer containing a token, reads and verifies the token, + leaving buf advanced past the token header, and setting body_size + to the number of remaining bytes */ + +int g_verify_token_header(const_gss_OID mech, int *body_size, + unsigned char **buf, int tok_type, int toksize) +{ + int seqsize; + gss_OID_desc toid; + + if ((toksize-=1) < 0) + return(0); + if (*(*buf)++ != 0x60) + return(0); + + if ((seqsize = der_read_length(buf, &toksize)) < 0) + return(0); + + if (seqsize != toksize) + return(0); + + if ((toksize-=1) < 0) + return(0); + if (*(*buf)++ != 0x06) + return(0); + + if ((toksize-=1) < 0) + return(0); + toid.length = *(*buf)++; + + if ((toksize-=toid.length) < 0) + return(0); + toid.elements = *buf; + (*buf)+=toid.length; + + if (! g_OID_equal(&toid, mech)) + return(0); + + if ((toksize-=2) < 0) + return(0); + + if ((*(*buf)++ != ((tok_type>>8)&0xff)) || + (*(*buf)++ != (tok_type&0xff))) + return(0); + + *body_size = toksize; + + return(1); +} diff --git a/src/lib/gssapi/generic/util_validate.c b/src/lib/gssapi/generic/util_validate.c new file mode 100644 index 000000000..0c25c2644 --- /dev/null +++ b/src/lib/gssapi/generic/util_validate.c @@ -0,0 +1,153 @@ +/* + * 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$ + */ + +/* + * functions to validate name, credential, and context handles + */ + +#include "gssapiP_generic.h" + +#include +#include +#include +#include + +#define V_NAME 1 +#define V_CRED_ID 2 +#define V_CTX_ID 3 + +typedef struct _vkey { + int type; + void *ptr; +} vkey; + +static const int one = 1; +static const DBT dbtone = { (void *) &one, sizeof(one) }; + +/* All these functions return 0 on failure, and non-zero on success */ + +static int g_save(DB **vdb, int type, void *ptr) +{ + vkey vk; + DBT key; + + if (!*vdb) + *vdb = dbopen(NULL, O_CREAT|O_RDWR, O_CREAT|O_RDWR, DB_HASH, NULL); + + vk.type = type; + vk.ptr = ptr; + + key.data = &vk; + key.size = sizeof(vk); + + return((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0); +} + +static int g_validate(DB **vdb, int type, void *ptr) +{ + vkey vk; + DBT key, value; + + if (!*vdb) + return(0); + + vk.type = type; + vk.ptr = ptr; + + key.data = &vk; + key.size = sizeof(vk); + + if ((*((*vdb)->get))(*vdb, &key, &value, 0)) + return(0); + + return((value.size == sizeof(one)) && + (*((int *) value.data) == one)); +} + +static int g_delete(DB **vdb, int type, void *ptr) +{ + vkey vk; + DBT key; + + if (!*vdb) + return(0); + + vk.type = type; + vk.ptr = ptr; + + key.data = &vk; + key.size = sizeof(vk); + + return((*((*vdb)->del))(*vdb, &key, 0) == 0); +} + +/* functions for each type */ + +/* save */ + +int g_save_name(void **vdb, gss_name_t *name) +{ + return(g_save((DB **) vdb, V_NAME, (void *) name)); +} +int g_save_cred_id(void **vdb, gss_cred_id_t *cred) +{ + return(g_save((DB **) vdb, V_CRED_ID, (void *) cred)); +} +int g_save_ctx_id(void **vdb, gss_ctx_id_t *ctx) +{ + return(g_save((DB **) vdb, V_CTX_ID, (void *) ctx)); +} + +/* validate */ + +int g_validate_name(void **vdb, gss_name_t *name) +{ + return(g_validate((DB **) vdb, V_NAME, (void *) name)); +} +int g_validate_cred_id(void **vdb, gss_cred_id_t *cred) +{ + return(g_validate((DB **) vdb, V_CRED_ID, (void *) cred)); +} +int g_validate_ctx_id(void **vdb, gss_ctx_id_t *ctx) +{ + return(g_validate((DB **) vdb, V_CTX_ID, (void *) ctx)); +} + +/* delete */ + +int g_delete_name(void **vdb, gss_name_t *name) +{ + return(g_delete((DB **) vdb, V_NAME, (void *) name)); +} +int g_delete_cred_id(void **vdb, gss_cred_id_t *cred) +{ + return(g_delete((DB **) vdb, V_CRED_ID, (void *) cred)); +} +int g_delete_ctx_id(void **vdb, gss_ctx_id_t *ctx) +{ + return(g_delete((DB **) vdb, V_CTX_ID, (void *) ctx)); +} + diff --git a/src/lib/gssapi/krb5/Makefile b/src/lib/gssapi/krb5/Makefile new file mode 100644 index 000000000..0235b4d1f --- /dev/null +++ b/src/lib/gssapi/krb5/Makefile @@ -0,0 +1,98 @@ +# +# 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$ + +TOP = ../../.. +include $(TOP)/config.mk/template + +CCSRCS = \ + accept_sec_context.c \ + acquire_cred.c \ + compare_name.c \ + context_time.c \ + delete_sec_context.c \ + display_name.c \ + display_status.c \ + get_tkt_flags.c \ + gssapi_krb5.c \ + import_name.c \ + indicate_mechs.c \ + init_sec_context.c \ + inquire_context.c \ + inquire_cred.c \ + k5seal.c \ + k5unseal.c \ + krb5_gss_glue.c \ + process_context_token.c \ + release_cred.c \ + release_name.c \ + seal.c \ + sign.c \ + unseal.c \ + util_cksum.c \ + util_crypt.c \ + util_seed.c \ + util_seqnum.c \ + verify.c +CCOBJS = $(addsuffix .o,$(basename $(CCSRCS))) + +ETSRCS = gssapi_krb5_err.et +ETCS = $(addsuffix .c,$(basename $(ETSRCS))) +ETHS = $(addsuffix .h,$(basename $(ETSRCS))) +ETOBJS = $(addsuffix .o,$(basename $(ETSRCS))) + +GENERICOBJS := $(addprefix ../generic/,$(shell $(MAKE) -f ../generic/Makefile listobjs)) +GENERICSRCS := $(addsuffix .c,$(basename $(GENERICOBJS))) + +CFLAGS := -I. -I../generic $(CFLAGS) + +KRB5LIB = libgssapi_krb5.a + +all:: $(KRB5LIB) + +all:: $(ETHS) $(ETCS) + +$(GENERICOBJS): + @echo Not all generic objects exist. + false + +SRCS = $(CCSRCS) +DEPENDS = $(ETHS) +expand Depend + +ETABLES = $(ETSRCS) +expand ErrorTables + +LIB = $(KRB5LIB) +OBJS = $(CCOBJS) $(ETOBJS) $(GENERICOBJS) +expand InstallLibrary + +SRCS = $(CCSRCS) +expand Saber + +clean:: + $(CLEAN) $(CCOBJS) $(ETOBJS) + +HDRS = gssapi_krb5.h +HDRS_DIR = gssapi +expand InstallIncludes diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c new file mode 100644 index 000000000..ae51bdff3 --- /dev/null +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -0,0 +1,441 @@ +/* + * 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" +#include + +/* + * $Id$ + */ + +/* 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 +static krb5_error_code +rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, + krb5_kvno kvno, krb5_keyblock **keyblock) +#include +{ + 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); +} + +static krb5_error_code +make_ap_rep(krb5_tkt_authent *authdat, + krb5_keyblock *subkey, + krb5_int32 *seq_send, + gss_buffer_t token) +{ + krb5_error_code code; + krb5_ap_rep_enc_part ap_rep_data; + krb5_data ap_rep; + int tlen; + unsigned char *t, *ptr; + + /* make the ap_rep */ + + ap_rep_data.ctime = authdat->authenticator->ctime; + ap_rep_data.cusec = authdat->authenticator->cusec; + ap_rep_data.subkey = authdat->authenticator->subkey; + + if (code = krb5_generate_seq_number(authdat->ticket->enc_part2->session, + &ap_rep_data.seq_number)) + return(code); + + if (code = krb5_mk_rep(&ap_rep_data, subkey, &ap_rep)) + return(code); + + /* build up the token */ + + /* allocate space for the token */ + tlen = g_token_size(gss_mech_krb5, ap_rep.length); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { + xfree(ap_rep.data); + return(ENOMEM); + } + + /* fill in the buffer */ + + ptr = t; + + g_make_token_header(gss_mech_krb5, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); + + TWRITE_STR(ptr, ap_rep.data, ap_rep.length); + + /* free the ap_rep */ + + xfree(ap_rep.data); + + /* pass everything back */ + + *seq_send = ap_rep_data.seq_number; + + token->length = tlen; + token->value = (void *) t; + + return(0); +} + +OM_uint32 +krb5_gss_accept_sec_context(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, + int *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + unsigned char *ptr, *ptr2; + long tmp; + krb5_gss_cred_id_t cred; + krb5_data ap_req; + int i; + krb5_error_code code; + krb5_address addr, *paddr; + krb5_tkt_authent *authdat; + krb5_checksum md5; + krb5_rcache rcache; + krb5_principal name; + int gss_flags; + krb5_gss_ctx_id_rec *ctx; + krb5_timestamp now; + gss_buffer_desc token; + + /* set up returns to be freeable */ + + if (src_name) + *src_name = GSS_C_NO_NAME; + output_token->length = 0; + output_token->value = NULL; + if (mech_type) + *mech_type = GSS_C_NULL_OID; + /* return a bogus cred handle */ + if (delegated_cred_handle) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + + /* context handle must be unspecified */ + + /*SUPPRESS 29*/ + if (*context_handle != GSS_C_NO_CONTEXT) { + *minor_status = 0; + return(GSS_S_NO_CONTEXT); + } + + /* validate the cred handle - no default */ + + /*SUPPRESS 29*/ + if (verifier_cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return(GSS_S_NO_CRED); + } else { + if (! kg_validate_cred_id(verifier_cred_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL); + } + } + + cred = (krb5_gss_cred_id_t) verifier_cred_handle; + + /* make sure the supplied credentials are valid for accept */ + + if ((cred->usage != GSS_C_ACCEPT) && + (cred->usage != GSS_C_BOTH)) { + *minor_status = 0; + return(GSS_S_NO_CRED); + } + + /* verify the token's integrity, and leave the token in ap_req */ + + ptr = (unsigned char *) input_token->value; + + if (! g_verify_token_header(gss_mech_krb5, &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, input_token->length)) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + TREAD_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); + + /* construct the sender_addr */ + + if ((input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) && + (input_chan_bindings->initiator_addrtype == GSS_C_AF_INET)) { + /* XXX is this right? */ + addr.addrtype = ADDRTYPE_INET; + addr.length = input_chan_bindings->initiator_address.length; + addr.contents = input_chan_bindings->initiator_address.value; + + paddr = &addr; + } else { + paddr = NULL; + } + + /* decode the AP_REQ message */ + + /* get the rcache pointer */ + + if (krb5_princ_size(cred->princ) > 1) { + if (code = krb5_get_server_rcache(krb5_princ_component(cred->princ, 1), + &rcache)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + rcache = NULL; + } + + /* decode the message */ + + if (code = krb5_rd_req(&ap_req, cred->princ, paddr, NULL, &rd_req_keyproc, + (krb5_pointer) cred->keytab, rcache, &authdat)) { + (void) krb5_rc_close(rcache); + xfree(rcache); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* close and free the rcache */ + + krb5_rc_close(rcache); + xfree(rcache); + + /* 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); + } + + /* verify that the checksum is correct */ + + /* 24 == checksum length: see token formats document */ + if ((authdat->authenticator->checksum->checksum_type != CKSUMTYPE_KG_CB) || + (authdat->authenticator->checksum->length != 24)) { + krb5_free_tkt_authent(authdat); + *minor_status = 0; + return(GSS_S_BAD_BINDINGS); + } + + ptr = (unsigned char *) authdat->authenticator->checksum->contents; + + if (code = kg_checksum_channel_bindings(input_chan_bindings, &md5)) { + krb5_free_tkt_authent(authdat); + *minor_status = code; + return(GSS_S_FAILURE); + } + + TREAD_INT(ptr, tmp); + if (tmp != md5.length) { + xfree(md5.contents); + krb5_free_tkt_authent(authdat); + *minor_status = KG_BAD_LENGTH; + return(GSS_S_FAILURE); + } + + TREAD_STR(ptr, ptr2, md5.length); + if (memcmp(ptr2, md5.contents, md5.length) != 0) { + xfree(md5.contents); + krb5_free_tkt_authent(authdat); + *minor_status = 0; + return(GSS_S_BAD_BINDINGS); + } + + xfree(md5.contents); + + TREAD_INT(ptr, gss_flags); + + /* create the ctx struct and start filling it in */ + + if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) + == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + ctx->initiate = 0; + ctx->mutual = gss_flags & GSS_C_MUTUAL_FLAG; + ctx->seed_init = 0; + ctx->cred = cred; + + if (code = krb5_copy_principal(cred->princ, &ctx->here)) { + xfree(ctx); + krb5_free_tkt_authent(authdat); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = krb5_copy_principal(authdat->authenticator->client, + &ctx->there)) { + krb5_free_principal(ctx->here); + xfree(ctx); + krb5_free_tkt_authent(authdat); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = krb5_copy_keyblock(authdat->authenticator->subkey, + &ctx->subkey)) { + krb5_free_principal(ctx->there); + krb5_free_principal(ctx->here); + xfree(ctx); + krb5_free_tkt_authent(authdat); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* fill in the encryption descriptors */ + + krb5_use_cstype(&ctx->enc.eblock, ETYPE_RAW_DES_CBC); + ctx->enc.processed = 0; + if (code = krb5_copy_keyblock(ctx->subkey, &ctx->enc.key)) + return(code); + for (i=0; ienc.key->length; i++) + /*SUPPRESS 113*/ + ctx->enc.key->contents[i] ^= 0xf0; + + krb5_use_cstype(&ctx->seq.eblock, ETYPE_RAW_DES_CBC); + ctx->seq.processed = 0; + ctx->seq.key = ctx->subkey; + + ctx->endtime = authdat->ticket->enc_part2->times.endtime; + + ctx->flags = authdat->ticket->enc_part2->flags; + + ctx->seq_recv = authdat->authenticator->seq_number; + + /* at this point, the entire context structure is filled in, + so it can be released. */ + + /* generate an AP_REP if necessary */ + + if (ctx->mutual) { + if (code = make_ap_rep(authdat, ctx->subkey, &ctx->seq_send, &token)) { + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, + NULL); + krb5_free_tkt_authent(authdat); + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + token.length = 0; + token.value = NULL; + ctx->seq_send = ctx->seq_recv; + } + + /* done with authdat! */ + krb5_free_tkt_authent(authdat); + + /* set the return arguments */ + + if (src_name) { + if (code = krb5_copy_principal(ctx->there, &name)) { + if (token.value) + xfree(token.value); + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, + NULL); + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + if (mech_type) + *mech_type = (gss_OID) gss_mech_krb5; + + if (time_rec) { + if (code = krb5_timeofday(&now)) { + if (src_name) + krb5_free_principal(name); + xfree(token.value); + (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 | ctx->mutual; + + ctx->established = 1; + + + /* intern the src_name */ + + if (src_name) + if (! kg_save_name((gss_name_t) name)) { + krb5_free_principal(name); + if (token.value) + xfree(token.value); + (void)krb5_gss_delete_sec_context(minor_status, + (gss_ctx_id_t *) &ctx, NULL); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* intern the context handle */ + + if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { + if (src_name) { + (void) kg_delete_name((gss_name_t) name); + krb5_free_principal(name); + } + if (token.value) + xfree(token.value); + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, + NULL); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + *context_handle = ctx; + + *output_token = token; + + if (src_name) + *src_name = (gss_name_t) name; + + /* finally! */ + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c new file mode 100644 index 000000000..d09c70809 --- /dev/null +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -0,0 +1,418 @@ +/* + * 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$ + */ + +/* 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 + of the return value. + If successful, set the keytab-specific fields in cred + */ + +static OM_uint32 +acquire_accept_cred(OM_uint32 *minor_status, + gss_name_t desired_name, + krb5_principal *output_princ, + krb5_gss_cred_id_rec *cred) +{ + krb5_error_code code; + krb5_principal princ; + krb5_keytab kt; + krb5_keytab_entry entry; + krb5_kt_cursor cur; + + *output_princ = NULL; + cred->keytab = NULL; + + /* open the default keytab */ + + if (code = krb5_kt_default(&kt)) { + *minor_status = code; + return(GSS_S_CRED_UNAVAIL); + } + + /* figure out what principal to use. If the default name is + requested, use the default sn2princ output */ + + if (desired_name == GSS_C_NO_NAME) { + if (code = krb5_sname_to_principal(NULL, NULL, KRB5_NT_SRV_HST, + &princ)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + *output_princ = princ; + } else { + princ = (krb5_principal) desired_name; + } + + /* iterate over the keytab searching for the principal */ + + if (code = krb5_kt_start_seq_get(kt, &cur)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + while (!(code = krb5_kt_next_entry(kt, &entry, &cur))) { + if (krb5_principal_compare(entry.principal, princ)) { + code = 0; + krb5_kt_free_entry(&entry); + break; + } + krb5_kt_free_entry(&entry); + } + + if (code == KRB5_KT_END) { + /* this means that the principal wasn't in the keytab */ + (void)krb5_kt_end_seq_get(kt, &cur); + *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(kt, &cur); + *minor_status = code; + return(GSS_S_FAILURE); + } else { + /* this means that we found a matching entry */ + if (code = krb5_kt_end_seq_get(kt, &cur)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + /* hooray. we made it */ + + cred->keytab = kt; + return(GSS_S_COMPLETE); +} + +/* get credentials corresponding to the default credential cache. + 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 + of the return value. + If successful, set the ccache-specific fields in cred. + */ + +static OM_uint32 +acquire_init_cred(OM_uint32 *minor_status, + gss_name_t desired_name, + krb5_principal *output_princ, + krb5_gss_cred_id_rec *cred) +{ + krb5_error_code code; + krb5_ccache ccache; + krb5_principal princ; + krb5_flags flags; + krb5_cc_cursor cur; + krb5_creds creds; + int got_endtime; + + cred->ccache = NULL; + + /* open the default credential cache */ + + if (code = krb5_cc_default(&ccache)) { + *minor_status = code; + return(GSS_S_CRED_UNAVAIL); + } + + /* turn off OPENCLOSE mode while extensive frobbing is going on */ + + flags = 0; /* turns off OPENCLOSE mode */ + if (code = krb5_cc_set_flags(ccache, flags)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* get out the principal name and see if it matches */ + + if (code = krb5_cc_get_principal(ccache, &princ)) { + (void)krb5_cc_close(ccache); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (desired_name != GSS_C_NO_NAME) { + if (! krb5_principal_compare(princ, (krb5_principal) desired_name)) { + (void)krb5_free_principal(princ); + (void)krb5_cc_close(ccache); + *minor_status = KG_CCACHE_NOMATCH; + return(GSS_S_CRED_UNAVAIL); + } + (void)krb5_free_principal(princ); + princ = (krb5_principal) desired_name; + } else { + *output_princ = princ; + } + + /* iterate over the ccache, find the tgt */ + + if (code = krb5_cc_start_seq_get(ccache, &cur)) { + (void)krb5_cc_close(ccache); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* this is hairy. If there's a tgt for the principal's local realm + in here, that's what we want for the expire time. But if + there's not, then we want to use the first key. */ + + got_endtime = 0; + + while (!(code = krb5_cc_next_cred(ccache, &cur, &creds))) { + if ((creds.server->length == 2) && + (strcmp(creds.server->realm.data, princ->realm.data) == 0) && + (strcmp((char *) creds.server->data[0].data, "krbtgt") == 0) && + (strcmp((char *) creds.server->data[1].data, + princ->realm.data) == 0)) { + cred->tgt_expire = creds.times.endtime; + got_endtime = 1; + *minor_status = 0; + code = 0; + krb5_free_cred_contents(&creds); + break; + } + if (got_endtime == 0) { + cred->tgt_expire = creds.times.endtime; + got_endtime = 1; + *minor_status = KG_TGT_MISSING; + } + krb5_free_cred_contents(&creds); + } + + if (code && code != KRB5_CC_END) { + /* this means some error occurred reading the ccache */ + (void)krb5_cc_end_seq_get(ccache, &cur); + (void)krb5_cc_close(ccache); + *minor_status = code; + return(GSS_S_FAILURE); + } else { + /* this means that we found an endtime to use. */ + if (code = krb5_cc_end_seq_get(ccache, &cur)) { + (void)krb5_cc_close(ccache); + *minor_status = code; + return(GSS_S_FAILURE); + } + flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */ + if (code = krb5_cc_set_flags(ccache, flags)) { + (void)krb5_cc_close(ccache); + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + /* the credentials match and are valid */ + + cred->ccache = ccache; + /* minor_status is set while we are iterating over the ccache */ + return(GSS_S_COMPLETE); +} + +/*ARGSUSED*/ +OM_uint32 +krb5_gss_acquire_cred(OM_uint32 *minor_status, + gss_name_t desired_name, + OM_uint32 time_req, + gss_OID_set desired_mechs, + int cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + int i; + krb5_gss_cred_id_t cred; + gss_OID_set mechs; + OM_uint32 ret; + krb5_error_code code; + + /* make sure all outputs are valid */ + + *output_cred_handle = NULL; + if (actual_mechs) + *actual_mechs = NULL; + if (time_rec) + *time_rec = 0; + + /* validate the name */ + + /*SUPPRESS 29*/ + if ((desired_name != GSS_C_NO_NAME) && + (! kg_validate_name(desired_name))) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + /* verify that the requested mechanism set is the default, or + contains krb5 */ + + if (desired_mechs != GSS_C_NULL_OID_SET) { + for (i=0; icount; i++) + if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) + break; + if (i == desired_mechs->count) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + } + + /* create the gss cred structure */ + + if ((cred = + (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + cred->usage = cred_usage; + cred->princ = NULL; + + cred->keytab = NULL; + cred->ccache = NULL; + + if ((cred_usage != GSS_C_INITIATE) && + (cred_usage != GSS_C_ACCEPT) && + (cred_usage != GSS_C_BOTH)) { + xfree(cred); + *minor_status = G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + /* if requested, acquire credentials for accepting */ + /* this will fill in cred->princ if the desired_name is not specified */ + + if ((cred_usage == GSS_C_ACCEPT) || + (cred_usage == GSS_C_BOTH)) + if ((ret = acquire_accept_cred(minor_status, desired_name, + &(cred->princ), cred)) + != GSS_S_COMPLETE) { + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + /* minor_status set by acquire_accept_cred() */ + return(ret); + } + + /* if requested, acquire credentials for initiation */ + /* this will fill in cred->princ if it wasn't set above, and + the desired_name is not specified */ + + if ((cred_usage == GSS_C_INITIATE) || + (cred_usage == GSS_C_BOTH)) + if ((ret = + acquire_init_cred(minor_status, + cred->princ?cred->princ:desired_name, + &(cred->princ), cred)) + != GSS_S_COMPLETE) { + if (cred->keytab) + krb5_kt_close(cred->keytab); + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + /* minor_status set by acquire_init_cred() */ + return(ret); + } + + /* if the princ wasn't filled in already, fill it in now */ + + if (!cred->princ) + if (code = krb5_copy_principal((krb5_principal) desired_name, + &(cred->princ))) { + if (cred->ccache) + (void)krb5_cc_close(cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(cred->keytab); + xfree(cred); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /*** at this point, the cred structure has been completely created */ + + /* compute time_rec */ + + if (cred_usage == GSS_C_ACCEPT) { + if (time_rec) + *time_rec = GSS_C_INDEFINITE; + } else { + krb5_timestamp now; + + if (code = krb5_timeofday(&now)) { + if (cred->ccache) + (void)krb5_cc_close(cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(cred->keytab); + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (time_rec) + *time_rec = cred->tgt_expire - now; + } + + /* create mechs */ + + if (actual_mechs) { + if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) { + if (cred->ccache) + (void)krb5_cc_close(cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(cred->keytab); + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + } + + /* intern the credential handle */ + + if (! kg_save_cred_id((gss_cred_id_t) cred)) { + free(mechs->elements); + free(mechs); + if (cred->ccache) + (void)krb5_cc_close(cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(cred->keytab); + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* return success */ + + *minor_status = 0; + *output_cred_handle = (gss_cred_id_t) cred; + if (actual_mechs) + *actual_mechs = mechs; + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/compare_name.c b/src/lib/gssapi/krb5/compare_name.c new file mode 100644 index 000000000..455bd6ddd --- /dev/null +++ b/src/lib/gssapi/krb5/compare_name.c @@ -0,0 +1,49 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id$ + */ + +#include "gssapiP_krb5.h" + +OM_uint32 +krb5_gss_compare_name(OM_uint32 *minor_status, + gss_name_t name1, + gss_name_t name2, + int *name_equal) +{ + if (! kg_validate_name(name1)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + if (! kg_validate_name(name2)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + *minor_status = 0; + *name_equal = krb5_principal_compare((krb5_principal) name1, + (krb5_principal) name2); + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c new file mode 100644 index 000000000..00b8ae3ab --- /dev/null +++ b/src/lib/gssapi/krb5/context_time.c @@ -0,0 +1,66 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_context_time(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + OM_uint32 *time_rec) +{ + krb5_error_code code; + krb5_gss_ctx_id_rec *ctx; + krb5_timestamp now; + krb5_deltat lifetime; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + if (code = krb5_timeofday(&now)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if ((lifetime = ctx->endtime - now) <= 0) { + *time_rec = 0; + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } else { + *time_rec = lifetime; + *minor_status = 0; + return(GSS_S_COMPLETE); + } +} diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c new file mode 100644 index 000000000..04196072c --- /dev/null +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -0,0 +1,92 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_delete_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token) +{ + krb5_gss_ctx_id_rec *ctx; + + if (output_token) { + output_token->length = 0; + output_token->value = NULL; + } + + /*SUPPRESS 29*/ + if (*context_handle == GSS_C_NO_CONTEXT) { + *minor_status = 0; + return(GSS_S_COMPLETE); + } + + /*SUPPRESS 29*/ + /* validate the context handle */ + if (! kg_validate_ctx_id(*context_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } + + /* construct a delete context token if necessary */ + + if (output_token) { + OM_uint32 major; + gss_buffer_desc empty = {0, NULL}; + + if (major = kg_seal(minor_status, *context_handle, 0, GSS_C_QOP_DEFAULT, + &empty, NULL, output_token, KG_TOK_DEL_CTX)) + return(major); + } + + /* invalidate the context handle */ + + (void)kg_delete_ctx_id(*context_handle); + + /* free all the context state */ + + ctx = (gss_ctx_id_t) *context_handle; + + if (ctx->enc.processed) + krb5_finish_key(&ctx->enc.eblock); + krb5_free_keyblock(ctx->enc.key); + + if (ctx->seq.processed) + krb5_finish_key(&ctx->seq.eblock); + + krb5_free_principal(ctx->here); + krb5_free_principal(ctx->there); + krb5_free_keyblock(ctx->subkey); + + xfree(ctx); + + /* zero the handle itself */ + + *context_handle = GSS_C_NO_CONTEXT; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/display_name.c b/src/lib/gssapi/krb5/display_name.c new file mode 100644 index 000000000..d5a83127f --- /dev/null +++ b/src/lib/gssapi/krb5/display_name.c @@ -0,0 +1,64 @@ +/* + * 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 +krb5_gss_display_name(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type) +{ + krb5_error_code code; + char *str; + + output_name_buffer->length = 0; + output_name_buffer->value = NULL; + + if (! kg_validate_name(input_name)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + if (code = krb5_unparse_name((krb5_principal) input_name, &str)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (! g_make_string_buffer(str, output_name_buffer)) { + xfree(str); + + *minor_status = G_BUFFER_ALLOC; + return(GSS_S_FAILURE); + } + + xfree(str); + + *minor_status = 0; + if (output_name_type) + *output_name_type = (gss_OID) gss_mech_krb5; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/display_status.c b/src/lib/gssapi/krb5/display_status.c new file mode 100644 index 000000000..974698d78 --- /dev/null +++ b/src/lib/gssapi/krb5/display_status.c @@ -0,0 +1,76 @@ +/* + * 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" +#include + +/* + * $Id$ + */ + +/* XXXX internationalization!! */ + +/**/ + +static int init_et = 0; + +/**/ + +OM_uint32 +krb5_gss_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const_gss_OID mech_type, + int *message_context, + gss_buffer_t status_string) +{ + status_string->length = 0; + status_string->value = NULL; + + if ((mech_type != GSS_C_NULL_OID) && + (! g_OID_equal(gss_mech_krb5, mech_type))) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + + if (status_type == GSS_C_GSS_CODE) { + return(g_display_major_status(minor_status, status_value, + message_context, status_string)); + } else if (status_type == GSS_C_MECH_CODE) { + if (!init_et) { + krb5_init_ets(); + initialize_k5g_error_table(); + init_et = 1; + } + + if (*message_context) { + *minor_status = G_BAD_MSG_CTX; + return(GSS_S_FAILURE); + } + + return(g_display_com_err_status(minor_status, status_value, + status_string)); + } else { + *minor_status = 0; + return(GSS_S_BAD_STATUS); + } +} diff --git a/src/lib/gssapi/krb5/get_tkt_flags.c b/src/lib/gssapi/krb5/get_tkt_flags.c new file mode 100644 index 000000000..a35259c06 --- /dev/null +++ b/src/lib/gssapi/krb5/get_tkt_flags.c @@ -0,0 +1,54 @@ +/* + * 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$ + */ + +OM_uint32 +gss_krb5_get_tkt_flags(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_flags *ticket_flags) +{ + krb5_gss_ctx_id_rec *ctx; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + if (ticket_flags) + *ticket_flags = ctx->flags; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h new file mode 100644 index 000000000..e61dae7b3 --- /dev/null +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -0,0 +1,322 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GSSAPIP_KRB5_H_ +#define _GSSAPIP_KRB5_H_ + +/* + * $Id$ + */ + +#include +#include +#include + +/* work around sunos braindamage */ +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif + +/* this must be after , since krb5 #defines xfree(), too */ +#include "../generic/gssapiP_generic.h" +#include "gssapi_krb5.h" +#include "gssapi_krb5_err.h" + +/** constants **/ + +#define CKSUMTYPE_KG_CB 0x8003 + +#define KG_TOK_CTX_AP_REQ 0x0100 +#define KG_TOK_CTX_AP_REP 0x0200 +#define KG_TOK_CTX_ERROR 0x0300 +#define KG_TOK_SIGN_MSG 0x0101 +#define KG_TOK_SEAL_MSG 0x0201 +#define KG_TOK_DEL_CTX 0x0102 + +/** internal types **/ + +typedef krb5_principal krb5_gss_name_t; + +typedef struct _krb5_gss_cred_id_rec { + /* name/type of credential */ + int usage; + krb5_principal princ; /* this is not interned as a gss_name_t */ + + /* keytab (accept) data */ + krb5_keytab keytab; + + /* ccache (init) data */ + krb5_ccache ccache; + krb5_timestamp tgt_expire; +} krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; + +typedef struct _krb5_gss_enc_desc { + int processed; + krb5_keyblock *key; + krb5_encrypt_block eblock; +} krb5_gss_enc_desc; + +typedef struct _krb5_gss_ctx_id_rec { + int initiate; /* nonzero if initiating, zero if accepting */ + int mutual; + int seed_init; + unsigned char seed[16]; + krb5_gss_cred_id_t cred; + krb5_principal here; + krb5_principal there; + krb5_keyblock *subkey; + krb5_gss_enc_desc enc; + krb5_gss_enc_desc seq; + krb5_timestamp endtime; + krb5_flags flags; + krb5_int32 seq_send; + krb5_int32 seq_recv; + int established; +} krb5_gss_ctx_id_rec, krb5_gss_ctx_id_t; + +extern void *kg_vdb; + +/* helper macros */ + +#define kg_save_name(name) g_save_name(&kg_vdb,name) +#define kg_save_cred_id(cred) g_save_cred_id(&kg_vdb,cred) +#define kg_save_ctx_id(ctx) g_save_ctx_id(&kg_vdb,ctx) + +#define kg_validate_name(name) g_validate_name(&kg_vdb,name) +#define kg_validate_cred_id(cred) g_validate_cred_id(&kg_vdb,cred) +#define kg_validate_ctx_id(ctx) g_validate_ctx_id(&kg_vdb,ctx) + +#define kg_delete_name(name) g_delete_name(&kg_vdb,name) +#define kg_delete_cred_id(cred) g_delete_cred_id(&kg_vdb,cred) +#define kg_delete_ctx_id(ctx) g_delete_ctx_id(&kg_vdb,ctx) + +/** helper functions **/ + +OM_uint32 kg_get_defcred(OM_uint32 *minor_status, gss_cred_id_t *cred); + +OM_uint32 kg_release_defcred(OM_uint32 *minor_status); + +krb5_error_code kg_checksum_channel_bindings(gss_channel_bindings_t cb, + krb5_checksum *cksum); + +krb5_error_code kg_make_seq_num(krb5_gss_enc_desc *ed, int direction, + int seqnum, unsigned char *cksum, + unsigned char *buf); + +krb5_error_code kg_make_seed(krb5_keyblock *key, unsigned char *seed); + +int kg_confounder_size(krb5_gss_enc_desc *ed); + +krb5_error_code kg_make_confounder(krb5_gss_enc_desc *ed, unsigned char *buf); + +int kg_encrypt_size(krb5_gss_enc_desc *ed, int n); + +krb5_error_code kg_encrypt(krb5_gss_enc_desc *ed, krb5_pointer iv, + krb5_pointer in, krb5_pointer out, int length); + +krb5_error_code kg_decrypt(krb5_gss_enc_desc *ed, krb5_pointer iv, + krb5_pointer in, krb5_pointer out, int length); + +OM_uint32 kg_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer, + int toktype); + +OM_uint32 kg_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_token_buffer, + gss_buffer_t message_buffer, + int *conf_state, + int *qop_state, + int toktype); + +/** declarations of internal name mechanism functions **/ + +OM_uint32 krb5_gss_acquire_cred + (OM_uint32*, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + int, /* cred_usage */ + gss_cred_id_t*, /* output_cred_handle */ + gss_OID_set*, /* actual_mechs */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 krb5_gss_release_cred + (OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + +OM_uint32 krb5_gss_init_sec_context + (OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + const_gss_OID, /* mech_type */ + int, /* 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 */ + int*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 krb5_gss_accept_sec_context + (OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_cred_id_t, /* verifier_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, + /* input_chan_bindings */ + gss_name_t*, /* src_name */ + gss_OID*, /* mech_type */ + gss_buffer_t, /* output_token */ + int*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + +OM_uint32 krb5_gss_process_context_token + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + +OM_uint32 krb5_gss_delete_sec_context + (OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + +OM_uint32 krb5_gss_context_time + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + +OM_uint32 krb5_gss_sign + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +OM_uint32 krb5_gss_verify + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + +OM_uint32 krb5_gss_seal + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +OM_uint32 krb5_gss_unseal + (OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int* /* qop_state */ + ); + +OM_uint32 krb5_gss_display_status + (OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + const_gss_OID, /* mech_type */ + int*, /* message_context */ + gss_buffer_t /* status_string */ + ); + +OM_uint32 krb5_gss_indicate_mechs + (OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + +OM_uint32 krb5_gss_compare_name + (OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + +OM_uint32 krb5_gss_display_name + (OM_uint32*, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID* /* output_name_type */ + ); + +OM_uint32 krb5_gss_import_name + (OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + const_gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + +OM_uint32 krb5_gss_release_name + (OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + +OM_uint32 krb5_gss_inquire_cred + (OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + int *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + +OM_uint32 krb5_gss_inquire_context + (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 */ + int*, /* ret_flags */ + int* /* locally_initiated */ + ); + +#endif /* _GSSAPIP_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c new file mode 100644 index 000000000..ada5f6f4a --- /dev/null +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -0,0 +1,90 @@ +/* + * 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" + +/** exported constants defined in gssapi_krb5.h **/ + +/* these are bogus, but will compile */ + +static const gss_OID_desc oids[] = { + /* this OID is from Ted. It's not official yet, but it's close. */ + {5, "\053\005\001\005\002"}, + {2, "\002\002"}, + {2, "\002\003"}, +}; + +const_gss_OID gss_mech_krb5 = oids+0; +const_gss_OID gss_nt_krb5_name = oids+1; +const_gss_OID gss_nt_krb5_principal = oids+2; + +static const gss_OID_set_desc oidsets[] = { + {1, (gss_OID) oids}, +}; + +const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0; + +void *kg_vdb = NULL; + +/** default credential support */ + +/* default credentials */ + +static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL; + +/* XXX what happens when the default credentials expire or are invalidated? */ + +OM_uint32 +kg_get_defcred(OM_uint32 *minor_status, gss_cred_id_t *cred) +{ + if (defcred == GSS_C_NO_CREDENTIAL) { + OM_uint32 major; + + if ((major = krb5_gss_acquire_cred(minor_status, GSS_C_NO_NAME, + GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, + GSS_C_INITIATE, &defcred, NULL, + NULL)) && + GSS_ERROR(major)) { + defcred = GSS_C_NO_CREDENTIAL; + return(major); + } + } + + *cred = defcred; + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +OM_uint32 +kg_release_defcred(OM_uint32 *minor_status) +{ + if (defcred == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return(GSS_S_COMPLETE); + } + + return(krb5_gss_release_cred(minor_status, &defcred)); +} diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h new file mode 100644 index 000000000..937609d64 --- /dev/null +++ b/src/lib/gssapi/krb5/gssapi_krb5.h @@ -0,0 +1,44 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GSSAPI_KRB5_H_ +#define _GSSAPI_KRB5_H_ + +/* + * $Id$ + */ + +#include +#include + +extern const gss_OID_desc * const gss_mech_krb5; +extern const gss_OID_set_desc * const gss_mech_set_krb5; + +extern const gss_OID_desc * const gss_nt_krb5_name; +extern const gss_OID_desc * const gss_nt_krb5_principal; + +OM_uint32 gss_krb5_get_tkt_flags(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_flags *ticket_flags); + + +#endif /* _GSSAPI_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/gssapi_krb5_err.et b/src/lib/gssapi/krb5/gssapi_krb5_err.et new file mode 100644 index 000000000..ca7a5434b --- /dev/null +++ b/src/lib/gssapi/krb5/gssapi_krb5_err.et @@ -0,0 +1,38 @@ +# +# Copyright 1993 by OpenVision Technologies, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software +# and its documentation for any purpose is hereby granted without fee, +# provided that the above copyright notice appears in all copies and +# that both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of OpenVision not be used +# in advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. OpenVision makes no +# representations about the suitability of this software for any +# purpose. It is provided "as is" without express or implied warranty. +# +# OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# + +# +# $Id$ +# + +error_table k5g + +error_code KG_CCACHE_NOMATCH, "Principal in credential cache does not match desired name" +error_code KG_KEYTAB_NOMATCH, "No principal in keytab matches desired name" +error_code KG_TGT_MISSING, "Credential cache has no TGT" +error_code KG_NO_SUBKEY, "Authenticator has no subkey" +error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established" +error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token" +error_code KG_BAD_LENGTH, "Invalid field length in token" +error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context" + +end diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c new file mode 100644 index 000000000..51fbd9f43 --- /dev/null +++ b/src/lib/gssapi/krb5/import_name.c @@ -0,0 +1,146 @@ +/* + * 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 +#include + +#include "gssapiP_krb5.h" + +/* + * errors: + * GSS_S_BAD_NAMETYPE if the type is bogus + * GSS_S_BAD_NAME if the type is good but the name is bogus + * GSS_S_FAILURE if memory allocation fails + */ + +OM_uint32 +krb5_gss_import_name(OM_uint32 *minor_status, + gss_buffer_t input_name_buffer, + const_gss_OID input_name_type, + gss_name_t *output_name) +{ + krb5_principal princ; + krb5_error_code code; + char *stringrep; + struct passwd *pw; + + /* set up default returns */ + + *output_name = NULL; + *minor_status = 0; + + /* Go find the appropriate string rep to pass into parse_name */ + + if ((input_name_type != GSS_C_NULL_OID) && + g_OID_equal(input_name_type, gss_nt_service_name)) { + char *tmp, *service, *host; + + if ((tmp = + (char *) xmalloc(strlen(input_name_buffer->value)+1)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + strcpy(tmp, input_name_buffer->value); + + service = tmp; + if ((host = strchr(tmp, '@')) == NULL) { + xfree(tmp); + *minor_status = G_BAD_SERVICE_NAME; + return(GSS_S_BAD_NAME); + } + *host = '\0'; + host++; + + code = krb5_sname_to_principal(host, service, KRB5_NT_SRV_HST, + &princ); + + xfree(tmp); + } else if ((input_name_type != GSS_C_NULL_OID) && + (g_OID_equal(input_name_type, gss_nt_krb5_principal))) { + krb5_principal input; + + if (input_name_buffer->length != sizeof(krb5_principal)) { + *minor_status = G_WRONG_SIZE; + return(GSS_S_BAD_NAME); + } + + input = *((krb5_principal *) input_name_buffer->value); + + if (code = krb5_copy_principal(input, &princ)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + stringrep = NULL; + + if ((input_name_type == GSS_C_NULL_OID) || + g_OID_equal(input_name_type, gss_nt_krb5_name) || + g_OID_equal(input_name_type, gss_nt_user_name)) { + stringrep = (char *) input_name_buffer->value; + } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) { + if (pw = getpwuid(*((uid_t *) input_name_buffer->value))) + stringrep = pw->pw_name; + else + *minor_status = G_NOUSER; + } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) { + if (pw = getpwuid((uid_t) atoi(input_name_buffer->value))) + stringrep = pw->pw_name; + else + *minor_status = G_NOUSER; + } else { + return(GSS_S_BAD_NAMETYPE); + } + + /* at this point, stringrep is set, or if not, *minor_status is. */ + + if (stringrep) + code = krb5_parse_name((char *) stringrep, &princ); + else + return(GSS_S_BAD_NAME); + } + + /* at this point, a krb5 function has been called to set princ. code + contains the return status */ + + if (code) { + *minor_status = (OM_uint32) code; + return(GSS_S_BAD_NAME); + } + + /* save the name in the validation database */ + + if (! kg_save_name((gss_name_t) princ)) { + krb5_free_principal(princ); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* return it */ + + *output_name = (gss_name_t) princ; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/indicate_mechs.c b/src/lib/gssapi/krb5/indicate_mechs.c new file mode 100644 index 000000000..c20679f95 --- /dev/null +++ b/src/lib/gssapi/krb5/indicate_mechs.c @@ -0,0 +1,36 @@ +/* + * 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 +krb5_gss_indicate_mechs(OM_uint32 *minor_status, + gss_OID_set *mech_set) +{ + *minor_status = 0; + *mech_set = (gss_OID_set) gss_mech_set_krb5; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c new file mode 100644 index 000000000..a62a286d6 --- /dev/null +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -0,0 +1,417 @@ +/* + * 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" +#include + +/* + * $Id$ + */ + +static krb5_error_code +make_ap_req(krb5_gss_cred_id_t cred, + krb5_principal server, + krb5_timestamp *endtime, + gss_channel_bindings_t chan_bindings, + int do_mutual, + krb5_keyblock **subkey, + krb5_flags *flags, + krb5_int32 *seqnum, + gss_buffer_t token) +{ + krb5_error_code code; + krb5_checksum md5, checksum; + krb5_creds creds; + krb5_authenticator authent; + krb5_data ap_req; + long tmp; + unsigned char *ptr; + unsigned char ckbuf[24]; /* see the token formats doc */ + unsigned char *t; + int tlen; + + /* build the checksum buffer */ + + /* compute the hash of the channel bindings */ + + if (code = kg_checksum_channel_bindings(chan_bindings, &md5)) + return(code); + + ptr = ckbuf; + + TWRITE_INT(ptr, tmp, md5.length); + TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length); + TWRITE_INT(ptr, tmp, do_mutual?GSS_C_MUTUAL_FLAG:0); + + /* done with this, free it */ + xfree(md5.contents); + + checksum.checksum_type = CKSUMTYPE_KG_CB; + checksum.length = sizeof(ckbuf); + checksum.contents = (krb5_octet *) ckbuf; + + /* fill in the necessary fields in creds */ + + memset((char *) &creds, 0, sizeof(creds)); + creds.client = cred->princ; + creds.server = server; + + creds.times.endtime = *endtime; + + /* call mk_req. subkey and ap_req need to be used or destroyed */ + + if (code = krb5_mk_req_extended(do_mutual?AP_OPTS_MUTUAL_REQUIRED:0, + &checksum, 0, 0, subkey, cred->ccache, + &creds, &authent, &ap_req)) + return(code); + + /* store the interesting stuff from creds and authent */ + *endtime = creds.times.endtime; + *flags = creds.ticket_flags; + *seqnum = authent.seq_number; + + /* free stuff which was created */ + + /* XXXX There's a bug in krb5 here, but I have no clue what it is. + This is a workaround. */ + if (creds.client == cred->princ) + creds.client = NULL; + + krb5_free_cred_contents(&creds); + + /* build up the token */ + + /* allocate space for the token */ + tlen = g_token_size(gss_mech_krb5, ap_req.length); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { + xfree(ap_req.data); + krb5_free_keyblock(*subkey); + return(ENOMEM); + } + + /* fill in the buffer */ + + ptr = t; + + g_make_token_header(gss_mech_krb5, ap_req.length, + &ptr, KG_TOK_CTX_AP_REQ); + + TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); + + /* free the ap_req */ + + xfree(ap_req.data); + + /* pass it back */ + + token->length = tlen; + token->value = (void *) t; + + return(0); +} + +OM_uint32 +krb5_gss_init_sec_context(OM_uint32 *minor_status, + gss_cred_id_t claimant_cred_handle, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + const_gss_OID mech_type, + int 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, + int *ret_flags, + OM_uint32 *time_rec) +{ + 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; + + /* 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); + } + + /* verify the credential, or use the default */ + /*SUPPRESS 29*/ + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { + OM_uint32 major; + + if ((major = kg_get_defcred(minor_status, &claimant_cred_handle)) && + GSS_ERROR(major)) { + return(major); + } + } else { + if (! kg_validate_cred_id(claimant_cred_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL); + } + } + + cred = (krb5_gss_cred_id_t) claimant_cred_handle; + + /* verify that the target_name is valid and usable */ + + if (! kg_validate_name(target_name)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + /* is this a new connection or not? */ + + /*SUPPRESS 29*/ + if (*context_handle == GSS_C_NO_CONTEXT) { + /* make sure the cred is usable for init */ + + if ((cred->usage != GSS_C_INITIATE) && + (cred->usage != GSS_C_BOTH)) { + *minor_status = 0; + return(GSS_S_NO_CRED); + } + + /* complain if the input token is nonnull */ + + if (input_token != GSS_C_NO_BUFFER) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + /* create the ctx */ + + if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) + == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + /* fill in the ctx */ + + ctx->initiate = 1; + ctx->mutual = req_flags & GSS_C_MUTUAL_FLAG; + ctx->seed_init = 0; + ctx->cred = cred; + + if (time_req == 0 || time_req == GSS_C_INDEFINITE) { + ctx->endtime = 0; + } else { + if (code = krb5_timeofday(&now)) { + free(ctx); + *minor_status = code; + return(GSS_S_FAILURE); + } + ctx->endtime = now + time_req; + } + + if (code = krb5_copy_principal(cred->princ, &ctx->here)) { + xfree(ctx); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = krb5_copy_principal((krb5_principal) target_name, + &ctx->there)) { + krb5_free_principal(ctx->here); + xfree(ctx); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = make_ap_req(ctx->cred, ctx->there, &ctx->endtime, + input_chan_bindings, ctx->mutual, + &ctx->subkey, &ctx->flags, + &ctx->seq_send, &token)) { + krb5_free_principal(ctx->here); + krb5_free_principal(ctx->there); + xfree(ctx); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* fill in the encryption descriptors */ + + /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ + + krb5_use_cstype(&ctx->enc.eblock, ETYPE_RAW_DES_CBC); + ctx->enc.processed = 0; + if (code = krb5_copy_keyblock(ctx->subkey, &ctx->enc.key)) + return(code); + for (i=0; ienc.key->length; i++) + /*SUPPRESS 113*/ + ctx->enc.key->contents[i] ^= 0xf0; + + krb5_use_cstype(&ctx->seq.eblock, ETYPE_RAW_DES_CBC); + ctx->seq.processed = 0; + ctx->seq.key = ctx->subkey; + + /* at this point, the context is constructed and valid, + hence, releaseable */ + + /* intern the context handle */ + + if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { + xfree(token.value); + krb5_free_keyblock(ctx->subkey); + krb5_free_principal(ctx->here); + krb5_free_principal(ctx->there); + xfree(ctx); + + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* compute time_rec */ + + if (time_rec) { + if (code = krb5_timeofday(&now)) { + xfree(token.value); + (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; + } + + /* set the other returns */ + + *context_handle = (gss_ctx_id_t) ctx; + + *output_token = token; + + if (ret_flags) + *ret_flags = ((req_flags & GSS_C_MUTUAL_FLAG) | + GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG); + + /* return successfully */ + + *minor_status = 0; + if (ctx->mutual) { + ctx->established = 0; + return(GSS_S_CONTINUE_NEEDED); + } else { + ctx->seq_recv = ctx->seq_send; + ctx->established = 1; + return(GSS_S_COMPLETE); + } + } else { + unsigned char *ptr; + krb5_data ap_rep; + krb5_ap_rep_enc_part *ap_rep_data; + + /* validate the context handle */ + /*SUPPRESS 29*/ + if (! kg_validate_ctx_id(*context_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } + + ctx = (gss_ctx_id_t) *context_handle; + + /* make sure the context is non-established, and that certain + arguments are unchanged */ + + if ((ctx->established) || + (((gss_cred_id_t) ctx->cred) != claimant_cred_handle) || + ((req_flags & GSS_C_MUTUAL_FLAG) == 0)) { + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *minor_status = KG_CONTEXT_ESTABLISHED; + return(GSS_S_FAILURE); + } + + if (! krb5_principal_compare(ctx->there, (krb5_principal) target_name)) { + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *minor_status = 0; + return(GSS_S_BAD_NAME); + } + + /* 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(minor_status, context_handle, NULL); + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + ptr = (unsigned char *) input_token->value; + + if (! g_verify_token_header(gss_mech_krb5, &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length)) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + TREAD_STR(ptr, (unsigned char *) ap_rep.data, ap_rep.length); + + /* decode the ap_rep */ + if (code = krb5_rd_rep(&ap_rep, ctx->subkey, &ap_rep_data)) { + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* store away the sequence number */ + ctx->seq_recv = ap_rep_data->seq_number; + + /* free the ap_rep_data */ + krb5_free_ap_rep_enc_part(ap_rep_data); + + /* set established */ + ctx->established = 1; + + /* set returns */ + + if (time_rec) { + if (code = krb5_timeofday(&now)) { + (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; + + /* success */ + + *minor_status = 0; + return(GSS_S_COMPLETE); + } +} diff --git a/src/lib/gssapi/krb5/inquire_context.c b/src/lib/gssapi/krb5/inquire_context.c new file mode 100644 index 000000000..771a35213 --- /dev/null +++ b/src/lib/gssapi/krb5/inquire_context.c @@ -0,0 +1,125 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_inquire_context(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, + int *ret_flags, + int *locally_initiated) +{ + krb5_error_code code; + krb5_gss_ctx_id_rec *ctx; + krb5_principal init, accept; + krb5_timestamp now; + krb5_deltat lifetime; + + if (initiator_name) + *initiator_name = GSS_C_NO_NAME; + if (acceptor_name) + *acceptor_name = GSS_C_NO_NAME; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + init = NULL; + accept = NULL; + + if (code = krb5_timeofday(&now)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if ((lifetime = ctx->endtime - now) < 0) + lifetime = 0; + + if (initiator_name) { + if (code = krb5_copy_principal(ctx->initiate?ctx->here:ctx->there, + &init)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + if (! kg_save_name((gss_name_t) init)) { + krb5_free_principal(init); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + } + + if (acceptor_name) { + if (code = krb5_copy_principal(ctx->initiate?ctx->there:ctx->here, + &accept)) { + if (init) krb5_free_principal(init); + *minor_status = code; + return(GSS_S_FAILURE); + } + if (! kg_save_name((gss_name_t) accept)) { + krb5_free_principal(accept); + if (init) { + kg_delete_name((gss_name_t) accept); + krb5_free_principal(init); + } + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + } + + if (initiator_name) + *initiator_name = (gss_name_t) init; + + if (acceptor_name) + *acceptor_name = (gss_name_t) accept; + + if (lifetime_rec) + *lifetime_rec = lifetime; + + if (mech_type) + *mech_type = (gss_OID) gss_mech_krb5; + + if (ret_flags) + *ret_flags = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | ctx->mutual; + + if (locally_initiated) + *locally_initiated = ctx->initiate; + + *minor_status = 0; + return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/inquire_cred.c b/src/lib/gssapi/krb5/inquire_cred.c new file mode 100644 index 000000000..7795fca15 --- /dev/null +++ b/src/lib/gssapi/krb5/inquire_cred.c @@ -0,0 +1,108 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_inquire_cred(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_name_t *name, + OM_uint32 *lifetime_ret, + int *cred_usage, + gss_OID_set *mechanisms) +{ + krb5_gss_cred_id_t cred; + krb5_error_code code; + krb5_timestamp now; + krb5_deltat lifetime; + krb5_principal ret_name; + gss_OID_set mechs; + + if (name) *name = NULL; + if (mechanisms) *mechanisms = NULL; + + /* check for default credential */ + /*SUPPRESS 29*/ + if (cred_handle == GSS_C_NO_CREDENTIAL) { + OM_uint32 major; + + if ((major = kg_get_defcred(minor_status, &cred_handle)) && + GSS_ERROR(major)) { + return(major); + } + } else { + if (! kg_validate_cred_id(cred_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED); + } + } + + cred = (krb5_gss_cred_id_t) cred_handle; + + if (code = krb5_timeofday(&now)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if ((lifetime = cred->tgt_expire - now) < 0) + lifetime = 0; + + if (name) { + if (code = krb5_copy_principal(cred->princ, &ret_name)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + if (mechanisms) + if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) { + krb5_free_principal(ret_name); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + if (name) { + if (! kg_save_name((gss_name_t) ret_name)) { + (void)gss_release_oid_set(minor_status, &mechs); + krb5_free_principal(ret_name); + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + *name = (gss_name_t) ret_name; + } + + if (lifetime_ret) + *lifetime_ret = lifetime; + + if (cred_usage) + *cred_usage = cred->usage; + + if (mechanisms) + *mechanisms = mechs; + + *minor_status = 0; + return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c new file mode 100644 index 000000000..dd5e56310 --- /dev/null +++ b/src/lib/gssapi/krb5/k5seal.c @@ -0,0 +1,224 @@ +/* + * 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" +#include +#include + +/* + * $Id$ + */ + +static krb5_error_code +make_seal_token(krb5_gss_enc_desc *enc_ed, + krb5_gss_enc_desc *seq_ed, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + int encrypt, + int toktype) +{ + krb5_error_code code; + MD5_CTX md5; + krb5_checksum desmac; + int tmsglen, tlen; + unsigned char *t, *ptr; + + /* create the token buffer */ + + if (toktype == KG_TOK_SEAL_MSG) { + tmsglen = text->length; + if (encrypt) + tmsglen = (kg_confounder_size(enc_ed) + + kg_encrypt_size(enc_ed, tmsglen+1)); + } else { + tmsglen = 0; + } + + tlen = g_token_size(gss_mech_krb5, 22+tmsglen); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); + + /*** fill in the token */ + + ptr = t; + + g_make_token_header(gss_mech_krb5, 22+tmsglen, &ptr, toktype); + + /* for now, only generate DES integrity */ + + ptr[0] = 0; + ptr[1] = 0; + + /* SEAL_ALG, or filler */ + + if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { + ptr[2] = 0; + ptr[3] = 0; + } else { + ptr[2] = 0xff; + ptr[3] = 0xff; + } + + /* filler */ + + ptr[4] = 0xff; + ptr[5] = 0xff; + + /* compute the checksum */ + + MD5Init(&md5); + MD5Update(&md5, (unsigned char *) ptr-2, 8); + MD5Update(&md5, text->value, text->length); + MD5Final(&md5); + + /* XXX this depends on the key being a single-des key, but that's + all that kerberos supports right now */ + + if (code = krb5_calculate_checksum(CKSUMTYPE_DESCBC, md5.digest, 16, + seq_ed->key->contents, + seq_ed->key->length, + &desmac)) { + xfree(t); + return(code); + } + + memcpy(ptr+14, desmac.contents, 8); + + /* XXX krb5_free_checksum_contents? */ + xfree(desmac.contents); + + /* create the seq_num */ + + if (code = kg_make_seq_num(seq_ed, direction?0xff:0, *seqnum, + ptr+14, ptr+6)) { + xfree(t); + return(code); + } + + /* include seal token fields */ + + if (toktype == KG_TOK_SEAL_MSG) { + if (encrypt) { + unsigned char *plain; + unsigned char pad; + + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + xfree(t); + return(ENOMEM); + } + + if (code = kg_make_confounder(enc_ed, plain)) { + xfree(plain); + xfree(t); + return(code); + } + + memcpy(plain+8, text->value, text->length); + + pad = 8-(text->length%8); + + memset(plain+8+text->length, pad, pad); + + if (code = kg_encrypt(enc_ed, NULL, (krb5_pointer) plain, + (krb5_pointer) (ptr+22), tmsglen)) { + xfree(plain); + xfree(t); + return(code); + } + + xfree(plain); + } else { + memcpy(ptr+22, text->value, text->length); + } + } + + /* that's it. return the token */ + + (*seqnum)++; + + token->length = tlen; + token->value = (void *) t; + + return(0); +} + +/* if signonly is true, ignore conf_req, conf_state, + and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ + +OM_uint32 +kg_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer, + int toktype) +{ + krb5_gss_ctx_id_rec *ctx; + krb5_error_code code; + krb5_timestamp now; + + output_message_buffer->length = 0; + output_message_buffer->value = NULL; + + /* only default qop is allowed */ + if (qop_req != GSS_C_QOP_DEFAULT) { + *minor_status = G_UNKNOWN_QOP; + return(GSS_S_FAILURE); + } + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + if (code = krb5_timeofday(&now)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = make_seal_token(&ctx->enc, &ctx->seq, &ctx->seq_send, + ctx->initiate, + input_message_buffer, output_message_buffer, + conf_req_flag, toktype)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + 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); +} diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c new file mode 100644 index 000000000..2a83ac7b2 --- /dev/null +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -0,0 +1,236 @@ +/* + * 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" +#include +#include +#include + +/* + * $Id$ + */ + +/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX + conf_state is only valid if SEAL. + */ + +OM_uint32 +kg_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_token_buffer, + gss_buffer_t message_buffer, + int *conf_state, + int *qop_state, + int toktype) +{ + krb5_gss_ctx_id_rec *ctx; + krb5_error_code code; + int bodysize; + int tmsglen; + int signalg; + int sealalg; + gss_buffer_desc token; + unsigned char *ptr; + krb5_checksum desmac; + MD5_CTX md5; + unsigned char *cksum; + krb5_timestamp now; + + if (toktype == KG_TOK_SEAL_MSG) { + message_buffer->length = 0; + message_buffer->value = NULL; + } + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + /* parse the token, leave the data in message_buffer, setting conf_state */ + + /* verify the header */ + + ptr = (unsigned char *) input_token_buffer->value; + + if (! g_verify_token_header(gss_mech_krb5, &bodysize, + &ptr, toktype, input_token_buffer->length)) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if (toktype == KG_TOK_SEAL_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) && (sealalg != 0xffff)) || + ((toktype == KG_TOK_SEAL_MSG) && + ((sealalg != 0xffff) && (sealalg != 0))) || + (ptr[4] != 0xff) || + (ptr[5] != 0xff)) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + /* get the token parameters */ + + /* decode the message, if SEAL */ + + if (toktype == KG_TOK_SEAL_MSG) { + if (sealalg == 0) { + unsigned char *plain; + + 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)) { + xfree(plain); + *minor_status = code; + return(GSS_S_FAILURE); + } + + token.length = tmsglen - 8 - plain[tmsglen-1]; + + if ((token.value = xmalloc(token.length)) == NULL) { + xfree(plain); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(token.value, plain+8, token.length); + + xfree(plain); + } else { + token.length = tmsglen; + + if ((token.value = xmalloc(token.length)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(token.value, ptr+22, token.length); + } + } else if (toktype == KG_TOK_SIGN_MSG) { + token = *message_buffer; + } else { + token.length = 0; + token.value = NULL; + } + + /* compute the checksum of the message */ + + if (signalg == 0) { + MD5Init(&md5); + MD5Update(&md5, (unsigned char *) ptr-2, 8); + MD5Update(&md5, token.value, token.length); + MD5Final(&md5); + + /* XXX this depends on the key being a single-des key, but that's + all that kerberos supports right now */ + + if (code = krb5_calculate_checksum(CKSUMTYPE_DESCBC, md5.digest, 16, + ctx->seq.key->contents, + ctx->seq.key->length, + &desmac)) { + 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 (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } + ctx->seed_init = 1; + } + + MD5Init(&md5); + MD5Update(&md5, ctx->seed, sizeof(ctx->seed)); + MD5Update(&md5, (unsigned char *) ptr-2, 8); + MD5Update(&md5, token.value, token.length); + MD5Final(&md5); + + cksum = md5.digest; + } + + /* compare the computed checksum against the transmitted checksum */ + + if (memcmp(cksum, ptr+14, 8) != 0) { + if (signalg == 0) + xfree(desmac.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = 0; + return(GSS_S_BAD_SIG); + } + + if (signalg == 0) + xfree(desmac.contents); + + /* 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) + *message_buffer = token; + + if (conf_state) + *conf_state = (sealalg == 0); + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + if (code = krb5_timeofday(&now)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* success */ + + *minor_status = 0; + return(GSS_S_COMPLETE); +} 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..ecebdd161 --- /dev/null +++ b/src/lib/gssapi/krb5/krb5_gss_glue.c @@ -0,0 +1,304 @@ +/* + * 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 +gss_accept_sec_context(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, + int *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 +gss_acquire_cred(OM_uint32 *minor_status, + gss_name_t desired_name, + OM_uint32 time_req, + gss_OID_set desired_mechs, + int 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)); +} + +OM_uint32 +gss_compare_name(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 +gss_context_time(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)); +} + +OM_uint32 +gss_delete_sec_context(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 +gss_display_name(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 +gss_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const_gss_OID mech_type, + int *message_context, + gss_buffer_t status_string) { + return(krb5_gss_display_status(minor_status, + status_value, + status_type, + mech_type, + message_context, + status_string)); +} + +OM_uint32 +gss_import_name(OM_uint32 *minor_status, + gss_buffer_t input_name_buffer, + const_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)); +} + +OM_uint32 +gss_indicate_mechs(OM_uint32 *minor_status, + gss_OID_set *mech_set) { + return(krb5_gss_indicate_mechs(minor_status, + mech_set)); +} + +OM_uint32 +gss_init_sec_context(OM_uint32 *minor_status, + gss_cred_id_t claimant_cred_handle, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + const_gss_OID mech_type, + int 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, + int *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 +gss_inquire_context(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, + int *ret_flags, + int *locally_initiated) { + return(krb5_gss_inquire_context(minor_status, + context_handle, + initiator_name, + acceptor_name, + lifetime_rec, + mech_type, + ret_flags, + locally_initiated)); +} + +OM_uint32 +gss_inquire_cred(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_name_t *name, + OM_uint32 *lifetime_ret, + int *cred_usage, + gss_OID_set *mechanisms) { + return(krb5_gss_inquire_cred(minor_status, + cred_handle, + name, + lifetime_ret, + cred_usage, + mechanisms)); +} + +OM_uint32 +gss_process_context_token(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 +gss_release_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle) { + return(krb5_gss_release_cred(minor_status, + cred_handle)); +} + +OM_uint32 +gss_release_name(OM_uint32 *minor_status, + gss_name_t *input_name) { + return(krb5_gss_release_name(minor_status, + input_name)); +} + +OM_uint32 +gss_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + return(generic_gss_release_buffer(minor_status, + buffer)); +} + +OM_uint32 +gss_release_oid_set(OM_uint32* minor_status, + gss_OID_set *set) +{ + return(generic_gss_release_oid_set(minor_status, + set)); +} + +OM_uint32 +gss_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) { + return(krb5_gss_seal(minor_status, + context_handle, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer)); +} + +OM_uint32 +gss_sign(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int qop_req, + gss_buffer_t message_buffer, + gss_buffer_t message_token) { + return(krb5_gss_sign(minor_status, + context_handle, + qop_req, + message_buffer, + message_token)); +} + +OM_uint32 +gss_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + int *qop_state) { + return(krb5_gss_unseal(minor_status, + context_handle, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state)); +} + +OM_uint32 +gss_verify(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t message_buffer, + gss_buffer_t token_buffer, + int *qop_state) { + return(krb5_gss_verify(minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state)); +} diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c new file mode 100644 index 000000000..2b57bdcf4 --- /dev/null +++ b/src/lib/gssapi/krb5/process_context_token.c @@ -0,0 +1,61 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_process_context_token(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t token_buffer) +{ + krb5_gss_ctx_id_rec *ctx; + OM_uint32 majerr; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = 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); + } + + /* "unseal" the token */ + + if (GSS_ERROR(majerr = kg_unseal(minor_status, ctx, token_buffer, + GSS_C_NO_BUFFER, NULL, NULL, + KG_TOK_DEL_CTX))) + return(majerr); + + /* that's it. delete the context */ + + return(krb5_gss_delete_sec_context(minor_status, &context_handle, + GSS_C_NO_BUFFER)); +} diff --git a/src/lib/gssapi/krb5/release_cred.c b/src/lib/gssapi/krb5/release_cred.c new file mode 100644 index 000000000..02425f30d --- /dev/null +++ b/src/lib/gssapi/krb5/release_cred.c @@ -0,0 +1,69 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_release_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle) +{ + krb5_gss_cred_id_t cred; + krb5_error_code code1, code2; + + if (*cred_handle == GSS_C_NO_CREDENTIAL) + return(kg_release_defcred(minor_status)); + + if (! kg_delete_cred_id(*cred_handle)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED); + } + + cred = *cred_handle; + + if (cred->ccache) + code1 = krb5_cc_close(cred->ccache); + else + code1 = 0; + + if (cred->keytab) + code2 = krb5_kt_close(cred->keytab); + else + code2 = 0; + + if (cred->princ) + krb5_free_principal(cred->princ); + xfree(cred); + + *cred_handle = NULL; + + *minor_status = 0; + if (code1) + *minor_status = code1; + if (code2) + *minor_status = code2; + + return(*minor_status?GSS_S_FAILURE:GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/release_name.c b/src/lib/gssapi/krb5/release_name.c new file mode 100644 index 000000000..6f7b026a4 --- /dev/null +++ b/src/lib/gssapi/krb5/release_name.c @@ -0,0 +1,46 @@ +/* + * 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 +krb5_gss_release_name(OM_uint32 *minor_status, + gss_name_t *input_name) +{ + if (! kg_validate_name(*input_name)) { + *minor_status = G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + (void)kg_delete_name(*input_name); + + krb5_free_principal((krb5_principal) *input_name); + + *input_name = GSS_C_NO_NAME; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/seal.c b/src/lib/gssapi/krb5/seal.c new file mode 100644 index 000000000..03b9716df --- /dev/null +++ b/src/lib/gssapi/krb5/seal.c @@ -0,0 +1,41 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + return(kg_seal(minor_status, context_handle, conf_req_flag, + qop_req, input_message_buffer, conf_state, + output_message_buffer, KG_TOK_SEAL_MSG)); +} diff --git a/src/lib/gssapi/krb5/sign.c b/src/lib/gssapi/krb5/sign.c new file mode 100644 index 000000000..f27f4ff16 --- /dev/null +++ b/src/lib/gssapi/krb5/sign.c @@ -0,0 +1,39 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_sign(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int qop_req, + gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + return(kg_seal(minor_status, context_handle, 0, + qop_req, message_buffer, NULL, + message_token, KG_TOK_SIGN_MSG)); +} diff --git a/src/lib/gssapi/krb5/unseal.c b/src/lib/gssapi/krb5/unseal.c new file mode 100644 index 000000000..d55505856 --- /dev/null +++ b/src/lib/gssapi/krb5/unseal.c @@ -0,0 +1,40 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + int *qop_state) +{ + return(kg_unseal(minor_status, context_handle, + input_message_buffer, output_message_buffer, + conf_state, qop_state, KG_TOK_SEAL_MSG)); +} diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c new file mode 100644 index 000000000..ff2c88821 --- /dev/null +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -0,0 +1,93 @@ +/* + * 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" +#include + +/* + * $Id$ + */ + +krb5_error_code kg_checksum_channel_bindings(gss_channel_bindings_t cb, + krb5_checksum *cksum) +{ + int len; + char *buf, *ptr; + long tmp; + krb5_error_code code; + + /* 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(CKSUMTYPE_RSA_MD5))) == NULL) + return(ENOMEM); + + cksum->checksum_type = CKSUMTYPE_RSA_MD5; + memset(cksum->contents, '\0', + (cksum->length = krb5_checksum_size(CKSUMTYPE_RSA_MD5))); + return(0); + } + + /* create the buffer to checksum into */ + + len = (sizeof(tmp)*5+ + cb->initiator_address.length+ + cb->acceptor_address.length+ + cb->application_data.length); + + if ((buf = (char *) xmalloc(len)) == NULL) + return(ENOMEM); + + /* allocate the cksum contents buffer */ + if ((cksum->contents = (krb5_octet *) + xmalloc(krb5_checksum_size(CKSUMTYPE_RSA_MD5))) == NULL) { + free(buf); + return(ENOMEM); + } + + /* helper macros. This code currently depends on a long being 32 + bits, and htonl dtrt. */ + + ptr = buf; + + TWRITE_INT(ptr, tmp, cb->initiator_addrtype); + TWRITE_BUF(ptr, tmp, cb->initiator_address); + TWRITE_INT(ptr, tmp, cb->acceptor_addrtype); + TWRITE_BUF(ptr, tmp, cb->acceptor_address); + TWRITE_BUF(ptr, tmp, cb->application_data); + + /* checksum the data */ + + if (code = krb5_calculate_checksum(CKSUMTYPE_RSA_MD5, buf, len, + NULL, 0, cksum)) { + xfree(cksum->contents); + xfree(buf); + return(code); + } + + /* success */ + + xfree(buf); + return(0); +} diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c new file mode 100644 index 000000000..b569cb692 --- /dev/null +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -0,0 +1,97 @@ +/* + * 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" +#include + +/* + * $Id$ + */ + +static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; + +int kg_confounder_size(krb5_gss_enc_desc *ed) +{ + /* XXX Is this an abstraction violation? */ + + return(ed->eblock.crypto_entry->block_length); +} + +krb5_error_code +kg_make_confounder(krb5_gss_enc_desc *ed, unsigned char *buf) +{ + return(krb5_random_confounder(ed->eblock.crypto_entry->block_length, buf)); +} + +int kg_encrypt_size(krb5_gss_enc_desc *ed, int n) +{ + return(krb5_encrypt_size(n, ed->eblock.crypto_entry)); +} + +krb5_error_code +kg_encrypt(krb5_gss_enc_desc *ed, krb5_pointer iv, + krb5_pointer in, krb5_pointer out, int length) +{ + krb5_error_code code; + + if (! ed->processed) { + if (code = krb5_process_key(&ed->eblock, ed->key)) + return(code); + ed->processed = 1; + } + + if (code = krb5_encrypt(in, out, length, &ed->eblock, iv?iv:zeros)) + return(code); + + return(0); +} + +/* length is the length of the cleartext. */ + +krb5_error_code +kg_decrypt(krb5_gss_enc_desc *ed, krb5_pointer iv, + krb5_pointer in, krb5_pointer out, int length) +{ + krb5_error_code code; + int elen; + char *buf; + + if (! ed->processed) { + if (code = krb5_process_key(&ed->eblock, ed->key)) + return(code); + ed->processed = 1; + } + + elen = krb5_encrypt_size(length, ed->eblock.crypto_entry); + if ((buf = (char *) xmalloc(elen)) == NULL) + return(ENOMEM); + + if (code = krb5_decrypt(in, buf, elen, &ed->eblock, iv?iv:zeros)) { + xfree(buf); + return(code); + } + + memcpy(out, buf, length); + xfree(buf); + + return(0); +} diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c new file mode 100644 index 000000000..9eb57c1cc --- /dev/null +++ b/src/lib/gssapi/krb5/util_seed.c @@ -0,0 +1,56 @@ +/* + * 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" +#include + +/* + * $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(krb5_keyblock *key, unsigned char *seed) +{ + krb5_error_code code; + krb5_gss_enc_desc ed; + int i; + + if (code = krb5_copy_keyblock(key, &ed.key)) + return(code); + + /* reverse the key bytes, as per spec */ + + for (i=0; ilength; i++) + ed.key->contents[i] = key->contents[key->length - 1 - i]; + + krb5_use_cstype(&ed.eblock, ETYPE_RAW_DES_CBC); + ed.processed = 0; + + code = kg_encrypt(&ed, NULL, zeros, seed, 16); + + krb5_finish_key(&ed.eblock); + krb5_free_keyblock(ed.key); + + return(code); +} diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c new file mode 100644 index 000000000..9ab27bf4b --- /dev/null +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -0,0 +1,46 @@ +/* + * 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$ + */ + +krb5_error_code kg_make_seq_num(krb5_gss_enc_desc *ed, int direction, + int seqnum, unsigned char *cksum, + unsigned char *buf) +{ + unsigned char plain[8]; + + plain[0] = seqnum&0xff; + plain[1] = (seqnum>>8)&0xff; + plain[2] = (seqnum>>16)&0xff; + plain[3] = (seqnum>>24)&0xff; + + plain[4] = direction; + plain[5] = direction; + plain[6] = direction; + plain[7] = direction; + + return(kg_encrypt(ed, cksum, plain, buf, 8)); +} diff --git a/src/lib/gssapi/krb5/verify.c b/src/lib/gssapi/krb5/verify.c new file mode 100644 index 000000000..1057e2d06 --- /dev/null +++ b/src/lib/gssapi/krb5/verify.c @@ -0,0 +1,39 @@ +/* + * 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$ + */ + +OM_uint32 +krb5_gss_verify(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t message_buffer, + gss_buffer_t token_buffer, + int *qop_state) +{ + return(kg_unseal(minor_status, context_handle, + token_buffer, message_buffer, + NULL, qop_state, KG_TOK_SIGN_MSG)); +} -- 2.26.2