From 533024be44861c8d2c8ba3232738c7d2dbbe2e4f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2010 11:55:22 +1100 Subject: s4:heimdal: import lorikeet-heimdal-201003262338 (commit f4e0dc17709829235f057e0e100d34802d3929ff) --- source4/heimdal/lib/krb5/constants.c | 1 + source4/heimdal/lib/krb5/context.c | 36 ++++++++++++++------- source4/heimdal/lib/krb5/crypto.c | 54 +++++++++++++++++++++++++++----- source4/heimdal/lib/krb5/get_cred.c | 4 +-- source4/heimdal/lib/krb5/init_creds_pw.c | 12 +++---- source4/heimdal/lib/krb5/principal.c | 14 +++++++++ source4/heimdal/lib/krb5/rd_req.c | 2 +- source4/heimdal/lib/krb5/send_to_kdc.c | 2 +- source4/heimdal/lib/krb5/ticket.c | 12 ++++--- 9 files changed, 103 insertions(+), 34 deletions(-) (limited to 'source4/heimdal/lib/krb5') diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index b85f0cf607..6223fb5d6b 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -42,6 +42,7 @@ KRB5_LIB_VARIABLE const char *krb5_config_file = "~/Library/Preferences/edu.mit.Kerberos:" "/Library/Preferences/edu.mit.Kerberos:" #endif /* __APPLE__ */ +"~/.krb5/config:" SYSCONFDIR "/krb5.conf" #ifndef _WIN32 ":/etc/krb5.conf" diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index dff7a700c4..adcbb703ee 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -535,7 +535,8 @@ krb5_free_context(krb5_context context) krb5_set_send_to_kdc_func(context, NULL, NULL); #ifdef PKINIT - hx509_context_free(&context->hx509ctx); + if (context->hx509ctx) + hx509_context_free(&context->hx509ctx); #endif HEIMDAL_MUTEX_destroy(context->mutex); @@ -824,23 +825,33 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_set_default_in_tkt_etypes(krb5_context context, const krb5_enctype *etypes) { + krb5_error_code ret; krb5_enctype *p = NULL; - int i; + unsigned int n, m; if(etypes) { - for (i = 0; etypes[i]; ++i) { - krb5_error_code ret; - ret = krb5_enctype_valid(context, etypes[i]); - if (ret) - return ret; - } - ++i; - ALLOC(p, i); + for (n = 0; etypes[n]; n++) + ; + n++; + ALLOC(p, n); if(!p) { - krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", "")); + krb5_set_error_message (context, ENOMEM, + N_("malloc: out of memory", "")); return ENOMEM; } - memmove(p, etypes, i * sizeof(krb5_enctype)); + for (n = 0, m = 0; etypes[n]; n++) { + ret = krb5_enctype_valid(context, etypes[n]); + if (ret) + continue; + p[m++] = etypes[n]; + } + p[m] = ETYPE_NULL; + if (m == 0) { + free(p); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + N_("no valid enctype set", "")); + return KRB5_PROG_ETYPE_NOSUPP; + } } if(context->etypes) free(context->etypes); @@ -1375,6 +1386,7 @@ _krb5_homedir_access(krb5_context context) * @param allow allow if TRUE home directory * @return the old value * + * @ingroup krb5 */ krb5_boolean diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 5906d43f5f..ed8765542c 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -67,6 +67,7 @@ struct krb5_crypto_data { #define F_PSEUDO 16 /* not a real protocol type */ #define F_SPECIAL 32 /* backwards */ #define F_DISABLED 64 /* enctype/checksum disabled */ +#define F_WEAK 128 /* enctype is considered weak */ struct salt_type { krb5_salttype type; @@ -2612,7 +2613,7 @@ static struct encryption_type enctype_des_cbc_crc = { &keytype_des, &checksum_crc32, NULL, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_key_ivec, 0, NULL @@ -2626,7 +2627,7 @@ static struct encryption_type enctype_des_cbc_md4 = { &keytype_des, &checksum_rsa_md4, &checksum_rsa_md4_des, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2640,7 +2641,7 @@ static struct encryption_type enctype_des_cbc_md5 = { &keytype_des, &checksum_rsa_md5, &checksum_rsa_md5_des, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2654,7 +2655,7 @@ static struct encryption_type enctype_des_cbc_none = { &keytype_des, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2668,7 +2669,7 @@ static struct encryption_type enctype_des_cfb64_none = { &keytype_des_old, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, DES_CFB64_encrypt_null_ivec, 0, NULL @@ -2682,7 +2683,7 @@ static struct encryption_type enctype_des_pcbc_none = { &keytype_des_old, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, DES_PCBC_encrypt_key_ivec, 0, NULL @@ -3143,8 +3144,14 @@ decrypt_internal(krb5_context context, krb5_clear_error_message(context); return KRB5_BAD_MSIZE; } - checksum_sz = CHECKSUMSIZE(et->checksum); + if (len < checksum_sz + et->confoundersize) { + krb5_set_error_message(context, KRB5_BAD_MSIZE, + N_("Encrypted data shorter then " + "checksum + confunder", "")); + return KRB5_BAD_MSIZE; + } + p = malloc(len); if(len != 0 && p == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); @@ -3206,6 +3213,12 @@ decrypt_internal_special(krb5_context context, krb5_clear_error_message(context); return KRB5_BAD_MSIZE; } + if (len < cksum_sz + et->confoundersize) { + krb5_set_error_message(context, KRB5_BAD_MSIZE, + N_("Encrypted data shorter then " + "checksum + confunder", "")); + return KRB5_BAD_MSIZE; + } p = malloc (len); if (p == NULL) { @@ -4402,6 +4415,33 @@ krb5_enctype_enable(krb5_context context, return 0; } +/** + * Enable or disable all weak encryption types + * + * @param context Kerberos 5 context + * @param enable true to enable, false to disable + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_allow_weak_crypto(krb5_context context, + krb5_boolean enable) +{ + int i; + + for(i = 0; i < num_etypes; i++) + if(etypes[i]->flags & F_WEAK) { + if(enable) + etypes[i]->flags &= ~F_DISABLED; + else + etypes[i]->flags |= F_DISABLED; + } + return 0; +} + KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_string_to_key_derived(krb5_context context, diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 3d76391fa8..75e44f0cd4 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -952,9 +952,7 @@ get_cred_kdc_referral(krb5_context context, ticket.server)) break; - if (ticket.server->name.name_string.len != 2 && - strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0) - { + if (!krb5_principal_is_krbtgt(context, ticket.server)) { krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US, N_("Got back an non krbtgt " "ticket referrals", "")); diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 4637a6d941..f443788075 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -134,12 +134,12 @@ free_init_creds_ctx(krb5_context context, krb5_init_creds_context ctx) free (ctx->pre_auth_types); if (ctx->in_tkt_service) free(ctx->in_tkt_service); - if (ctx->password) { - memset(ctx->password, 0, strlen(ctx->password)); - free(ctx->password); - } if (ctx->keytab_data) free(ctx->keytab_data); + if (ctx->password) { + memset(ctx->password, 0, strlen(ctx->password)); + free(ctx->password); + } krb5_data_free(&ctx->req_buffer); krb5_free_cred_contents(context, &ctx->cred); free_METHOD_DATA(&ctx->md); @@ -1436,8 +1436,8 @@ krb5_init_creds_set_password(krb5_context context, const char *password) { if (ctx->password) { - memset(ctx->password, 0, strlen(ctx->password)); - free(ctx->password); + memset(ctx->password, 0, strlen(ctx->password)); + free(ctx->password); } if (password) { ctx->password = strdup(password); diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 00c967a72e..8e6341fd62 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -1551,3 +1551,17 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) N_("Failed to find name type %s", ""), str); return KRB5_PARSE_MALFORMED; } + +/** + * Check if the cname part of the principal is a krbtgt principal + * + * @ingroup krb5_principal + */ + +krb5_boolean +krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p) +{ + return p->name.name_string.len == 2 && + strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0; + +} diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 6b2ffbdaac..9f6a85b1a2 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -821,7 +821,7 @@ out: * @param inbuf the (AP-REQ) authentication buffer * * @param server the server with authenticate as, if NULL the function - * will try to find any available credential in the keytab + * will try to find any avaiable credentintial in the keytab * that will verify the reply. The function will prefer the * server the server client specified in the AP-REQ, but if * there is no mach, it will try all keytab entries for a diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index a9be31e819..9ff52fa545 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -288,7 +288,7 @@ send_via_proxy (krb5_context context, return krb5_eai_to_heim_errno(ret, errno); for (a = ai; a != NULL; a = a->ai_next) { - s = socket (a->ai_family, a->ai_socktype, a->ai_protocol | SOCK_CLOEXEC); + s = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol); if (s < 0) continue; rk_cloexec(s); diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 4d8da93579..e7d4d9532d 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -443,9 +443,7 @@ check_server_referral(krb5_context context, return KRB5KRB_AP_ERR_MODIFIED; } - if (returned->name.name_string.len == 2 && - strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0) - { + if (krb5_principal_is_krbtgt(context, returned)) { const char *realm = returned->name.name_string.val[1]; if (ref.referred_realm == NULL @@ -485,7 +483,13 @@ check_server_referral(krb5_context context, return ret; noreferral: - if (krb5_principal_compare(context, requested, returned) == FALSE) { + /* + * Expect excact match or that we got a krbtgt + */ + if (krb5_principal_compare(context, requested, returned) != TRUE && + (krb5_realm_compare(context, requested, returned) != TRUE && + krb5_principal_is_krbtgt(context, returned) != TRUE)) + { krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, N_("Not same server principal returned " "as requested", "")); -- cgit