The client sorts the enctype list returned by etype_info ordering
authorSam Hartman <hartmans@mit.edu>
Sat, 15 Feb 2003 01:15:10 +0000 (01:15 +0000)
committerSam Hartman <hartmans@mit.edu>
Sat, 15 Feb 2003 01:15:10 +0000 (01:15 +0000)
enctypes that it requested or that are similar to ones it requested
first.

The KDC only includes enctypes in etype_info if they were requested by
the client.

ticket: 1006

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

src/kdc/ChangeLog
src/kdc/kdc_preauth.c
src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/preauth2.c

index 346305c2e68fcb191c7080c6a7ce47a690e140e6..d20710cf2dde700f009eec1e9acda2051f8407e2 100644 (file)
@@ -1,3 +1,9 @@
+2003-02-14  Sam Hartman  <hartmans@mit.edu>
+
+       * kdc_preauth.c (request_contains_enctype): New function
+       (get_etype_info): Use it to filter out enctypes not requested by
+       the client 
+
 2003-02-08  Ken Hornstein  <kenh@cmf.nrl.navy.mil>
 
        * Makefile.in, configure.in, fakeka.c: New file to implement
index 1087e76c0a1f7013744d2bd5bed6c4423466a497..391bcd8bc0d5b9e680cafcebd243586c200fa893 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * kdc/kdc_preauth.c
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995, 2003 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -431,6 +431,18 @@ cleanup:
     return (retval);
 }
 
+static krb5_boolean
+request_contains_enctype (krb5_context context,  const krb5_kdc_req *request,
+                         krb5_enctype enctype)
+{
+    int i;
+    for (i =0; i < request->nktypes; i++)
+       if (request->ktype[i] == enctype)
+           return 1;
+    return 0;
+}
+
+
 static krb5_error_code
 verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
                     krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
@@ -542,6 +554,13 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
            db_etype = ENCTYPE_DES_CBC_CRC;
        
        while (1) {
+           if (!request_contains_enctype(context,
+                                         request, db_etype)) {
+               if (db_etype = ENCTYPE_DES_CBC_CRC)
+                    continue;
+                else break;
+            }
+
            if ((entry[i] = malloc(sizeof(krb5_etype_info_entry))) == NULL) {
                retval = ENOMEM;
                goto cleanup;
index bc158827590340dbf40d95d696c7201214c9568d..95da8d84a39148de3e820fdfeb1b40ed596b369c 100644 (file)
@@ -1,3 +1,8 @@
+2003-02-14  Sam Hartman  <hartmans@mit.edu>
+
+       * preauth2.c (krb5_do_preauth): Sort incoming etype info based on
+       preference order in request  
+
 2003-02-13  Sam Hartman  <hartmans@mit.edu>
 
        * gic_keytab.c (krb5_get_as_key_keytab): Nathan Neulinger points
index f99379fa2338adaefc9205c20c92bdcc11bba8cf..34cb40f22ccad737bc20753c5b49691fb9c0ff99 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995 by the Massachusetts Institute of Technology.  All
+ * Copyright 1995, 2003 by the Massachusetts Institute of Technology.  All
  * Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -825,6 +825,76 @@ static const pa_types_t pa_types[] = {
     },
 };
 
+static void
+sort_etype_info(krb5_context  context, krb5_kdc_req *request,
+                krb5_etype_info_entry **etype_info)
+{
+/* Originally adapted from a proposed solution in ticket 1006.  This
+ * solution  is  not efficient, but implementing an efficient sort
+ * with a comparison function based on order in the kdc request would
+ * be difficult.*/
+    krb5_etype_info_entry *tmp;
+    int i, j, e;
+    krb5_boolean similar;
+
+    if (etype_info == NULL)
+       return;
+
+    /* First, move up etype_info_entries whose enctype exactly matches a
+     * requested enctype.
+     */
+    e = 0;
+    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
+    {
+       if (request->ktype[i] == etype_info[e]->etype)
+       {
+           e++;
+           continue;
+       }
+       for ( j = e+1 ; etype_info[j] ; j++ )
+           if (request->ktype[i] == etype_info[j]->etype)
+               break;
+       if (etype_info[j] == NULL)
+           continue;
+
+       tmp = etype_info[j];
+       etype_info[j] = etype_info[e];
+       etype_info[e] = tmp;
+       e++;
+    }
+
+    /* Then move up etype_info_entries whose enctype is similar to a
+     * requested enctype.
+     */
+    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
+    {
+       if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[e]->etype, &similar) != 0)
+           continue;
+
+       if (similar)
+       {
+           e++;
+           continue;
+       }
+       for ( j = e+1 ; etype_info[j] ; j++ )
+       {
+           if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[j]->etype, &similar) != 0)
+               continue;
+
+           if (similar)
+               break;
+       }
+       if (etype_info[j] == NULL)
+           continue;
+
+       tmp = etype_info[j];
+       etype_info[j] = etype_info[e];
+       etype_info[e] = tmp;
+       e++;
+    }
+}
+
+
 krb5_error_code
 krb5_do_preauth(krb5_context context,
                krb5_kdc_req *request,
@@ -891,6 +961,7 @@ krb5_do_preauth(krb5_context context,
                    etype_info = NULL;
                    break;
                }
+                sort_etype_info(context, request, etype_info);
                salt->data = (char *) etype_info[0]->salt;
                salt->length = etype_info[0]->length;
                *etype = etype_info[0]->etype;