From ec0035c9b8e0690f3bc21f3de089c39eae660916 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 Jul 2007 08:00:08 +0000 Subject: r23678: Update to current lorikeet-heimdal (-r 767), which should fix the panics on hosts without /dev/random. Andrew Bartlett (This used to be commit 14a4ddb131993fec72316f7e8e371638749e6f1f) --- source4/heimdal/kdc/default_config.c | 19 +++-- source4/heimdal/kdc/digest.c | 140 +++++++++++++++++++++-------------- source4/heimdal/kdc/kdc-protos.h | 7 +- source4/heimdal/kdc/kdc.h | 8 +- source4/heimdal/kdc/krb5tgs.c | 32 ++++---- source4/heimdal/kdc/misc.c | 11 ++- source4/heimdal/kdc/pkinit.c | 16 +++- 7 files changed, 142 insertions(+), 91 deletions(-) (limited to 'source4/heimdal/kdc') diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c index c28bd424ea..e06366f214 100644 --- a/source4/heimdal/kdc/default_config.c +++ b/source4/heimdal/kdc/default_config.c @@ -36,10 +36,9 @@ #include #include -RCSID("$Id: default_config.c 20532 2007-04-23 07:46:57Z lha $"); +RCSID("$Id: default_config.c 21296 2007-06-25 14:49:11Z lha $"); - -int +krb5_error_code krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) { krb5_kdc_configuration *c; @@ -62,7 +61,8 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) c->enable_524 = FALSE; c->enable_v4_cross_realm = FALSE; c->enable_pkinit = FALSE; - c->enable_pkinit_princ_in_cert = TRUE; + c->pkinit_princ_in_cert = TRUE; + c->pkinit_require_binding = TRUE; c->db = NULL; c->num_db = 0; c->logf = NULL; @@ -257,12 +257,19 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) krb5_config_free_strings(pool_list); krb5_config_free_strings(revoke_list); - c->enable_pkinit_princ_in_cert = + c->pkinit_princ_in_cert = krb5_config_get_bool_default(context, NULL, - c->enable_pkinit_princ_in_cert, + c->pkinit_princ_in_cert, "kdc", "pkinit_principal_in_certificate", NULL); + + c->pkinit_require_binding = + krb5_config_get_bool_default(context, NULL, + c->pkinit_require_binding, + "kdc", + "pkinit_win2k_require_binding", + NULL); } c->pkinit_dh_min_bits = diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c index 811ab639f1..801449fe5e 100644 --- a/source4/heimdal/kdc/digest.c +++ b/source4/heimdal/kdc/digest.c @@ -34,7 +34,7 @@ #include "kdc_locl.h" #include -RCSID("$Id: digest.c 20877 2007-06-04 04:07:26Z lha $"); +RCSID("$Id: digest.c 21241 2007-06-20 11:30:19Z lha $"); #define MS_CHAP_V2 0x20 #define CHAP_MD5 0x10 @@ -156,6 +156,44 @@ static const unsigned char ms_rfc3079_magic1[27] = { 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; +/* + * + */ + +static krb5_error_code +get_password_entry(krb5_context context, + krb5_kdc_configuration *config, + const char *username, + char **password) +{ + krb5_principal clientprincipal; + krb5_error_code ret; + hdb_entry_ex *user; + HDB *db; + + /* get username */ + ret = krb5_parse_name(context, username, &clientprincipal); + if (ret) + return ret; + + ret = _kdc_db_fetch(context, config, clientprincipal, + HDB_F_GET_CLIENT, &db, &user); + krb5_free_principal(context, clientprincipal); + if (ret) + return ret; + + ret = hdb_entry_get_password(context, db, &user->entry, password); + if (ret || password == NULL) { + if (ret == 0) { + ret = EINVAL; + krb5_set_error_string(context, "password missing"); + } + memset(user, 0, sizeof(*user)); + } + _kdc_free_ent (context, user); + return ret; +} + /* * */ @@ -461,9 +499,6 @@ _kdc_do_digest(krb5_context context, break; } case choice_DigestReqInner_digestRequest: { - krb5_principal clientprincipal; - HDB *db; - sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; @@ -571,29 +606,6 @@ _kdc_do_digest(krb5_context context, } } - /* get username */ - ret = krb5_parse_name(context, - ireq.u.digestRequest.username, - &clientprincipal); - if (ret) - goto out; - - ret = _kdc_db_fetch(context, config, clientprincipal, - HDB_F_GET_CLIENT, &db, &user); - - krb5_free_principal(context, clientprincipal); - if (ret) - goto out; - - ret = hdb_entry_get_password(context, db, &user->entry, &password); - if (ret || password == NULL) { - if (ret == 0) { - ret = EINVAL; - krb5_set_error_string(context, "password missing"); - } - goto out; - } - if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; @@ -618,6 +630,12 @@ _kdc_do_digest(krb5_context context, goto out; } + ret = get_password_entry(context, config, + ireq.u.digestRequest.username, + &password); + if (ret) + goto out; + MD5_Init(&ctx); MD5_Update(&ctx, &id, 1); MD5_Update(&ctx, password, strlen(password)); @@ -664,6 +682,12 @@ _kdc_do_digest(krb5_context context, if (ireq.u.digestRequest.realm == NULL) goto out; + ret = get_password_entry(context, config, + ireq.u.digestRequest.username, + &password); + if (ret) + goto failed; + MD5_Init(&ctx); MD5_Update(&ctx, ireq.u.digestRequest.username, strlen(ireq.u.digestRequest.username)); @@ -692,7 +716,7 @@ _kdc_do_digest(krb5_context context, if (A1 == NULL) { krb5_set_error_string(context, "out of memory"); ret = ENOMEM; - goto out; + goto failed; } MD5_Init(&ctx); @@ -712,7 +736,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "out of memory"); ret = ENOMEM; free(A1); - goto out; + goto failed; } MD5_Init(&ctx); @@ -758,6 +782,7 @@ _kdc_do_digest(krb5_context context, } else if (strcasecmp(ireq.u.digestRequest.type, "MS-CHAP-V2") == 0) { unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH]; + krb5_principal clientprincipal = NULL; char *mdx; const char *username; struct ntlm_buf answer; @@ -766,20 +791,20 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & MS_CHAP_V2) == 0) { kdc_log(context, config, 0, "MS-CHAP-V2 not allowed"); - goto out; + goto failed; } if (ireq.u.digestRequest.clientNonce == NULL) { krb5_set_error_string(context, "MS-CHAP-V2 clientNonce missing"); ret = EINVAL; - goto out; + goto failed; } if (serverNonce.length != 16) { krb5_set_error_string(context, "MS-CHAP-V2 serverNonce wrong length"); ret = EINVAL; - goto out; + goto failed; } /* strip of the domain component */ @@ -821,7 +846,7 @@ _kdc_do_digest(krb5_context context, /* NtPasswordHash */ ret = krb5_parse_name(context, username, &clientprincipal); if (ret) - goto out; + goto failed; ret = _kdc_db_fetch(context, config, clientprincipal, HDB_F_GET_CLIENT, NULL, &user); @@ -830,7 +855,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "MS-CHAP-V2 user %s not in database", username); - goto out; + goto failed; } ret = hdb_enctype2key(context, &user->entry, @@ -839,7 +864,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "MS-CHAP-V2 missing arcfour key %s", username); - goto out; + goto failed; } /* ChallengeResponse */ @@ -848,7 +873,7 @@ _kdc_do_digest(krb5_context context, challange, &answer); if (ret) { krb5_set_error_string(context, "NTLM missing arcfour key"); - goto out; + goto failed; } hex_encode(answer.data, answer.length, &mdx); @@ -861,15 +886,15 @@ _kdc_do_digest(krb5_context context, r.element = choice_DigestRepInner_response; ret = strcasecmp(mdx, ireq.u.digestRequest.responseData); - free(mdx); if (ret == 0) { r.u.response.success = TRUE; } else { kdc_log(context, config, 0, - "MS-CHAP-V2 reply mismatch for %s", + "MS-CHAP-V2 hash mismatch for %s", ireq.u.digestRequest.username); r.u.response.success = FALSE; } + free(mdx); if (r.u.response.success) { unsigned char hashhash[MD4_DIGEST_LENGTH]; @@ -958,7 +983,7 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & (NTLM_V1|NTLM_V1_SESSION|NTLM_V2)) == 0) { kdc_log(context, config, 0, "NTLM not allowed"); - goto out; + goto failed; } r.element = choice_DigestRepInner_ntlmInitReply; @@ -967,14 +992,14 @@ _kdc_do_digest(krb5_context context, if ((ireq.u.ntlmInit.flags & NTLM_NEG_UNICODE) == 0) { kdc_log(context, config, 0, "NTLM client have no unicode"); - goto out; + goto failed; } if (ireq.u.ntlmInit.flags & NTLM_NEG_NTLM) r.u.ntlmInitReply.flags |= NTLM_NEG_NTLM; else { kdc_log(context, config, 0, "NTLM client doesn't support NTLM"); - goto out; + goto failed; } r.u.ntlmInitReply.flags |= @@ -1095,7 +1120,7 @@ _kdc_do_digest(krb5_context context, ireq.u.ntlmRequest.username, &clientprincipal); if (ret) - goto out; + goto failed; ret = _kdc_db_fetch(context, config, clientprincipal, HDB_F_GET_CLIENT, NULL, &user); @@ -1103,20 +1128,23 @@ _kdc_do_digest(krb5_context context, if (ret) { krb5_set_error_string(context, "NTLM user %s not in database", ireq.u.ntlmRequest.username); - goto out; + goto failed; } ret = get_digest_key(context, config, server, &crypto); if (ret) - goto out; + goto failed; ret = krb5_decrypt(context, crypto, KRB5_KU_DIGEST_OPAQUE, ireq.u.ntlmRequest.opaque.data, ireq.u.ntlmRequest.opaque.length, &buf); krb5_crypto_destroy(context, crypto); crypto = NULL; - if (ret) - goto out; + if (ret) { + kdc_log(context, config, 0, + "Failed to decrypt nonce from %s", from); + goto failed; + } sp = krb5_storage_from_data(&buf); if (sp == NULL) { @@ -1185,7 +1213,7 @@ _kdc_do_digest(krb5_context context, free(targetname); if (ret) { krb5_set_error_string(context, "NTLM v2 verify failed"); - goto out; + goto failed; } /* XXX verify infotarget matches client (checksum ?) */ @@ -1205,14 +1233,14 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & NTLM_V1_SESSION) == 0) { kdc_log(context, config, 0, "NTLM v1-session not allowed"); ret = EINVAL; - goto out; + goto failed; } if (ireq.u.ntlmRequest.lm.length != 24) { krb5_set_error_string(context, "LM hash have wrong length " "for NTLM session key"); ret = EINVAL; - goto out; + goto failed; } MD5_Init(&md5ctx); @@ -1223,7 +1251,7 @@ _kdc_do_digest(krb5_context context, } else { if ((config->digests_allowed & NTLM_V1) == 0) { kdc_log(context, config, 0, "NTLM v1 not allowed"); - goto out; + goto failed; } } @@ -1232,7 +1260,7 @@ _kdc_do_digest(krb5_context context, challange, &answer); if (ret) { krb5_set_error_string(context, "NTLM missing arcfour key"); - goto out; + goto failed; } if (ireq.u.ntlmRequest.ntlm.length != answer.length || @@ -1241,7 +1269,7 @@ _kdc_do_digest(krb5_context context, free(answer.data); ret = EINVAL; krb5_set_error_string(context, "NTLM hash mismatch"); - goto out; + goto failed; } free(answer.data); @@ -1265,7 +1293,7 @@ _kdc_do_digest(krb5_context context, "NTLM client failed to neg key " "exchange but still sent key"); ret = EINVAL; - goto out; + goto failed; } len = ireq.u.ntlmRequest.sessionkey->length; @@ -1273,7 +1301,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "NTLM master key wrong length: %lu", (unsigned long)len); - goto out; + goto failed; } RC4_set_key(&rc4, sizeof(sessionkey), sessionkey); @@ -1301,12 +1329,12 @@ _kdc_do_digest(krb5_context context, r.u.ntlmResponse.success = 1; kdc_log(context, config, 0, "NTLM version %d successful for %s", version, ireq.u.ntlmRequest.username); - break; } default: + failed: r.element = choice_DigestRepInner_error; - r.u.error.reason = strdup("unknown operation"); + r.u.error.reason = strdup("unknown/failed operation"); if (r.u.error.reason == NULL) { krb5_set_error_string(context, "out of memory"); ret = ENOMEM; diff --git a/source4/heimdal/kdc/kdc-protos.h b/source4/heimdal/kdc/kdc-protos.h index f7df365eb2..15e8c29f4c 100644 --- a/source4/heimdal/kdc/kdc-protos.h +++ b/source4/heimdal/kdc/kdc-protos.h @@ -37,7 +37,7 @@ kdc_openlog ( krb5_context /*context*/, krb5_kdc_configuration */*config*/); -int +krb5_error_code krb5_kdc_get_config ( krb5_context /*context*/, krb5_kdc_configuration **/*config*/); @@ -74,6 +74,11 @@ krb5_kdc_save_request ( const krb5_data */*reply*/, const struct sockaddr */*sa*/); +krb5_error_code +krb5_kdc_set_dbinfo ( + krb5_context /*context*/, + struct krb5_kdc_configuration */*c*/); + void krb5_kdc_update_time (struct timeval */*tv*/); diff --git a/source4/heimdal/kdc/kdc.h b/source4/heimdal/kdc/kdc.h index eb24b4ee97..6c129f38f5 100644 --- a/source4/heimdal/kdc/kdc.h +++ b/source4/heimdal/kdc/kdc.h @@ -35,7 +35,7 @@ */ /* - * $Id: kdc.h 19907 2007-01-14 23:10:24Z lha $ + * $Id: kdc.h 21287 2007-06-25 14:09:03Z lha $ */ #ifndef __KDC_H__ @@ -73,13 +73,13 @@ typedef struct krb5_kdc_configuration { krb5_boolean enable_524; krb5_boolean enable_pkinit; - krb5_boolean enable_pkinit_princ_in_cert; + krb5_boolean pkinit_princ_in_cert; char *pkinit_kdc_ocsp_file; + int pkinit_dh_min_bits; + int pkinit_require_binding; krb5_log_facility *logf; - int pkinit_dh_min_bits; - int enable_digest; int digests_allowed; diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 02cd92de2e..4d6be60f68 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: krb5tgs.c 21041 2007-06-10 06:21:12Z lha $"); +RCSID("$Id: krb5tgs.c 21262 2007-06-21 15:18:37Z lha $"); /* * return the realm of a krbtgt-ticket or NULL @@ -475,12 +475,14 @@ check_tgs_flags(krb5_context context, et->endtime = min(*et->renew_till, et->endtime); } +#if 0 /* checks for excess flags */ if(f.request_anonymous && !config->allow_anonymous){ kdc_log(context, config, 0, "Request for anonymous ticket"); return KRB5KDC_ERR_BADOPTION; } +#endif return 0; } @@ -731,10 +733,12 @@ tgs_make_reply(krb5_context context, &rep.ticket.realm); _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal); copy_Realm(&tgt_name->realm, &rep.crealm); +/* if (f.request_anonymous) _kdc_make_anonymous_principalname (&rep.cname); - else - copy_PrincipalName(&tgt_name->name, &rep.cname); + else */ + + copy_PrincipalName(&tgt_name->name, &rep.cname); rep.ticket.tkt_vno = 5; ek.caddr = et.caddr; @@ -1707,24 +1711,20 @@ server_lookup: goto out; } - /* check PAC if there is one */ - { + /* check PAC if not cross realm and if there is one */ + if (!cross_realm) { Key *tkey; - krb5_keyblock *tgtkey = NULL; - if (!cross_realm) { - ret = hdb_enctype2key(context, &krbtgt->entry, - krbtgt_etype, &tkey); - if(ret) { - kdc_log(context, config, 0, - "Failed to find key for krbtgt PAC check"); - goto out; - } - tgtkey = &tkey->key; + ret = hdb_enctype2key(context, &krbtgt->entry, + krbtgt_etype, &tkey); + if(ret) { + kdc_log(context, config, 0, + "Failed to find key for krbtgt PAC check"); + goto out; } ret = check_PAC(context, config, client_principal, - client, server, ekey, tgtkey, + client, server, ekey, &tkey->key, tgt, &rspac, &require_signedpath); if (ret) { kdc_log(context, config, 0, diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index ebf2873599..072df44042 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: misc.c 17951 2006-08-28 14:41:49Z lha $"); +RCSID("$Id: misc.c 21106 2007-06-18 10:18:11Z lha $"); struct timeval _kdc_now; @@ -46,12 +46,14 @@ _kdc_db_fetch(krb5_context context, hdb_entry_ex **h) { hdb_entry_ex *ent; - krb5_error_code ret = HDB_ERR_NOENTRY; + krb5_error_code ret; int i; ent = calloc (1, sizeof (*ent)); - if (ent == NULL) + if (ent == NULL) { + krb5_set_error_string(context, "out of memory"); return ENOMEM; + } for(i = 0; i < config->num_db; i++) { ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0); @@ -74,7 +76,8 @@ _kdc_db_fetch(krb5_context context, } } free(ent); - return ret; + krb5_set_error_string(context, "no such entry found in hdb"); + return HDB_ERR_NOENTRY; } void diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index bf62f879db..ead961022d 100755 --- a/source4/heimdal/kdc/pkinit.c +++ b/source4/heimdal/kdc/pkinit.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: pkinit.c 21039 2007-06-10 06:20:31Z lha $"); +RCSID("$Id: pkinit.c 21290 2007-06-25 14:13:23Z lha $"); #ifdef PKINIT @@ -380,6 +380,7 @@ _kdc_pk_rd_padata(krb5_context context, *ret_params = NULL; if (!config->enable_pkinit) { + kdc_log(context, config, 0, "PK-INIT request but PK-INIT not enabled"); krb5_clear_error_string(context); return 0; } @@ -676,6 +677,7 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer) static krb5_error_code pk_mk_pa_reply_enckey(krb5_context context, + krb5_kdc_configuration *config, pk_client_params *client_params, const KDC_REQ *req, const krb5_data *req_buffer, @@ -700,8 +702,11 @@ pk_mk_pa_reply_enckey(krb5_context context, switch (client_params->type) { case PKINIT_COMPAT_WIN2K: { int i = 0; - if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL) + if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL + && config->pkinit_require_binding == 0) + { do_win2k = 1; + } break; } case PKINIT_COMPAT_27: @@ -1015,6 +1020,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, goto out; } ret = pk_mk_pa_reply_enckey(context, + config, client_params, req, req_buffer, @@ -1110,6 +1116,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, goto out; } ret = pk_mk_pa_reply_enckey(context, + config, client_params, req, req_buffer, @@ -1384,7 +1391,7 @@ _kdc_pk_check_client(krb5_context context, "Trying to authorize PK-INIT subject DN %s", *subject_name); - if (config->enable_pkinit_princ_in_cert) { + if (config->pkinit_princ_in_cert) { ret = match_rfc_san(context, config, client_params->cert, client->entry.principal); @@ -1508,7 +1515,8 @@ _kdc_add_inital_verified_cas(krb5_context context, krb5_abortx(context, "internal asn.1 encoder error"); ret = _kdc_tkt_add_if_relevant_ad(context, tkt, - ad_initial_verified_cas, &data); + KRB5_AUTHDATA_INITIAL_VERIFIED_CAS, + &data); krb5_data_free(&data); return ret; } -- cgit