From 85fa9e1e2073d2c0ec2a82205bcfd13080e854f0 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Mon, 15 Mar 2004 02:05:11 +0000 Subject: [PATCH] * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Add a krb5 context object. * init_sec_context.c (krb5_gss_init_sec_context): Create a new krb5 context, and store it in the security context if successful. If there's already a security context, use the krb5 context in it. * accept_sec_context.c (krb5_gss_accept_sec_context): Create a new krb5 context, and store it in the security context if successful. * delete_sec_context.c (krb5_gss_delete_sec_context): If the security context has a krb5 context, free it. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16170 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/krb5/ChangeLog | 12 +++++++ src/lib/gssapi/krb5/accept_sec_context.c | 40 +++++++++++++++--------- src/lib/gssapi/krb5/delete_sec_context.c | 11 ++++--- src/lib/gssapi/krb5/gssapiP_krb5.h | 1 + src/lib/gssapi/krb5/init_sec_context.c | 30 ++++++++++++++++-- 5 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index ad17ecc1e..a3704fa97 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,5 +1,17 @@ 2004-03-14 Ken Raeburn + * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Add a krb5 + context object. + * init_sec_context.c (krb5_gss_init_sec_context): Create a new + krb5 context, and store it in the security context if + successful. If there's already a security context, use the krb5 + context in it. + * accept_sec_context.c (krb5_gss_accept_sec_context): Create a + new krb5 context, and store it in the security context if + successful. + * delete_sec_context.c (krb5_gss_delete_sec_context): If the + security context has a krb5 context, free it. + * gssapi_krb5.c (kg_vdb): Change type to g_set and initialize. * gssapiP_krb5.h (kg_vdb): Declaration updated. diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 9db7e7e55..021866ab3 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -193,10 +193,10 @@ cleanup: if (out_cred) *out_cred = cred; /* return credential */ - if (new_auth_ctx) - krb5_auth_con_free(context, new_auth_ctx); + if (new_auth_ctx) + krb5_auth_con_free(context, new_auth_ctx); - krb5_auth_con_setflags(context, auth_context, flags_org); + krb5_auth_con_setflags(context, auth_context, flags_org); return retval; } @@ -251,13 +251,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5int_access kaccess; code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); - if (code) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); + if (code) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + code = krb5_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } /* set up returns to be freeable */ @@ -892,8 +895,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (ap_rep.data) krb5_free_data_contents(context, &ap_rep); - if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED) + if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED) { + ctx->k5_context = context; return(major_status); + } /* from here on is the real "fail" code */ @@ -925,8 +930,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (decode_req_message) { krb5_ap_req * request; - if (decode_krb5_ap_req(&ap_req, &request)) + if (decode_krb5_ap_req(&ap_req, &request)) { + krb5_free_context(context); return (major_status); + } if (request->ap_options & AP_OPTS_MUTUAL_REQUIRED) gss_flags |= GSS_C_MUTUAL_FLAG; krb5_free_ap_req(context, request); @@ -954,16 +961,20 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb_error_data.server = cred->princ; code = krb5_mk_error(context, &krb_error_data, &scratch); - if (code) + if (code) { + krb5_free_context(context); return (major_status); + } tmsglen = scratch.length; toktype = KG_TOK_CTX_ERROR; token.length = g_token_size((gss_OID) mech_used, tmsglen); token.value = (unsigned char *) xmalloc(token.length); - if (!token.value) + if (!token.value) { + krb5_free_context(context); return (major_status); + } ptr = token.value; g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); @@ -976,5 +987,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (!verifier_cred_handle && cred_handle) { krb5_gss_release_cred(minor_status, cred_handle); } + krb5_free_context(context); return (major_status); } diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index 94702b862..70a79f5e9 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -35,9 +35,6 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) krb5_context context; krb5_gss_ctx_id_rec *ctx; - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); - if (output_token) { output_token->length = 0; output_token->value = NULL; @@ -56,6 +53,9 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) return(GSS_S_NO_CONTEXT); } + ctx = (gss_ctx_id_t) *context_handle; + context = ctx->k5_context; + /* construct a delete context token if necessary */ if (output_token) { @@ -75,8 +75,6 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) /* free all the context state */ - ctx = (gss_ctx_id_t) *context_handle; - if (ctx->seqstate) g_order_free(&(ctx->seqstate)); @@ -103,6 +101,9 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) if (ctx->mech_used) gss_release_oid(minor_status, &ctx->mech_used); + if (ctx->k5_context) + krb5_free_context(ctx->k5_context); + /* Zero out context */ memset(ctx, 0, sizeof(*ctx)); xfree(ctx); diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index e5b5c2663..7c58c9a85 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -180,6 +180,7 @@ typedef struct _krb5_gss_ctx_id_rec { gssint_uint64 seq_send; gssint_uint64 seq_recv; void *seqstate; + krb5_context k5_context; krb5_auth_context auth_context; gss_OID_desc *mech_used; /* Protocol spec revision diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index bb17dc5d5..48015cccd 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -829,12 +829,20 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, krb5_context context; krb5_gss_cred_id_t cred; int err; + krb5_error_code kerr; int default_mech = 0; OM_uint32 major_status; OM_uint32 tmp_min_stat; - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); + if (*context_handle == GSS_C_NO_CONTEXT) { + kerr = krb5_init_context(&context); + if (kerr) { + *minor_status = kerr; + return GSS_S_FAILURE; + } + } else { + context = ((krb5_gss_ctx_id_rec *) context_handle)->k5_context; + } /* set up return values so they can be "freed" successfully */ @@ -848,6 +856,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, if (! kg_validate_name(target_name)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } @@ -856,12 +866,17 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { major_status = kg_get_defcred(minor_status, &cred); if (major_status && GSS_ERROR(major_status)) { + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); return(major_status); } } else { major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle); - if (GSS_ERROR(major_status)) + if (GSS_ERROR(major_status)) { + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); return(major_status); + } cred = (krb5_gss_cred_id_t) claimant_cred_handle; } @@ -891,6 +906,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) krb5_gss_release_cred(minor_status, (gss_cred_id_t)cred); *minor_status = 0; + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); return(GSS_S_BAD_MECH); } @@ -904,6 +921,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, input_token, actual_mech_type, output_token, ret_flags, time_rec, context, default_mech); + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + else + ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context; } else { major_status = mutual_auth(minor_status, cred, context_handle, target_name, mech_type, req_flags, @@ -911,6 +932,9 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, input_token, actual_mech_type, output_token, ret_flags, time_rec, context); + /* If context_handle is now NO_CONTEXT, mutual_auth called + delete_sec_context, which would've zapped the krb5 context + too. */ } if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) -- 2.26.2