]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
unknown token id stuff; delete old enctype list hacks
authorKen Raeburn <raeburn@mit.edu>
Wed, 10 Dec 2003 22:00:52 +0000 (22:00 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 10 Dec 2003 22:00:52 +0000 (22:00 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/raeburn-gssapi-cfx@15876 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/init_sec_context.c
src/lib/gssapi/krb5/k5sealv3.c

index 716e12686bbccd2a0f82638413340eb6246b5cb4..2a60b87f6e72a21e7025fddb2bf2519214cfbf6b 100644 (file)
@@ -128,7 +128,8 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
                if ((retval = krb5_auth_con_init(context, &new_auth_ctx)))
                        goto cleanup;
                krb5_auth_con_setflags(context, new_auth_ctx, 0);
-               if ((retval = krb5_rd_cred(context, new_auth_ctx, inbuf, &creds, NULL)))
+               if ((retval = krb5_rd_cred(context, new_auth_ctx, inbuf,
+                                          &creds, NULL)))
                        goto cleanup;
                }
 
@@ -248,6 +249,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    gss_cred_id_t cred_handle = NULL;
    krb5_gss_cred_id_t deleg_cred = NULL;
 
+   _log("%s:%d: accept_sec_context input_token len %d\n",
+       SFILE, __LINE__, input_token->length);
+
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
 
@@ -285,6 +289,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
                                            GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
                                            GSS_C_ACCEPT, &cred_handle,
                                            NULL, NULL);
+       _log("%s:%d: krb5_gss_acquire_cred returns %d, cred_handle %p\n",
+           SFILE, __LINE__, major_status, cred_handle);
        if (major_status != GSS_S_COMPLETE) {
           code = *minor_status;
           goto fail;
@@ -300,6 +306,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    }
 
    cred = (krb5_gss_cred_id_t) cred_handle;
+   _log("%s:%d: cred=%p\n", SFILE, __LINE__, cred);
 
    /* make sure the supplied credentials are valid for accept */
 
@@ -334,6 +341,13 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        * old behavior.
        */
        mech_used = gss_mech_krb5_old;
+   } else if (code == G_WRONG_TOKID) {
+       major_status = GSS_S_CONTINUE_NEEDED;
+       code = KRB5KRB_AP_ERR_MSG_TYPE;
+       mech_used = gss_mech_krb5;
+       _log("%s:%d: ooh, G_WRONG_TOKID! sending AP_ERR_MSG_TYPE\n",
+           SFILE, __LINE__);
+       goto fail;
    } else {
        major_status = GSS_S_DEFECTIVE_TOKEN;
        goto fail;
@@ -854,7 +868,7 @@ 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))
+   if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED)
        return(major_status);
 
    /* from here on is the real "fail" code */
@@ -894,7 +908,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        krb5_free_ap_req(context, request);
    }
 
-   if (cred && (gss_flags & GSS_C_MUTUAL_FLAG)) {
+   _log("%s:%d: cred=%p mutual=%d major_status=%d (cont-need=%d)\n",
+       SFILE, __LINE__, cred, gss_flags & GSS_C_MUTUAL_FLAG, major_status,
+       GSS_S_CONTINUE_NEEDED);
+   if (cred
+       && ((gss_flags & GSS_C_MUTUAL_FLAG)
+          || (major_status == GSS_S_CONTINUE_NEEDED))) {
        unsigned int tmsglen;
        int toktype;
 
@@ -902,39 +921,62 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        * The client is expecting a response, so we can send an
        * error token back
        */
+       _log("%s:%d: here\n", SFILE, __LINE__);
        memset(&krb_error_data, 0, sizeof(krb_error_data));
 
-       code  -= ERROR_TABLE_BASE_krb5;
+       code -= ERROR_TABLE_BASE_krb5;
        if (code < 0 || code > 128)
           code = 60 /* KRB_ERR_GENERIC */;
 
        krb_error_data.error = code;
        (void) krb5_us_timeofday(context, &krb_error_data.stime,
                                &krb_error_data.susec);
-       krb_error_data.server = cred->princ;
+       if (cred)
+          krb_error_data.server = cred->princ;
+       else {
+          code = krb5_parse_name(context, "server/principal/name@unknown",
+                                 &krb_error_data.server);
+       _log("%s:%d: here\n", SFILE, __LINE__);
+          if (code)
+              return major_status;
+       }
           
+       _log("%s:%d: here\n", SFILE, __LINE__);
        code = krb5_mk_error(context, &krb_error_data, &scratch);
+       if (cred == NULL) {
+          krb5_free_principal(context, krb_error_data.server);
+          krb_error_data.server = NULL;
+       }
        if (code)
           return (major_status);
+       _log("%s:%d: here\n", SFILE, __LINE__);
 
        tmsglen = scratch.length;
        toktype = KG_TOK_CTX_ERROR;
 
+       _log("%s:%d: here\n", SFILE, __LINE__);
        token.length = g_token_size((gss_OID) mech_used, tmsglen);
+       _log("%s:%d: here\n", SFILE, __LINE__);
        token.value = (unsigned char *) xmalloc(token.length);
+       _log("%s:%d: token.length=%d .value=%p\n", SFILE, __LINE__,
+           token.length, token.value);
        if (!token.value)
           return (major_status);
 
+       _log("%s:%d: here\n", SFILE, __LINE__);
        ptr = token.value;
        g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype);
 
        TWRITE_STR(ptr, scratch.data, scratch.length);
        krb5_free_data_contents(context, &scratch);
 
+       _log("%s:%d: sending back error token size %d\n",
+           SFILE, __LINE__, token.length);
        *output_token = token;
    }
    if (!verifier_cred_handle && cred_handle) {
           krb5_gss_release_cred(minor_status, cred_handle);
    }
+   _log("%s:%d: returning major status 0x%x\n", SFILE, __LINE__, major_status);
    return (major_status);
 }
index 7fc75db5e3e10d0c8907bdd2d938807f4277eed3..445dd3d29554521061af318761f5011616ba9484 100644 (file)
@@ -169,6 +169,9 @@ typedef struct _krb5_gss_ctx_id_rec {
    unsigned int big_endian : 1;
    unsigned int have_acceptor_subkey : 1;
    unsigned int seed_init : 1; /* XXX tested but never actually set */
+#ifdef CFX_EXERCISE
+   unsigned int testing_unknown_tokid : 1; /* for testing only */
+#endif
    OM_uint32 gss_flags;
    unsigned char seed[16];
    krb5_principal here;
@@ -197,6 +200,9 @@ typedef struct _krb5_gss_ctx_id_rec {
    krb5_cksumtype cksumtype;   /* for "main" subkey */
    krb5_keyblock *acceptor_subkey; /* CFX only */
    krb5_cksumtype acceptor_subkey_cksumtype;
+#ifdef CFX_EXERCISE
+    gss_buffer_desc init_token;
+#endif
 } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
 
 extern void *kg_vdb;
index 4a06a208dc18c096a1b68f54d560c0bf027d4d74..7954bac265ba2287767515a258c2bf0f7ccb24e9 100644 (file)
@@ -90,13 +90,12 @@ int krb5_gss_dbg_client_expcreds = 0;
  * ccache.
  */
 static krb5_error_code get_credentials(context, cred, server, now,
-                                      endtime, enctypes, out_creds)
+                                      endtime, out_creds)
     krb5_context context;
     krb5_gss_cred_id_t cred;
     krb5_principal server;
     krb5_timestamp now;
     krb5_timestamp endtime;
-    const krb5_enctype *enctypes;
     krb5_creds **out_creds;
 {
     krb5_error_code    code;
@@ -112,10 +111,7 @@ static krb5_error_code get_credentials(context, cred, server, now,
 
     in_creds.keyblock.enctype = 0;
 
-    code = krb5_set_default_tgs_enctypes (context, enctypes);
-    if (code)
-      goto cleanup;
-        code = krb5_get_credentials(context, 0, cred->ccache,
+    code = krb5_get_credentials(context, 0, cred->ccache,
                                &in_creds, out_creds);
     if (code)
        goto cleanup;
@@ -324,85 +320,6 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
    return (code);
 }
 
-/*
- * get_requested_enctypes
- *
- * Filter the krb5 library's default enctype list with the set of
- * enctypes we support for GSSAPI.
- */
-static krb5_error_code
-get_requested_enctypes(
-   krb5_context context,
-   krb5_enctype **ret_enctypes)
-{
-   krb5_error_code code;
-   int i, j, k;
-   int is_duplicate_enctype;
-   int is_wanted_enctype;
-   static const krb5_enctype wanted_enctypes[] = {
-     ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
-     ENCTYPE_DES3_CBC_SHA1,
-     ENCTYPE_ARCFOUR_HMAC,
-     ENCTYPE_DES_CBC_CRC,
-     ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
-   };
-#define N_WANTED_ENCTYPES (sizeof(wanted_enctypes)/sizeof(wanted_enctypes[0]))
-   krb5_enctype *default_enctypes = 0;
-   krb5_enctype *requested_enctypes;
-
-   *ret_enctypes = malloc((N_WANTED_ENCTYPES + 1) * sizeof(krb5_enctype));
-   if (*ret_enctypes == NULL)
-      return ENOMEM;
-
-   code = krb5_get_tgs_ktypes (context, 0, &default_enctypes);
-   if (code) {
-      free(*ret_enctypes);
-      *ret_enctypes = NULL;
-      return code;
-   }
-   requested_enctypes = *ret_enctypes;
-
-   /* "i" denotes *next* slot to fill.  Don't forget to save room
-      for a trailing zero.  */
-   i = 0;
-   for (j = 0;
-       (default_enctypes[j] != 0
-        /* This part should be redundant, but let's be paranoid.  */
-        && i < N_WANTED_ENCTYPES);
-       j++) {
-
-      krb5_enctype e = default_enctypes[j];
-
-      /* Is this enctype one of the ones we want for GSSAPI?  */
-      is_wanted_enctype = 0;
-      for (k = 0; k < N_WANTED_ENCTYPES; k++) {
-        if (wanted_enctypes[k] == e) {
-           is_wanted_enctype = 1;
-           break;
-        }
-      }
-      /* If unwanted, go to the next one. */
-      if (!is_wanted_enctype)
-        continue;
-
-      /* Is this enctype already in the list of enctypes to
-        request?  (Is it a duplicate?)  */
-      is_duplicate_enctype = 0;
-      for (k = 0; k < i; k++) {
-        if (requested_enctypes[k] == e) {
-           is_duplicate_enctype = 1;
-           break;
-        }
-      }
-      /* If it is not a duplicate, add it. */
-      if (!is_duplicate_enctype)
-        requested_enctypes[i++] = e;
-   }
-   krb5_free_ktypes(context, default_enctypes);
-   requested_enctypes[i++] = 0;
-   return GSS_S_COMPLETE;
-}
-
 /*
  * setup_enc
  *
@@ -493,6 +410,7 @@ fail:
  *
  * Do the grunt work of setting up a new context.
  */
+#include <stdio.h>
 static OM_uint32
 new_connection(
    OM_uint32 *minor_status,
@@ -534,8 +452,17 @@ new_connection(
    /* complain if the input token is non-null */
 
    if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
-      *minor_status = 0;
-      return(GSS_S_DEFECTIVE_TOKEN);
+#ifdef CFX_EXERCISE
+       if (*context_handle != GSS_C_NO_CONTEXT
+          && ((krb5_gss_ctx_id_t)*context_handle)->testing_unknown_tokid) {
+          /* XXX Should check for a KRB_ERROR message that we can
+             parse, and which contains the expected error code.  */
+          ctx = (krb5_gss_ctx_id_t)*context_handle;
+          goto resume_after_testing;
+       }
+#endif
+       *minor_status = 0;
+       return(GSS_S_DEFECTIVE_TOKEN);
    }
 
    /* create the ctx */
@@ -575,13 +502,8 @@ new_connection(
                                   &ctx->there)))
       goto fail;
 
-   code = get_requested_enctypes(context, &requested_enctypes);
-   if (code)
-      goto fail;
-
    code = get_credentials(context, cred, ctx->there, now,
-                         ctx->endtime, requested_enctypes, &k_cred);
-   free(requested_enctypes);
+                         ctx->endtime, &k_cred);
    if (code)
       goto fail;
 
@@ -638,6 +560,46 @@ new_connection(
    *context_handle = (gss_ctx_id_t) ctx;
    ctx_free = 0;
 
+#ifdef CFX_EXERCISE
+   if (ctx->proto == 1
+       && (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
+       && (rand() & 3)) {
+       /* Create a bogus token and return it, with status
+         GSS_S_CONTINUE_NEEDED.  Save enough data that we can resume
+         on the next call.  */
+       static const unsigned char hack_token[20] = {
+          0x60, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+          0xf7, 0x12, 0x01, 0x02, 0x02, 0x12, 0x34, 0x68,
+          0x65, 0x6c, 0x6c, 0x6f
+       };
+       ctx->testing_unknown_tokid = 1;
+       ctx->init_token = token;
+       token.value = malloc(20);
+       token.length = 20;
+       if (token.value == NULL) {
+          /* Skip testing.  We'll probably die soon enough, but let's
+             not do it because we couldn't exercise this code
+             path.  */
+          goto resume_after_testing;
+       }
+       memcpy(token.value, hack_token, sizeof(hack_token));
+       _log("%s:%d: sending bogus token to test unknown-TOK_ID handling\n",
+           SFILE, __LINE__);
+       /* Can just fall through into the normal return path, because
+         it'll always return GSS_S_CONTINUE_NEEDED because we're
+         doing mutual authentication.  */
+   }
+   if (0) {
+   resume_after_testing:
+       _log("%s:%d: resuming after bogus-token test\n", SFILE, __LINE__);
+       token = ctx->init_token;
+       ctx->init_token.value = 0;
+       ctx->init_token.length = 0;
+       ctx->testing_unknown_tokid = 0;
+       ctx_free = 0;
+   }
+#endif
+
    /* compute time_rec */
    if (time_rec) {
       if ((code = krb5_timeofday(context, &now)))
@@ -888,6 +850,9 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
    OM_uint32 major_status;
    OM_uint32 tmp_min_stat;
 
+   _log("%s:%d: %s input_token len %d\n", SFILE, __LINE__, __func__,
+       input_token == GSS_C_NO_BUFFER ? -1 : input_token->length);
+
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
 
@@ -952,7 +917,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
    /* is this a new connection or not? */
 
    /*SUPPRESS 29*/
-   if (*context_handle == GSS_C_NO_CONTEXT) {
+   if (*context_handle == GSS_C_NO_CONTEXT
+       || ((krb5_gss_ctx_id_t)*context_handle)->testing_unknown_tokid) {
       major_status = new_connection(minor_status, cred, context_handle,
                                    target_name, mech_type, req_flags,
                                    time_req, input_chan_bindings,
index 9d5024bd339fb36691576cfb02bcf28d44e11615..e14d620cb7cf0a75287be9a4e6d7a8174273d9a7 100644 (file)
@@ -103,6 +103,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
     _log("%s:%d: wrap input token: %d @%p toktype=0x%x\n", SFILE, __LINE__,
         message->length, message->value, toktype);
 
+#ifdef CFX_EXERCISE
     {
        static int initialized = 0;
        if (!initialized) {
@@ -110,6 +111,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
            initialized = 1;
        }
     }
+#endif
 
     if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) {
        krb5_data plain;