summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2003-05-12 02:59:06 +0000
committerSam Hartman <hartmans@mit.edu>2003-05-12 02:59:06 +0000
commitb7d2f686d8c563ab64636974d64b5fae92ad1766 (patch)
treef4e69e6922c7ffa87a633a5caf3ef8c018ae23a7
parent57a21011ff605a03c3ae5d021c4a0c2ef8361b4c (diff)
downloadkrb5-b7d2f686d8c563ab64636974d64b5fae92ad1766.tar.gz
krb5-b7d2f686d8c563ab64636974d64b5fae92ad1766.tar.xz
krb5-b7d2f686d8c563ab64636974d64b5fae92ad1766.zip
* IMplement etype_info in KDC. If the request contains any new
enctypes (currently AES but anything not explicitly listed as old) then only etype_info2 is sent back in response. Send back etype_info2 all the time. Also send back etype_info2 to provide salt and s2kparams with AS reply not just for preauth errors. * Expose interface for getting string2key with parameters (previously implemented but not exported) * IN the client (at least for get_init_creds interface) prfer etype_info2 to etype_info and pw_salt. Pass s2kparams and use string2key_with_params. Ticket: 1454 Status: open Target_Version: 1.3 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15412 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/ChangeLog10
-rw-r--r--src/include/k5-int.h4
-rw-r--r--src/include/krb5.hin9
-rw-r--r--src/kdc/ChangeLog13
-rw-r--r--src/kdc/kdc_preauth.c130
-rw-r--r--src/lib/ChangeLog4
-rw-r--r--src/lib/crypto/ChangeLog4
-rw-r--r--src/lib/crypto/string_to_key.c1
-rw-r--r--src/lib/krb5/krb/ChangeLog18
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c11
-rw-r--r--src/lib/krb5/krb/gic_keytab.c1
-rw-r--r--src/lib/krb5/krb/gic_pwd.c4
-rw-r--r--src/lib/krb5/krb/preauth2.c142
-rw-r--r--src/lib/krb5_32.def1
14 files changed, 257 insertions, 95 deletions
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index 00f359f4a..58a85676d 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -1,3 +1,13 @@
+2003-05-08 Sam Hartman <hartmans@mit.edu>
+
+ * krb5.hin: Add prototype for krb5_c_string_to_key_with_params
+
+ * k5-int.h: Add s2kparams to krb5_gic_get_as_key_fct
+
+2003-05-07 Sam Hartman <hartmans@mit.edu>
+
+ * krb5.hin: Add KRB5_PADATA_ETYPE_INFO2
+
2003-05-09 Ken Raeburn <raeburn@mit.edu>
* k5-int.h (struct _krb5_context): New fields conf_tgs_ktypes,
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 596784bef..b9f8722c1 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -914,6 +914,7 @@ typedef krb5_error_code (*krb5_gic_get_as_key_fct)
krb5_prompter_fct,
void *prompter_data,
krb5_data *salt,
+ krb5_data *s2kparams,
krb5_keyblock *as_key,
void *gak_data);
@@ -936,7 +937,8 @@ krb5_get_init_creds
krb5_error_code krb5_do_preauth
(krb5_context, krb5_kdc_req *,
krb5_pa_data **, krb5_pa_data ***,
- krb5_data *, krb5_enctype *,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *,
krb5_keyblock *,
krb5_prompter_fct, void *,
krb5_gic_get_as_key_fct, void *);
diff --git a/src/include/krb5.hin b/src/include/krb5.hin
index c1f66cb3e..7d033902c 100644
--- a/src/include/krb5.hin
+++ b/src/include/krb5.hin
@@ -491,6 +491,13 @@ krb5_error_code KRB5_CALLCONV
(krb5_context context, krb5_enctype enctype,
const krb5_data *string, const krb5_data *salt,
krb5_keyblock *key);
+krb5_error_code KRB5_CALLCONV
+krb5_c_string_to_key_with_params(krb5_context context,
+ krb5_enctype enctype,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key);
krb5_error_code KRB5_CALLCONV
krb5_c_enctype_compare
@@ -874,7 +881,7 @@ krb5_error_code krb5_decrypt_data
#define KRB5_PADATA_SAM_RESPONSE 13 /* draft challenge system response */
#define KRB5_PADATA_PK_AS_REQ 14 /* PKINIT */
#define KRB5_PADATA_PK_AS_REP 15 /* PKINIT */
-
+#define KRB5_PADATA_ETYPE_INFO2 19
#define KRB5_PADATA_SAM_CHALLENGE_2 30 /* draft challenge system, updated */
#define KRB5_PADATA_SAM_RESPONSE_2 31 /* draft challenge system, updated */
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog
index bf28f9c93..64fbb4844 100644
--- a/src/kdc/ChangeLog
+++ b/src/kdc/ChangeLog
@@ -1,3 +1,8 @@
+2003-05-08 Sam Hartman <hartmans@mit.edu>
+
+ * kdc_preauth.c (return_pw_salt): Don't return pw-salt if the
+ client's enctype list mandates it supports enctype-info2
+
2003-05-09 Tom Yu <tlyu@mit.edu>
* kdc_util.c (kdc_process_tgs_req): Rename getremotesubkey ->
@@ -8,6 +13,14 @@
* kdc_preauth.c (get_etype_info): Patch from Sun to reorganize
code and make sure that even for md5 the database order is
preserved.
+ (enctype_requires_etype_info_2): new function; determines wether a
+ particular enctype in a client request means that the client is
+ required to support etype_info2 by Kerberos clarifications.
+ (etype_info_helper): Renamed from get_etype_info to abstract out
+ code in common between etype_info and etype_info2
+ (get_enctype_info): Return etype info only if request contains no
+ enctypes that require etype_info2
+ (return_etype_info2): New function.
2003-04-02 Sam Hartman <hartmans@mit.edu>
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 8d7a2ff56..31e6f4705 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -59,6 +59,8 @@
#include "adm_proto.h"
#include <syslog.h>
+#include <assert.h>
+
/* XXX This is ugly and should be in a header file somewhere */
#ifndef KRB5INT_DES_TYPES_DEFINED
#define KRB5INT_DES_TYPES_DEFINED
@@ -104,6 +106,18 @@ static krb5_error_code get_etype_info
(krb5_context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_pa_data *data);
+static krb5_error_code
+get_etype_info2(krb5_context context, krb5_kdc_req *request,
+ krb5_db_entry *client, krb5_db_entry *server,
+ krb5_pa_data *pa_data);
+static krb5_error_code
+return_etype_info2(krb5_context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa);
+
static krb5_error_code return_pw_salt
(krb5_context, krb5_pa_data * padata,
krb5_db_entry *client,
@@ -156,6 +170,14 @@ static krb5_preauth_systems preauth_systems[] = {
0
},
{
+ "etype-info2",
+ KRB5_PADATA_ETYPE_INFO2,
+ 0,
+ get_etype_info2,
+ 0,
+ return_etype_info2
+ },
+ {
"pw-salt",
KRB5_PADATA_PW_SALT,
PA_PSEUDO, /* Don't include this in the error list */
@@ -432,6 +454,26 @@ cleanup:
}
static krb5_boolean
+enctype_requires_etype_info_2(krb5_enctype enctype)
+{
+ switch(enctype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD4:
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES3_CBC_SHA1:
+ case ENCTYPE_DES3_CBC_RAW:
+ case ENCTYPE_ARCFOUR_HMAC:
+ case ENCTYPE_ARCFOUR_HMAC_EXP :
+ case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
+ return 0;
+ default:
+ if (krb5_c_valid_enctype(enctype))
+ return 1;
+ else return 0;
+ }
+}
+
+static krb5_boolean
request_contains_enctype (krb5_context context, const krb5_kdc_req *request,
krb5_enctype enctype)
{
@@ -574,12 +616,13 @@ fail:
/*
* This function returns the etype information for a particular
* client, to be passed back in the preauth list in the KRB_ERROR
- * message.
+ * message. It supports generating both etype_info and etype_info2
+ * as most of the work is the same.
*/
static krb5_error_code
-get_etype_info(krb5_context context, krb5_kdc_req *request,
+etype_info_helper(krb5_context context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
- krb5_pa_data *pa_data)
+ krb5_pa_data *pa_data, int etype_info2)
{
krb5_etype_info_entry ** entry = 0;
krb5_key_data *client_key;
@@ -607,6 +650,8 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
db_etype = ENCTYPE_DES_CBC_MD5;
if (request_contains_enctype(context, request, db_etype)) {
+ assert(etype_info2 ||
+ !enctype_requires_etype_info_2(db_etype));
if ((retval = _make_etype_info_entry(context, request, client_key,
db_etype, &entry[i])) != 0) {
goto cleanup;
@@ -642,7 +687,10 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
seen_des++;
}
}
- retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry,
+ if (etype_info2)
+ retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry,
+ &scratch);
+ else retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry,
&scratch);
if (retval)
goto cleanup;
@@ -659,6 +707,75 @@ cleanup:
}
static krb5_error_code
+get_etype_info(krb5_context context, krb5_kdc_req *request,
+ krb5_db_entry *client, krb5_db_entry *server,
+ krb5_pa_data *pa_data)
+{
+ int i;
+ for (i=0; i < request->nktypes; i++) {
+ if (enctype_requires_etype_info_2(request->ktype[i]))
+ return KRB5KDC_ERR_PADATA_TYPE_NOSUPP ;;;; /*Caller will
+ * skip this
+ * type*/
+ }
+ return etype_info_helper(context, request, client, server, pa_data, 0);
+}
+
+static krb5_error_code
+get_etype_info2(krb5_context context, krb5_kdc_req *request,
+ krb5_db_entry *client, krb5_db_entry *server,
+ krb5_pa_data *pa_data)
+{
+ return etype_info_helper( context, request, client, server, pa_data, 1);
+}
+
+static krb5_error_code
+return_etype_info2(krb5_context context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa)
+{
+ krb5_error_code retval;
+ krb5_pa_data *tmp_padata;
+ krb5_etype_info_entry **entry = NULL;
+ krb5_data *scratch = NULL;
+ tmp_padata = malloc( sizeof(krb5_pa_data));
+ if (tmp_padata == NULL)
+ return ENOMEM;
+ tmp_padata->pa_type = KRB5_PADATA_ETYPE_INFO2;
+ entry = malloc(2 * sizeof(krb5_etype_info_entry *));
+ if (entry == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ entry[0] = NULL;
+ entry[1] = NULL;
+ retval = _make_etype_info_entry(context, request, client_key, client_key->key_data_type[0],
+ entry);
+ if (retval)
+ goto cleanup;
+ retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry, &scratch);
+ if (retval)
+ goto cleanup;
+ tmp_padata->contents = scratch->data;
+ tmp_padata->length = scratch->length;
+ *send_pa = tmp_padata;
+ cleanup:
+ if (entry)
+ krb5_free_etype_info(context, entry);
+ if (retval) {
+ if (tmp_padata)
+ free(tmp_padata);
+ if (scratch)
+ krb5_free_data(context, scratch);
+ }
+ return retval;
+}
+
+
+static krb5_error_code
return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
krb5_db_entry *client, krb5_kdc_req *request,
krb5_kdc_rep *reply, krb5_key_data *client_key,
@@ -668,7 +785,12 @@ return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
krb5_pa_data * padata;
krb5_data * scratch;
krb5_data salt_data;
+ int i;
+ for (i = 0; i < request->nktypes; i++) {
+ if (enctype_requires_etype_info_2(request->ktype[i]))
+ return 0;
+ }
if (client_key->key_data_ver == 1 ||
client_key->key_data_type[1] == KRB5_KDB_SALTTYPE_NORMAL)
return 0;
diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog
index 2a1601859..205153305 100644
--- a/src/lib/ChangeLog
+++ b/src/lib/ChangeLog
@@ -1,3 +1,7 @@
+2003-05-08 Sam Hartman <hartmans@mit.edu>
+
+ * krb5_32.def: Add krb5_c_string_to_key_with_params
+
2003-05-09 Tom Yu <tlyu@mit.edu>
* krb5_32.def: Add krb5_auth_con_getrecvsubkey,
diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog
index 1db561252..07ba371ef 100644
--- a/src/lib/crypto/ChangeLog
+++ b/src/lib/crypto/ChangeLog
@@ -1,3 +1,7 @@
+2003-05-08 Sam Hartman <hartmans@mit.edu>
+
+ * string_to_key.c: Move krb5_c_string_to_key_with_params to krb5.h
+
2003-04-13 Ken Raeburn <raeburn@mit.edu>
* pbkdf2.c (krb5int_pbkdf2): Provide a temporary buffer for the
diff --git a/src/lib/crypto/string_to_key.c b/src/lib/crypto/string_to_key.c
index c9434e08d..3bd7a4e73 100644
--- a/src/lib/crypto/string_to_key.c
+++ b/src/lib/crypto/string_to_key.c
@@ -27,7 +27,6 @@
#include "k5-int.h"
#include "etypes.h"
-/* Eventually this declaration should move to krb5.h. */
krb5_error_code KRB5_CALLCONV
krb5_c_string_to_key_with_params(krb5_context context,
krb5_enctype enctype,
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
index 46c4754d6..b6e2480e1 100644
--- a/src/lib/krb5/krb/ChangeLog
+++ b/src/lib/krb5/krb/ChangeLog
@@ -1,3 +1,21 @@
+2003-05-09 Sam Hartman <hartmans@mit.edu>
+
+ * preauth2.c: Patch from Sun to reorganize code for handling
+ etype_info requests. More efficient and easier to implement etype_info2
+ (krb5_do_preauth): Support enctype_info2
+
+2003-05-08 Sam Hartman <hartmans@mit.edu>
+
+ * preauth2.c: Add s2kparams to the declaration of a preauth
+ function, to every instance of a preauth function and to every
+ call to gak_fct
+
+ * get_in_tkt.c (krb5_get_init_creds): Add s2kparams support
+
+ * gic_keytab.c (krb5_get_as_key_keytab): Add s2kparams
+
+ * gic_pwd.c (krb5_get_as_key_password): Add s2kparams support
+
2003-05-09 Ken Raeburn <raeburn@mit.edu>
* init_ctx.c (init_common): Copy tgs_ktypes array to
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index dc06c5353..2f426d721 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1,7 +1,7 @@
/*
* lib/krb5/krb/get_in_tkt.c
*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991, 2003 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -734,6 +734,7 @@ krb5_get_init_creds(krb5_context context,
krb5_deltat renew_life;
int loopcount;
krb5_data salt;
+ krb5_data s2kparams;
krb5_keyblock as_key;
krb5_error *err_reply;
krb5_kdc_rep *local_as_reply;
@@ -742,6 +743,8 @@ krb5_get_init_creds(krb5_context context,
/* initialize everything which will be freed at cleanup */
+ s2kparams.data = NULL;
+ s2kparams.length = 0;
request.server = NULL;
request.ktype = NULL;
request.addresses = NULL;
@@ -927,7 +930,7 @@ krb5_get_init_creds(krb5_context context,
if ((ret = krb5_do_preauth(context, &request,
padata, &request.padata,
- &salt, &etype, &as_key, prompter,
+ &salt, &s2kparams, &etype, &as_key, prompter,
prompter_data, gak_fct, gak_data)))
goto cleanup;
@@ -973,7 +976,7 @@ krb5_get_init_creds(krb5_context context,
if ((ret = krb5_do_preauth(context, &request,
local_as_reply->padata, &padata,
- &salt, &etype, &as_key, prompter,
+ &salt, &s2kparams, &etype, &as_key, prompter,
prompter_data, gak_fct, gak_data)))
goto cleanup;
@@ -1005,7 +1008,7 @@ krb5_get_init_creds(krb5_context context,
if ((ret = ((*gak_fct)(context, request.client,
local_as_reply->enc_part.enctype,
- prompter, prompter_data, &salt,
+ prompter, prompter_data, &salt, &s2kparams,
&as_key, gak_data))))
goto cleanup;
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
index a7cb773a0..e7fb1aec6 100644
--- a/src/lib/krb5/krb/gic_keytab.c
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -8,6 +8,7 @@ krb5_get_as_key_keytab(
krb5_prompter_fct prompter,
void *prompter_data,
krb5_data *salt,
+ krb5_data *params,
krb5_keyblock *as_key,
void *gak_data)
{
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 7b5e0bab3..54cf5f461 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -9,6 +9,7 @@ krb5_get_as_key_password(
krb5_prompter_fct prompter,
void *prompter_data,
krb5_data *salt,
+ krb5_data *params,
krb5_keyblock *as_key,
void *gak_data)
{
@@ -74,7 +75,8 @@ krb5_get_as_key_password(
defsalt.length = 0;
}
- ret = krb5_c_string_to_key(context, etype, password, salt, as_key);
+ ret = krb5_c_string_to_key_with_params(context, etype, password, salt,
+ params->data?params:NULL, as_key);
if (defsalt.length)
krb5_xfree(defsalt.data);
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index e50440e2b..5a9c1ba9e 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -35,7 +35,7 @@ typedef krb5_error_code (*pa_function)(krb5_context,
krb5_kdc_req *request,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
- krb5_data *salt,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter_fct,
@@ -57,7 +57,7 @@ krb5_error_code pa_salt(krb5_context context,
krb5_kdc_req *request,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
- krb5_data *salt,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter, void *prompter_data,
@@ -94,6 +94,7 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
krb5_data *salt,
+ krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter,
@@ -119,7 +120,7 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
if ((ret = ((*gak_fct)(context, request->client,
*etype ? *etype : request->ktype[0],
prompter, prompter_data,
- salt, as_key, gak_data))))
+ salt, s2kparams, as_key, gak_data))))
return(ret);
}
@@ -233,6 +234,7 @@ krb5_error_code pa_sam(krb5_context context,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
krb5_data *salt,
+ krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter,
@@ -283,7 +285,7 @@ krb5_error_code pa_sam(krb5_context context,
*etype = ENCTYPE_DES_CBC_CRC;
if ((ret = (gak_fct)(context, request->client, *etype, prompter,
- prompter_data, salt, as_key, gak_data)))
+ prompter_data, salt, s2kparams, as_key, gak_data)))
return(ret);
}
sprintf(name, "%.*s",
@@ -472,6 +474,7 @@ krb5_error_code pa_sam_2(krb5_context context,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
krb5_data *salt,
+ krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter,
@@ -542,7 +545,7 @@ krb5_error_code pa_sam_2(krb5_context context,
retval = (gak_fct)(context, request->client,
sc2b->sam_etype, prompter,
- prompter_data, salt, as_key, gak_data);
+ prompter_data, salt, s2kparams, as_key, gak_data);
if (retval) {
krb5_free_sam_challenge_2(context, sc2);
krb5_free_sam_challenge_2_body(context, sc2b);
@@ -827,86 +830,18 @@ 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,
krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
- krb5_data *salt, krb5_enctype *etype,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter, void *prompter_data,
krb5_gic_get_as_key_fct gak_fct, void *gak_data)
{
int h, i, j, out_pa_list_size;
+ int seen_etype_info2 = 0;
krb5_pa_data *out_pa, **out_pa_list;
krb5_data scratch;
krb5_etype_info etype_info = NULL;
@@ -938,6 +873,7 @@ krb5_do_preauth(krb5_context context,
for (h=0; h<(sizeof(paorder)/sizeof(paorder[0])); h++) {
realdone = 0;
for (i=0; in_padata[i] && !realdone; i++) {
+ int k, l, etype_found, valid_etype_found;
/*
* This is really gross, but is necessary to prevent
* lossge when talking to a 1.0.x KDC, which returns an
@@ -946,8 +882,20 @@ krb5_do_preauth(krb5_context context,
*/
switch (in_padata[i]->pa_type) {
case KRB5_PADATA_ETYPE_INFO:
- if (etype_info)
- continue;
+ case KRB5_PADATA_ETYPE_INFO2:
+ {
+ krb5_preauthtype pa_type = in_padata[i]->pa_type;
+ if (etype_info) {
+ if (seen_etype_info2 || pa_type != KRB5_PADATA_ETYPE_INFO2)
+ continue;
+ if (pa_type == KRB5_PADATA_ETYPE_INFO2) {
+ krb5_free_etype_info( context, etype_info);
+ etype_info = NULL;
+ }
+ }
+
+ if (pa_type == KRB5_PADATA_ETYPE_INFO2)
+ seen_etype_info2++;
scratch.length = in_padata[i]->length;
scratch.data = (char *) in_padata[i]->contents;
ret = decode_krb5_etype_info(&scratch, &etype_info);
@@ -963,10 +911,37 @@ 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;
+ /*
+ * Select first etype in our request which is also in
+ * etype-info (preferring client request ktype order).
+ */
+ for (etype_found = 0, valid_etype_found = 0, k = 0;
+ !etype_found && k < request->nktypes; k++) {
+ for (l = 0; etype_info[l]; l++) {
+ if (etype_info[l]->etype == request->ktype[k]) {
+ etype_found++;
+ break;
+ }
+ /* check if program has support for this etype for more
+ * precise error reporting.
+ */
+ if (valid_enctype(etype_info[l]->etype))
+ valid_etype_found++;
+ }
+ }
+ if (!etype_found) {
+ if (valid_etype_found)
+ /* supported enctype but not requested */
+ return KRB5_CONFIG_ETYPE_NOSUPP;
+ else
+ /* unsupported enctype */
+ return KRB5_PROG_ETYPE_NOSUPP;
+
+ }
+ salt->data = (char *) etype_info[l]->salt;
+ salt->length = etype_info[l]->length;
+ *etype = etype_info[l]->etype;
+ *s2kparams = etype_info[l]->s2kparams;
#ifdef DEBUG
for (j = 0; etype_info[j]; j++) {
krb5_etype_info_entry *e = etype_info[j];
@@ -978,6 +953,7 @@ krb5_do_preauth(krb5_context context,
}
#endif
break;
+ }
case KRB5_PADATA_PW_SALT:
case KRB5_PADATA_AFS3_SALT:
if (etype_info)
@@ -993,7 +969,7 @@ krb5_do_preauth(krb5_context context,
if ((ret = ((*pa_types[j].fct)(context, request,
in_padata[i], &out_pa,
- salt, etype, as_key,
+ salt, s2kparams, etype, as_key,
prompter, prompter_data,
gak_fct, gak_data)))) {
if (out_pa_list) {
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index 257dd287e..db136c44a 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -67,6 +67,7 @@ EXPORTS
krb5_c_random_make_octets
krb5_c_random_seed
krb5_c_string_to_key
+krb5_c_string_to_key_with_params
krb5_c_valid_cksumtype
krb5_c_valid_enctype
krb5_c_verify_checksum