* gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Add a krb5 context object.
authorKen Raeburn <raeburn@mit.edu>
Mon, 15 Mar 2004 02:05:11 +0000 (02:05 +0000)
committerKen Raeburn <raeburn@mit.edu>
Mon, 15 Mar 2004 02:05:11 +0000 (02:05 +0000)
* 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
src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/delete_sec_context.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/init_sec_context.c

index ad17ecc1ea87f023e910defe6267ffd441ccdf08..a3704fa97ac12faf5b90330c9c2c87c801cefccf 100644 (file)
@@ -1,5 +1,17 @@
 2004-03-14  Ken Raeburn  <raeburn@mit.edu>
 
+       * 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.
 
index 9db7e7e55e03a10321a3ca75f5c4f8de0727dd71..021866ab3de11f42c2e4a17ea1d08aee282d9873 100644 (file)
@@ -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);
 }
index 94702b862701f785f9bbc7621f8cef672fb6fe73..70a79f5e938632182c5a60dd233c8143d5afc569 100644 (file)
@@ -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);
index e5b5c2663473d25c57a7acdd8fe0e01eaaa3e8b6..7c58c9a8596849c682fb19eac5e4893a25330d2c 100644 (file)
@@ -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
index bb17dc5d5cb980e92e65a99246f16a0f5b342af1..48015cccde5c5ccd13465a4fe02ba81968b74b05 100644 (file)
@@ -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)