From 022e7d431935479a0e1090d4131cd498d28bf273 Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Wed, 26 Aug 2009 22:32:50 -0700 Subject: [PATCH] Return unwrapped delegated credentials if the actual mech is not the called mech Assumes that pseudo mechs are are of how mechglue credentails look like and return credentials like that. Pointed out on krbdev by Nicolas Williams --- lib/gssapi/mech/gss_accept_sec_context.c | 15 +++- lib/gssapi/spnego/accept_sec_context.c | 42 ++------- lib/gssapi/spnego/compat.c | 6 +- lib/gssapi/spnego/cred_stubs.c | 110 +++-------------------- lib/gssapi/spnego/init_sec_context.c | 16 ++-- lib/gssapi/spnego/spnego_locl.h | 4 - lib/gssapi/test_context.c | 6 +- 7 files changed, 44 insertions(+), 155 deletions(-) diff --git a/lib/gssapi/mech/gss_accept_sec_context.c b/lib/gssapi/mech/gss_accept_sec_context.c index 134511f34..934c206c8 100644 --- a/lib/gssapi/mech/gss_accept_sec_context.c +++ b/lib/gssapi/mech/gss_accept_sec_context.c @@ -161,6 +161,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, struct _gss_mechanism_cred *mc; gss_cred_id_t acceptor_mc, delegated_mc; gss_name_t src_mn; + gss_OID mech_ret_type = NULL; *minor_status = 0; if (src_name) @@ -228,7 +229,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, input_token, input_chan_bindings, &src_mn, - mech_type, + &mech_ret_type, output_token, &mech_ret_flags, time_rec, @@ -241,6 +242,9 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, return (major_status); } + if (mech_type) + *mech_type = mech_ret_type; + if (src_name && src_mn) { /* * Make a new name and mark it as an MN. @@ -262,6 +266,15 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, m->gm_release_cred(minor_status, &delegated_mc); if (ret_flags) *ret_flags &= ~GSS_C_DELEG_FLAG; + } else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) { + /* + * If the returned mech_type is not the same + * as the mech, assume its pseudo mech type + * and the returned type is already a + * mech-glue object + */ + *delegated_cred_handle = delegated_mc; + } else if (delegated_mc) { struct _gss_cred *dcred; struct _gss_mechanism_cred *dmc; diff --git a/lib/gssapi/spnego/accept_sec_context.c b/lib/gssapi/spnego/accept_sec_context.c index 2bdfc28eb..247c25611 100644 --- a/lib/gssapi/spnego/accept_sec_context.c +++ b/lib/gssapi/spnego/accept_sec_context.c @@ -496,7 +496,6 @@ acceptor_start gss_buffer_desc mech_buf; gss_OID preferred_mech_type = GSS_C_NO_OID; gssspnego_ctx ctx; - gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle; int get_mic = 0; int first_ok = 0; @@ -564,25 +563,18 @@ acceptor_start &preferred_mech_type); if (ret == 0 && ni->mechToken != NULL) { - gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL; - gss_cred_id_t mech_cred; gss_buffer_desc ibuf; ibuf.length = ni->mechToken->length; ibuf.value = ni->mechToken->data; mech_input_token = &ibuf; - if (acceptor_cred != NULL) - mech_cred = acceptor_cred->negotiated_cred_id; - else - mech_cred = GSS_C_NO_CREDENTIAL; - if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&junk, &ctx->mech_src_name); ret = gss_accept_sec_context(minor_status, &ctx->negotiated_ctx_id, - mech_cred, + acceptor_cred_handle, mech_input_token, input_chan_bindings, &ctx->mech_src_name, @@ -590,18 +582,10 @@ acceptor_start &mech_output_token, &ctx->mech_flags, &ctx->mech_time_rec, - &mech_delegated_cred); - - if (mech_delegated_cred && delegated_cred_handle) { - _gss_spnego_alloc_cred(&junk, - mech_delegated_cred, - delegated_cred_handle); - } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&junk, &mech_delegated_cred); + delegated_cred_handle); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { ctx->preferred_mech_type = preferred_mech_type; - ctx->negotiated_mech_type = preferred_mech_type; if (ret == GSS_S_COMPLETE) ctx->open = 1; @@ -646,7 +630,6 @@ acceptor_start } ctx->preferred_mech_type = preferred_mech_type; - ctx->negotiated_mech_type = preferred_mech_type; } /* @@ -719,7 +702,7 @@ acceptor_continue gss_cred_id_t *delegated_cred_handle ) { - OM_uint32 ret, ret2, minor, junk; + OM_uint32 ret, ret2, minor; NegotiationToken nt; size_t nt_len; NegTokenResp *na; @@ -728,7 +711,6 @@ acceptor_continue gss_buffer_t mech_output_token = GSS_C_NO_BUFFER; gss_buffer_desc mech_buf; gssspnego_ctx ctx; - gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle; mech_buf.value = NULL; @@ -774,20 +756,13 @@ acceptor_continue } if (mech_input_token != GSS_C_NO_BUFFER) { - gss_cred_id_t mech_cred; - gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL; - - if (acceptor_cred != NULL) - mech_cred = acceptor_cred->negotiated_cred_id; - else - mech_cred = GSS_C_NO_CREDENTIAL; if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&minor, &ctx->mech_src_name); ret = gss_accept_sec_context(&minor, &ctx->negotiated_ctx_id, - mech_cred, + acceptor_cred_handle, mech_input_token, input_chan_bindings, &ctx->mech_src_name, @@ -795,14 +770,7 @@ acceptor_continue &obuf, &ctx->mech_flags, &ctx->mech_time_rec, - &mech_delegated_cred); - - if (mech_delegated_cred && delegated_cred_handle) { - _gss_spnego_alloc_cred(&junk, - mech_delegated_cred, - delegated_cred_handle); - } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&junk, &mech_delegated_cred); + delegated_cred_handle); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { mech_output_token = &obuf; diff --git a/lib/gssapi/spnego/compat.c b/lib/gssapi/spnego/compat.c index ee25b5943..ff0a3a75e 100644 --- a/lib/gssapi/spnego/compat.c +++ b/lib/gssapi/spnego/compat.c @@ -236,7 +236,7 @@ _gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status, gss_name_t target_name, OM_uint32 (*func)(gss_name_t, gss_OID), int includeMSCompatOID, - const gssspnego_cred cred_handle, + const gss_cred_id_t cred_handle, MechTypeList *mechtypelist, gss_OID *preferred_mech) { @@ -248,9 +248,9 @@ _gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status, mechtypelist->len = 0; mechtypelist->val = NULL; - if (cred_handle != NULL) { + if (cred_handle) { ret = gss_inquire_cred(minor_status, - cred_handle->negotiated_cred_id, + cred_handle, NULL, NULL, NULL, diff --git a/lib/gssapi/spnego/cred_stubs.c b/lib/gssapi/spnego/cred_stubs.c index a10a10f1e..8d6b1270d 100644 --- a/lib/gssapi/spnego/cred_stubs.c +++ b/lib/gssapi/spnego/cred_stubs.c @@ -37,50 +37,20 @@ RCSID("$Id$"); OM_uint32 _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) { - gssspnego_cred cred; OM_uint32 ret; *minor_status = 0; - if (*cred_handle == GSS_C_NO_CREDENTIAL) { + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) return GSS_S_COMPLETE; - } - cred = (gssspnego_cred)*cred_handle; - ret = gss_release_cred(minor_status, &cred->negotiated_cred_id); + ret = gss_release_cred(minor_status, cred_handle); - free(cred); *cred_handle = GSS_C_NO_CREDENTIAL; return ret; } -OM_uint32 -_gss_spnego_alloc_cred(OM_uint32 *minor_status, - gss_cred_id_t mech_cred_handle, - gss_cred_id_t *cred_handle) -{ - gssspnego_cred cred; - - if (*cred_handle != GSS_C_NO_CREDENTIAL) { - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - - cred = calloc(1, sizeof(*cred)); - if (cred == NULL) { - *cred_handle = GSS_C_NO_CREDENTIAL; - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - cred->negotiated_cred_id = mech_cred_handle; - - *cred_handle = (gss_cred_id_t)cred; - - return GSS_S_COMPLETE; -} - /* * For now, just a simple wrapper that avoids recursion. When * we support gss_{get,set}_neg_mechs() we will need to expose @@ -103,8 +73,6 @@ OM_uint32 _gss_spnego_acquire_cred gss_OID_set_desc actual_desired_mechs; gss_OID_set mechs; int i, j; - gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; - gssspnego_cred cred; *output_cred_handle = GSS_C_NO_CREDENTIAL; @@ -140,22 +108,14 @@ OM_uint32 _gss_spnego_acquire_cred } actual_desired_mechs.count = j; - ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL, - &cred_handle); - if (ret != GSS_S_COMPLETE) - goto out; - - cred = (gssspnego_cred)cred_handle; ret = gss_acquire_cred(minor_status, name, time_req, &actual_desired_mechs, cred_usage, - &cred->negotiated_cred_id, + output_cred_handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) goto out; - *output_cred_handle = cred_handle; - out: gss_release_name(minor_status, &name); gss_release_oid_set(&tmp, &mechs); @@ -163,7 +123,7 @@ out: free(actual_desired_mechs.elements); } if (ret != GSS_S_COMPLETE) { - _gss_spnego_release_cred(&tmp, &cred_handle); + _gss_spnego_release_cred(&tmp, output_cred_handle); } return ret; @@ -178,7 +138,6 @@ OM_uint32 _gss_spnego_inquire_cred gss_OID_set * mechanisms ) { - gssspnego_cred cred; spnego_name sname = NULL; OM_uint32 ret; @@ -195,10 +154,8 @@ OM_uint32 _gss_spnego_inquire_cred } } - cred = (gssspnego_cred)cred_handle; - ret = gss_inquire_cred(minor_status, - cred->negotiated_cred_id, + cred_handle, sname ? &sname->mech : NULL, lifetime, cred_usage, @@ -228,37 +185,23 @@ OM_uint32 _gss_spnego_add_cred ( OM_uint32 * acceptor_time_rec ) { - gss_cred_id_t spnego_output_cred_handle = GSS_C_NO_CREDENTIAL; OM_uint32 ret, tmp; - gssspnego_cred input_cred, output_cred; *output_cred_handle = GSS_C_NO_CREDENTIAL; - ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL, - &spnego_output_cred_handle); - if (ret) - return ret; - - input_cred = (gssspnego_cred)input_cred_handle; - output_cred = (gssspnego_cred)spnego_output_cred_handle; - ret = gss_add_cred(minor_status, - input_cred->negotiated_cred_id, + input_cred_handle, desired_name, desired_mech, cred_usage, initiator_time_req, acceptor_time_req, - &output_cred->negotiated_cred_id, + output_cred_handle, actual_mechs, initiator_time_rec, acceptor_time_rec); - if (ret) { - _gss_spnego_release_cred(&tmp, &spnego_output_cred_handle); + if (ret) return ret; - } - - *output_cred_handle = spnego_output_cred_handle; return GSS_S_COMPLETE; } @@ -273,7 +216,6 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech ( gss_cred_usage_t * cred_usage ) { - gssspnego_cred cred; spnego_name sname = NULL; OM_uint32 ret; @@ -290,10 +232,8 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech ( } } - cred = (gssspnego_cred)cred_handle; - ret = gss_inquire_cred_by_mech(minor_status, - cred->negotiated_cred_id, + cred_handle, mech_type, sname ? &sname->mech : NULL, initiator_lifetime, @@ -317,17 +257,15 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid const gss_OID desired_object, gss_buffer_set_t *data_set) { - gssspnego_cred cred; OM_uint32 ret; if (cred_handle == GSS_C_NO_CREDENTIAL) { *minor_status = 0; return GSS_S_NO_CRED; } - cred = (gssspnego_cred)cred_handle; ret = gss_inquire_cred_by_oid(minor_status, - cred->negotiated_cred_id, + cred_handle, desired_object, data_set); @@ -340,16 +278,13 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status, const gss_OID object, const gss_buffer_t value) { - gssspnego_cred cred; - if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { *minor_status = 0; return GSS_S_NO_CRED; } - cred = (gssspnego_cred)*cred_handle; return gss_set_cred_option(minor_status, - &cred->negotiated_cred_id, + cred_handle, object, value); } @@ -360,9 +295,7 @@ _gss_spnego_export_cred (OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t value) { - gssspnego_cred cred = (gssspnego_cred)cred_handle; - - return gss_export_cred(minor_status, cred->negotiated_cred_id, value); + return gss_export_cred(minor_status, cred_handle, value); } OM_uint32 @@ -370,23 +303,6 @@ _gss_spnego_import_cred (OM_uint32 *minor_status, gss_buffer_t value, gss_cred_id_t *cred_handle) { - gssspnego_cred cred; - OM_uint32 major; - - *cred_handle = GSS_C_NO_CREDENTIAL; - - cred = calloc(1, sizeof(*cred)); - if (cred == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id); - if (major == GSS_S_COMPLETE) - *cred_handle = (gss_cred_id_t)cred; - else - free(cred); - - return major; + return gss_import_cred(minor_status, value, cred_handle); } diff --git a/lib/gssapi/spnego/init_sec_context.c b/lib/gssapi/spnego/init_sec_context.c index ac32432d5..6afd524a5 100644 --- a/lib/gssapi/spnego/init_sec_context.c +++ b/lib/gssapi/spnego/init_sec_context.c @@ -179,7 +179,7 @@ spnego_reply_internal(OM_uint32 *minor_status, static OM_uint32 spnego_initial (OM_uint32 * minor_status, - gssspnego_cred cred, + gss_cred_id_t cred, gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, @@ -254,8 +254,7 @@ spnego_initial /* generate optimistic token */ sub = gss_init_sec_context(&minor, - (cred != NULL) ? cred->negotiated_cred_id : - GSS_C_NO_CREDENTIAL, + cred, &ctx->negotiated_ctx_id, ctx->target_name, ctx->preferred_mech_type, @@ -377,7 +376,7 @@ spnego_initial static OM_uint32 spnego_reply (OM_uint32 * minor_status, - const gssspnego_cred cred, + const gss_cred_id_t cred, gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, @@ -498,8 +497,7 @@ spnego_reply /* Fall through as if the negotiated mechanism was requested explicitly */ ret = gss_init_sec_context(&minor, - (cred != NULL) ? cred->negotiated_cred_id : - GSS_C_NO_CREDENTIAL, + cred, &ctx->negotiated_ctx_id, ctx->target_name, &mech, @@ -629,11 +627,9 @@ OM_uint32 _gss_spnego_init_sec_context OM_uint32 * time_rec ) { - gssspnego_cred cred = (gssspnego_cred)initiator_cred_handle; - if (*context_handle == GSS_C_NO_CONTEXT) return spnego_initial (minor_status, - cred, + initiator_cred_handle, context_handle, target_name, mech_type, @@ -647,7 +643,7 @@ OM_uint32 _gss_spnego_init_sec_context time_rec); else return spnego_reply (minor_status, - cred, + initiator_cred_handle, context_handle, target_name, mech_type, diff --git a/lib/gssapi/spnego/spnego_locl.h b/lib/gssapi/spnego/spnego_locl.h index 44fa8b117..e8cad1488 100644 --- a/lib/gssapi/spnego/spnego_locl.h +++ b/lib/gssapi/spnego/spnego_locl.h @@ -73,10 +73,6 @@ #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) -typedef struct { - gss_cred_id_t negotiated_cred_id; -} *gssspnego_cred; - typedef struct { MechTypeList initiator_mech_types; gss_OID preferred_mech_type; diff --git a/lib/gssapi/test_context.c b/lib/gssapi/test_context.c index 987e3fa1a..8074ed5ae 100644 --- a/lib/gssapi/test_context.c +++ b/lib/gssapi/test_context.c @@ -483,7 +483,7 @@ main(int argc, char **argv) OM_uint32 min_stat, maj_stat; gss_ctx_id_t cctx, sctx; void *ctx; - gss_OID nameoid, mechoid, actual_mech; + gss_OID nameoid, mechoid, actual_mech, actual_mech2; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; setprogname(argv[0]); @@ -775,7 +775,7 @@ main(int argc, char **argv) gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL; gss_buffer_desc cb; - loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, &cred2); + loop(actual_mech, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech2, &cred2); gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); @@ -797,7 +797,7 @@ main(int argc, char **argv) gss_release_buffer(&min_stat, &cb); gss_release_cred(&min_stat, &deleg_cred); - loop(mechoid, nameoid, argv[0], cred2, &cctx, &sctx, &actual_mech, &deleg_cred); + loop(actual_mech, nameoid, argv[0], cred2, &cctx, &sctx, &actual_mech2, &deleg_cred); gss_release_cred(&min_stat, &cred2); }