Index: lib/krb5/krb/ChangeLog =================================================================== RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/ChangeLog,v retrieving revision 5.371 diff -u -r5.371 ChangeLog --- lib/krb5/krb/ChangeLog 2003/02/13 20:09:21 5.371 +++ lib/krb5/krb/ChangeLog 2003/02/15 00:10:27 @@ -1,3 +1,8 @@ +2003-02-14 Sam Hartman + + * preauth2.c (krb5_do_preauth): Sort incoming etype info based on + preference order in request + 2003-02-13 Sam Hartman * gic_keytab.c (krb5_get_as_key_keytab): Nathan Neulinger points Index: lib/krb5/krb/preauth2.c =================================================================== RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/preauth2.c,v retrieving revision 5.20 diff -u -r5.20 preauth2.c --- lib/krb5/krb/preauth2.c 2002/11/07 20:14:19 5.20 +++ lib/krb5/krb/preauth2.c 2003/02/15 00:10:27 @@ -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 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 @@ 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; Index: kdc/ChangeLog =================================================================== RCS file: /cvs/krbdev/krb5/src/kdc/ChangeLog,v retrieving revision 5.247 diff -u -r5.247 ChangeLog --- kdc/ChangeLog 2003/02/06 23:45:55 5.247 +++ kdc/ChangeLog 2003/02/15 00:10:27 @@ -1,3 +1,9 @@ +2003-02-14 Sam Hartman + + * 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 * Makefile.in, configure.in, fakeka.c: New file to implement Index: kdc/kdc_preauth.c =================================================================== RCS file: /cvs/krbdev/krb5/src/kdc/kdc_preauth.c,v retrieving revision 5.33 diff -u -r5.33 kdc_preauth.c --- kdc/kdc_preauth.c 2003/01/21 19:02:58 5.33 +++ kdc/kdc_preauth.c 2003/02/15 00:10:27 @@ -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 @@ 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 @@ 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;