diff options
Diffstat (limited to 'source4/heimdal')
42 files changed, 555 insertions, 115 deletions
diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c index fe977ded5a..6fbf5fdae1 100644 --- a/source4/heimdal/kdc/default_config.c +++ b/source4/heimdal/kdc/default_config.c @@ -54,7 +54,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) c->as_use_strongest_session_key = FALSE; c->preauth_use_strongest_session_key = FALSE; c->tgs_use_strongest_session_key = FALSE; - c->use_strongest_server_key = FALSE; + c->use_strongest_server_key = TRUE; c->check_ticket_addresses = TRUE; c->allow_null_ticket_addresses = TRUE; c->allow_anonymous = FALSE; diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index 4bc1619170..c13abb7ce0 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -978,7 +978,7 @@ _kdc_as_rep(krb5_context context, krb5_crypto crypto; Key *ckey, *skey; EncryptionKey *reply_key = NULL, session_key; - int flags = 0; + int flags = HDB_F_FOR_AS_REQ; #ifdef PKINIT pk_client_params *pkp = NULL; #endif diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 92cce5759f..6aad65d408 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1216,7 +1216,7 @@ tgs_parse_request(krb5_context context, } if(ap_req.ticket.enc_part.kvno && - (unsigned int)*ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){ + *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){ char *p; ret = krb5_unparse_name (context, princ, &p); @@ -1508,6 +1508,7 @@ tgs_build_reply(krb5_context context, Key *tkey_check; Key *tkey_sign; + int flags = HDB_F_FOR_TGS_REQ; memset(&sessionkey, 0, sizeof(sessionkey)); memset(&adtkt, 0, sizeof(adtkt)); @@ -1517,6 +1518,9 @@ tgs_build_reply(krb5_context context, s = b->sname; r = b->realm; + if (b->kdc_options.canonicalize) + flags |= HDB_F_CANON; + if(b->kdc_options.enc_tkt_in_skey){ Ticket *t; hdb_entry_ex *uu; @@ -1591,7 +1595,7 @@ tgs_build_reply(krb5_context context, */ server_lookup: - ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | HDB_F_CANON, + ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags, NULL, NULL, &server); if(ret == HDB_ERR_NOT_FOUND_HERE) { @@ -1777,7 +1781,7 @@ server_lookup: goto out; } - ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON, + ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, NULL, &clientdb, &client); if(ret == HDB_ERR_NOT_FOUND_HERE) { /* This is OK, we are just trying to find out if they have @@ -1912,7 +1916,7 @@ server_lookup: if(rspac.data) { krb5_pac p = NULL; krb5_data_free(&rspac); - ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | HDB_F_CANON, + ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags, NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client); if (ret) { const char *msg; diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index f9b34571a3..1b2c440005 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -40,7 +40,7 @@ _kdc_db_fetch(krb5_context context, krb5_kdc_configuration *config, krb5_const_principal principal, unsigned flags, - krb5int32 *kvno_ptr, + krb5uint32 *kvno_ptr, HDB **db, hdb_entry_ex **h) { diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index a02cb816ab..d85b156500 100644 --- a/source4/heimdal/kdc/pkinit.c +++ b/source4/heimdal/kdc/pkinit.c @@ -1420,7 +1420,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, memset(&rep, 0, sizeof(rep)); pa_type = KRB5_PADATA_PK_AS_REP_19; - rep.element = choice_PA_PK_AS_REP_encKeyPack; + rep.element = choice_PA_PK_AS_REP_Win2k_encKeyPack; ret = krb5_generate_random_keyblock(context, enctype, &cp->reply_key); diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index e872fef9be..0b3876dcc5 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -434,7 +434,7 @@ get_new_tickets(krb5_context context, pac_flag ? TRUE : FALSE); if (canonicalize_flag) krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); - if ((pk_enterprise_flag || enterprise_flag || canonicalize_flag) && windows_flag) + if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag) krb5_get_init_creds_opt_set_win2k(context, opt, TRUE); if (pk_user_id || ent_user_id || anonymous_flag) { ret = krb5_get_init_creds_opt_set_pkinit(context, opt, diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1 index 02fab7a3a6..568fe0cd04 100644 --- a/source4/heimdal/lib/asn1/krb5.asn1 +++ b/source4/heimdal/lib/asn1/krb5.asn1 @@ -361,7 +361,7 @@ LastReq ::= SEQUENCE OF SEQUENCE { EncryptedData ::= SEQUENCE { etype[0] ENCTYPE, -- EncryptionType - kvno[1] krb5int32 OPTIONAL, + kvno[1] krb5uint32 OPTIONAL, cipher[2] OCTET STRING -- ciphertext } diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index fa53a29d24..bbb2fd54c9 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -61,6 +61,11 @@ #endif #endif +/* Compatiblity with MIT Kerberos on the Mac */ +#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) +#pragma pack(push,2) +#endif + #ifdef __cplusplus #define GSSAPI_CPP_START extern "C" { #define GSSAPI_CPP_END } @@ -1041,7 +1046,8 @@ GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL gss_userok(const gss_name_t name, const char *user); -extern GSSAPI_LIB_VARIABLE gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER; +extern GSSAPI_LIB_VARIABLE gss_buffer_desc __gss_c_attr_local_login_user; +#define GSS_C_ATTR_LOCAL_LOGIN_USER (&__gss_c_attr_local_login_user) /* * Naming extensions @@ -1105,6 +1111,10 @@ gss_name_to_oid(const char *name); GSSAPI_CPP_END +#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) +#pragma pack(pop) +#endif + #undef GSSAPI_DEPRECATED_FUNCTION #endif /* GSSAPI_GSSAPI_H_ */ diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 0264207e4a..f5e41e4056 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -86,7 +86,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key, cksum_k5.checksum.data = k5_data; cksum_k5.checksum.length = sizeof(k5_data); - if (key->keytype == KEYTYPE_ARCFOUR_56) { + if (key->keytype == KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56) { char L40[14] = "fortybits"; memcpy(L40 + 10, T, sizeof(T)); @@ -100,7 +100,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key, if (ret) return ret; - key5.keytype = KEYTYPE_ARCFOUR; + key5.keytype = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5; key5.keyvalue = cksum_k5.checksum; cksum_k6.checksum.data = key6_data; diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 0109ca7c6e..d032d23d5f 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -285,7 +285,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_keyblock *key; OM_uint32 ret; - krb5_keytype keytype; GSSAPI_KRB5_INIT (&context); @@ -300,10 +299,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (context, key->keytype, &keytype); - switch (keytype) { - case KEYTYPE_DES : + switch (key->keytype) { + case KRB5_ENCTYPE_DES_CBC_CRC : + case KRB5_ENCTYPE_DES_CBC_MD4 : + case KRB5_ENCTYPE_DES_CBC_MD5 : #ifdef HEIM_WEAK_CRYPTO ret = mic_des (minor_status, ctx, context, qop_req, message_buffer, message_token, key); @@ -311,12 +311,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic ret = GSS_S_FAILURE; #endif break; - case KEYTYPE_DES3 : + case KRB5_ENCTYPE_DES3_CBC_MD5 : + case KRB5_ENCTYPE_DES3_CBC_SHA1 : ret = mic_des3 (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; - case KEYTYPE_ARCFOUR: - case KEYTYPE_ARCFOUR_56: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56: ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index d6bc204777..b3da35ee9e 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -392,7 +392,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap krb5_keyblock *key; krb5_context context; OM_uint32 ret; - krb5_keytype keytype; gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; output_message_buffer->value = NULL; @@ -414,12 +413,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (context, key->keytype, &keytype); *minor_status = 0; - switch (keytype) { - case KEYTYPE_DES : + switch (key->keytype) { + case KRB5_ENCTYPE_DES_CBC_CRC : + case KRB5_ENCTYPE_DES_CBC_MD4 : + case KRB5_ENCTYPE_DES_CBC_MD5 : #ifdef HEIM_WEAK_CRYPTO ret = unwrap_des (minor_status, ctx, input_message_buffer, output_message_buffer, @@ -428,13 +428,14 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap ret = GSS_S_FAILURE; #endif break; - case KEYTYPE_DES3 : + case KRB5_ENCTYPE_DES3_CBC_MD5 : + case KRB5_ENCTYPE_DES3_CBC_SHA1 : ret = unwrap_des3 (minor_status, ctx, context, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; - case KEYTYPE_ARCFOUR: - case KEYTYPE_ARCFOUR_56: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56: ret = _gssapi_unwrap_arcfour (minor_status, ctx, context, input_message_buffer, output_message_buffer, conf_state, qop_state, key); diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 3123787ff4..af06e0a1e3 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -281,7 +281,6 @@ _gsskrb5_verify_mic_internal { krb5_keyblock *key; OM_uint32 ret; - krb5_keytype keytype; if (ctx->more_flags & IS_CFX) return _gssapi_verify_mic_cfx (minor_status, ctx, @@ -296,9 +295,11 @@ _gsskrb5_verify_mic_internal return GSS_S_FAILURE; } *minor_status = 0; - krb5_enctype_to_keytype (context, key->keytype, &keytype); - switch (keytype) { - case KEYTYPE_DES : + + switch (key->keytype) { + case KRB5_ENCTYPE_DES_CBC_CRC : + case KRB5_ENCTYPE_DES_CBC_MD4 : + case KRB5_ENCTYPE_DES_CBC_MD5 : #ifdef HEIM_WEAK_CRYPTO ret = verify_mic_des (minor_status, ctx, context, message_buffer, token_buffer, qop_state, key, @@ -307,13 +308,14 @@ _gsskrb5_verify_mic_internal ret = GSS_S_FAILURE; #endif break; - case KEYTYPE_DES3 : + case KRB5_ENCTYPE_DES3_CBC_MD5 : + case KRB5_ENCTYPE_DES3_CBC_SHA1 : ret = verify_mic_des3 (minor_status, ctx, context, message_buffer, token_buffer, qop_state, key, type); break; - case KEYTYPE_ARCFOUR : - case KEYTYPE_ARCFOUR_56 : + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56: ret = _gssapi_verify_mic_arcfour (minor_status, ctx, context, message_buffer, token_buffer, diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index efd0d82c49..4d095c8e87 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -147,7 +147,6 @@ _gsskrb5_wrap_size_limit ( krb5_context context; krb5_keyblock *key; OM_uint32 ret; - krb5_keytype keytype; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; GSSAPI_KRB5_INIT (&context); @@ -164,23 +163,25 @@ _gsskrb5_wrap_size_limit ( *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (context, key->keytype, &keytype); - switch (keytype) { - case KEYTYPE_DES : + switch (key->keytype) { + case KRB5_ENCTYPE_DES_CBC_CRC : + case KRB5_ENCTYPE_DES_CBC_MD4 : + case KRB5_ENCTYPE_DES_CBC_MD5 : #ifdef HEIM_WEAK_CRYPTO ret = sub_wrap_size(req_output_size, max_input_size, 8, 22); #else ret = GSS_S_FAILURE; #endif break; - case KEYTYPE_ARCFOUR: - case KEYTYPE_ARCFOUR_56: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56: ret = _gssapi_wrap_size_arcfour(minor_status, ctx, context, conf_req_flag, qop_req, req_output_size, max_input_size, key); break; - case KEYTYPE_DES3 : + case KRB5_ENCTYPE_DES3_CBC_MD5 : + case KRB5_ENCTYPE_DES3_CBC_SHA1 : ret = sub_wrap_size(req_output_size, max_input_size, 8, 34); break; default : @@ -538,7 +539,6 @@ _gsskrb5_wrap krb5_context context; krb5_keyblock *key; OM_uint32 ret; - krb5_keytype keytype; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; output_message_buffer->value = NULL; @@ -558,10 +558,11 @@ _gsskrb5_wrap *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (context, key->keytype, &keytype); - switch (keytype) { - case KEYTYPE_DES : + switch (key->keytype) { + case KRB5_ENCTYPE_DES_CBC_CRC : + case KRB5_ENCTYPE_DES_CBC_MD4 : + case KRB5_ENCTYPE_DES_CBC_MD5 : #ifdef HEIM_WEAK_CRYPTO ret = wrap_des (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, @@ -570,13 +571,14 @@ _gsskrb5_wrap ret = GSS_S_FAILURE; #endif break; - case KEYTYPE_DES3 : + case KRB5_ENCTYPE_DES3_CBC_MD5 : + case KRB5_ENCTYPE_DES3_CBC_SHA1 : ret = wrap_des3 (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; - case KEYTYPE_ARCFOUR: - case KEYTYPE_ARCFOUR_56: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5: + case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56: ret = _gssapi_wrap_arcfour (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); diff --git a/source4/heimdal/lib/gssapi/version-script.map b/source4/heimdal/lib/gssapi/version-script.map index ebd8ee21ac..bcb79bf8f7 100644 --- a/source4/heimdal/lib/gssapi/version-script.map +++ b/source4/heimdal/lib/gssapi/version-script.map @@ -14,7 +14,7 @@ HEIMDAL_GSS_2.0 { __gss_c_attr_stream_sizes_oid_desc; __gss_c_cred_password_oid_desc; __gss_c_cred_certificate_oid_desc; - GSS_C_ATTR_LOCAL_LOGIN_USER; + __gss_c_attr_local_login_user; gss_accept_sec_context; gss_acquire_cred; gss_acquire_cred_with_password; diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index a890f01a3d..ff0f77644e 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -55,6 +55,13 @@ PKCS12_key_gen(const void *key, size_t keylen, unsigned char *outp = out; int i, vlen; + /** + * The argument key is pointing to an utf16 string, and thus + * keylen that is no a multiple of 2 is invalid. + */ + if (keylen & 1) + return 0; + ctx = EVP_MD_CTX_create(); if (ctx == NULL) return 0; @@ -83,7 +90,7 @@ PKCS12_key_gen(const void *key, size_t keylen, * empty string, in the empty string the UTF16 NUL terminator is * included into the string. */ - if (key && keylen >= 0) { + if (key) { for (i = 0; i < vlen / 2; i++) { I[(i * 2) + size_I] = 0; I[(i * 2) + size_I + 1] = ((unsigned char*)key)[i % (keylen + 1)]; diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c index 69940edf89..2ed054a631 100644 --- a/source4/heimdal/lib/hdb/db.c +++ b/source4/heimdal/lib/hdb/db.c @@ -65,12 +65,24 @@ DB_lock(krb5_context context, HDB *db, int operation) { DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); + krb5_error_code ret; + + if (db->lock_count > 0) { + db->lock_count++; + if (db->lock_type == HDB_WLOCK || db->lock_type == operation) + return 0; + } + if(fd < 0) { krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, "Can't lock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; } - return hdb_lock(fd, operation); + ret = hdb_lock(fd, operation); + if (ret) + return ret; + db->lock_count++; + return 0; } static krb5_error_code @@ -78,6 +90,14 @@ DB_unlock(krb5_context context, HDB *db) { DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); + + if (db->lock_count > 1) { + db->lock_count--; + return 0; + } + heim_assert(db->lock_count == 1, "HDB lock/unlock sequence does not match"); + db->lock_count--; + if(fd < 0) { krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, "Can't unlock database: %s", db->hdb_name); diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c index d2a4373b9b..f4f1715240 100644 --- a/source4/heimdal/lib/hdb/ext.c +++ b/source4/heimdal/lib/hdb/ext.c @@ -432,3 +432,67 @@ hdb_entry_get_aliases(const hdb_entry *entry, const HDB_Ext_Aliases **a) return 0; } + +unsigned int +hdb_entry_get_kvno_diff_clnt(const hdb_entry *entry) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, + choice_HDB_extension_data_hist_kvno_diff_clnt); + if (ext) + return ext->data.u.hist_kvno_diff_clnt; + return 1; +} + +krb5_error_code +hdb_entry_set_kvno_diff_clnt(krb5_context context, hdb_entry *entry, + unsigned int diff) +{ + HDB_extension ext; + + if (diff > 16384) + return EINVAL; + ext.data.element = choice_HDB_extension_data_hist_kvno_diff_clnt; + ext.data.u.hist_kvno_diff_clnt = diff; + return hdb_replace_extension(context, entry, &ext); +} + +krb5_error_code +hdb_entry_clear_kvno_diff_clnt(krb5_context context, hdb_entry *entry) +{ + return hdb_clear_extension(context, entry, + choice_HDB_extension_data_hist_kvno_diff_clnt); +} + +unsigned int +hdb_entry_get_kvno_diff_svc(const hdb_entry *entry) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, + choice_HDB_extension_data_hist_kvno_diff_svc); + if (ext) + return ext->data.u.hist_kvno_diff_svc; + return 1024; /* max_life effectively provides a better default */ +} + +krb5_error_code +hdb_entry_set_kvno_diff_svc(krb5_context context, hdb_entry *entry, + unsigned int diff) +{ + HDB_extension ext; + + if (diff > 16384) + return EINVAL; + ext.data.element = choice_HDB_extension_data_hist_kvno_diff_svc; + ext.data.u.hist_kvno_diff_svc = diff; + return hdb_replace_extension(context, entry, &ext); +} + +krb5_error_code +hdb_entry_clear_kvno_diff_svc(krb5_context context, hdb_entry *entry) +{ + return hdb_clear_extension(context, entry, + choice_HDB_extension_data_hist_kvno_diff_svc); +} diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1 index a72851c9f2..0594b313b7 100644 --- a/source4/heimdal/lib/hdb/hdb.asn1 +++ b/source4/heimdal/lib/hdb/hdb.asn1 @@ -46,8 +46,9 @@ HDBFlags ::= BIT STRING { trusted-for-delegation(14), -- Trusted to print forwardabled tickets allow-kerberos4(15), -- Allow Kerberos 4 requests allow-digest(16), -- Allow digest requests - locked-out(17) -- Account is locked out, + locked-out(17), -- Account is locked out, -- authentication will be denied + do-not-store(31) -- Not to be modified and stored in HDB } GENERATION ::= SEQUENCE { @@ -87,6 +88,17 @@ HDB-Ext-Aliases ::= SEQUENCE { aliases[1] SEQUENCE OF Principal -- all names, inc primary } +Keys ::= SEQUENCE OF Key + +hdb_keyset ::= SEQUENCE { + kvno[0] INTEGER (0..4294967295), + keys[1] Keys, + set-time[2] KerberosTime OPTIONAL, -- time this keyset was created/set + ... +} + +HDB-Ext-KeySet ::= SEQUENCE OF hdb_keyset + HDB-extension ::= SEQUENCE { mandatory[0] BOOLEAN, -- kdc MUST understand this extension, @@ -102,6 +114,10 @@ HDB-extension ::= SEQUENCE { aliases[6] HDB-Ext-Aliases, last-pw-change[7] KerberosTime, pkinit-cert[8] HDB-Ext-PKINIT-cert, + hist-keys[9] HDB-Ext-KeySet, + hist-kvno-diff-clnt[10] INTEGER (0..4294967295), + hist-kvno-diff-svc[11] INTEGER (0..4294967295), + policy[12] UTF8String, ... }, ... @@ -109,16 +125,11 @@ HDB-extension ::= SEQUENCE { HDB-extensions ::= SEQUENCE OF HDB-extension -hdb_keyset ::= SEQUENCE { - kvno[1] INTEGER (0..4294967295), - keys[0] SEQUENCE OF Key -} - hdb_entry ::= SEQUENCE { principal[0] Principal OPTIONAL, -- this is optional only -- for compatibility with libkrb5 kvno[1] INTEGER (0..4294967295), - keys[2] SEQUENCE OF Key, + keys[2] Keys, created-by[3] Event, modified-by[4] Event OPTIONAL, valid-start[5] KerberosTime OPTIONAL, diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index ca05cc4a17..5dc5a0957e 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -168,13 +168,14 @@ hdb_unlock(int fd) void hdb_free_entry(krb5_context context, hdb_entry_ex *ent) { + Key *k; size_t i; if (ent->free_entry) (*ent->free_entry)(context, ent); - for(i = 0; i < ent->entry.keys.len; ++i) { - Key *k = &ent->entry.keys.val[i]; + for(i = 0; i < ent->entry.keys.len; i++) { + k = &ent->entry.keys.val[i]; memset (k->key.keyvalue.data, 0, k->key.keyvalue.length); } diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index 469ec82ec0..75d18770f0 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -57,6 +57,12 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_CANON 32 /* want canonicalition */ #define HDB_F_ADMIN_DATA 64 /* want data that kdc don't use */ #define HDB_F_KVNO_SPECIFIED 128 /* we want a particular KVNO */ +#define HDB_F_CURRENT_KVNO 256 /* we want the current KVNO */ +#define HDB_F_LIVE_CLNT_KVNOS 512 /* we want all live keys for pre-auth */ +#define HDB_F_LIVE_SVC_KVNOS 1024 /* we want all live keys for tix */ +#define HDB_F_ALL_KVNOS 2048 /* we want all the keys, live or not */ +#define HDB_F_FOR_AS_REQ 4096 /* fetch is for a AS REQ */ +#define HDB_F_FOR_TGS_REQ 8192 /* fetch is for a TGS REQ */ /* hdb_capability_flags */ #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 @@ -102,6 +108,8 @@ typedef struct HDB{ hdb_master_key hdb_master_key; int hdb_openp; int hdb_capability_flags; + int lock_count; + int lock_type; /** * Open (or create) the a Kerberos database. * diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et index 2cad4daba4..0bdcb385f6 100644 --- a/source4/heimdal/lib/hdb/hdb_err.et +++ b/source4/heimdal/lib/hdb/hdb_err.et @@ -26,5 +26,6 @@ error_code NO_MKEY, "No correct master key" error_code MANDATORY_OPTION, "Entry contains unknown mandatory extension" error_code NO_WRITE_SUPPORT, "HDB backend doesn't contain write support" error_code NOT_FOUND_HERE, "The secret for this entry is not replicated to this database" +error_code MISUSE, "Incorrect use of the API" end diff --git a/source4/heimdal/lib/hdb/hdb_locl.h b/source4/heimdal/lib/hdb/hdb_locl.h index e896b58025..c210b98b84 100644 --- a/source4/heimdal/lib/hdb/hdb_locl.h +++ b/source4/heimdal/lib/hdb/hdb_locl.h @@ -36,6 +36,9 @@ #ifndef __HDB_LOCL_H__ #define __HDB_LOCL_H__ +#include <assert.h> +#include <heimbase.h> + #include <config.h> #include <stdio.h> diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c index 3d0b9d7c1b..0bc3392fb6 100644 --- a/source4/heimdal/lib/hdb/keys.c +++ b/source4/heimdal/lib/hdb/keys.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2011 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,9 +39,9 @@ */ void -hdb_free_keys (krb5_context context, int len, Key *keys) +hdb_free_keys(krb5_context context, int len, Key *keys) { - int i; + size_t i; for (i = 0; i < len; i++) { free(keys[i].mkvno); @@ -68,15 +68,15 @@ hdb_free_keys (krb5_context context, int len, Key *keys) */ static const krb5_enctype des_etypes[] = { - ETYPE_DES_CBC_MD5, - ETYPE_DES_CBC_MD4, - ETYPE_DES_CBC_CRC + KRB5_ENCTYPE_DES_CBC_MD5, + KRB5_ENCTYPE_DES_CBC_MD4, + KRB5_ENCTYPE_DES_CBC_CRC }; static const krb5_enctype all_etypes[] = { - ETYPE_AES256_CTS_HMAC_SHA1_96, - ETYPE_ARCFOUR_HMAC_MD5, - ETYPE_DES3_CBC_SHA1 + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96, + KRB5_ENCTYPE_ARCFOUR_HMAC_MD5, + KRB5_ENCTYPE_DES3_CBC_SHA1 }; static krb5_error_code @@ -114,7 +114,7 @@ parse_key_set(krb5_context context, const char *key, enctypes = des_etypes; num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]); } else if(strcmp(buf[i], "des3") == 0) { - e = ETYPE_DES3_CBC_SHA1; + e = KRB5_ENCTYPE_DES3_CBC_SHA1; enctypes = &e; num_enctypes = 1; } else { @@ -196,6 +196,68 @@ parse_key_set(krb5_context context, const char *key, return 0; } + +/** + * This function adds an HDB entry's current keyset to the entry's key + * history. The current keyset is left alone; the caller is responsible + * for freeing it. + * + * @param context Context + * @param entry HDB entry + */ +krb5_error_code +hdb_add_current_keys_to_history(krb5_context context, hdb_entry *entry) +{ + krb5_boolean replace = FALSE; + krb5_error_code ret; + HDB_extension *ext; + hdb_keyset newkey; + time_t newtime; + + + ext = hdb_find_extension(entry, choice_HDB_extension_data_hist_keys); + if (ext == NULL) { + replace = TRUE; + ext = calloc(1, sizeof (*ext)); + if (ext == NULL) + return krb5_enomem(context); + + ext->data.element = choice_HDB_extension_data_hist_keys; + } + + /* + * Copy in newest old keyset + */ + + ret = hdb_entry_get_pw_change_time(entry, &newtime); + if (ret) + goto out; + + memset(&newkey, 0, sizeof(newkey)); + newkey.keys = entry->keys; + newkey.kvno = entry->kvno; + newkey.set_time = &newtime; + + ret = add_HDB_Ext_KeySet(&ext->data.u.hist_keys, &newkey); + if (ret) + goto out; + + if (replace) { + /* hdb_replace_extension() deep-copies ext; what a waste */ + ret = hdb_replace_extension(context, entry, ext); + if (ret) + goto out; + } + + out: + if (replace && ext) { + free_HDB_extension(ext); + free(ext); + } + return ret; +} + + static krb5_error_code add_enctype_to_key_set(Key **key_set, size_t *nkeyset, krb5_enctype enctype, krb5_salt *salt) @@ -243,6 +305,50 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset, } +static +krb5_error_code +ks_tuple2str(krb5_context context, int n_ks_tuple, + krb5_key_salt_tuple *ks_tuple, char ***ks_tuple_strs) +{ + size_t i; + char **ksnames; + char *ename, *sname; + krb5_error_code rc = KRB5_PROG_ETYPE_NOSUPP; + + *ks_tuple_strs = NULL; + if (n_ks_tuple < 1) + return 0; + + if ((ksnames = calloc(n_ks_tuple, sizeof (*ksnames))) == NULL) + return (errno); + + for (i = 0; i < n_ks_tuple; i++) { + if (krb5_enctype_to_string(context, ks_tuple[i].ks_enctype, &ename)) + goto out; + if (krb5_salttype_to_string(context, ks_tuple[i].ks_enctype, + ks_tuple[i].ks_salttype, &sname)) + goto out; + + if (asprintf(&ksnames[i], "%s:%s", ename, sname) == -1) { + rc = errno; + free(ename); + free(sname); + goto out; + } + free(ename); + free(sname); + } + + *ks_tuple_strs = ksnames; + rc = 0; + +out: + for (i = 0; i < n_ks_tuple; i++) + free(ksnames[i]); + free(ksnames); + return (rc); +} + /* * Generate the `key_set' from the [kadmin]default_keys statement. If * `no_salt' is set, salt is not important (and will not be set) since @@ -251,12 +357,15 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset, krb5_error_code hdb_generate_key_set(krb5_context context, krb5_principal principal, + int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, Key **ret_key_set, size_t *nkeyset, int no_salt) { - char **ktypes, **kp; + char **ktypes = NULL; + char **kp; krb5_error_code ret; Key *k, *key_set; size_t i, j; + char **ks_tuple_strs; static const char *default_keytypes[] = { "aes256-cts-hmac-sha1-96:pw-salt", "des3-cbc-sha1:pw-salt", @@ -264,16 +373,18 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, NULL }; - ktypes = krb5_config_get_strings(context, NULL, "kadmin", - "default_keys", NULL); + if ((ret = ks_tuple2str(context, n_ks_tuple, ks_tuple, &ks_tuple_strs))) + return ret; + + if (ks_tuple_strs == NULL) + ktypes = krb5_config_get_strings(context, NULL, "kadmin", + "default_keys", NULL); if (ktypes == NULL) ktypes = (char **)(intptr_t)default_keytypes; *ret_key_set = key_set = NULL; *nkeyset = 0; - ret = 0; - for(kp = ktypes; kp && *kp; kp++) { const char *p; krb5_salt salt; @@ -366,7 +477,7 @@ hdb_generate_key_set_password(krb5_context context, krb5_error_code ret; size_t i; - ret = hdb_generate_key_set(context, principal, + ret = hdb_generate_key_set(context, principal, 0, NULL, keys, num_keys, 0); if (ret) return ret; diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c index 9a13d55a51..6dcfc02942 100644 --- a/source4/heimdal/lib/hdb/mkey.c +++ b/source4/heimdal/lib/hdb/mkey.c @@ -228,7 +228,7 @@ read_master_encryptionkey(krb5_context context, const char *filename, should cover all cases, but will break if someone has hacked this code to really use des-cbc-md5 -- but then that's not my problem. */ - if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5) + if(key.keytype == ETYPE_DES_CBC_CRC || key.keytype == ETYPE_DES_CBC_MD5) key.keytype = ETYPE_DES_CFB64_NONE; ret = hdb_process_master_key(context, 0, &key, 0, mkey); @@ -480,6 +480,131 @@ hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent) } krb5_error_code +hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno, + unsigned flags, hdb_entry *ent) +{ + krb5_error_code ret = HDB_ERR_NOENTRY; + HDB_extension *ext; + HDB_Ext_KeySet *hist_keys; + Key *tmp_val; + time_t tmp_set_time; + unsigned int tmp_len; + unsigned int kvno_diff = 0; + krb5_kvno tmp_kvno; + size_t i, k; + int exclude_dead = 0; + KerberosTime now = 0; + time_t *set_time; + + if (kvno == 0) + ret = 0; + + if ((flags & HDB_F_LIVE_CLNT_KVNOS) || (flags & HDB_F_LIVE_SVC_KVNOS)) { + exclude_dead = 1; + now = time(NULL); + if (HDB_F_LIVE_CLNT_KVNOS) + kvno_diff = hdb_entry_get_kvno_diff_clnt(ent); + else + kvno_diff = hdb_entry_get_kvno_diff_svc(ent); + } + + ext = hdb_find_extension(ent, choice_HDB_extension_data_hist_keys); + if (ext == NULL) + return ret; + + /* For swapping; see below */ + tmp_len = ent->keys.len; + tmp_val = ent->keys.val; + tmp_kvno = ent->kvno; + (void) hdb_entry_get_pw_change_time(ent, &tmp_set_time); + + hist_keys = &ext->data.u.hist_keys; + + for (i = 0; i < hist_keys->len; i++) { + if (kvno != 0 && hist_keys->val[i].kvno != kvno) + continue; + + if (exclude_dead && + ((ent->max_life != NULL && + hist_keys->val[i].set_time != NULL && + (*hist_keys->val[i].set_time) < (now - (*ent->max_life))) || + (hist_keys->val[i].kvno < kvno && + (kvno - hist_keys->val[i].kvno) > kvno_diff))) + /* + * The KDC may want to to check for this keyset's set_time + * is within the TGS principal's max_life, say. But we stop + * here. + */ + continue; + + /* Either the keys we want, or all the keys */ + for (k = 0; k < hist_keys->val[i].keys.len; k++) { + ret = hdb_unseal_key_mkey(context, + &hist_keys->val[i].keys.val[k], + db->hdb_master_key); + /* + * If kvno == 0 we might not want to bail here! E.g., if we + * no longer have the right master key, so just ignore this. + * + * We could filter out keys that we can't decrypt here + * because of HDB_ERR_NO_MKEY. However, it seems safest to + * filter them out only where necessary, say, in kadm5. + */ + if (ret && kvno != 0) + return ret; + if (ret && ret != HDB_ERR_NO_MKEY) + return (ret); + } + + if (kvno == 0) + continue; + + /* + * What follows is a bit of a hack. + * + * This is the keyset we're being asked for, but it's not the + * current keyset. So we add the current keyset to the history, + * leave the one we were asked for in the history, and pretend + * the one we were asked for is also the current keyset. + * + * This is a bit of a defensive hack in case an entry fetched + * this way ever gets modified then stored: if the keyset is not + * changed we can detect this and put things back, else we won't + * drop any keysets from history by accident. + * + * Note too that we only ever get called with a non-zero kvno + * either in the KDC or in cases where we aren't changing the + * HDB entry anyways, which is why this is just a defensive + * hack. We also don't fetch specific kvnos in the dump case, + * so there's no danger that we'll dump this entry and load it + * again, repeatedly causing the history to grow boundelessly. + */ + set_time = malloc(sizeof (*set_time)); + if (set_time == NULL) + return ENOMEM; + + /* Swap key sets */ + ent->kvno = hist_keys->val[i].kvno; + ent->keys.val = hist_keys->val[i].keys.val; + ent->keys.len = hist_keys->val[i].keys.len; + if (hist_keys->val[i].set_time != NULL) + /* Sloppy, but the callers we expect won't care */ + (void) hdb_entry_set_pw_change_time(context, ent, + *hist_keys->val[i].set_time); + hist_keys->val[i].kvno = tmp_kvno; + hist_keys->val[i].keys.val = tmp_val; + hist_keys->val[i].keys.len = tmp_len; + if (hist_keys->val[i].set_time != NULL) + /* Sloppy, but the callers we expect won't care */ + *hist_keys->val[i].set_time = tmp_set_time; + + return 0; + } + + return (ret); +} + +krb5_error_code hdb_unseal_key(krb5_context context, HDB *db, Key *k) { if (db->hdb_master_key_set == 0) @@ -526,14 +651,31 @@ hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) krb5_error_code hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) { - size_t i; - for(i = 0; i < ent->keys.len; i++){ - krb5_error_code ret; + HDB_extension *ext; + HDB_Ext_KeySet *hist_keys; + size_t i, k; + krb5_error_code ret; + for(i = 0; i < ent->keys.len; i++){ ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey); if (ret) return ret; } + + ext = hdb_find_extension(ent, choice_HDB_extension_data_hist_keys); + if (ext == NULL) + return 0; + hist_keys = &ext->data.u.hist_keys; + + for (i = 0; i < hist_keys->len; i++) { + for (k = 0; k < hist_keys->val[i].keys.len; k++) { + ret = hdb_seal_key_mkey(context, &hist_keys->val[i].keys.val[k], + mkey); + if (ret) + return ret; + } + } + return 0; } diff --git a/source4/heimdal/lib/hdb/version-script.map b/source4/heimdal/lib/hdb/version-script.map index 50a36cec0a..f80fb78a65 100644 --- a/source4/heimdal/lib/hdb/version-script.map +++ b/source4/heimdal/lib/hdb/version-script.map @@ -4,6 +4,7 @@ HEIMDAL_HDB_1.0 { global: encode_hdb_keyset; hdb_add_master_key; + hdb_add_current_keys_to_history; hdb_check_db_format; hdb_clear_extension; hdb_clear_master_key; @@ -74,33 +75,44 @@ HEIMDAL_HDB_1.0 { hdb_kt_ops; # some random bits needed for libkadm - HDBFlags2int; + add_HDB_Ext_KeySet; + add_Keys; asn1_HDBFlags_units; copy_Event; copy_HDB_extensions; copy_Key; + copy_Keys; copy_Salt; decode_HDB_Ext_Aliases; - decode_HDB_Ext_PKINIT_acl; decode_HDB_extension; + decode_HDB_Ext_PKINIT_acl; decode_Key; + decode_Keys; encode_HDB_Ext_Aliases; - encode_HDB_Ext_PKINIT_acl; encode_HDB_extension; + encode_HDB_Ext_PKINIT_acl; encode_Key; + encode_Keys; free_Event; + free_hdb_entry; free_HDB_Ext_Aliases; - free_HDB_Ext_PKINIT_acl; free_HDB_extension; free_HDB_extensions; + free_HDB_Ext_PKINIT_acl; + free_hdb_keyset; free_Key; + free_Keys; free_Salt; - free_hdb_entry; + HDBFlags2int; int2HDBFlags; length_HDB_Ext_Aliases; - length_HDB_Ext_PKINIT_acl; length_HDB_extension; + length_HDB_Ext_PKINIT_acl; length_Key; + length_Keys; + remove_Keys; + add_Keys; + add_HDB_Ext_Keyset; local: *; diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c index 518e19359c..33f4ed283d 100644 --- a/source4/heimdal/lib/krb5/auth_context.c +++ b/source4/heimdal/lib/krb5/auth_context.c @@ -58,7 +58,7 @@ krb5_auth_con_init(krb5_context context, p->remote_address = NULL; p->local_port = 0; p->remote_port = 0; - p->keytype = KEYTYPE_NULL; + p->keytype = KRB5_ENCTYPE_NULL; p->cksumtype = CKSUMTYPE_NONE; *auth_context = p; return 0; diff --git a/source4/heimdal/lib/krb5/crypto-aes.c b/source4/heimdal/lib/krb5/crypto-aes.c index e8facd85dd..783372b399 100644 --- a/source4/heimdal/lib/krb5/crypto-aes.c +++ b/source4/heimdal/lib/krb5/crypto-aes.c @@ -38,7 +38,7 @@ */ static struct _krb5_key_type keytype_aes128 = { - KEYTYPE_AES128, + KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96, "aes-128", 128, 16, @@ -52,7 +52,7 @@ static struct _krb5_key_type keytype_aes128 = { }; static struct _krb5_key_type keytype_aes256 = { - KEYTYPE_AES256, + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96, "aes-256", 256, 32, diff --git a/source4/heimdal/lib/krb5/crypto-arcfour.c b/source4/heimdal/lib/krb5/crypto-arcfour.c index 82769aea62..1d4f94672a 100644 --- a/source4/heimdal/lib/krb5/crypto-arcfour.c +++ b/source4/heimdal/lib/krb5/crypto-arcfour.c @@ -38,7 +38,7 @@ #include "krb5_locl.h" static struct _krb5_key_type keytype_arcfour = { - KEYTYPE_ARCFOUR, + KRB5_ENCTYPE_ARCFOUR_HMAC_MD5, "arcfour", 128, 16, diff --git a/source4/heimdal/lib/krb5/crypto-des.c b/source4/heimdal/lib/krb5/crypto-des.c index 63ce901d92..f6f1c6881c 100644 --- a/source4/heimdal/lib/krb5/crypto-des.c +++ b/source4/heimdal/lib/krb5/crypto-des.c @@ -69,7 +69,7 @@ krb5_DES_random_to_key(krb5_context context, } static struct _krb5_key_type keytype_des_old = { - KEYTYPE_DES, + ETYPE_DES_CBC_CRC, "des-old", 56, 8, @@ -83,7 +83,7 @@ static struct _krb5_key_type keytype_des_old = { }; static struct _krb5_key_type keytype_des = { - KEYTYPE_DES, + ETYPE_DES_CBC_CRC, "des", 56, 8, diff --git a/source4/heimdal/lib/krb5/crypto-des3.c b/source4/heimdal/lib/krb5/crypto-des3.c index d50c5cebe2..43806038b7 100644 --- a/source4/heimdal/lib/krb5/crypto-des3.c +++ b/source4/heimdal/lib/krb5/crypto-des3.c @@ -55,7 +55,7 @@ DES3_random_key(krb5_context context, #ifdef DES3_OLD_ENCTYPE static struct _krb5_key_type keytype_des3 = { - KEYTYPE_DES3, + ETYPE_OLD_DES3_CBC_SHA1, "des3", 168, 24, @@ -70,7 +70,7 @@ static struct _krb5_key_type keytype_des3 = { #endif static struct _krb5_key_type keytype_des3_derived = { - KEYTYPE_DES3, + ETYPE_OLD_DES3_CBC_SHA1, "des3", 168, 24, diff --git a/source4/heimdal/lib/krb5/crypto-null.c b/source4/heimdal/lib/krb5/crypto-null.c index 69d0e7c34e..b647a6d109 100644 --- a/source4/heimdal/lib/krb5/crypto-null.c +++ b/source4/heimdal/lib/krb5/crypto-null.c @@ -38,7 +38,7 @@ #endif static struct _krb5_key_type keytype_null = { - KEYTYPE_NULL, + KRB5_ENCTYPE_NULL, "null", 0, 0, diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 63aedc4568..732311bec9 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -693,24 +693,36 @@ krb5_enctype_to_keytype(krb5_context context, return 0; } +/** + * Check if a enctype is valid, return 0 if it is. + * + * @param context Kerberos context + * @param etype enctype to check if its valid or not + * + * @return Return an error code for an failure or 0 on success (enctype valid). + * @ingroup krb5_crypto + */ + KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_enctype_valid(krb5_context context, krb5_enctype etype) { struct _krb5_encryption_type *e = _krb5_find_enctype(etype); + if(e && (e->flags & F_DISABLED) == 0) + return 0; + if (context == NULL) + return KRB5_PROG_ETYPE_NOSUPP; if(e == NULL) { krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, N_("encryption type %d not supported", ""), etype); return KRB5_PROG_ETYPE_NOSUPP; } - if (e->flags & F_DISABLED) { - krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, - N_("encryption type %s is disabled", ""), - e->name); - return KRB5_PROG_ETYPE_NOSUPP; - } - return 0; + /* Must be (e->flags & F_DISABLED) */ + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + N_("encryption type %s is disabled", ""), + e->name); + return KRB5_PROG_ETYPE_NOSUPP; } /** @@ -1886,11 +1898,11 @@ _krb5_derive_key(krb5_context context, /* XXX keytype dependent post-processing */ switch(kt->type) { - case KEYTYPE_DES3: + case KRB5_ENCTYPE_OLD_DES3_CBC_SHA1: _krb5_DES3_random_to_key(context, key->key, k, nblocks * et->blocksize); break; - case KEYTYPE_AES128: - case KEYTYPE_AES256: + case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96: + case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96: memcpy(key->key->keyvalue.data, k, key->key->keyvalue.length); break; default: diff --git a/source4/heimdal/lib/krb5/crypto.h b/source4/heimdal/lib/krb5/crypto.h index bf945875b9..9b95b8f0cb 100644 --- a/source4/heimdal/lib/krb5/crypto.h +++ b/source4/heimdal/lib/krb5/crypto.h @@ -69,7 +69,7 @@ struct salt_type { }; struct _krb5_key_type { - krb5_keytype type; /* XXX */ + krb5_enctype type; const char *name; size_t bits; size_t size; diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index 7a7b989b69..bebd4c490e 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -59,6 +59,8 @@ krb5_clear_error_message(krb5_context context) * Set the context full error string for a specific error code. * The error that is stored should be internationalized. * + * The if context is NULL, no error string is stored. + * * @param context Kerberos 5 context * @param ret The error code * @param fmt Error string for the error code @@ -82,6 +84,8 @@ krb5_set_error_message(krb5_context context, krb5_error_code ret, /** * Set the context full error string for a specific error code. * + * The if context is NULL, no error string is stored. + * * @param context Kerberos 5 context * @param ret The error code * @param fmt Error string for the error code @@ -98,6 +102,9 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret, { int r; + if (context == NULL) + return; + HEIMDAL_MUTEX_lock(context->mutex); if (context->error_string) { free(context->error_string); @@ -114,6 +121,8 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret, * Prepend the context full error string for a specific error code. * The error that is stored should be internationalized. * + * The if context is NULL, no error string is stored. + * * @param context Kerberos 5 context * @param ret The error code * @param fmt Error string for the error code @@ -137,6 +146,8 @@ krb5_prepend_error_message(krb5_context context, krb5_error_code ret, /** * Prepend the contexts's full error string for a specific error code. * + * The if context is NULL, no error string is stored. + * * @param context Kerberos 5 context * @param ret The error code * @param fmt Error string for the error code @@ -151,6 +162,10 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, __attribute__ ((format (printf, 3, 0))) { char *str = NULL, *str2 = NULL; + + if (context == NULL) + return; + HEIMDAL_MUTEX_lock(context->mutex); if (context->error_code != ret) { HEIMDAL_MUTEX_unlock(context->mutex); diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index e3bb23a2e9..51550daa4c 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -543,6 +543,11 @@ get_cred_kdc(krb5_context context, /* this should go someplace else */ out_creds->times.endtime = in_creds->times.endtime; + /* + * Windows KDCs always canonicalize the server name + */ + eflags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + /* XXX should do better testing */ if (flags.b.constrained_delegation || impersonate_principal) eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index 979fc9b0ae..2ec1c5e41b 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -407,7 +407,7 @@ krb5_get_forwarded_creds (krb5_context context, */ if (auth_context->flags & KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED) { - cred.enc_part.etype = ENCTYPE_NULL; + cred.enc_part.etype = KRB5_ENCTYPE_NULL; cred.enc_part.kvno = NULL; cred.enc_part.cipher.data = buf; cred.enc_part.cipher.length = buf_size; diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index 27f4964e61..41618b9616 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -480,7 +480,7 @@ krb5_get_in_cred(krb5_context context, } } if(pa) { - salt.salttype = pa->padata_type; + salt.salttype = (krb5_salttype)pa->padata_type; salt.saltvalue = pa->padata_value; ret = (*key_proc)(context, etype, salt, keyseed, &key); diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index f2185628e5..6c874126ab 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -859,7 +859,7 @@ pa_pw_or_afs3_salt(krb5_context context, heim_octet_string *data) { krb5_error_code ret; - if (paid->etype == ENCTYPE_NULL) + if (paid->etype == KRB5_ENCTYPE_NULL) return NULL; ret = set_paid(paid, context, paid->etype, @@ -915,7 +915,7 @@ process_pa_info(krb5_context context, PA_DATA *pa = find_pa_data(md, pa_prefs[i].type); if (pa == NULL) continue; - paid->salt.salttype = pa_prefs[i].type; + paid->salt.salttype = (krb5_salttype)pa_prefs[i].type; p = (*pa_prefs[i].salt_info)(context, client, asreq, paid, &pa->padata_value); } @@ -1204,7 +1204,7 @@ process_pa_data_to_md(krb5_context context, paid = calloc(1, sizeof(*paid)); - paid->etype = ENCTYPE_NULL; + paid->etype = KRB5_ENCTYPE_NULL; ppaid = process_pa_info(context, creds->client, a, paid, in_md); if (ppaid) diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index 9ba9c4b290..6e781aca78 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -65,7 +65,7 @@ krb5_free_keyblock_contents(krb5_context context, if (keyblock->keyvalue.data != NULL) memset(keyblock->keyvalue.data, 0, keyblock->keyvalue.length); krb5_data_free (&keyblock->keyvalue); - keyblock->keytype = ENCTYPE_NULL; + keyblock->keytype = KRB5_ENCTYPE_NULL; } } diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 2224b92e95..9c0f566946 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -326,7 +326,9 @@ typedef HostAddress krb5_address; typedef HostAddresses krb5_addresses; -typedef enum krb5_keytype { +typedef krb5_enctype krb5_keytype; + +enum krb5_keytype_old { KEYTYPE_NULL = ETYPE_NULL, KEYTYPE_DES = ETYPE_DES_CBC_CRC, KEYTYPE_DES3 = ETYPE_OLD_DES3_CBC_SHA1, @@ -334,7 +336,7 @@ typedef enum krb5_keytype { KEYTYPE_AES256 = ETYPE_AES256_CTS_HMAC_SHA1_96, KEYTYPE_ARCFOUR = ETYPE_ARCFOUR_HMAC_MD5, KEYTYPE_ARCFOUR_56 = ETYPE_ARCFOUR_HMAC_MD5_56 -} krb5_keytype; +}; typedef EncryptionKey krb5_keyblock; @@ -876,6 +878,11 @@ typedef struct { typedef krb5_error_code (KRB5_CALLCONV * krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *); +typedef struct { + krb5_enctype ks_enctype; + krb5int32 ks_salttype; +}krb5_key_salt_tuple; + /* * */ diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c index 803a5bf289..16c230a11f 100644 --- a/source4/heimdal/lib/krb5/mit_glue.c +++ b/source4/heimdal/lib/krb5/mit_glue.c @@ -139,7 +139,7 @@ krb5_checksum_free(krb5_context context, krb5_checksum *cksum) KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_c_valid_enctype (krb5_enctype etype) { - return krb5_enctype_valid(NULL, etype); + return !krb5_enctype_valid(NULL, etype); } KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map index fad84ebb5b..818e6e071c 100644 --- a/source4/heimdal/lib/krb5/version-script.map +++ b/source4/heimdal/lib/krb5/version-script.map @@ -285,6 +285,7 @@ HEIMDAL_KRB5_2.0 { krb5_free_creds_contents; krb5_free_data; krb5_free_data_contents; + krb5_free_default_realm; krb5_free_error; krb5_free_error_contents; krb5_free_error_string; |