krb5 commit: Get default cred only once in gss-krb5 initiator
Greg Hudson
ghudson at MIT.EDU
Mon Jul 2 00:57:41 EDT 2012
https://github.com/krb5/krb5/commit/49ba7c90fce86581ff6faaa9ee48c80b0be9491e
commit 49ba7c90fce86581ff6faaa9ee48c80b0be9491e
Author: Greg Hudson <ghudson at mit.edu>
Date: Mon Jul 2 00:57:34 2012 -0400
Get default cred only once in gss-krb5 initiator
In the regular krb5 code path, only get a default krb5 cred for the
initial token, since we don't need the cred for mutual_auth anyway.
In the IAKERB mechanism, cache the default cred in iakerb_ctx_id_rec
so we don't have to construct it again for each token. Also, get an
IAKERB default cred, not a regular krb5 cred (a bug which is harmless
now, but becomes more of a problem with keytab initiation changes).
src/lib/gssapi/krb5/iakerb.c | 32 ++++++++++---------
src/lib/gssapi/krb5/init_sec_context.c | 51 +++++++++++++++-----------------
2 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index 31fd190..1b3236e 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -40,6 +40,7 @@ enum iakerb_state {
struct _iakerb_ctx_id_rec {
krb5_magic magic; /* KG_IAKERB_CONTEXT */
krb5_context k5c;
+ gss_cred_id_t defcred; /* Initiator only */
enum iakerb_state state; /* Initiator only */
krb5_init_creds_context icc; /* Initiator only */
krb5_tkt_creds_context tcc; /* Initiator only */
@@ -65,6 +66,7 @@ iakerb_release_context(iakerb_ctx_id_t ctx)
if (ctx == NULL)
return;
+ krb5_gss_release_cred(&tmp, &ctx->defcred);
krb5_init_creds_free(ctx->k5c, ctx->icc);
krb5_tkt_creds_free(ctx->k5c, ctx->tcc);
krb5_gss_delete_sec_context(&tmp, &ctx->gssc, NULL);
@@ -710,6 +712,7 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx)
ctx = k5alloc(sizeof(*ctx), &code);
if (ctx == NULL)
goto cleanup;
+ ctx->defcred = GSS_C_NO_CREDENTIAL;
ctx->magic = KG_IAKERB_CONTEXT;
ctx->state = IAKERB_AS_REQ;
ctx->count = 0;
@@ -893,10 +896,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
OM_uint32 *time_rec)
{
OM_uint32 major_status = GSS_S_FAILURE;
- OM_uint32 tmpmin;
krb5_error_code code;
iakerb_ctx_id_t ctx;
- gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
krb5_gss_cred_id_t kcred;
krb5_gss_name_t kname;
krb5_boolean cred_locked = FALSE;
@@ -908,22 +909,24 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
*minor_status = code;
goto cleanup;
}
- } else
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+ major_status = iakerb_gss_acquire_cred(minor_status, NULL,
+ GSS_C_INDEFINITE,
+ GSS_C_NULL_OID_SET,
+ GSS_C_INITIATE,
+ &ctx->defcred, NULL, NULL);
+ if (GSS_ERROR(major_status))
+ goto cleanup;
+ claimant_cred_handle = ctx->defcred;
+ }
+ } else {
ctx = (iakerb_ctx_id_t)*context_handle;
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+ claimant_cred_handle = ctx->defcred;
+ }
kname = (krb5_gss_name_t)target_name;
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
- major_status = krb5_gss_acquire_cred(minor_status, NULL,
- GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET,
- GSS_C_INITIATE,
- &defcred, NULL, NULL);
- if (GSS_ERROR(major_status))
- goto cleanup;
- claimant_cred_handle = defcred;
- }
-
major_status = kg_cred_resolve(minor_status, ctx->k5c,
claimant_cred_handle, target_name);
if (GSS_ERROR(major_status))
@@ -1011,7 +1014,6 @@ cleanup:
iakerb_release_context(ctx);
*context_handle = GSS_C_NO_CONTEXT;
}
- krb5_gss_release_cred(&tmpmin, &defcred);
return major_status;
}
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 6451a6d..d0eda5f 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -948,29 +948,6 @@ krb5_gss_init_sec_context_ext(
if (actual_mech_type)
*actual_mech_type = NULL;
- /* verify the credential, or use the default */
- /*SUPPRESS 29*/
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
- major_status = kg_get_defcred(minor_status, &defcred);
- if (major_status && GSS_ERROR(major_status)) {
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(major_status);
- }
- claimant_cred_handle = defcred;
- }
-
- major_status = kg_cred_resolve(minor_status, context, claimant_cred_handle,
- target_name);
- if (GSS_ERROR(major_status)) {
- save_error_info(*minor_status, context);
- krb5_gss_release_cred(&tmp_min_stat, &defcred);
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(major_status);
- }
- cred = (krb5_gss_cred_id_t)claimant_cred_handle;
-
/* verify the mech_type */
if (mech_type == GSS_C_NULL_OID || g_OID_equal(mech_type, gss_mech_krb5)) {
@@ -982,8 +959,6 @@ krb5_gss_init_sec_context_ext(
} else if (g_OID_equal(mech_type, gss_mech_iakerb)) {
mech_type = (gss_OID) gss_mech_iakerb;
} else {
- k5_mutex_unlock(&cred->lock);
- krb5_gss_release_cred(minor_status, &defcred);
*minor_status = 0;
if (*context_handle == GSS_C_NO_CONTEXT)
krb5_free_context(context);
@@ -994,6 +969,29 @@ krb5_gss_init_sec_context_ext(
/*SUPPRESS 29*/
if (*context_handle == GSS_C_NO_CONTEXT) {
+ /* verify the credential, or use the default */
+ /*SUPPRESS 29*/
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+ major_status = kg_get_defcred(minor_status, &defcred);
+ if (major_status && GSS_ERROR(major_status)) {
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(major_status);
+ }
+ claimant_cred_handle = defcred;
+ }
+
+ major_status = kg_cred_resolve(minor_status, context,
+ claimant_cred_handle, target_name);
+ if (GSS_ERROR(major_status)) {
+ save_error_info(*minor_status, context);
+ krb5_gss_release_cred(&tmp_min_stat, &defcred);
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(major_status);
+ }
+ cred = (krb5_gss_cred_id_t)claimant_cred_handle;
+
major_status = kg_new_connection(minor_status, cred, context_handle,
target_name, mech_type, req_flags,
time_req, input_chan_bindings,
@@ -1001,6 +999,7 @@ krb5_gss_init_sec_context_ext(
output_token, ret_flags, time_rec,
context, exts);
k5_mutex_unlock(&cred->lock);
+ krb5_gss_release_cred(&tmp_min_stat, &defcred);
if (*context_handle == GSS_C_NO_CONTEXT) {
save_error_info (*minor_status, context);
krb5_free_context(context);
@@ -1008,7 +1007,6 @@ krb5_gss_init_sec_context_ext(
((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
} else {
/* mutual_auth doesn't care about the credentials */
- k5_mutex_unlock(&cred->lock);
major_status = mutual_auth(minor_status, context_handle,
target_name, mech_type, req_flags,
time_req, input_chan_bindings,
@@ -1020,7 +1018,6 @@ krb5_gss_init_sec_context_ext(
too. */
}
- krb5_gss_release_cred(&tmp_min_stat, &defcred);
return(major_status);
}
More information about the cvs-krb5
mailing list