Stop using SALT_TYPE_AFS_LENGTH
authorGreg Hudson <ghudson@mit.edu>
Fri, 27 Apr 2012 21:11:04 +0000 (21:11 +0000)
committerGreg Hudson <ghudson@mit.edu>
Fri, 27 Apr 2012 21:11:04 +0000 (21:11 +0000)
In krb5_init_creds_ctx and krb5_clpreauth_rock_st, use a boolean to
track whether we're still using the default salt instead of
overloading salt.length.  In preauth2.c, process afs3 salt values like
we would in krb5int_des_string_to_key, and set an s2kparams indicator
instead of overloading salt.length.  Also use an s2kparams indicator
in kdb_cpw.c's add_key_pwd.  Remove the s2k code to handle overloaded
salt lengths, except for a sanity check.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25837 dc483132-0cff-0310-8789-dd5450dbe970

src/include/k5-int.h
src/include/krb5/krb5.hin
src/lib/crypto/krb/s2k_des.c
src/lib/crypto/krb/string_to_key.c
src/lib/kdb/kdb_cpw.c
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/gic_pwd.c
src/lib/krb5/krb/init_creds_ctx.h
src/lib/krb5/krb/preauth2.c
src/lib/krb5/libkrb5.exports

index 752b40efc0db74af0e599eda43449961ef398577..23869c79c51e30c7958c615dfd8b1661a197274d 100644 (file)
@@ -754,6 +754,7 @@ struct krb5_clpreauth_rock_st {
     krb5_keyblock *as_key;
     krb5_gic_get_as_key_fct *gak_fct;
     void **gak_data;
+    krb5_boolean *default_salt;
     krb5_data *salt;
     krb5_data *s2kparams;
     krb5_principal client;
index bdd42063e83c6ab53367c3f8683ef4d79cd2ddcf..94a78a004c6f3adc4d9f10145cd0aab588a151a1 100644 (file)
@@ -218,12 +218,7 @@ typedef struct _krb5_octet_data {
     krb5_octet *data;
 } krb5_octet_data;
 
-/*
- * Hack length for crypto library to use the afs_string_to_key It is
- * equivalent to -1 without possible sign extension
- * We also overload for an unset salt type length - which is also -1, but
- * hey, why not....
- */
+/* Originally used to recognize AFS and default salts.  No longer used. */
 #define SALT_TYPE_AFS_LENGTH UINT_MAX
 #define SALT_TYPE_NO_LENGTH  UINT_MAX
 
index fd2143054b9ba1db1928cc684a7ce7fe03e8e32b..61b3c0f012a5dbd50d4463e64f333e7cbc99e870 100644 (file)
@@ -670,7 +670,6 @@ krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
                           const krb5_data *parm, krb5_keyblock *keyblock)
 {
     int type;
-    krb5_data afssalt;
 
     if (parm != NULL) {
         if (parm->length != 1)
@@ -685,12 +684,5 @@ krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
     if (type == 1)
         return afs_s2k(string, salt, keyblock->contents);
 
-    /* Also use AFS string to key if the salt indicates it. */
-    if (salt != NULL && (salt->length == SALT_TYPE_AFS_LENGTH
-                         || salt->length == (unsigned)-1)) {
-        afssalt = make_data(salt->data, strcspn(salt->data, "@"));
-        return afs_s2k(string, &afssalt, keyblock->contents);
-    }
-
     return des_s2k(string, salt, keyblock->contents);
 }
index cd46d454a880c134adc21b4b7a2f5b3705598ba3..b55ee75d2f343ccb7cf543e90ce8136ecae4d429 100644 (file)
@@ -51,21 +51,9 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
         return KRB5_BAD_ENCTYPE;
     keylength = ktp->enc->keylength;
 
-    /*
-     * xxx AFS string2key function is indicated by a special length  in
-     * the salt in much of the code.  However only the DES enctypes can
-     * deal with this.  Using s2kparams would be a much better solution.
-     */
-    if (salt && salt->length == SALT_TYPE_AFS_LENGTH) {
-        switch (enctype) {
-        case ENCTYPE_DES_CBC_CRC:
-        case ENCTYPE_DES_CBC_MD4:
-        case ENCTYPE_DES_CBC_MD5:
-            break;
-        default:
-            return KRB5_CRYPTO_INTERNAL;
-        }
-    }
+    /* Fail gracefully if someone is using the old AFS string-to-key hack. */
+    if (salt != NULL && salt->length == SALT_TYPE_AFS_LENGTH)
+        return EINVAL;
 
     key->contents = malloc(keylength);
     if (key->contents == NULL)
index abaae4f7c4a892880808f1a127b60c0a203c3d8f..7b00fcf5f3645e05a351c5bcc91cb3c12aa24e5e 100644 (file)
@@ -389,6 +389,7 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
     krb5_keysalt          key_salt;
     krb5_keyblock         key;
     krb5_data             pwd;
+    krb5_data             afs_params = string2data("\1"), *s2k_params = NULL;
     int                   i, j, k;
     krb5_key_data         tmp_key_data;
     krb5_key_data        *tptr;
@@ -452,15 +453,12 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
             key_salt.data.data = 0;
             break;
         case KRB5_KDB_SALTTYPE_AFS3:
-            /* The afs_mit_string_to_key needs to use strlen, and the
-               realm field is not (necessarily) NULL terminated.  */
-            retval = krb5int_copy_data_contents_add0(context,
-                                                     krb5_princ_realm(context,
-                                                                      db_entry->princ),
-                                                     &key_salt.data);
+            retval = krb5int_copy_data_contents(context,
+                                                &db_entry->princ->realm,
+                                                &key_salt.data);
             if (retval)
                 return retval;
-            key_salt.data.length = SALT_TYPE_AFS_LENGTH; /*length actually used below...*/
+            s2k_params = &afs_params;
             break;
         case KRB5_KDB_SALTTYPE_SPECIAL:
             retval = make_random_salt(context, &key_salt);
@@ -474,18 +472,15 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
         pwd.data = passwd;
         pwd.length = strlen(passwd);
 
-        /* AFS string to key will happen here */
-        if ((retval = krb5_c_string_to_key(context, ks_tuple[i].ks_enctype,
-                                           &pwd, &key_salt.data, &key))) {
-            if (key_salt.data.data)
-                free(key_salt.data.data);
-            return(retval);
+        retval = krb5_c_string_to_key_with_params(context,
+                                                  ks_tuple[i].ks_enctype,
+                                                  &pwd, &key_salt.data,
+                                                  s2k_params, &key);
+        if (retval) {
+            free(key_salt.data.data);
+            return retval;
         }
 
-        if (key_salt.data.length == SALT_TYPE_AFS_LENGTH)
-            key_salt.data.length =
-                krb5_princ_realm(context, db_entry->princ)->length;
-
         /* memory allocation to be done by db. So, use temporary block and later copy
            it to the memory allocated by db */
         retval = krb5_dbe_encrypt_key_data(context, master_key, &key,
index 471834611a16830445538bfc192038e84fd57bfd..738bd9c3778ed9020c730570d11edd1ddee766a3 100644 (file)
@@ -822,6 +822,7 @@ krb5_init_creds_init(krb5_context context,
     ctx->preauth_rock.as_key = &ctx->as_key;
     ctx->preauth_rock.gak_fct = &ctx->gak_fct;
     ctx->preauth_rock.gak_data = &ctx->gak_data;
+    ctx->preauth_rock.default_salt = &ctx->default_salt;
     ctx->preauth_rock.salt = &ctx->salt;
     ctx->preauth_rock.s2kparams = &ctx->s2kparams;
     ctx->preauth_rock.client = client;
@@ -944,9 +945,10 @@ krb5_init_creds_init(krb5_context context,
         code = krb5int_copy_data_contents(context, opte->salt, &ctx->salt);
         if (code != 0)
             goto cleanup;
+        ctx->default_salt = FALSE;
     } else {
-        ctx->salt.length = SALT_TYPE_AFS_LENGTH;
-        ctx->salt.data = NULL;
+        ctx->salt = empty_data();
+        ctx->default_salt = TRUE;
     }
 
     /* Anonymous. */
@@ -1416,7 +1418,7 @@ init_creds_step_reply(krb5_context context,
      * salt.  local_as_reply->client will be checked later on in
      * verify_as_reply.
      */
-    if (ctx->salt.length == SALT_TYPE_AFS_LENGTH && ctx->salt.data == NULL) {
+    if (ctx->default_salt) {
         code = krb5_principal2salt(context, ctx->reply->client, &ctx->salt);
         TRACE_INIT_CREDS_SALT_PRINC(context, &ctx->salt);
         if (code != 0)
index 40b448d150f59e0732d141bb2a82b9d8099c6dd5..68d28fe9d335fab1b4ea76feab7f578ba467a188 100644 (file)
@@ -63,7 +63,7 @@ krb5_get_as_key_password(krb5_context context,
             return(ret);
     }
 
-    if (salt->length == SALT_TYPE_AFS_LENGTH && salt->data == NULL) {
+    if (salt == NULL) {
         if ((ret = krb5_principal2salt(context, client, &defsalt)))
             return(ret);
 
index 48376fccd4edca3c1b92100f2f8d893118593668..2653ee1613f2aa1d50eb78c99def758504d17370 100644 (file)
@@ -36,6 +36,7 @@ struct _krb5_init_creds_context {
     krb5_data *encoded_previous_request;
     struct krb5int_fast_request_state *fast_state;
     krb5_pa_data **preauth_to_use;
+    krb5_boolean default_salt;
     krb5_data salt;
     krb5_data s2kparams;
     krb5_keyblock as_key;
index 2ff862409ed885fc8bd3d0f8c1d70242a34c5313..7c5452790218ae0128732bd4d4db72231a1fc05b 100644 (file)
@@ -391,10 +391,12 @@ get_as_key(krb5_context context, krb5_clpreauth_rock rock,
            krb5_keyblock **keyblock)
 {
     krb5_error_code ret;
+    krb5_data *salt;
 
     if (rock->as_key->length == 0) {
+        salt = (*rock->default_salt) ? NULL : rock->salt;
         ret = (*rock->gak_fct)(context, rock->client, *rock->etype,
-                               rock->prompter, rock->prompter_data, rock->salt,
+                               rock->prompter, rock->prompter_data, salt,
                                rock->s2kparams, rock->as_key, *rock->gak_data);
         if (ret)
             return ret;
@@ -565,6 +567,7 @@ get_etype_info(krb5_context context, krb5_pa_data **padata,
     krb5_etype_info etype_info = NULL, e;
     krb5_etype_info_entry *entry;
     krb5_boolean valid_found;
+    const char *p;
     int i;
 
     /* Find an etype-info2 or etype-info element in padata. */
@@ -604,6 +607,10 @@ get_etype_info(krb5_context context, krb5_pa_data **padata,
         if (entry->length != KRB5_ETYPE_NO_SALT) {
             *rock->salt = make_data(entry->salt, entry->length);
             entry->salt = NULL;
+            *rock->default_salt = FALSE;
+        } else {
+            *rock->salt = empty_data();
+            *rock->default_salt = TRUE;
         }
         krb5_free_data_contents(context, rock->s2kparams);
         *rock->s2kparams = entry->s2kparams;
@@ -619,12 +626,27 @@ get_etype_info(krb5_context context, krb5_pa_data **padata,
             /* Set rock->salt based on the element we found. */
             krb5_free_data_contents(context, rock->salt);
             d = padata2data(*pa);
-            ret = krb5int_copy_data_contents_add0(context, &d, rock->salt);
+            ret = krb5int_copy_data_contents(context, &d, rock->salt);
             if (ret)
                 goto cleanup;
+            if (pa->pa_type == KRB5_PADATA_AFS3_SALT) {
+                /* Work around a (possible) old Heimdal KDC foible. */
+                p = memchr(rock->salt->data, '@', rock->salt->length);
+                if (p != NULL)
+                    rock->salt->length = p - rock->salt->data;
+                /* Tolerate extra null in MIT KDC afs3-salt value. */
+                if (rock->salt->length > 0 &&
+                    rock->salt->data[rock->salt->length - 1] == '\0')
+                    rock->salt->length--;
+                /* Set an s2kparams value to indicate AFS string-to-key. */
+                krb5_free_data_contents(context, rock->s2kparams);
+                ret = alloc_data(rock->s2kparams, 1);
+                if (ret)
+                    goto cleanup;
+                rock->s2kparams->data[0] = '\1';
+            }
+            *rock->default_salt = FALSE;
             TRACE_PREAUTH_SALT(context, rock->salt, pa->pa_type);
-            if (pa->pa_type == KRB5_PADATA_AFS3_SALT)
-                rock->salt->length = SALT_TYPE_AFS_LENGTH;
         }
     }
 
index 04a09eb45b62d66fb35cdbac444e6a4a5f9474f4..cb73a147141c5b6650c667481251e718f0792aeb 100644 (file)
@@ -577,6 +577,7 @@ krb5int_cc_default
 krb5int_cleanup_library
 krb5int_clean_hostname
 krb5int_cm_call_select
+krb5int_copy_data_contents
 krb5int_copy_data_contents_add0
 krb5int_find_pa_data
 krb5int_foreach_localaddr