From 9b261c008a395a323e0516f4cd3f3134aa050577 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Jun 2009 19:06:16 +1000 Subject: s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e892ff34b6865ba) Also including the supporting changes required to pass make test A number of heimdal functions and constants have changed since we last imported a tree (for the better, but inconvenient for us). Andrew Bartlett --- source4/heimdal/lib/gssapi/mech/context.c | 2 +- .../lib/gssapi/mech/gss_accept_sec_context.c | 3 +- source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c | 2 +- source4/heimdal/lib/gssapi/mech/gss_aeap.c | 184 +++++++++++++++++++++ .../lib/gssapi/mech/gss_canonicalize_name.c | 24 +++ source4/heimdal/lib/gssapi/mech/gss_get_mic.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_import_name.c | 85 +++++++--- source4/heimdal/lib/gssapi/mech/gss_krb5.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_mech_switch.c | 14 +- .../heimdal/lib/gssapi/mech/gss_pseudo_random.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_verify_mic.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_wrap.c | 4 +- .../heimdal/lib/gssapi/mech/gss_wrap_size_limit.c | 4 +- source4/heimdal/lib/gssapi/mech/mech_locl.h | 1 + source4/heimdal/lib/gssapi/mech/mech_switch.h | 1 + 15 files changed, 305 insertions(+), 35 deletions(-) create mode 100644 source4/heimdal/lib/gssapi/mech/gss_aeap.c (limited to 'source4/heimdal/lib/gssapi/mech') diff --git a/source4/heimdal/lib/gssapi/mech/context.c b/source4/heimdal/lib/gssapi/mech/context.c index a06a1e9e37..b032d8aa0e 100644 --- a/source4/heimdal/lib/gssapi/mech/context.c +++ b/source4/heimdal/lib/gssapi/mech/context.c @@ -1,4 +1,4 @@ -#include "mech/mech_locl.h" +#include "mech_locl.h" #include "heim_threads.h" RCSID("$Id$"); diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index 50011a9b0d..134511f34b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -260,7 +260,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, if (mech_ret_flags & GSS_C_DELEG_FLAG) { if (!delegated_cred_handle) { m->gm_release_cred(minor_status, &delegated_mc); - *ret_flags &= ~GSS_C_DELEG_FLAG; + if (ret_flags) + *ret_flags &= ~GSS_C_DELEG_FLAG; } else if (delegated_mc) { struct _gss_cred *dcred; struct _gss_mechanism_cred *dmc; diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c index b21b3f62e8..a8ebe644ab 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -51,7 +51,7 @@ gss_acquire_cred(OM_uint32 *minor_status, *minor_status = 0; if (output_cred_handle) - *output_cred_handle = GSS_C_NO_CREDENTIAL; + return GSS_S_CALL_INACCESSIBLE_READ; if (actual_mechs) *actual_mechs = GSS_C_NO_OID_SET; if (time_rec) diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c new file mode 100644 index 0000000000..cbe0cd1460 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c @@ -0,0 +1,184 @@ +/* + * AEAD support + */ + +#include "mech_locl.h" +RCSID("$Id$"); + +/** + * Encrypts or sign the data. + * + * The maximum packet size is gss_context_stream_sizes.max_msg_size. + * + * The caller needs provide the folloing buffers: + * + * - HEADER (of size gss_context_stream_sizes.header) + * SIGN_ONLY (optional, zero or more) + * DATA + * SIGN_ONLY (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize) + * TRAILER (of size gss_context_stream_sizes.trailer) + * + * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the + * DATA elements is padded to a block bountry. + * + * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER + * + * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or + * gss_context_query_attributes(). + * + * @ingroup gssapi + */ + + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int * conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_wrap_iov == NULL) { + if (minor_status) + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + + return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, conf_state, + iov, iov_count); +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_unwrap_iov(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (qop_state) + *qop_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_unwrap_iov == NULL) { + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + + return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx, + conf_state, qop_state, + iov, iov_count); +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov_length(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_wrap_iov_length == NULL) { + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + + return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, conf_state, + iov, iov_count); +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_release_iov_buffer(OM_uint32 *minor_status, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 junk; + size_t i; + + if (minor_status) + *minor_status = 0; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + for (i = 0; i < iov_count; i++) { + if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) + continue; + gss_release_buffer(&junk, &iov[i].buffer); + } + return GSS_S_COMPLETE; +} + +/** + * Query the context for parameters. + * + * SSPI equivalent if this function is QueryContextAttributes. + * + * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. + */ + +static gss_OID_desc gss_c_attr_stream_sizes_desc = + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")}; + +gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES = + &gss_c_attr_stream_sizes_desc; + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_context_query_attributes(OM_uint32 *minor_status, + gss_OID attribute, + void *data, + size_t len) +{ + *minor_status = 0; + + if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) { + memset(data, 0, len); + return GSS_S_COMPLETE; + } + + return GSS_S_FAILURE; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c index 91a08fb2bc..db976f2453 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c @@ -29,6 +29,30 @@ #include "mech_locl.h" RCSID("$Id$"); +/** + * gss_canonicalize_name takes a Internal Name (IN) and converts in into a + * mechanism specific Mechanism Name (MN). + * + * The input name may multiple name, or generic name types. + * + * If the input_name if of the GSS_C_NT_USER_NAME, and the Kerberos + * mechanism is specified, the resulting MN type is a + * GSS_KRB5_NT_PRINCIPAL_NAME. + * + * For more information about @ref internalVSmechname. + * + * @param minor_status minor status code. + * @param input_name name to covert, unchanged by gss_canonicalize_name(). + * @param mech_type the type to convert Name too. + * @param output_name the resulting type, release with + * gss_release_name(), independent of input_name. + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_canonicalize_name(OM_uint32 *minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c index 9cd5060fc9..3a0f3fb757 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c @@ -37,7 +37,7 @@ gss_get_mic(OM_uint32 *minor_status, gss_buffer_t message_token) { struct _gss_context *ctx = (struct _gss_context *) context_handle; - gssapi_mech_interface m = ctx->gc_mech; + gssapi_mech_interface m; _mg_buffer_zero(message_token); if (ctx == NULL) { @@ -45,6 +45,8 @@ gss_get_mic(OM_uint32 *minor_status, return GSS_S_NO_CONTEXT; } + m = ctx->gc_mech; + return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req, message_buffer, message_token)); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c index 040e228410..c1dffdc614 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c @@ -145,9 +145,12 @@ gss_import_name(OM_uint32 *minor_status, const gss_OID input_name_type, gss_name_t *output_name) { + struct _gss_mechanism_name *mn; gss_OID name_type = input_name_type; - OM_uint32 major_status; + OM_uint32 major_status, ms; struct _gss_name *name; + struct _gss_mech_switch *m; + gss_name_t rname; *output_name = GSS_C_NO_NAME; @@ -156,6 +159,8 @@ gss_import_name(OM_uint32 *minor_status, return (GSS_S_BAD_NAME); } + _gss_load_mech(); + /* * Use GSS_NT_USER_NAME as default name type. */ @@ -172,29 +177,15 @@ gss_import_name(OM_uint32 *minor_status, input_name_buffer, output_name); } - /* - * Only allow certain name types. This is pretty bogus - we - * should figure out the list of supported name types using - * gss_inquire_names_for_mech. - */ - if (!gss_oid_equal(name_type, GSS_C_NT_USER_NAME) - && !gss_oid_equal(name_type, GSS_C_NT_MACHINE_UID_NAME) - && !gss_oid_equal(name_type, GSS_C_NT_STRING_UID_NAME) - && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE_X) - && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE) - && !gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS) - && !gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) { - *minor_status = 0; - return (GSS_S_BAD_NAMETYPE); - } *minor_status = 0; - name = malloc(sizeof(struct _gss_name)); + name = calloc(1, sizeof(struct _gss_name)); if (!name) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } - memset(name, 0, sizeof(struct _gss_name)); + + SLIST_INIT(&name->gn_mn); major_status = _gss_copy_oid(minor_status, name_type, &name->gn_type); @@ -205,14 +196,62 @@ gss_import_name(OM_uint32 *minor_status, major_status = _gss_copy_buffer(minor_status, input_name_buffer, &name->gn_value); - if (major_status) { - gss_name_t rname = (gss_name_t)name; - gss_release_name(minor_status, &rname); - return (GSS_S_FAILURE); + if (major_status) + goto out; + + /* + * Walk over the mechs and import the name into a mech name + * for those supported this nametype. + */ + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + int present = 0; + + major_status = gss_test_oid_set_member(minor_status, + name_type, m->gm_name_types, &present); + + if (major_status || present == 0) + continue; + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto out; + } + + major_status = (*m->gm_mech.gm_import_name)(minor_status, + &name->gn_value, + (name->gn_type.elements + ? &name->gn_type : GSS_C_NO_OID), + &mn->gmn_name); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(&m->gm_mech, major_status, *minor_status); + free(mn); + goto out; + } + + mn->gmn_mech = &m->gm_mech; + mn->gmn_mech_oid = &m->gm_mech_oid; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); } - SLIST_INIT(&name->gn_mn); + /* + * If we can't find a mn for the name, bail out already here. + */ + + mn = SLIST_FIRST(&name->gn_mn); + if (!mn) { + *minor_status = 0; + major_status = GSS_S_NAME_NOT_MN; + goto out; + } *output_name = (gss_name_t) name; return (GSS_S_COMPLETE); + + out: + rname = (gss_name_t)name; + gss_release_name(&ms, &rname); + return major_status; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c index 5318f6cdba..5d883c45c2 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -278,7 +278,7 @@ gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, || *context_handle == GSS_C_NO_CONTEXT || version != 1) { - ret = EINVAL; + *minor_status = EINVAL; return GSS_S_FAILURE; } @@ -715,7 +715,7 @@ gsskrb5_extract_key(OM_uint32 *minor_status, krb5_storage *sp = NULL; if (context_handle == GSS_C_NO_CONTEXT) { - ret = EINVAL; + *minor_status = EINVAL; return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c index fc2e8816c5..3321819d28 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -186,6 +186,15 @@ add_builtin(gssapi_mech_interface mech) gss_add_oid_set_member(&minor_status, &m->gm_mech.gm_mech_oid, &_gss_mech_oids); + /* pick up the oid sets of names */ + + if (m->gm_mech.gm_inquire_names_for_mech) { + (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status, + &m->gm_mech.gm_mech_oid, &m->gm_name_types); + } else { + gss_create_empty_oid_set(&minor_status, &m->gm_name_types); + } + SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); return 0; } @@ -221,9 +230,7 @@ _gss_load_mech(void) add_builtin(__gss_krb5_initialize()); add_builtin(__gss_spnego_initialize()); -#ifndef HEIMDAL_SMALLER add_builtin(__gss_ntlm_initialize()); -#endif #ifdef HAVE_DLOPEN fp = fopen(_PATH_GSS_MECH, "r"); @@ -308,6 +315,9 @@ _gss_load_mech(void) OPTSYM(set_sec_context_option); OPTSYM(set_cred_option); OPTSYM(pseudo_random); + OPTSYM(wrap_iov); + OPTSYM(unwrap_iov); + OPTSYM(wrap_iov_length); SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); continue; diff --git a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c index b907f94038..771efcb434 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c +++ b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c @@ -45,7 +45,7 @@ gss_pseudo_random(OM_uint32 *minor_status, gss_buffer_t prf_out) { struct _gss_context *ctx = (struct _gss_context *) context; - gssapi_mech_interface m = ctx->gc_mech; + gssapi_mech_interface m; OM_uint32 major_status; _mg_buffer_zero(prf_out); @@ -56,6 +56,8 @@ gss_pseudo_random(OM_uint32 *minor_status, return GSS_S_NO_CONTEXT; } + m = ctx->gc_mech; + if (m->gm_pseudo_random == NULL) return GSS_S_UNAVAILABLE; diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c index 1a411729c6..60ef3bff85 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c @@ -37,7 +37,7 @@ gss_verify_mic(OM_uint32 *minor_status, gss_qop_t *qop_state) { struct _gss_context *ctx = (struct _gss_context *) context_handle; - gssapi_mech_interface m = ctx->gc_mech; + gssapi_mech_interface m; if (qop_state) *qop_state = 0; @@ -46,6 +46,8 @@ gss_verify_mic(OM_uint32 *minor_status, return GSS_S_NO_CONTEXT; } + m = ctx->gc_mech; + return (m->gm_verify_mic(minor_status, ctx->gc_ctx, message_buffer, token_buffer, qop_state)); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c index b3363d3f20..9476d01ddd 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c @@ -39,7 +39,7 @@ gss_wrap(OM_uint32 *minor_status, gss_buffer_t output_message_buffer) { struct _gss_context *ctx = (struct _gss_context *) context_handle; - gssapi_mech_interface m = ctx->gc_mech; + gssapi_mech_interface m; if (conf_state) *conf_state = 0; @@ -49,6 +49,8 @@ gss_wrap(OM_uint32 *minor_status, return GSS_S_NO_CONTEXT; } + m = ctx->gc_mech; + return (m->gm_wrap(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer)); diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c index 15b86a9367..a5a80b21d7 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c @@ -38,7 +38,7 @@ gss_wrap_size_limit(OM_uint32 *minor_status, OM_uint32 *max_input_size) { struct _gss_context *ctx = (struct _gss_context *) context_handle; - gssapi_mech_interface m = ctx->gc_mech; + gssapi_mech_interface m; *max_input_size = 0; if (ctx == NULL) { @@ -46,6 +46,8 @@ gss_wrap_size_limit(OM_uint32 *minor_status, return GSS_S_NO_CONTEXT; } + m = ctx->gc_mech; + return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, req_output_size, max_input_size)); } diff --git a/source4/heimdal/lib/gssapi/mech/mech_locl.h b/source4/heimdal/lib/gssapi/mech/mech_locl.h index 42c069eb2d..17721fd3ce 100644 --- a/source4/heimdal/lib/gssapi/mech/mech_locl.h +++ b/source4/heimdal/lib/gssapi/mech/mech_locl.h @@ -53,6 +53,7 @@ #include #include +#include #include "mechqueue.h" diff --git a/source4/heimdal/lib/gssapi/mech/mech_switch.h b/source4/heimdal/lib/gssapi/mech/mech_switch.h index e83a4c8a5a..56e3b7dea7 100644 --- a/source4/heimdal/lib/gssapi/mech/mech_switch.h +++ b/source4/heimdal/lib/gssapi/mech/mech_switch.h @@ -32,6 +32,7 @@ struct _gss_mech_switch { SLIST_ENTRY(_gss_mech_switch) gm_link; gss_OID_desc gm_mech_oid; + gss_OID_set gm_name_types; void *gm_so; gssapi_mech_interface_desc gm_mech; }; -- cgit