From 9cb1a31d926cbac8e53395651e58d4ea7c43cc43 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Thu, 9 Nov 1995 05:08:09 +0000 Subject: [PATCH] * kdc_preauth.c (get_etype_info): Added function to return the etype_info preauth hint to the client. * kdc_util.c (get_salt_from_key): Added new function which determines the salting information from the krb5_key_data structure. * main.c (kdc_initialize_rcache): Replace use of krb5_clockskew with context->clockskew. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7073 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/ChangeLog | 12 +++++ src/kdc/do_as_req.c | 2 +- src/kdc/kdc_preauth.c | 111 +++++++++++++++++++++++++++++++++++++----- src/kdc/kdc_util.c | 50 +++++++++++++++++++ src/kdc/kdc_util.h | 11 +++-- src/kdc/main.c | 3 +- 6 files changed, 171 insertions(+), 18 deletions(-) diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index dbb44172b..bea2674c1 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,15 @@ +Thu Nov 9 00:05:55 1995 Theodore Y. Ts'o + + * kdc_preauth.c (get_etype_info): Added function to return the + etype_info preauth hint to the client. + + * kdc_util.c (get_salt_from_key): Added new function which + determines the salting information from the krb5_key_data + structure. + + * main.c (kdc_initialize_rcache): Replace use of krb5_clockskew + with context->clockskew. + Wed Nov 8 02:57:15 1995 Theodore Y. Ts'o * kdc_util.c (): Added new helper functions diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index ad9b10c22..3e7ebc99a 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -293,7 +293,7 @@ krb5_data **response; /* filled in with a response packet */ status = missing_required_preauth(&client, &server, &enc_tkt_reply); if (status) { errcode = KRB5KDC_ERR_PREAUTH_REQUIRED; - get_preauth_hint_list(&client, &server, &e_data); + get_preauth_hint_list(request, &client, &server, &e_data); goto errout; } diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 5670625cf..056cd0681 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -34,7 +34,9 @@ typedef krb5_error_code (verify_proc) krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data)); typedef krb5_error_code (edata_proc) - KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client, krb5_pa_data *data)); + KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_pa_data *data)); typedef struct _krb5_preauth_systems { int type; @@ -44,6 +46,7 @@ typedef struct _krb5_preauth_systems { } krb5_preauth_systems; static verify_proc verify_enc_timestamp; +static edata_proc get_etype_info; /* * Preauth property flags @@ -59,6 +62,12 @@ static krb5_preauth_systems preauth_systems[] = { 0, verify_enc_timestamp, }, + { + KRB5_PADATA_ETYPE_INFO, + 0, + get_etype_info, + 0 + }, { -1,} }; @@ -146,7 +155,8 @@ const char *missing_required_preauth(client, server, enc_tkt_reply) return 0; } -void get_preauth_hint_list(client, server, e_data) +void get_preauth_hint_list(request, client, server, e_data) + krb5_kdc_req *request; krb5_db_entry *client, *server; krb5_data *e_data; { @@ -177,7 +187,7 @@ void get_preauth_hint_list(client, server, e_data) (*pa)->magic = KV5M_PA_DATA; (*pa)->pa_type = ap->type; if (ap->get_edata) - (ap->get_edata)(kdc_context, client, *pa); + (ap->get_edata)(kdc_context, request, client, server, *pa); pa++; } retval = encode_krb5_padata_sequence((const krb5_pa_data **) pa_data, @@ -229,6 +239,8 @@ check_padata (context, client, request, enc_tkt_reply) break; } } + if (retval) + retval = KRB5KDC_ERR_PREAUTH_FAILED; return retval; } @@ -305,15 +317,90 @@ cleanup: return retval; } +/* + * This function returns the etype information for a particular + * client, to be passed back in the preauth list in the KRB_ERROR + * message. + */ +static krb5_error_code +get_etype_info(context, request, client, server, pa_data) + krb5_context context; + krb5_kdc_req * request; + krb5_db_entry * client; + krb5_db_entry * server; + krb5_pa_data * pa_data; +{ + krb5_etype_info_entry ** entry = 0; + krb5_key_data *client_key; + krb5_error_code retval; + krb5_data salt; + krb5_data * scratch; + krb5_enctype db_etype; + int i = 0; + int start = 0; -#if 0 + salt.data = 0; - setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH); - /* - * If pa_type is one in which additional hardware authentication - * was performed set TKT_FLG_HW_AUTH too. - */ - if (pa_flags & KRB5_PREAUTH_FLAGS_HARDWARE) - setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH); + entry = malloc((client->n_key_data * 2) * sizeof(krb5_etype_info_entry *)); + if (entry == NULL) + return ENOMEM; + entry[0] = NULL; + + while (1) { + retval = krb5_dbe_search_enctype(context, client, &start, -1, + -1, 0, &client_key); + if (retval == ENOENT) + break; + if (retval) + goto cleanup; + db_etype = client_key->key_data_type[0]; + if (db_etype == ENCTYPE_DES_CBC_MD4 || db_etype == ENCTYPE_DES_CBC_MD5) + db_etype = ENCTYPE_DES_CBC_CRC; + + while (1) { + if ((entry[i] = malloc(sizeof(krb5_etype_info_entry))) == NULL) { + retval = ENOMEM; + goto cleanup; + } + entry[i+1] = 0; + entry[i]->magic = KV5M_ETYPE_INFO_ENTRY; + entry[i]->etype = db_etype; + entry[i]->length = -1; + entry[i]->salt = 0; + retval = get_salt_from_key(context, request->client, + client_key, &salt); + if (retval) + goto cleanup; + if (salt.length >= 0) { + entry[i]->length = salt.length; + entry[i]->salt = salt.data; + salt.data = 0; + } + i++; + /* + * If we have a DES_CRC key, it can also be used as a + * DES_MD5 key. + */ + if (db_etype == ENCTYPE_DES_CBC_CRC) + db_etype = ENCTYPE_DES_CBC_MD5; + else + break; + } + } + retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry, + &scratch); + if (retval) + goto cleanup; + pa_data->contents = scratch->data; + pa_data->length = scratch->length; + + retval = 0; + +cleanup: + if (entry) + krb5_free_etype_info(context, entry); + if (salt.data) + krb5_xfree(salt.data); + return retval; +} -#endif diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 49573bf95..c76f6fb18 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -1313,7 +1313,57 @@ select_session_keytype(context, server, nktypes, ktype) return 0; } +/* + * This function returns salt information for a particular client_key + */ +krb5_error_code +get_salt_from_key(context, client, client_key, salt) + krb5_context context; + krb5_principal client; + krb5_key_data * client_key; + krb5_data * salt; +{ + krb5_error_code retval; + krb5_data * realm; + + salt->data = 0; + salt->length = -1; + + if (client_key->key_data_ver == 1) + return 0; + switch (client_key->key_data_type[1]) { + case KRB5_KDB_SALTTYPE_NORMAL: + break; + case KRB5_KDB_SALTTYPE_V4: + /* send an empty (V4) salt */ + salt->data = 0; + salt->length = 0; + break; + + case KRB5_KDB_SALTTYPE_NOREALM: + if ((retval = krb5_principal2salt_norealm(context, client, salt))) + return retval; + break; + case KRB5_KDB_SALTTYPE_ONLYREALM: + realm = krb5_princ_realm(context, client); + salt->length = realm->length; + if ((salt->data = malloc(realm->length)) == NULL) + return ENOMEM; + memcpy(salt->data, realm->data, realm->length); + break; + case KRB5_KDB_SALTTYPE_SPECIAL: + salt->length = client_key->key_data_length[1]; + if ((salt->data = malloc(salt->length)) == NULL) + return ENOMEM; + memcpy(salt->data, client_key->key_data_contents[1], salt->length); + break; + } + return 0; +} + + + diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index f1b742506..7491ca905 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -89,6 +89,10 @@ select_session_keytype PROTOTYPE((krb5_context context, int nktypes, krb5_enctype *ktypes)); +krb5_error_code +get_salt_from_key PROTOTYPE((krb5_context, krb5_principal, + krb5_key_data *, krb5_data *)); + /* do_as_req.c */ krb5_error_code process_as_req PROTOTYPE((krb5_kdc_req *, const krb5_fulladdr *, @@ -127,9 +131,10 @@ int against_local_policy_tgs PROTOTYPE((krb5_kdc_req *, krb5_db_entry, const char * missing_required_preauth PROTOTYPE((krb5_db_entry *client, krb5_db_entry *server, krb5_enc_tkt_part *enc_tkt_reply)); -void get_preauth_hint_list PROTOTYPE((krb5_db_entry *client, - krb5_db_entry *server, - krb5_data *e_data)); +void get_preauth_hint_list PROTOTYPE((krb5_kdc_req * request, + krb5_db_entry *client, + krb5_db_entry *server, + krb5_data *e_data)); /* replay.c */ krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, krb5_data **)); diff --git a/src/kdc/main.c b/src/kdc/main.c index b698a0fa3..260c40257 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -179,7 +179,6 @@ kdc_initialize_rcache(kcontext, rcache_name) char *rcache_name; { krb5_error_code retval; - extern krb5_deltat krb5_clockskew; char *rcname; char *sname; @@ -191,7 +190,7 @@ kdc_initialize_rcache(kcontext, rcache_name) if (!(retval = krb5_rc_recover(kcontext, kdc_rcache)) || !(retval = krb5_rc_initialize(kcontext, kdc_rcache, - krb5_clockskew)) + kcontext->clockskew)) ) { /* Expunge the replay cache */ if (!(retval = krb5_rc_expunge(kcontext, kdc_rcache))) { -- 2.26.2