diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-06-13 05:44:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:53:18 -0500 |
commit | 91adebe749beb0dc23cacaea316cb2b724776aad (patch) | |
tree | 133d480f5b23b99fcf1149861136103dc4525cb1 /source4/heimdal | |
parent | f7110d928afd61cee203d07fd85968af993a327f (diff) | |
download | samba-91adebe749beb0dc23cacaea316cb2b724776aad.tar.gz samba-91adebe749beb0dc23cacaea316cb2b724776aad.tar.bz2 samba-91adebe749beb0dc23cacaea316cb2b724776aad.zip |
r23456: Update Samba4 to current lorikeet-heimdal.
Andrew Bartlett
(This used to be commit ae0f81ab235c72cceb120bcdeb051a483cf3cc4f)
Diffstat (limited to 'source4/heimdal')
449 files changed, 8568 insertions, 2876 deletions
diff --git a/source4/heimdal/kdc/524.c b/source4/heimdal/kdc/524.c index 56c12efd60..3e4ad29253 100644 --- a/source4/heimdal/kdc/524.c +++ b/source4/heimdal/kdc/524.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: 524.c,v 1.40 2006/10/06 17:06:30 lha Exp $"); +RCSID("$Id: 524.c 18270 2006-10-06 17:06:30Z lha $"); #include <krb5-v4compat.h> diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c index 2352020d86..c28bd424ea 100644 --- a/source4/heimdal/kdc/default_config.c +++ b/source4/heimdal/kdc/default_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * * All rights reserved. @@ -33,110 +33,61 @@ */ #include "kdc_locl.h" +#include <getarg.h> +#include <parse_bytes.h> -int require_preauth = -1; /* 1 == require preauth for all principals */ +RCSID("$Id: default_config.c 20532 2007-04-23 07:46:57Z lha $"); -const char *trpolicy_str; -int disable_des = -1; -int enable_v4 = -1; -int enable_kaserver = -1; -int enable_524 = -1; -int enable_v4_cross_realm = -1; -int detach_from_console = -1; - -char *v4_realm; - -/* - * Setup some of the defaults for the KDC configuration. - * - * Note: Caller must also fill in: - * - db - * - num_db - * - logf - * -*/ - -void -krb5_kdc_default_config(krb5_kdc_configuration *config) -{ - memset(config, 0, sizeof(*config)); - config->require_preauth = TRUE; - config->kdc_warn_pwexpire = 0; - config->encode_as_rep_as_tgs_rep = FALSE; /* bug compatibility */ - config->check_ticket_addresses = TRUE; - config->allow_null_ticket_addresses = TRUE; - config->allow_anonymous = FALSE; - config->trpolicy = TRPOLICY_ALWAYS_CHECK; - config->enable_v4 = FALSE; - config->enable_kaserver = FALSE; - config->enable_524 = FALSE; /* overriden by enable_v4 in configure()) */ - config->enable_v4_cross_realm = FALSE; - config->enable_pkinit = FALSE; - config->enable_pkinit_princ_in_cert = TRUE; - config->db = NULL; - config->num_db = 0; - config->logf = NULL; -} - - -/* - * Setup some valudes for the KDC configuration, from the config file - * - * Note: Caller must also fill in: - * - db - * - num_db - * - logf - * -*/ - -void krb5_kdc_configure(krb5_context context, krb5_kdc_configuration *config) +int +krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) { - const char *p; - if(require_preauth == -1) { - config->require_preauth = krb5_config_get_bool_default(context, NULL, - config->require_preauth, - "kdc", - "require-preauth", NULL); - } else { - config->require_preauth = require_preauth; - } + krb5_kdc_configuration *c; - if(enable_v4 == -1) { - config->enable_v4 = krb5_config_get_bool_default(context, NULL, - config->enable_v4, - "kdc", - "enable-kerberos4", - NULL); - } else { - config->enable_v4 = enable_v4; + c = calloc(1, sizeof(*c)); + if (c == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; } - if(enable_v4_cross_realm == -1) { - config->enable_v4_cross_realm = - krb5_config_get_bool_default(context, NULL, - config->enable_v4_cross_realm, - "kdc", - "enable-kerberos4-cross-realm", - NULL); - } else { - config->enable_v4_cross_realm = enable_v4_cross_realm; - } - - if(enable_524 == -1) { - config->enable_524 = krb5_config_get_bool_default(context, NULL, - config->enable_v4, - "kdc", "enable-524", - NULL); - } else { - config->enable_524 = enable_524; - } - - config->enable_digest = + c->require_preauth = TRUE; + c->kdc_warn_pwexpire = 0; + c->encode_as_rep_as_tgs_rep = FALSE; + c->check_ticket_addresses = TRUE; + c->allow_null_ticket_addresses = TRUE; + c->allow_anonymous = FALSE; + c->trpolicy = TRPOLICY_ALWAYS_CHECK; + c->enable_v4 = FALSE; + c->enable_kaserver = FALSE; + c->enable_524 = FALSE; + c->enable_v4_cross_realm = FALSE; + c->enable_pkinit = FALSE; + c->enable_pkinit_princ_in_cert = TRUE; + c->db = NULL; + c->num_db = 0; + c->logf = NULL; + + c->require_preauth = krb5_config_get_bool_default(context, NULL, - FALSE, - "kdc", - "enable-digest", NULL); + c->require_preauth, + "kdc", "require-preauth", NULL); + c->enable_v4 = + krb5_config_get_bool_default(context, NULL, + c->enable_v4, + "kdc", "enable-kerberos4", NULL); + c->enable_v4_cross_realm = + krb5_config_get_bool_default(context, NULL, + c->enable_v4_cross_realm, + "kdc", + "enable-kerberos4-cross-realm", NULL); + c->enable_524 = + krb5_config_get_bool_default(context, NULL, + c->enable_v4, + "kdc", "enable-524", NULL); + c->enable_digest = + krb5_config_get_bool_default(context, NULL, + FALSE, + "kdc", "enable-digest", NULL); { const char *digests; @@ -146,46 +97,57 @@ void krb5_kdc_configure(krb5_context context, krb5_kdc_configuration *config) "digests_allowed", NULL); if (digests == NULL) digests = "ntlm-v2"; - config->digests_allowed = parse_flags(digests, - _kdc_digestunits, - 0); - if (config->digests_allowed == -1) { - kdc_log(context, config, 0, + c->digests_allowed = parse_flags(digests,_kdc_digestunits, 0); + if (c->digests_allowed == -1) { + kdc_log(context, c, 0, "unparsable digest units (%s), turning off digest", digests); - config->enable_digest = 0; - } else if (config->digests_allowed == 0) { - kdc_log(context, config, 0, + c->enable_digest = 0; + } else if (c->digests_allowed == 0) { + kdc_log(context, c, 0, "no digest enable, turning digest off", digests); - config->enable_digest = 0; + c->enable_digest = 0; } } - config->enable_kx509 = + c->enable_kx509 = krb5_config_get_bool_default(context, NULL, FALSE, - "kdc", - "enable-kx509", NULL); + "kdc", "enable-kx509", NULL); + + if (c->enable_kx509) { + c->kx509_template = + krb5_config_get_string(context, NULL, + "kdc", "kx509_template", NULL); + c->kx509_ca = + krb5_config_get_string(context, NULL, + "kdc", "kx509_ca", NULL); + if (c->kx509_ca == NULL || c->kx509_template == NULL) { + kdc_log(context, c, 0, + "missing kx509 configuration, turning off"); + c->enable_kx509 = FALSE; + } + } - config->check_ticket_addresses = + c->check_ticket_addresses = krb5_config_get_bool_default(context, NULL, - config->check_ticket_addresses, + c->check_ticket_addresses, "kdc", "check-ticket-addresses", NULL); - config->allow_null_ticket_addresses = + c->allow_null_ticket_addresses = krb5_config_get_bool_default(context, NULL, - config->allow_null_ticket_addresses, + c->allow_null_ticket_addresses, "kdc", "allow-null-ticket-addresses", NULL); - config->allow_anonymous = + c->allow_anonymous = krb5_config_get_bool_default(context, NULL, - config->allow_anonymous, + c->allow_anonymous, "kdc", "allow-anonymous", NULL); - config->max_datagram_reply_length = + c->max_datagram_reply_length = krb5_config_get_int_default(context, NULL, 1400, @@ -193,178 +155,124 @@ void krb5_kdc_configure(krb5_context context, krb5_kdc_configuration *config) "max-kdc-datagram-reply-length", NULL); - trpolicy_str = - krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc", - "transited-policy", NULL); - if(strcasecmp(trpolicy_str, "always-check") == 0) { - config->trpolicy = TRPOLICY_ALWAYS_CHECK; - } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) { - config->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL; - } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) { - config->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST; - } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) { - /* default */ - } else { - kdc_log(context, config, - 0, "unknown transited-policy: %s, reverting to default (always-check)", - trpolicy_str); + { + const char *trpolicy_str; + + trpolicy_str = + krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc", + "transited-policy", NULL); + if(strcasecmp(trpolicy_str, "always-check") == 0) { + c->trpolicy = TRPOLICY_ALWAYS_CHECK; + } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) { + c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL; + } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) { + c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST; + } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) { + /* default */ + } else { + kdc_log(context, c, 0, + "unknown transited-policy: %s, " + "reverting to default (always-check)", + trpolicy_str); + } } - - if (krb5_config_get_string(context, NULL, "kdc", - "enforce-transited-policy", NULL)) - krb5_errx(context, 1, "enforce-transited-policy deprecated, " - "use [kdc]transited-policy instead"); - if(v4_realm == NULL){ + { + const char *p; p = krb5_config_get_string (context, NULL, "kdc", "v4-realm", NULL); if(p != NULL) { - config->v4_realm = strdup(p); - if (config->v4_realm == NULL) + c->v4_realm = strdup(p); + if (c->v4_realm == NULL) krb5_errx(context, 1, "out of memory"); } else { - config->v4_realm = NULL; + c->v4_realm = NULL; } - } else { - config->v4_realm = v4_realm; } - if (enable_kaserver == -1) { - config->enable_kaserver = - krb5_config_get_bool_default(context, - NULL, - config->enable_kaserver, - "kdc", - "enable-kaserver", - NULL); - } else { - config->enable_kaserver = enable_kaserver; - } + c->enable_kaserver = + krb5_config_get_bool_default(context, + NULL, + c->enable_kaserver, + "kdc", "enable-kaserver", NULL); - config->encode_as_rep_as_tgs_rep = + + c->encode_as_rep_as_tgs_rep = krb5_config_get_bool_default(context, NULL, - config->encode_as_rep_as_tgs_rep, + c->encode_as_rep_as_tgs_rep, "kdc", - "encode_as_rep_as_tgs_rep", - NULL); - - config->kdc_warn_pwexpire = + "encode_as_rep_as_tgs_rep", NULL); + + c->kdc_warn_pwexpire = krb5_config_get_time_default (context, NULL, - config->kdc_warn_pwexpire, - "kdc", - "kdc_warn_pwexpire", - NULL); + c->kdc_warn_pwexpire, + "kdc", "kdc_warn_pwexpire", NULL); - if(detach_from_console == -1) - detach_from_console = krb5_config_get_bool_default(context, NULL, - DETACH_IS_DEFAULT, - "kdc", - "detach", NULL); #ifdef PKINIT - config->enable_pkinit = + c->enable_pkinit = krb5_config_get_bool_default(context, NULL, - config->enable_pkinit, + c->enable_pkinit, "kdc", "enable-pkinit", NULL); - if (config->enable_pkinit) { + if (c->enable_pkinit) { const char *user_id, *anchors, *ocsp_file; char **pool_list, **revoke_list; - user_id = krb5_config_get_string(context, NULL, - "kdc", - "pkinit_identity", - NULL); + user_id = + krb5_config_get_string(context, NULL, + "kdc", "pkinit_identity", NULL); if (user_id == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); anchors = krb5_config_get_string(context, NULL, - "kdc", - "pkinit_anchors", - NULL); + "kdc", "pkinit_anchors", NULL); if (anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); - pool_list = krb5_config_get_strings(context, NULL, - "kdc", - "pkinit_pool", - NULL); + pool_list = + krb5_config_get_strings(context, NULL, + "kdc", "pkinit_pool", NULL); - revoke_list = krb5_config_get_strings(context, NULL, - "kdc", - "pkinit_revoke", - NULL); + revoke_list = + krb5_config_get_strings(context, NULL, + "kdc", "pkinit_revoke", NULL); ocsp_file = krb5_config_get_string(context, NULL, - "kdc", - "pkinit_kdc_ocsp", - NULL); + "kdc", "pkinit_kdc_ocsp", NULL); if (ocsp_file) { - config->pkinit_kdc_ocsp_file = strdup(ocsp_file); - if (config->pkinit_kdc_ocsp_file == NULL) + c->pkinit_kdc_ocsp_file = strdup(ocsp_file); + if (c->pkinit_kdc_ocsp_file == NULL) krb5_errx(context, 1, "out of memory"); } - _kdc_pk_initialize(context, config, user_id, anchors, + + _kdc_pk_initialize(context, c, user_id, anchors, pool_list, revoke_list); krb5_config_free_strings(pool_list); krb5_config_free_strings(revoke_list); - config->enable_pkinit_princ_in_cert = - krb5_config_get_bool_default(context, - NULL, - config->enable_pkinit_princ_in_cert, + c->enable_pkinit_princ_in_cert = + krb5_config_get_bool_default(context, NULL, + c->enable_pkinit_princ_in_cert, "kdc", "pkinit_principal_in_certificate", NULL); } - config->pkinit_dh_min_bits = - krb5_config_get_int_default(context, - NULL, + c->pkinit_dh_min_bits = + krb5_config_get_int_default(context, NULL, 0, - "kdc", - "pkinit_dh_min_bits", - NULL); + "kdc", "pkinit_dh_min_bits", NULL); #endif - if(config->v4_realm == NULL && (config->enable_kaserver || config->enable_v4)){ -#ifdef KRB4 - config->v4_realm = malloc(40); /* REALM_SZ */ - if (config->v4_realm == NULL) - krb5_errx(context, 1, "out of memory"); - krb_get_lrealm(config->v4_realm, 1); -#else - krb5_errx(context, 1, "No Kerberos 4 realm configured"); -#endif - } - if(disable_des == -1) - disable_des = krb5_config_get_bool_default(context, NULL, - FALSE, - "kdc", - "disable-des", NULL); - if(disable_des) { - krb5_enctype_disable(context, ETYPE_DES_CBC_CRC); - krb5_enctype_disable(context, ETYPE_DES_CBC_MD4); - krb5_enctype_disable(context, ETYPE_DES_CBC_MD5); - krb5_enctype_disable(context, ETYPE_DES_CBC_NONE); - krb5_enctype_disable(context, ETYPE_DES_CFB64_NONE); - krb5_enctype_disable(context, ETYPE_DES_PCBC_NONE); - - kdc_log(context, config, - 0, "DES was disabled, turned off Kerberos V4, 524 " - "and kaserver"); - config->enable_v4 = 0; - config->enable_524 = 0; - config->enable_kaserver = 0; - } + *config = c; - _kdc_windc_init(context); + return 0; } - diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c index 2c012a2ead..811ab639f1 100644 --- a/source4/heimdal/kdc/digest.c +++ b/source4/heimdal/kdc/digest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -34,8 +34,9 @@ #include "kdc_locl.h" #include <hex.h> -RCSID("$Id: digest.c,v 1.19 2006/12/28 17:03:51 lha Exp $"); +RCSID("$Id: digest.c 20877 2007-06-04 04:07:26Z lha $"); +#define MS_CHAP_V2 0x20 #define CHAP_MD5 0x10 #define DIGEST_MD5 0x08 #define NTLM_V2 0x04 @@ -43,6 +44,7 @@ RCSID("$Id: digest.c,v 1.19 2006/12/28 17:03:51 lha Exp $"); #define NTLM_V1 0x01 const struct units _kdc_digestunits[] = { + {"ms-chap-v2", 1U << 5}, {"chap-md5", 1U << 4}, {"digest-md5", 1U << 3}, {"ntlm-v2", 1U << 2}, @@ -135,6 +137,25 @@ fill_targetinfo(krb5_context context, } +static const unsigned char ms_chap_v2_magic1[39] = { + 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 +}; +static const unsigned char ms_chap_v2_magic2[41] = { + 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E +}; +static const unsigned char ms_rfc3079_magic1[27] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 +}; + /* * */ @@ -382,11 +403,6 @@ _kdc_do_digest(krb5_context context, goto out; } - ret = krb5_store_stringz(sp, *r.u.initReply.identifier); - if (ret) { - krb5_clear_error_string(context); - goto out; - } } else r.u.initReply.identifier = NULL; @@ -461,13 +477,7 @@ _kdc_do_digest(krb5_context context, } krb5_store_stringz(sp, ireq.u.digestRequest.serverNonce); - if (ireq.u.digestRequest.identifier) { - ret = krb5_store_stringz(sp, *ireq.u.digestRequest.identifier); - if (ret) { - krb5_clear_error_string(context); - goto out; - } - } + if (ireq.u.digestRequest.hostname) { ret = krb5_store_stringz(sp, *ireq.u.digestRequest.hostname); if (ret) { @@ -587,6 +597,7 @@ _kdc_do_digest(krb5_context context, if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; + char *mdx; char id; if ((config->digests_allowed & CHAP_MD5) == 0) { @@ -613,16 +624,30 @@ _kdc_do_digest(krb5_context context, MD5_Update(&ctx, serverNonce.data, serverNonce.length); MD5_Final(md, &ctx); - r.element = choice_DigestRepInner_response; - hex_encode(md, sizeof(md), &r.u.response.responseData); - if (r.u.response.responseData == NULL) { + hex_encode(md, sizeof(md), &mdx); + if (mdx == NULL) { krb5_clear_error_string(context); ret = ENOMEM; goto out; } + + 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, + "CHAP reply mismatch for %s", + ireq.u.digestRequest.username); + r.u.response.success = FALSE; + } + } else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; + char *mdx; char *A1, *A2; if ((config->digests_allowed & DIGEST_MD5) == 0) { @@ -709,21 +734,212 @@ _kdc_do_digest(krb5_context context, MD5_Final(md, &ctx); - r.element = choice_DigestRepInner_response; - hex_encode(md, sizeof(md), &r.u.response.responseData); - free(A1); free(A2); - if (r.u.response.responseData == NULL) { - krb5_set_error_string(context, "out of memory"); + hex_encode(md, sizeof(md), &mdx); + if (mdx == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + + 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, + "DIGEST-MD5 reply mismatch for %s", + ireq.u.digestRequest.username); + r.u.response.success = FALSE; + } + + } else if (strcasecmp(ireq.u.digestRequest.type, "MS-CHAP-V2") == 0) { + unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH]; + char *mdx; + const char *username; + struct ntlm_buf answer; + Key *key = NULL; + SHA_CTX ctx; + + if ((config->digests_allowed & MS_CHAP_V2) == 0) { + kdc_log(context, config, 0, "MS-CHAP-V2 not allowed"); + goto out; + } + + if (ireq.u.digestRequest.clientNonce == NULL) { + krb5_set_error_string(context, + "MS-CHAP-V2 clientNonce missing"); + ret = EINVAL; + goto out; + } + if (serverNonce.length != 16) { + krb5_set_error_string(context, + "MS-CHAP-V2 serverNonce wrong length"); + ret = EINVAL; + goto out; + } + + /* strip of the domain component */ + username = strchr(ireq.u.digestRequest.username, '\\'); + if (username == NULL) + username = ireq.u.digestRequest.username; + else + username++; + + /* ChallangeHash */ + SHA1_Init(&ctx); + { + ssize_t ssize; + krb5_data clientNonce; + + clientNonce.length = strlen(*ireq.u.digestRequest.clientNonce); + clientNonce.data = malloc(clientNonce.length); + if (clientNonce.data == NULL) { + ret = ENOMEM; + krb5_set_error_string(context, "out of memory"); + goto out; + } + + ssize = hex_decode(*ireq.u.digestRequest.clientNonce, + clientNonce.data, clientNonce.length); + if (ssize != 16) { + krb5_set_error_string(context, + "Failed to decode clientNonce"); + ret = ENOMEM; + goto out; + } + SHA1_Update(&ctx, clientNonce.data, ssize); + free(clientNonce.data); + } + SHA1_Update(&ctx, serverNonce.data, serverNonce.length); + SHA1_Update(&ctx, username, strlen(username)); + SHA1_Final(challange, &ctx); + + /* NtPasswordHash */ + ret = krb5_parse_name(context, username, &clientprincipal); + if (ret) + goto out; + + ret = _kdc_db_fetch(context, config, clientprincipal, + HDB_F_GET_CLIENT, NULL, &user); + krb5_free_principal(context, clientprincipal); + if (ret) { + krb5_set_error_string(context, + "MS-CHAP-V2 user %s not in database", + username); + goto out; + } + + ret = hdb_enctype2key(context, &user->entry, + ETYPE_ARCFOUR_HMAC_MD5, &key); + if (ret) { + krb5_set_error_string(context, + "MS-CHAP-V2 missing arcfour key %s", + username); + goto out; + } + + /* ChallengeResponse */ + ret = heim_ntlm_calculate_ntlm1(key->key.keyvalue.data, + key->key.keyvalue.length, + challange, &answer); + if (ret) { + krb5_set_error_string(context, "NTLM missing arcfour key"); + goto out; + } + + hex_encode(answer.data, answer.length, &mdx); + if (mdx == NULL) { + free(answer.data); + krb5_clear_error_string(context); ret = ENOMEM; goto out; } + 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", + ireq.u.digestRequest.username); + r.u.response.success = FALSE; + } + + if (r.u.response.success) { + unsigned char hashhash[MD4_DIGEST_LENGTH]; + + /* hashhash */ + { + MD4_CTX hctx; + + MD4_Init(&hctx); + MD4_Update(&hctx, key->key.keyvalue.data, + key->key.keyvalue.length); + MD4_Final(hashhash, &hctx); + } + + /* GenerateAuthenticatorResponse */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, hashhash, sizeof(hashhash)); + SHA1_Update(&ctx, answer.data, answer.length); + SHA1_Update(&ctx, ms_chap_v2_magic1,sizeof(ms_chap_v2_magic1)); + SHA1_Final(md, &ctx); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, md, sizeof(md)); + SHA1_Update(&ctx, challange, 8); + SHA1_Update(&ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2)); + SHA1_Final(md, &ctx); + + r.u.response.rsp = calloc(1, sizeof(*r.u.response.rsp)); + if (r.u.response.rsp == NULL) { + free(answer.data); + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + + hex_encode(md, sizeof(md), r.u.response.rsp); + if (r.u.response.rsp == NULL) { + free(answer.data); + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + + /* get_master, rfc 3079 3.4 */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, hashhash, 16); /* md4(hash) */ + SHA1_Update(&ctx, answer.data, answer.length); + SHA1_Update(&ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1)); + SHA1_Final(md, &ctx); + + free(answer.data); + + r.u.response.session_key = + calloc(1, sizeof(*r.u.response.session_key)); + if (r.u.response.session_key == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + + ret = krb5_data_copy(r.u.response.session_key, md, 16); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + } + } else { r.element = choice_DigestRepInner_error; - asprintf(&r.u.error.reason, "unsupported digest type %s", + asprintf(&r.u.error.reason, "Unsupported digest type %s", ireq.u.digestRequest.type); if (r.u.error.reason == NULL) { krb5_set_error_string(context, "out of memory"); @@ -745,7 +961,6 @@ _kdc_do_digest(krb5_context context, goto out; } - r.element = choice_DigestRepInner_ntlmInitReply; r.u.ntlmInitReply.flags = NTLM_NEG_UNICODE; @@ -766,12 +981,12 @@ _kdc_do_digest(krb5_context context, NTLM_NEG_TARGET_DOMAIN | NTLM_ENC_128; -#define ALL \ - NTLM_NEG_SIGN| \ - NTLM_NEG_SEAL| \ - NTLM_NEG_ALWAYS_SIGN| \ - NTLM_NEG_NTLM2_SESSION| \ - NTLM_NEG_KEYEX +#define ALL \ + NTLM_NEG_SIGN| \ + NTLM_NEG_SEAL| \ + NTLM_NEG_ALWAYS_SIGN| \ + NTLM_NEG_NTLM2_SESSION| \ + NTLM_NEG_KEYEX r.u.ntlmInitReply.flags |= (ireq.u.ntlmInit.flags & (ALL)); @@ -989,6 +1204,7 @@ _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; } @@ -1048,6 +1264,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "NTLM client failed to neg key " "exchange but still sent key"); + ret = EINVAL; goto out; } diff --git a/source4/heimdal/kdc/headers.h b/source4/heimdal/kdc/headers.h index 56ddc8090b..64f6b6e438 100644 --- a/source4/heimdal/kdc/headers.h +++ b/source4/heimdal/kdc/headers.h @@ -32,7 +32,7 @@ */ /* - * $Id: headers.h,v 1.22 2007/01/04 00:15:34 lha Exp $ + * $Id: headers.h 19658 2007-01-04 00:15:34Z lha $ */ #ifndef __HEADERS_H__ diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c index ac282717ed..deb32e1019 100644 --- a/source4/heimdal/kdc/kaserver.c +++ b/source4/heimdal/kdc/kaserver.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kaserver.c,v 1.36 2006/08/23 11:43:44 lha Exp $"); +RCSID("$Id: kaserver.c 17904 2006-08-23 11:45:16Z lha $"); #include <krb5-v4compat.h> #include <rx.h> diff --git a/source4/heimdal/kdc/kdc-private.h b/source4/heimdal/kdc/kdc-private.h index d896bd10e9..030be9ae58 100644 --- a/source4/heimdal/kdc/kdc-private.h +++ b/source4/heimdal/kdc/kdc-private.h @@ -149,9 +149,9 @@ _kdc_find_etype ( Key **/*ret_key*/, krb5_enctype */*ret_etype*/); -PA_DATA* +const PA_DATA* _kdc_find_padata ( - KDC_REQ */*req*/, + const KDC_REQ */*req*/, int */*start*/, int /*type*/); @@ -249,8 +249,8 @@ krb5_error_code _kdc_pk_rd_padata ( krb5_context /*context*/, krb5_kdc_configuration */*config*/, - KDC_REQ */*req*/, - PA_DATA */*pa*/, + const KDC_REQ */*req*/, + const PA_DATA */*pa*/, pk_client_params **/*ret_params*/); krb5_error_code @@ -283,7 +283,4 @@ _kdc_windc_client_access ( struct hdb_entry_ex */*client*/, KDC_REQ */*req*/); -krb5_error_code -_kdc_windc_init (krb5_context /*context*/); - #endif /* __kdc_private_h__ */ diff --git a/source4/heimdal/kdc/kdc-protos.h b/source4/heimdal/kdc/kdc-protos.h index 69bc871b01..f7df365eb2 100644 --- a/source4/heimdal/kdc/kdc-protos.h +++ b/source4/heimdal/kdc/kdc-protos.h @@ -37,8 +37,10 @@ kdc_openlog ( krb5_context /*context*/, krb5_kdc_configuration */*config*/); -void -krb5_kdc_default_config (krb5_kdc_configuration */*config*/); +int +krb5_kdc_get_config ( + krb5_context /*context*/, + krb5_kdc_configuration **/*config*/); int krb5_kdc_process_krb5_request ( @@ -63,6 +65,21 @@ krb5_kdc_process_request ( struct sockaddr */*addr*/, int /*datagram_reply*/); +int +krb5_kdc_save_request ( + krb5_context /*context*/, + const char */*fn*/, + const unsigned char */*buf*/, + size_t /*len*/, + const krb5_data */*reply*/, + const struct sockaddr */*sa*/); + +void +krb5_kdc_update_time (struct timeval */*tv*/); + +krb5_error_code +krb5_kdc_windc_init (krb5_context /*context*/); + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/kdc/kdc.h b/source4/heimdal/kdc/kdc.h index ea9eb7125e..eb24b4ee97 100644 --- a/source4/heimdal/kdc/kdc.h +++ b/source4/heimdal/kdc/kdc.h @@ -35,7 +35,7 @@ */ /* - * $Id: kdc.h,v 1.11 2006/12/28 21:06:56 lha Exp $ + * $Id: kdc.h 19907 2007-01-14 23:10:24Z lha $ */ #ifndef __KDC_H__ @@ -86,6 +86,8 @@ typedef struct krb5_kdc_configuration { size_t max_datagram_reply_length; int enable_kx509; + const char *kx509_template; + const char *kx509_ca; } krb5_kdc_configuration; diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h index ae3b6584a5..fdbdf271de 100644 --- a/source4/heimdal/kdc/kdc_locl.h +++ b/source4/heimdal/kdc/kdc_locl.h @@ -32,7 +32,7 @@ */ /* - * $Id: kdc_locl.h,v 1.76 2006/12/26 17:18:14 lha Exp $ + * $Id: kdc_locl.h 20954 2007-06-07 03:30:15Z lha $ */ #ifndef __KDC_LOCL_H__ @@ -46,6 +46,7 @@ typedef struct pk_client_params pk_client_params; extern sig_atomic_t exit_flag; extern size_t max_request; +extern const char *request_log; extern const char *port_str; extern krb5_addresses explicit_addresses; @@ -55,18 +56,6 @@ extern int enable_http; extern int detach_from_console; -extern int require_preauth; /* 1 == require preauth for all principals */ - -extern const char *trpolicy_str; - -extern int disable_des; -extern int enable_v4; -extern int enable_kaserver; -extern int enable_524; -extern int enable_v4_cross_realm; - -extern char *v4_realm; - extern const struct units _kdc_digestunits[]; #define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf" @@ -81,6 +70,4 @@ loop(krb5_context context, krb5_kdc_configuration *config); krb5_kdc_configuration * configure(krb5_context context, int argc, char **argv); -void krb5_kdc_configure(krb5_context context, krb5_kdc_configuration *config); - #endif /* __KDC_LOCL_H__ */ diff --git a/source4/heimdal/kdc/kerberos4.c b/source4/heimdal/kdc/kerberos4.c index 97e98d86ad..3c76bb99b2 100644 --- a/source4/heimdal/kdc/kerberos4.c +++ b/source4/heimdal/kdc/kerberos4.c @@ -35,7 +35,7 @@ #include <krb5-v4compat.h> -RCSID("$Id: kerberos4.c,v 1.63 2006/10/08 13:43:27 lha Exp $"); +RCSID("$Id: kerberos4.c 18349 2006-10-08 13:43:52Z lha $"); #ifndef swap32 static uint32_t diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index bb0fda89e7..e34938447a 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kerberos5.c,v 1.231 2007/01/04 13:27:27 lha Exp $"); +RCSID("$Id: kerberos5.c 21040 2007-06-10 06:20:59Z lha $"); #define MAX_TIME ((time_t)((1U << 31) - 1)) @@ -70,9 +70,12 @@ set_salt_padata (METHOD_DATA *md, Salt *salt) } } -PA_DATA* -_kdc_find_padata(KDC_REQ *req, int *start, int type) +const PA_DATA* +_kdc_find_padata(const KDC_REQ *req, int *start, int type) { + if (req->padata == NULL) + return NULL; + while(*start < req->padata->len){ (*start)++; if(req->padata->val[*start - 1].padata_type == type) @@ -431,7 +434,8 @@ get_pa_etype_info(krb5_context context, ret = krb5_unparse_name(context, client->principal, &name); if (ret) name = rk_UNCONST("<unparse_name failed>"); - kdc_log(context, config, 0, "internal error in get_pa_etype_info(%s): %d != %d", + kdc_log(context, config, 0, + "internal error in get_pa_etype_info(%s): %d != %d", name, n, pa.len); if (ret == 0) free(name); @@ -689,11 +693,11 @@ log_as_req(krb5_context context, } { - char _str[128]; + char fixedstr[128]; unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(), - _str, sizeof(_str)); - if(*_str) - kdc_log(context, config, 2, "Requested flags: %s", _str); + fixedstr, sizeof(fixedstr)); + if(*fixedstr) + kdc_log(context, config, 2, "Requested flags: %s", fixedstr); } } @@ -870,7 +874,7 @@ send_pac_p(krb5_context context, KDC_REQ *req) { krb5_error_code ret; PA_PAC_REQUEST pacreq; - PA_DATA *pa; + const PA_DATA *pa; int i = 0; pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST); @@ -909,32 +913,37 @@ _kdc_as_rep(krb5_context context, KDCOptions f = b->kdc_options; hdb_entry_ex *client = NULL, *server = NULL; krb5_enctype cetype, setype, sessionetype; + krb5_data e_data; EncTicketPart et; EncKDCRepPart ek; krb5_principal client_princ = NULL, server_princ = NULL; char *client_name = NULL, *server_name = NULL; krb5_error_code ret = 0; const char *e_text = NULL; - krb5_data e_data; krb5_crypto crypto; Key *ckey, *skey; EncryptionKey *reply_key; + int flags = 0; #ifdef PKINIT pk_client_params *pkp = NULL; #endif memset(&rep, 0, sizeof(rep)); - memset(&e_data, 0, sizeof(e_data)); + krb5_data_zero(&e_data); + + if (f.canonicalize) + flags |= HDB_F_CANON; if(b->sname == NULL){ ret = KRB5KRB_ERR_GENERIC; e_text = "No server in request"; } else{ - _krb5_principalname2krb5_principal (context, - &server_princ, - *(b->sname), - b->realm); - ret = krb5_unparse_name(context, server_princ, &server_name); + ret = _krb5_principalname2krb5_principal (context, + &server_princ, + *(b->sname), + b->realm); + if (ret == 0) + ret = krb5_unparse_name(context, server_princ, &server_name); } if (ret) { kdc_log(context, config, 0, @@ -946,10 +955,26 @@ _kdc_as_rep(krb5_context context, ret = KRB5KRB_ERR_GENERIC; e_text = "No client in request"; } else { - _krb5_principalname2krb5_principal (context, - &client_princ, - *(b->cname), - b->realm); + + if (b->cname->name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { + if (b->cname->name_string.len != 1) { + kdc_log(context, config, 0, + "AS-REQ malformed canon request from %s", from); + ret = KRB5_PARSE_MALFORMED; + goto out; + } + ret = krb5_parse_name(context, b->cname->name_string.val[0], + &client_princ); + if (ret) + goto out; + } else { + ret = _krb5_principalname2krb5_principal (context, + &client_princ, + *(b->cname), + b->realm); + if (ret) + goto out; + } ret = krb5_unparse_name(context, client_princ, &client_name); } if (ret) { @@ -962,7 +987,7 @@ _kdc_as_rep(krb5_context context, client_name, from, server_name); ret = _kdc_db_fetch(context, config, client_princ, - HDB_F_GET_CLIENT, NULL, &client); + HDB_F_GET_CLIENT | flags, NULL, &client); if(ret){ kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, krb5_get_err_text(context, ret)); @@ -996,7 +1021,7 @@ _kdc_as_rep(krb5_context context, if(req->padata){ int i; - PA_DATA *pa; + const PA_DATA *pa; int found_pa = 0; log_patypes(context, config, req->padata); @@ -1041,7 +1066,7 @@ _kdc_as_rep(krb5_context context, kdc_log(context, config, 0, "%s", e_text); pkp = NULL; - goto ts_enc; + goto out; } found_pa = 1; et.flags.pre_authent = 1; @@ -1169,6 +1194,8 @@ _kdc_as_rep(krb5_context context, (unsigned)abs(kdc_time - p.patimestamp), context->max_skew, client_name); +#if 1 + /* This code is from samba, needs testing */ /* * the following is needed to make windows clients * to retry using the timestamp in the error message @@ -1177,6 +1204,9 @@ _kdc_as_rep(krb5_context context, * is present... */ e_text = NULL; +#else + e_text = "Too large time skew"; +#endif goto out; } et.flags.pre_authent = 1; @@ -1227,6 +1257,12 @@ _kdc_as_rep(krb5_context context, pa->padata_type = KRB5_PADATA_PK_AS_REQ; pa->padata_value.length = 0; pa->padata_value.data = NULL; + + ret = realloc_method_data(&method_data); + pa = &method_data.val[method_data.len-1]; + pa->padata_type = KRB5_PADATA_PK_AS_REQ_WIN; + pa->padata_value.length = 0; + pa->padata_value.data = NULL; #endif /* @@ -1253,12 +1289,12 @@ _kdc_as_rep(krb5_context context, e_data.data = buf; e_data.length = len; e_text ="Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ", + ret = KRB5KDC_ERR_PREAUTH_REQUIRED; kdc_log(context, config, 0, "No preauth found, returning PREAUTH-REQUIRED -- %s", client_name); - goto out; } @@ -1283,45 +1319,57 @@ _kdc_as_rep(krb5_context context, if(ret) goto out; + /* + * Select a session enctype from the list of the crypto systems + * supported enctype, is supported by the client and is one of the + * enctype of the enctype of the krbtgt. + * + * The later is used as a hint what enctype all KDC are supporting + * to make sure a newer version of KDC wont generate a session + * enctype that and older version of a KDC in the same realm can't + * decrypt. + * + * But if the KDC admin is paranoid and doesn't want to have "no + * the best" enctypes on the krbtgt, lets save the best pick from + * the client list and hope that that will work for any other + * KDCs. + */ { const krb5_enctype *p; - int i, j, y; + krb5_enctype clientbest = ETYPE_NULL; + int i, j; p = krb5_kerberos_enctypes(context); sessionetype = ETYPE_NULL; for (i = 0; p[i] != ETYPE_NULL && sessionetype == ETYPE_NULL; i++) { - /* check it's valid */ if (krb5_enctype_valid(context, p[i]) != 0) continue; - /* check if the client supports it */ for (j = 0; j < b->etype.len && sessionetype == ETYPE_NULL; j++) { - if (p[i] == b->etype.val[j]) { - /* - * if the server (krbtgt) has explicit etypes, - * check if it also supports it - */ - if (server->entry.etypes) { - for (y = 0; y < server->entry.etypes->len; y++) { - if (p[i] == server->entry.etypes->val[y]) { - sessionetype = p[i]; - break; - } - } - } else { - sessionetype = p[i]; - break; - } - } + Key *dummy; + /* check with client */ + if (p[i] != b->etype.val[j]) + continue; + /* save best of union of { client, crypto system } */ + if (clientbest == ETYPE_NULL) + clientbest = p[i]; + /* check with krbtgt */ + ret = hdb_enctype2key(context, &server->entry, p[i], &dummy); + if (ret) + continue; + sessionetype = p[i]; } } - if (sessionetype == ETYPE_NULL) { - kdc_log(context, config, 0, + /* if krbtgt had no shared keys with client, pick clients best */ + if (clientbest != ETYPE_NULL && sessionetype == ETYPE_NULL) { + sessionetype = clientbest; + } else if (sessionetype == ETYPE_NULL) { + kdc_log(context, config, 0, "Client (%s) from %s has no common enctypes with KDC" - "to use for the session key", - client_name, from); + "to use for the session key", + client_name, from); goto out; } } @@ -1534,6 +1582,58 @@ _kdc_as_rep(krb5_context context, set_salt_padata (rep.padata, ckey->salt); + /* Add signing of alias referral */ + if (f.canonicalize) { + PA_ClientCanonicalized canon; + krb5_data data; + PA_DATA pa; + krb5_crypto crypto; + size_t len; + + memset(&canon, 0, sizeof(canon)); + + canon.names.requested_name = *b->cname; + canon.names.real_name = client->entry.principal->name; + + ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, + &canon.names, &len, ret); + if (ret) + goto out; + if (data.length != len) + krb5_abortx(context, "internal asn.1 error"); + + /* sign using "returned session key" */ + ret = krb5_crypto_init(context, &et.key, 0, &crypto); + if (ret) { + free(data.data); + goto out; + } + + ret = krb5_create_checksum(context, crypto, + KRB5_KU_CANONICALIZED_NAMES, 0, + data.data, data.length, + &canon.canon_checksum); + free(data.data); + krb5_crypto_destroy(context, crypto); + if (ret) + goto out; + + ASN1_MALLOC_ENCODE(PA_ClientCanonicalized, data.data, data.length, + &canon, &len, ret); + free_Checksum(&canon.canon_checksum); + if (ret) + goto out; + if (data.length != len) + krb5_abortx(context, "internal asn.1 error"); + + pa.padata_type = KRB5_PADATA_CLIENT_CANONICALIZED; + pa.padata_value = data; + ret = add_METHOD_DATA(rep.padata, &pa); + free(data.data); + if (ret) + goto out; + } + if (rep.padata->len == 0) { free(rep.padata); rep.padata = NULL; diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index a056839e5f..02cd92de2e 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: krb5tgs.c,v 1.25 2007/01/04 12:49:45 lha Exp $"); +RCSID("$Id: krb5tgs.c 21041 2007-06-10 06:21:12Z lha $"); /* * return the realm of a krbtgt-ticket or NULL @@ -656,7 +656,7 @@ tgs_make_reply(krb5_context context, KDC_REQ_BODY *b, krb5_const_principal tgt_name, const EncTicketPart *tgt, - const EncryptionKey *ekey, + const EncryptionKey *serverkey, const krb5_keyblock *sessionkey, krb5_kvno kvno, AuthorizationData *auth_data, @@ -883,7 +883,7 @@ tgs_make_reply(krb5_context context, ret = _kdc_encode_reply(context, config, &rep, &et, &ek, et.key.keytype, kvno, - ekey, 0, &tgt->key, e_text, reply); + serverkey, 0, &tgt->key, e_text, reply); out: free_TGS_REP(&rep); free_TransitedEncoding(&et.transited); @@ -1010,7 +1010,7 @@ static krb5_error_code tgs_parse_request(krb5_context context, krb5_kdc_configuration *config, KDC_REQ_BODY *b, - PA_DATA *tgs_req, + const PA_DATA *tgs_req, hdb_entry_ex **krbtgt, krb5_enctype *krbtgt_etype, krb5_ticket **ticket, @@ -1258,6 +1258,7 @@ tgs_build_reply(krb5_context context, krb5_keyblock sessionkey; krb5_kvno kvno; krb5_data rspac; + int cross_realm = 0; PrincipalName *s; Realm r; @@ -1421,6 +1422,8 @@ server_lookup: kdc_log(context, config, 1, "Client not found in database: %s: %s", cpn, krb5_get_err_text(context, ret)); + + cross_realm = 1; } /* @@ -1707,21 +1710,25 @@ server_lookup: /* check PAC if there is one */ { Key *tkey; + krb5_keyblock *tgtkey = NULL; - 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; + 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 = check_PAC(context, config, client_principal, - client, server, ekey, &tkey->key, + client, server, ekey, tgtkey, tgt, &rspac, &require_signedpath); if (ret) { kdc_log(context, config, 0, - "check_PAC check failed for %s (%s) from %s with %s", + "Verify PAC failed for %s (%s) from %s with %s", spn, cpn, from, krb5_get_err_text(context, ret)); goto out; } @@ -1804,7 +1811,7 @@ _kdc_tgs_rep(krb5_context context, AuthorizationData *auth_data = NULL; krb5_error_code ret; int i = 0; - PA_DATA *tgs_req = NULL; + const PA_DATA *tgs_req; hdb_entry_ex *krbtgt = NULL; krb5_ticket *ticket = NULL; diff --git a/source4/heimdal/kdc/kx509.c b/source4/heimdal/kdc/kx509.c index d817338f73..8414ecb4b2 100644 --- a/source4/heimdal/kdc/kx509.c +++ b/source4/heimdal/kdc/kx509.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,8 +33,10 @@ #include "kdc_locl.h" #include <hex.h> +#include <rfc2459_asn1.h> +#include <hx509.h> -RCSID("$Id: kx509.c,v 1.1 2006/12/28 21:03:53 lha Exp $"); +RCSID("$Id: kx509.c 19992 2007-01-20 09:06:18Z lha $"); /* * @@ -140,72 +142,146 @@ build_certificate(krb5_context context, krb5_principal principal, krb5_data *certificate) { - /* XXX write code here to generate certificates */ - FILE *in, *out; - krb5_error_code ret; - const char *program; - char *str, *strkey; - char tstr[64]; - pid_t pid; + hx509_context hxctx = NULL; + hx509_ca_tbs tbs = NULL; + hx509_env env = NULL; + hx509_cert cert = NULL; + hx509_cert signer = NULL; + int ret; + + if (krb5_principal_get_comp_string(context, principal, 1) != NULL) { + kdc_log(context, config, 0, "Principal is not a user"); + return EINVAL; + } - snprintf(tstr, sizeof(tstr), "%lu", (unsigned long)endtime); + ret = hx509_context_init(&hxctx); + if (ret) + goto out; - ret = base64_encode(key->data, key->length, &strkey); - if (ret < 0) { - krb5_set_error_string(context, "failed to base64 encode key"); - return ENOMEM; - } + ret = hx509_env_init(hxctx, &env); + if (ret) + goto out; - program = krb5_config_get_string(context, - NULL, - "kdc", - "kx509_cert_program", - NULL); - if (program == NULL) { - free(strkey); - krb5_set_error_string(context, "no certificate program configured"); - return ENOENT; - } + ret = hx509_env_add(hxctx, env, "principal-name", + krb5_principal_get_comp_string(context, principal, 0)); + if (ret) + goto out; - ret = krb5_unparse_name(context, principal, &str); - if (ret) { - free(strkey); - return ret; + { + hx509_certs certs; + hx509_query *q; + + ret = hx509_certs_init(hxctx, config->kx509_ca, 0, + NULL, &certs); + if (ret) { + kdc_log(context, config, 0, "Failed to load CA %s", + config->kx509_ca); + goto out; + } + ret = hx509_query_alloc(hxctx, &q); + if (ret) { + hx509_certs_free(&certs); + goto out; + } + + hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); + hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN); + + ret = hx509_certs_find(hxctx, certs, q, &signer); + hx509_query_free(hxctx, q); + hx509_certs_free(&certs); + if (ret) { + kdc_log(context, config, 0, "Failed to find a CA in %s", + config->kx509_ca); + goto out; + } } - pid = pipe_execv(&in, &out, NULL, program, str, tstr, NULL); - free(str); - if (pid <= 0) { - free(strkey); - krb5_set_error_string(context, - "Failed to run the cert program %s", - program); - return ret; + ret = hx509_ca_tbs_init(hxctx, &tbs); + if (ret) + goto out; + + { + SubjectPublicKeyInfo spki; + heim_any any; + + memset(&spki, 0, sizeof(spki)); + + spki.subjectPublicKey.data = key->data; + spki.subjectPublicKey.length = key->length * 8; + + ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(), + &spki.algorithm.algorithm); + + any.data = "\x05\x00"; + any.length = 2; + spki.algorithm.parameters = &any; + + ret = hx509_ca_tbs_set_spki(hxctx, tbs, &spki); + der_free_oid(&spki.algorithm.algorithm); + if (ret) + goto out; } - fprintf(in, "%s\n", strkey); - fclose(in); - free(strkey); { - unsigned buf[1024 * 10]; - size_t len; + hx509_certs certs; + hx509_cert template; - len = fread(buf, 1, sizeof(buf), out); - fclose(out); - if(len == 0) { - krb5_set_error_string(context, - "Certificate program returned no data"); - return KRB5KDC_ERR_PREAUTH_FAILED; + ret = hx509_certs_init(hxctx, config->kx509_template, 0, + NULL, &certs); + if (ret) { + kdc_log(context, config, 0, "Failed to load template %s", + config->kx509_template); + goto out; } - ret = krb5_data_copy(certificate, buf, len); + ret = hx509_get_one_cert(hxctx, certs, &template); + hx509_certs_free(&certs); if (ret) { - krb5_set_error_string(context, "Failed To copy certificate"); - return ret; + kdc_log(context, config, 0, "Failed to find template in %s", + config->kx509_template); + goto out; } + ret = hx509_ca_tbs_set_template(hxctx, tbs, + HX509_CA_TEMPLATE_SUBJECT| + HX509_CA_TEMPLATE_KU| + HX509_CA_TEMPLATE_EKU, + template); + hx509_cert_free(template); + if (ret) + goto out; } - kill(pid, SIGKILL); - waitpid(pid, NULL, 0); + + hx509_ca_tbs_set_notAfter(hxctx, tbs, endtime); + + hx509_ca_tbs_subject_expand(hxctx, tbs, env); + hx509_env_free(&env); + + ret = hx509_ca_sign(hxctx, tbs, signer, &cert); + hx509_cert_free(signer); + if (ret) + goto out; + + hx509_ca_tbs_free(&tbs); + + ret = hx509_cert_binary(hxctx, cert, certificate); + hx509_cert_free(cert); + if (ret) + goto out; + + hx509_context_free(&hxctx); + return 0; +out: + if (env) + hx509_env_free(&env); + if (tbs) + hx509_ca_tbs_free(&tbs); + if (signer) + hx509_cert_free(signer); + if (hxctx) + hx509_context_free(&hxctx); + krb5_set_error_string(context, "cert creation failed"); + return ret; } /* @@ -299,6 +375,20 @@ _kdc_do_kx509(krb5_context context, if (ret) goto out; + /* Verify that the key is encoded RSA key */ + { + RSAPublicKey key; + size_t size; + + ret = decode_RSAPublicKey(req->pk_key.data, req->pk_key.length, + &key, &size); + if (ret) + goto out; + free_RSAPublicKey(&key); + if (size != req->pk_key.length) + ; + } + ALLOC(rep.certificate); if (rep.certificate == NULL) goto out; diff --git a/source4/heimdal/kdc/log.c b/source4/heimdal/kdc/log.c index c316b0c5f8..977b1c9476 100644 --- a/source4/heimdal/kdc/log.c +++ b/source4/heimdal/kdc/log.c @@ -32,7 +32,7 @@ */ #include "kdc_locl.h" -RCSID("$Id: log.c,v 1.16 2005/06/30 01:52:48 lha Exp $"); +RCSID("$Id: log.c 15532 2005-06-30 01:54:49Z lha $"); void kdc_openlog(krb5_context context, diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index b511e1a7a8..ebf2873599 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,v 1.32 2006/08/28 14:41:49 lha Exp $"); +RCSID("$Id: misc.c 17951 2006-08-28 14:41:49Z lha $"); struct timeval _kdc_now; diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index 418a38d030..bf62f879db 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,v 1.86 2007/01/04 12:54:09 lha Exp $"); +RCSID("$Id: pkinit.c 21039 2007-06-10 06:20:31Z lha $"); #ifdef PKINIT @@ -97,7 +97,7 @@ static struct { static krb5_error_code pk_check_pkauthenticator_win2k(krb5_context context, PKAuthenticator_Win2k *a, - KDC_REQ *req) + const KDC_REQ *req) { krb5_timestamp now; @@ -114,7 +114,7 @@ pk_check_pkauthenticator_win2k(krb5_context context, static krb5_error_code pk_check_pkauthenticator(krb5_context context, PKAuthenticator *a, - KDC_REQ *req) + const KDC_REQ *req) { u_char *buf = NULL; size_t buf_size; @@ -365,8 +365,8 @@ get_dh_param(krb5_context context, krb5_error_code _kdc_pk_rd_padata(krb5_context context, krb5_kdc_configuration *config, - KDC_REQ *req, - PA_DATA *pa, + const KDC_REQ *req, + const PA_DATA *pa, pk_client_params **ret_params) { pk_client_params *client_params; @@ -375,7 +375,6 @@ _kdc_pk_rd_padata(krb5_context context, krb5_data eContent = { 0, NULL }; krb5_data signed_content = { 0, NULL }; const char *type = "unknown type"; - const heim_oid *pa_contentType; int have_data = 0; *ret_params = NULL; @@ -385,6 +384,8 @@ _kdc_pk_rd_padata(krb5_context context, return 0; } + hx509_verify_set_time(kdc_identity->verify_ctx, _kdc_now.tv_sec); + client_params = calloc(1, sizeof(*client_params)); if (client_params == NULL) { krb5_clear_error_string(context); @@ -396,7 +397,6 @@ _kdc_pk_rd_padata(krb5_context context, PA_PK_AS_REQ_Win2k r; type = "PK-INIT-Win2k"; - pa_contentType = oid_id_pkcs7_data(); ret = decode_PA_PK_AS_REQ_Win2k(pa->padata_value.data, pa->padata_value.length, @@ -422,7 +422,6 @@ _kdc_pk_rd_padata(krb5_context context, PA_PK_AS_REQ r; type = "PK-INIT-IETF"; - pa_contentType = oid_id_pkauthdata(); ret = decode_PA_PK_AS_REQ(pa->padata_value.data, pa->padata_value.length, @@ -467,7 +466,7 @@ _kdc_pk_rd_padata(krb5_context context, edi->val[i].issuerAndSerialNumber->length, &iasn, &size); - if (ret || size != 0) { + if (ret) { hx509_query_free(kdc_identity->hx509ctx, q); continue; } @@ -527,6 +526,7 @@ _kdc_pk_rd_padata(krb5_context context, kdc_identity->verify_ctx, signed_content.data, signed_content.length, + NULL, kdc_identity->certpool, &eContentType, &eContent, @@ -547,7 +547,9 @@ _kdc_pk_rd_padata(krb5_context context, } /* Signature is correct, now verify the signed message */ - if (der_heim_oid_cmp(&eContentType, pa_contentType)) { + if (der_heim_oid_cmp(&eContentType, oid_id_pkcs7_data()) != 0 && + der_heim_oid_cmp(&eContentType, oid_id_pkauthdata()) != 0) + { krb5_set_error_string(context, "got wrong oid for pkauthdata"); ret = KRB5_BADMSGTYPE; goto out; @@ -639,6 +641,8 @@ _kdc_pk_rd_padata(krb5_context context, kdc_log(context, config, 0, "PK-INIT request of type %s", type); out: + if (ret) + krb5_warn(context, ret, "PKINIT"); if (signed_content.data) free(signed_content.data); @@ -678,18 +682,41 @@ pk_mk_pa_reply_enckey(krb5_context context, krb5_keyblock *reply_key, ContentInfo *content_info) { + const heim_oid *envelopedAlg = NULL, *sdAlg = NULL; krb5_error_code ret; krb5_data buf, signed_data; size_t size; + int do_win2k = 0; krb5_data_zero(&buf); krb5_data_zero(&signed_data); + /* + * If the message client is a win2k-type but it send pa data + * 09-binding it expects a IETF (checksum) reply so there can be + * no replay attacks. + */ + switch (client_params->type) { case PKINIT_COMPAT_WIN2K: { + int i = 0; + if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL) + do_win2k = 1; + break; + } + case PKINIT_COMPAT_27: + break; + default: + krb5_abortx(context, "internal pkinit error"); + } + + if (do_win2k) { ReplyKeyPack_Win2k kp; memset(&kp, 0, sizeof(kp)); + envelopedAlg = oid_id_rsadsi_des_ede3_cbc(); + sdAlg = oid_id_pkcs7_data(); + ret = copy_EncryptionKey(reply_key, &kp.replyKey); if (ret) { krb5_clear_error_string(context); @@ -701,13 +728,13 @@ pk_mk_pa_reply_enckey(krb5_context context, buf.data, buf.length, &kp, &size,ret); free_ReplyKeyPack_Win2k(&kp); - break; - } - case PKINIT_COMPAT_27: { + } else { krb5_crypto ascrypto; ReplyKeyPack kp; memset(&kp, 0, sizeof(kp)); + sdAlg = oid_id_pkrkeydata(); + ret = copy_EncryptionKey(reply_key, &kp.replyKey); if (ret) { krb5_clear_error_string(context); @@ -735,10 +762,6 @@ pk_mk_pa_reply_enckey(krb5_context context, } ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret); free_ReplyKeyPack(&kp); - break; - } - default: - krb5_abortx(context, "internal pkinit error"); } if (ret) { krb5_set_error_string(context, "ASN.1 encoding of ReplyKeyPack " @@ -768,7 +791,8 @@ pk_mk_pa_reply_enckey(krb5_context context, goto out; ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx, - oid_id_pkrkeydata(), + 0, + sdAlg, buf.data, buf.length, NULL, @@ -784,9 +808,21 @@ pk_mk_pa_reply_enckey(krb5_context context, if (ret) goto out; + if (client_params->type == PKINIT_COMPAT_WIN2K) { + ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), + &signed_data, + &buf); + if (ret) + goto out; + krb5_data_free(&signed_data); + signed_data = buf; + } + ret = hx509_cms_envelope_1(kdc_identity->hx509ctx, + 0, client_params->cert, - signed_data.data, signed_data.length, NULL, + signed_data.data, signed_data.length, + envelopedAlg, oid_id_pkcs7_signedData(), &buf); if (ret) goto out; @@ -881,6 +917,7 @@ pk_mk_pa_reply_dh(krb5_context context, goto out; ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx, + 0, oid_id_pkdhkeydata(), buf.data, buf.length, @@ -1125,6 +1162,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, krb5_data_free(&ocsp.data); ocsp.expire = 0; + ocsp.next_update = kdc_time + 60 * 5; fd = open(config->pkinit_kdc_ocsp_file, O_RDONLY); if (fd < 0) { @@ -1168,11 +1206,13 @@ _kdc_pk_mk_pa_reply(krb5_context context, "PK-INIT failed to verify ocsp data %d", ret); krb5_data_free(&ocsp.data); ocsp.expire = 0; - } else if (ocsp.expire > 180) + } else if (ocsp.expire > 180) { ocsp.expire -= 180; /* refetch the ocsp before it expire */ - + ocsp.next_update = ocsp.expire; + } else { + ocsp.next_update = kdc_time; + } out_ocsp: - ocsp.next_update = kdc_time + 3600; ret = 0; } @@ -1199,10 +1239,10 @@ out: } static int -pk_principal_from_X509(krb5_context context, - krb5_kdc_configuration *config, - hx509_cert client_cert, - krb5_const_principal match) +match_rfc_san(krb5_context context, + krb5_kdc_configuration *config, + hx509_cert client_cert, + krb5_const_principal match) { hx509_octet_string_list list; int ret, i, found = 0; @@ -1254,6 +1294,68 @@ out: return 0; } +static int +match_ms_upn_san(krb5_context context, + krb5_kdc_configuration *config, + hx509_cert client_cert, + krb5_const_principal match) +{ + hx509_octet_string_list list; + krb5_principal principal = NULL; + int ret, found = 0; + MS_UPN_SAN upn; + size_t size; + + memset(&list, 0 , sizeof(list)); + + ret = hx509_cert_find_subjectAltName_otherName(client_cert, + oid_id_pkinit_ms_san(), + &list); + if (ret) + goto out; + + if (list.len != 1) { + kdc_log(context, config, 0, + "More then one PK-INIT MS UPN SAN"); + goto out; + } + + ret = decode_MS_UPN_SAN(list.val[0].data, list.val[0].length, &upn, &size); + if (ret) { + kdc_log(context, config, 0, "Decode of MS-UPN-SAN failed"); + goto out; + } + + kdc_log(context, config, 0, "found MS UPN SAN: %s", upn); + + ret = krb5_parse_name(context, upn, &principal); + free_MS_UPN_SAN(&upn); + if (ret) { + kdc_log(context, config, 0, "Failed to parse principal in MS UPN SAN"); + goto out; + } + + /* + * This is very wrong, but will do for now, should really and a + * plugin to the windc layer to very this ACL. + */ + strupr(principal->realm); + + if (krb5_principal_compare(context, principal, match) == TRUE) + found = 1; + +out: + if (principal) + krb5_free_principal(context, principal); + hx509_free_octet_string_list(&list); + if (ret) + return ret; + + if (!found) + return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; + + return 0; +} krb5_error_code _kdc_pk_check_client(krb5_context context, @@ -1283,14 +1385,22 @@ _kdc_pk_check_client(krb5_context context, *subject_name); if (config->enable_pkinit_princ_in_cert) { - ret = pk_principal_from_X509(context, config, - client_params->cert, - client->entry.principal); + ret = match_rfc_san(context, config, + client_params->cert, + client->entry.principal); if (ret == 0) { kdc_log(context, config, 5, "Found matching PK-INIT SAN in certificate"); return 0; } + ret = match_ms_upn_san(context, config, + client_params->cert, + client->entry.principal); + if (ret == 0) { + kdc_log(context, config, 5, + "Found matching MS UPN SAN in certificate"); + return 0; + } } ret = hdb_entry_get_pkinit_acl(&client->entry, &acl); @@ -1330,10 +1440,17 @@ _kdc_pk_check_client(krb5_context context, return 0; } + krb5_set_error_string(context, + "PKINIT no matching principals for %s", + *subject_name); + + kdc_log(context, config, 5, + "PKINIT no matching principals for %s", + *subject_name); + free(*subject_name); *subject_name = NULL; - krb5_set_error_string(context, "PKINIT no matching principals"); return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; } @@ -1396,7 +1513,56 @@ _kdc_add_inital_verified_cas(krb5_context context, return ret; } +/* + * + */ +static void +load_mappings(krb5_context context, const char *fn) +{ + krb5_error_code ret; + char buf[1024]; + unsigned long lineno = 0; + FILE *f; + + f = fopen(fn, "r"); + if (f == NULL) + return; + + while (fgets(buf, sizeof(buf), f) != NULL) { + char *subject_name, *p; + + buf[strcspn(buf, "\n")] = '\0'; + lineno++; + + p = buf + strspn(buf, " \t"); + + if (*p == '#' || *p == '\0') + continue; + + subject_name = strchr(p, ':'); + if (subject_name == NULL) { + krb5_warnx(context, "pkinit mapping file line %lu " + "missing \":\" :%s", + lineno, buf); + continue; + } + *subject_name++ = '\0'; + + ret = add_principal_mapping(context, p, subject_name); + if (ret) { + krb5_warn(context, ret, "failed to add line %lu \":\" :%s\n", + lineno, buf); + continue; + } + } + + fclose(f); +} + +/* + * + */ krb5_error_code _kdc_pk_initialize(krb5_context context, @@ -1408,9 +1574,6 @@ _kdc_pk_initialize(krb5_context context, { const char *file; krb5_error_code ret; - char buf[1024]; - unsigned long lineno = 0; - FILE *f; file = krb5_config_get_string(context, NULL, "libdefaults", "moduli", NULL); @@ -1481,41 +1644,8 @@ _kdc_pk_initialize(krb5_context context, "kdc", "pkinit_mappings_file", NULL); - f = fopen(file, "r"); - if (f == NULL) { - krb5_warnx(context, "PKINIT: failed to load mappings file %s", file); - return 0; - } - - while (fgets(buf, sizeof(buf), f) != NULL) { - char *subject_name, *p; - - buf[strcspn(buf, "\n")] = '\0'; - lineno++; - - p = buf + strspn(buf, " \t"); - - if (*p == '#' || *p == '\0') - continue; - subject_name = strchr(p, ':'); - if (subject_name == NULL) { - krb5_warnx(context, "pkinit mapping file line %lu " - "missing \":\" :%s", - lineno, buf); - continue; - } - *subject_name++ = '\0'; - - ret = add_principal_mapping(context, p, subject_name); - if (ret) { - krb5_warn(context, ret, "failed to add line %lu \":\" :%s\n", - lineno, buf); - continue; - } - } - - fclose(f); + load_mappings(context, file); return 0; } diff --git a/source4/heimdal/kdc/process.c b/source4/heimdal/kdc/process.c index a64efaa05d..1d0a01a215 100644 --- a/source4/heimdal/kdc/process.c +++ b/source4/heimdal/kdc/process.c @@ -34,7 +34,20 @@ #include "kdc_locl.h" -RCSID("$Id: process.c,v 1.7 2006/12/28 21:09:35 lha Exp $"); +RCSID("$Id: process.c 20959 2007-06-07 04:46:06Z lha $"); + +/* + * + */ + +void +krb5_kdc_update_time(struct timeval *tv) +{ + if (tv == NULL) + gettimeofday(&_kdc_now, NULL); + else + _kdc_now = *tv; +} /* * handle the request in `buf, len', from `addr' (or `from' as a string), @@ -59,7 +72,6 @@ krb5_kdc_process_request(krb5_context context, krb5_error_code ret; size_t i; - gettimeofday(&_kdc_now, NULL); if(decode_AS_REQ(buf, len, &req, &i) == 0){ krb5_data req_buffer; @@ -121,7 +133,6 @@ krb5_kdc_process_krb5_request(krb5_context context, krb5_error_code ret; size_t i; - gettimeofday(&_kdc_now, NULL); if(decode_AS_REQ(buf, len, &req, &i) == 0){ krb5_data req_buffer; @@ -139,3 +150,70 @@ krb5_kdc_process_krb5_request(krb5_context context, } return -1; } + +/* + * + */ + +int +krb5_kdc_save_request(krb5_context context, + const char *fn, + const unsigned char *buf, + size_t len, + const krb5_data *reply, + const struct sockaddr *sa) +{ + krb5_storage *sp; + krb5_address a; + int fd, ret; + uint32_t t; + krb5_data d; + + memset(&a, 0, sizeof(a)); + + d.data = rk_UNCONST(buf); + d.length = len; + t = _kdc_now.tv_sec; + + fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600); + if (fd < 0) { + krb5_set_error_string(context, "Failed to open: %s", fn); + return errno; + } + + sp = krb5_storage_from_fd(fd); + close(fd); + if (sp == NULL) { + krb5_set_error_string(context, "Storage failed to open fd"); + return ENOMEM; + } + + ret = krb5_sockaddr2address(context, sa, &a); + if (ret) + goto out; + + krb5_store_uint32(sp, 1); + krb5_store_uint32(sp, t); + krb5_store_address(sp, a); + krb5_store_data(sp, d); + { + Der_class cl; + Der_type ty; + unsigned int tag; + ret = der_get_tag (reply->data, reply->length, + &cl, &ty, &tag, NULL); + if (ret) { + krb5_store_uint32(sp, 0xffffffff); + krb5_store_uint32(sp, 0xffffffff); + } else { + krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0)); + krb5_store_uint32(sp, tag); + } + } + + krb5_free_address(context, &a); +out: + krb5_storage_free(sp); + + return 0; +} diff --git a/source4/heimdal/kdc/rx.h b/source4/heimdal/kdc/rx.h index 370e33732f..18806d79da 100644 --- a/source4/heimdal/kdc/rx.h +++ b/source4/heimdal/kdc/rx.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: rx.h,v 1.5 2006/05/05 10:51:10 lha Exp $ */ +/* $Id: rx.h 17447 2006-05-05 10:52:01Z lha $ */ #ifndef __RX_H__ #define __RX_H__ diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c index 41e4ad1bbc..395ab73432 100644 --- a/source4/heimdal/kdc/windc.c +++ b/source4/heimdal/kdc/windc.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: windc.c,v 1.3 2007/01/04 11:10:06 lha Exp $"); +RCSID("$Id: windc.c 20559 2007-04-24 16:00:07Z lha $"); static krb5plugin_windc_ftable *windcft; static void *windcctx; @@ -43,7 +43,7 @@ static void *windcctx; */ krb5_error_code -_kdc_windc_init(krb5_context context) +krb5_kdc_windc_init(krb5_context context) { struct krb5_plugin *list = NULL, *e; krb5_error_code ret; @@ -91,10 +91,11 @@ _kdc_pac_verify(krb5_context context, krb5_pac *pac) { if (windcft == NULL) { - krb5_set_error_string(context, "Can't verify WINDC, no function"); + krb5_set_error_string(context, "Can't verify PAC, no function"); return EINVAL; } - return (windcft->pac_verify)(windcctx, context, client_principal, client, server, pac); + return (windcft->pac_verify)(windcctx, context, + client_principal, client, server, pac); } krb5_error_code diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h index a3b7534480..ec480cf950 100644 --- a/source4/heimdal/kdc/windc_plugin.h +++ b/source4/heimdal/kdc/windc_plugin.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: windc_plugin.h,v 1.2 2007/01/04 11:13:51 lha Exp $ */ +/* $Id: windc_plugin.h 19798 2007-01-10 15:24:51Z lha $ */ #ifndef HEIMDAL_KRB5_PAC_PLUGIN_H #define HEIMDAL_KRB5_PAC_PLUGIN_H 1 @@ -58,7 +58,9 @@ typedef krb5_error_code typedef krb5_error_code (*krb5plugin_windc_pac_verify)(void *, krb5_context, const krb5_principal, - struct hdb_entry_ex *, struct hdb_entry_ex *, krb5_pac *); + struct hdb_entry_ex *, + struct hdb_entry_ex *, + krb5_pac *); typedef krb5_error_code (*krb5plugin_windc_client_access)( diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index 667e0963b0..29a9bdd5c7 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -32,11 +32,9 @@ */ #include "kuser_locl.h" -RCSID("$Id: kinit.c,v 1.141 2006/12/12 16:35:41 lha Exp $"); +RCSID("$Id: kinit.c 20517 2007-04-22 10:42:26Z lha $"); -#ifndef KRB4 #include "krb5-v4compat.h" -#endif struct krb5_pk_identity; struct krb5_pk_cert; @@ -46,6 +44,7 @@ struct krb5_dh_moduli; struct krb5_plugin; enum plugin_type; #include "krb5-private.h" +#include "heimntlm.h" int forwardable_flag = -1; int proxiable_flag = -1; @@ -74,6 +73,8 @@ char *password_file = NULL; char *pk_user_id = NULL; char *pk_x509_anchors = NULL; int pk_use_enckey = 0; +static int canonicalize_flag = 0; +static char *ntlm_domain; static char *krb4_cc_name; @@ -153,18 +154,21 @@ static struct getargs args[] = { { "password-file", 0, arg_string, &password_file, "read the password from a file" }, + { "canonicalize",0, arg_flag, &canonicalize_flag, + "canonicalize client principal" }, #ifdef PKINIT - { "pk-user", 'C', arg_string, &pk_user_id, - "principal's public/private/certificate identifier", - "id" }, - - { "x509-anchors", 'D', arg_string, &pk_x509_anchors, - "directory with CA certificates", "directory" }, + { "pk-user", 'C', arg_string, &pk_user_id, + "principal's public/private/certificate identifier", "id" }, - { "pk-use-enckey", 0, arg_flag, &pk_use_enckey, - "Use RSA encrypted reply (instead of DH)" }, + { "x509-anchors", 'D', arg_string, &pk_x509_anchors, + "directory with CA certificates", "directory" }, + { "pk-use-enckey", 0, arg_flag, &pk_use_enckey, + "Use RSA encrypted reply (instead of DH)" }, #endif + { "ntlm-domain", 0, arg_string, &ntlm_domain, + "NTLM domain", "domain" }, + { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; @@ -179,130 +183,6 @@ usage (int ret) exit (ret); } -#ifdef KRB4 -/* for when the KDC tells us it's a v4 one, we try to talk that */ - -static int -key_to_key(const char *user, - char *instance, - const char *realm, - const void *arg, - des_cblock *key) -{ - memcpy(key, arg, sizeof(des_cblock)); - return 0; -} - -static int -do_v4_fallback (krb5_context context, - const krb5_principal principal, - int lifetime, - int use_srvtab, const char *srvtab_str, - const char *passwd) -{ - int ret; - krb_principal princ; - des_cblock key; - krb5_error_code kret; - - if (lifetime == 0) - lifetime = DEFAULT_TKT_LIFE; - else - lifetime = krb_time_to_life (0, lifetime); - - kret = krb5_524_conv_principal (context, principal, - princ.name, - princ.instance, - princ.realm); - if (kret) { - krb5_warn (context, kret, "krb5_524_conv_principal"); - return 1; - } - - if (use_srvtab || srvtab_str) { - if (srvtab_str == NULL) - srvtab_str = KEYFILE; - - ret = read_service_key (princ.name, princ.instance, princ.realm, - 0, srvtab_str, (char *)&key); - if (ret) { - warnx ("read_service_key %s: %s", srvtab_str, - krb_get_err_text (ret)); - return 1; - } - ret = krb_get_in_tkt (princ.name, princ.instance, princ.realm, - KRB_TICKET_GRANTING_TICKET, princ.realm, - lifetime, key_to_key, NULL, key); - } else { - ret = krb_get_pw_in_tkt(princ.name, princ.instance, princ.realm, - KRB_TICKET_GRANTING_TICKET, princ.realm, - lifetime, passwd); - } - memset (key, 0, sizeof(key)); - if (ret) { - warnx ("%s", krb_get_err_text(ret)); - return 1; - } - if (do_afslog && k_hasafs()) { - if ((ret = krb_afslog(NULL, NULL)) != 0 && ret != KDC_PR_UNKNOWN) { - if(ret > 0) - warnx ("%s", krb_get_err_text(ret)); - else - warnx ("failed to store AFS token"); - } - } - return 0; -} - - -/* - * the special version of get_default_principal that takes v4 into account - */ - -static krb5_error_code -kinit_get_default_principal (krb5_context context, - krb5_principal *princ) -{ - krb5_error_code ret; - krb5_ccache id; - krb_principal v4_princ; - int kret; - - ret = krb5_cc_default (context, &id); - if (ret == 0) { - ret = krb5_cc_get_principal (context, id, princ); - krb5_cc_close (context, id); - if (ret == 0) - return 0; - } - - kret = krb_get_tf_fullname (tkt_string(), - v4_princ.name, - v4_princ.instance, - v4_princ.realm); - if (kret == KSUCCESS) { - ret = krb5_425_conv_principal (context, - v4_princ.name, - v4_princ.instance, - v4_princ.realm, - princ); - if (ret == 0) - return 0; - } - return krb5_get_default_principal (context, princ); -} - -#else /* !KRB4 */ - -static krb5_error_code -kinit_get_default_principal (krb5_context context, - krb5_principal *princ) -{ - return krb5_get_default_principal (context, princ); -} - -#endif /* !KRB4 */ - static krb5_error_code get_server(krb5_context context, krb5_principal client, @@ -457,6 +337,39 @@ out: } static krb5_error_code +store_ntlmkey(krb5_context context, krb5_ccache id, + const char *domain, krb5_const_principal client, + struct ntlm_buf *buf) +{ + krb5_error_code ret; + krb5_creds cred; + + memset(&cred, 0, sizeof(cred)); + + ret = krb5_make_principal(context, &cred.server, + krb5_principal_get_realm(context, client), + "@ntlm-key", domain, NULL); + if (ret) + goto out; + ret = krb5_copy_principal(context, client, &cred.client); + if (ret) + goto out; + + cred.times.authtime = time(NULL); + cred.times.endtime = time(NULL) + 3600 * 24 * 30; /* XXX */ + cred.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5; + ret = krb5_data_copy(&cred.session.keyvalue, buf->data, buf->length); + if (ret) + goto out; + + ret = krb5_cc_store_cred(context, id, &cred); + +out: + krb5_free_cred_contents (context, &cred); + return 0; +} + +static krb5_error_code get_new_tickets(krb5_context context, krb5_principal principal, krb5_ccache ccache, @@ -471,7 +384,9 @@ get_new_tickets(krb5_context context, krb5_deltat renew = 0; char *renewstr = NULL; krb5_enctype *enctype = NULL; + struct ntlm_buf ntlmkey; + memset(&ntlmkey, 0, sizeof(ntlmkey)); passwd[0] = '\0'; if (password_file) { @@ -500,8 +415,8 @@ get_new_tickets(krb5_context context, if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); - krb5_get_init_creds_opt_set_default_flags(context, "kinit", - /* XXX */principal->realm, opt); + krb5_get_init_creds_opt_set_default_flags(context, "kinit", + krb5_principal_get_realm(context, principal), opt); if(forwardable_flag != -1) krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag); @@ -512,6 +427,8 @@ get_new_tickets(krb5_context context, if (pac_flag != -1) krb5_get_init_creds_opt_set_pac_request(context, opt, pac_flag ? TRUE : FALSE); + if (canonicalize_flag) + krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); if (pk_user_id) { ret = krb5_get_init_creds_opt_set_pkinit(context, opt, principal, @@ -629,19 +546,8 @@ get_new_tickets(krb5_context context, opt); } krb5_get_init_creds_opt_free(context, opt); -#ifdef KRB4 - if (ret == KRB5KRB_AP_ERR_V4_REPLY || ret == KRB5_KDC_UNREACH) { - int exit_val; - - exit_val = do_v4_fallback (context, principal, ticket_life, - use_keytab, keytab_str, passwd); - get_v4_tgt = 0; - do_afslog = 0; - memset(passwd, 0, sizeof(passwd)); - if (exit_val == 0 || ret == KRB5KRB_AP_ERR_V4_REPLY) - return exit_val; - } -#endif + if (ntlm_domain && passwd[0]) + heim_ntlm_nt_key(passwd, &ntlmkey); memset(passwd, 0, sizeof(passwd)); switch(ret){ @@ -651,8 +557,12 @@ get_new_tickets(krb5_context context, exit(1); case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_MODIFIED: + case KRB5KDC_ERR_PREAUTH_FAILED: krb5_errx(context, 1, "Password incorrect"); break; + case KRB5KRB_AP_ERR_V4_REPLY: + krb5_errx(context, 1, "Looks like a Kerberos 4 reply"); + break; default: krb5_err(context, 1, ret, "krb5_get_init_creds"); } @@ -685,6 +595,9 @@ get_new_tickets(krb5_context context, krb5_free_cred_contents (context, &cred); + if (ntlm_domain && ntlmkey.data) + store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey); + if (enctype) free(enctype); @@ -774,6 +687,7 @@ main (int argc, char **argv) krb5_principal principal; int optidx = 0; krb5_deltat ticket_life = 0; + int parseflags = 0; setprogname (argv[0]); @@ -797,12 +711,15 @@ main (int argc, char **argv) argc -= optidx; argv += optidx; + if (canonicalize_flag) + parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE; + if (argv[0]) { - ret = krb5_parse_name (context, argv[0], &principal); + ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal); if (ret) krb5_err (context, 1, ret, "krb5_parse_name"); } else { - ret = kinit_get_default_principal (context, &principal); + ret = krb5_get_default_principal (context, &principal); if (ret) krb5_err (context, 1, ret, "krb5_get_default_principal"); } diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h index 06403cbe67..36ea01a9a5 100644 --- a/source4/heimdal/kuser/kuser_locl.h +++ b/source4/heimdal/kuser/kuser_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: kuser_locl.h,v 1.13 2003/01/21 14:13:51 nectar Exp $ */ +/* $Id: kuser_locl.h 20458 2007-04-19 20:41:27Z lha $ */ #ifndef __KUSER_LOCL_H__ #define __KUSER_LOCL_H__ @@ -75,9 +75,6 @@ #include <err.h> #include <krb5.h> -#ifdef KRB4 -#include <krb.h> -#endif #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include <sys/ioctl.h> #endif diff --git a/source4/heimdal/lib/asn1/CMS.asn1 b/source4/heimdal/lib/asn1/CMS.asn1 index ce43c2cd02..685f0b1898 100644 --- a/source4/heimdal/lib/asn1/CMS.asn1 +++ b/source4/heimdal/lib/asn1/CMS.asn1 @@ -1,5 +1,5 @@ -- From RFC 3369 -- --- $Id: CMS.asn1,v 1.5 2006/09/07 12:20:42 lha Exp $ -- +-- $Id: CMS.asn1 18054 2006-09-07 12:20:42Z lha $ -- CMS DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/asn1/asn1-common.h b/source4/heimdal/lib/asn1/asn1-common.h index 5f09cd6794..15c4a09cd0 100644 --- a/source4/heimdal/lib/asn1/asn1-common.h +++ b/source4/heimdal/lib/asn1/asn1-common.h @@ -1,4 +1,4 @@ -/* $Id: asn1-common.h,v 1.7 2006/12/28 17:14:10 lha Exp $ */ +/* $Id: asn1-common.h 19539 2006-12-28 17:15:05Z lha $ */ #include <stddef.h> #include <time.h> diff --git a/source4/heimdal/lib/asn1/asn1_err.et b/source4/heimdal/lib/asn1/asn1_err.et index 938b8eb988..67af1a44fc 100644 --- a/source4/heimdal/lib/asn1/asn1_err.et +++ b/source4/heimdal/lib/asn1/asn1_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: asn1_err.et,v 1.6 2006/10/24 14:11:20 lha Exp $" +id "$Id: asn1_err.et 20010 2007-01-20 21:52:27Z lha $" error_table asn1 prefix ASN1 @@ -18,4 +18,5 @@ error_code BAD_LENGTH, "ASN.1 length doesn't match expected value" error_code BAD_FORMAT, "ASN.1 badly-formatted encoding" error_code PARSE_ERROR, "ASN.1 parse error" error_code EXTRA_DATA, "ASN.1 extra data past end of end structure" +error_code BAD_CHARACTER, "ASN.1 invalid character in string" end diff --git a/source4/heimdal/lib/asn1/asn1_gen.c b/source4/heimdal/lib/asn1/asn1_gen.c index 5dc0ba2e2d..65b382e6da 100644 --- a/source4/heimdal/lib/asn1/asn1_gen.c +++ b/source4/heimdal/lib/asn1/asn1_gen.c @@ -40,7 +40,7 @@ #include <hex.h> #include <err.h> -RCSID("$Id: asn1_gen.c,v 1.4 2006/01/30 15:06:03 lha Exp $"); +RCSID("$Id: asn1_gen.c 16666 2006-01-30 15:06:03Z lha $"); static int doit(const char *fn) diff --git a/source4/heimdal/lib/asn1/asn1_queue.h b/source4/heimdal/lib/asn1/asn1_queue.h index 2874b35f6a..3659b3859d 100644 --- a/source4/heimdal/lib/asn1/asn1_queue.h +++ b/source4/heimdal/lib/asn1/asn1_queue.h @@ -1,5 +1,5 @@ /* $NetBSD: queue.h,v 1.38 2004/04/18 14:12:05 lukem Exp $ */ -/* $Id: asn1_queue.h,v 1.2 2005/07/12 06:27:15 lha Exp $ */ +/* $Id: asn1_queue.h 15617 2005-07-12 06:27:42Z lha $ */ /* * Copyright (c) 1991, 1993 diff --git a/source4/heimdal/lib/asn1/canthandle.asn1 b/source4/heimdal/lib/asn1/canthandle.asn1 index 057f571bac..edb8375ee3 100644 --- a/source4/heimdal/lib/asn1/canthandle.asn1 +++ b/source4/heimdal/lib/asn1/canthandle.asn1 @@ -1,4 +1,4 @@ --- $Id: canthandle.asn1,v 1.6 2006/01/18 19:12:33 lha Exp $ -- +-- $Id: canthandle.asn1 16593 2006-01-18 19:12:33Z lha $ -- CANTHANDLE DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/asn1/der.c b/source4/heimdal/lib/asn1/der.c index 687b381121..c7b911b8d6 100644 --- a/source4/heimdal/lib/asn1/der.c +++ b/source4/heimdal/lib/asn1/der.c @@ -38,7 +38,7 @@ #include <getarg.h> #include <err.h> -RCSID("$Id: der.c,v 1.2 2005/07/12 06:27:19 lha Exp $"); +RCSID("$Id: der.c 15617 2005-07-12 06:27:42Z lha $"); static const char *class_names[] = { diff --git a/source4/heimdal/lib/asn1/der.h b/source4/heimdal/lib/asn1/der.h index b0170e35fe..13e39320d4 100644 --- a/source4/heimdal/lib/asn1/der.h +++ b/source4/heimdal/lib/asn1/der.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: der.h,v 1.36 2006/10/14 05:16:08 lha Exp $ */ +/* $Id: der.h 18437 2006-10-14 05:16:08Z lha $ */ #ifndef __DER_H__ #define __DER_H__ diff --git a/source4/heimdal/lib/asn1/der_copy.c b/source4/heimdal/lib/asn1/der_copy.c index 15e7b817a0..04c4531ca5 100644 --- a/source4/heimdal/lib/asn1/der_copy.c +++ b/source4/heimdal/lib/asn1/der_copy.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_copy.c,v 1.17 2006/12/28 17:14:17 lha Exp $"); +RCSID("$Id: der_copy.c 19539 2006-12-28 17:15:05Z lha $"); int der_copy_general_string (const heim_general_string *from, diff --git a/source4/heimdal/lib/asn1/der_format.c b/source4/heimdal/lib/asn1/der_format.c index 32cf23cb39..6908bddcc2 100644 --- a/source4/heimdal/lib/asn1/der_format.c +++ b/source4/heimdal/lib/asn1/der_format.c @@ -34,7 +34,7 @@ #include "der_locl.h" #include <hex.h> -RCSID("$Id: der_format.c,v 1.8 2006/11/27 10:32:21 lha Exp $"); +RCSID("$Id: der_format.c 20861 2007-06-03 20:18:29Z lha $"); int der_parse_hex_heim_integer (const char *p, heim_integer *data) @@ -51,7 +51,7 @@ der_parse_hex_heim_integer (const char *p, heim_integer *data) } len = strlen(p); - if (len < 0) { + if (len <= 0) { data->data = NULL; data->length = 0; return EINVAL; @@ -74,7 +74,7 @@ der_parse_hex_heim_integer (const char *p, heim_integer *data) { unsigned char *q = data->data; - while(*q == 0 && len > 0) { + while(len > 0 && *q == 0) { q++; len--; } diff --git a/source4/heimdal/lib/asn1/der_free.c b/source4/heimdal/lib/asn1/der_free.c index 6827486d9f..851cb1d407 100644 --- a/source4/heimdal/lib/asn1/der_free.c +++ b/source4/heimdal/lib/asn1/der_free.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_free.c,v 1.14 2006/12/28 17:14:21 lha Exp $"); +RCSID("$Id: der_free.c 19539 2006-12-28 17:15:05Z lha $"); void der_free_general_string (heim_general_string *str) diff --git a/source4/heimdal/lib/asn1/der_get.c b/source4/heimdal/lib/asn1/der_get.c index a1ed23f10b..3022435b33 100644 --- a/source4/heimdal/lib/asn1/der_get.c +++ b/source4/heimdal/lib/asn1/der_get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_get.c,v 1.51 2006/12/28 17:14:25 lha Exp $"); +RCSID("$Id: der_get.c 20570 2007-04-27 14:06:27Z lha $"); #include <version.h> @@ -135,8 +135,21 @@ int der_get_general_string (const unsigned char *p, size_t len, heim_general_string *str, size_t *size) { + const unsigned char *p1; char *s; + p1 = memchr(p, 0, len); + if (p1 != NULL) { + /* + * Allow trailing NULs. We allow this since MIT Kerberos sends + * an strings in the NEED_PREAUTH case that includes a + * trailing NUL. + */ + while (p1 - p < len && *p1 == '\0') + p1++; + if (p1 - p != len) + return ASN1_BAD_CHARACTER; + } if (len > len + 1) return ASN1_BAD_LENGTH; @@ -180,6 +193,8 @@ der_get_bmp_string (const unsigned char *p, size_t len, if (len & 1) return ASN1_BAD_FORMAT; data->length = len / 2; + if (data->length > UINT_MAX/sizeof(data->data[0])) + return ERANGE; data->data = malloc(data->length * sizeof(data->data[0])); if (data->data == NULL && data->length != 0) return ENOMEM; @@ -202,6 +217,8 @@ der_get_universal_string (const unsigned char *p, size_t len, if (len & 3) return ASN1_BAD_FORMAT; data->length = len / 4; + if (data->length > UINT_MAX/sizeof(data->data[0])) + return ERANGE; data->data = malloc(data->length * sizeof(data->data[0])); if (data->data == NULL && data->length != 0) return ENOMEM; @@ -366,7 +383,7 @@ int der_get_oid (const unsigned char *p, size_t len, heim_oid *data, size_t *size) { - int n; + size_t n; size_t oldlen = len; if (len < 1) @@ -375,7 +392,10 @@ der_get_oid (const unsigned char *p, size_t len, if (len > len + 1) return ASN1_BAD_LENGTH; - data->components = malloc((len + 1) * sizeof(*data->components)); + if (len + 1 > UINT_MAX/sizeof(data->components[0])) + return ERANGE; + + data->components = malloc((len + 1) * sizeof(data->components[0])); if (data->components == NULL) return ENOMEM; data->components[0] = (*p) / 40; diff --git a/source4/heimdal/lib/asn1/der_length.c b/source4/heimdal/lib/asn1/der_length.c index 93cabe466c..a7f8f593a2 100644 --- a/source4/heimdal/lib/asn1/der_length.c +++ b/source4/heimdal/lib/asn1/der_length.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_length.c,v 1.20 2006/12/28 17:14:28 lha Exp $"); +RCSID("$Id: der_length.c 19539 2006-12-28 17:15:05Z lha $"); size_t _heim_len_unsigned (unsigned val) diff --git a/source4/heimdal/lib/asn1/der_locl.h b/source4/heimdal/lib/asn1/der_locl.h index 1a87aaaee9..5b97557d74 100644 --- a/source4/heimdal/lib/asn1/der_locl.h +++ b/source4/heimdal/lib/asn1/der_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: der_locl.h,v 1.8 2006/10/19 16:24:02 lha Exp $ */ +/* $Id: der_locl.h 18608 2006-10-19 16:24:02Z lha $ */ #ifndef __DER_LOCL_H__ #define __DER_LOCL_H__ diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c index 9ed8f21906..1fdbfe1305 100644 --- a/source4/heimdal/lib/asn1/der_put.c +++ b/source4/heimdal/lib/asn1/der_put.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_put.c,v 1.34 2006/12/28 17:14:33 lha Exp $"); +RCSID("$Id: der_put.c 19539 2006-12-28 17:15:05Z lha $"); /* * All encoding functions take a pointer `p' to first position in diff --git a/source4/heimdal/lib/asn1/digest.asn1 b/source4/heimdal/lib/asn1/digest.asn1 index 92bfb23234..17341863c6 100644 --- a/source4/heimdal/lib/asn1/digest.asn1 +++ b/source4/heimdal/lib/asn1/digest.asn1 @@ -1,4 +1,4 @@ --- $Id: digest.asn1,v 1.10 2006/12/15 19:13:39 lha Exp $ +-- $Id: digest.asn1 20138 2007-02-02 21:08:24Z lha $ DIGEST DEFINITIONS ::= BEGIN @@ -25,6 +25,7 @@ DigestRequest ::= SEQUENCE { type UTF8String, -- http, sasl-md5, chap, cram-md5 -- digest UTF8String, -- http:md5/md5-sess sasl:clear/int/conf -- username UTF8String, -- username user used + responseData UTF8String, -- client response authid [0] UTF8String OPTIONAL, authentication-user [1] Principal OPTIONAL, -- principal to get key from realm [2] UTF8String OPTIONAL, @@ -48,14 +49,14 @@ DigestError ::= SEQUENCE { } DigestResponse ::= SEQUENCE { - responseData UTF8String, + success BOOLEAN, rsp [0] UTF8String OPTIONAL, tickets [1] SEQUENCE OF OCTET STRING OPTIONAL, channel [2] SEQUENCE { cb-type UTF8String, cb-binding UTF8String } OPTIONAL, - hash-a1 [3] OCTET STRING OPTIONAL + session-key [3] OCTET STRING OPTIONAL } NTLMInit ::= SEQUENCE { diff --git a/source4/heimdal/lib/asn1/extra.c b/source4/heimdal/lib/asn1/extra.c index 4f70f191df..e29a437878 100644 --- a/source4/heimdal/lib/asn1/extra.c +++ b/source4/heimdal/lib/asn1/extra.c @@ -34,7 +34,7 @@ #include "der_locl.h" #include "heim_asn1.h" -RCSID("$Id: extra.c,v 1.6 2006/01/31 09:44:54 lha Exp $"); +RCSID("$Id: extra.c 16672 2006-01-31 09:44:54Z lha $"); int encode_heim_any(unsigned char *p, size_t len, diff --git a/source4/heimdal/lib/asn1/gen.c b/source4/heimdal/lib/asn1/gen.c index 3bb9022be8..cc1a3056de 100644 --- a/source4/heimdal/lib/asn1/gen.c +++ b/source4/heimdal/lib/asn1/gen.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen.c,v 1.70 2006/12/28 17:14:37 lha Exp $"); +RCSID("$Id: gen.c 20670 2007-05-11 00:39:41Z lha $"); FILE *headerfile, *codefile, *logfile; @@ -167,6 +167,7 @@ init_generate (const char *filename, const char *base) " } \\\n" " } while (0)\n\n", headerfile); + fprintf (headerfile, "struct units;\n\n"); fprintf (headerfile, "#endif\n\n"); asprintf(&fn, "%s_files", base); if (fn == NULL) diff --git a/source4/heimdal/lib/asn1/gen_copy.c b/source4/heimdal/lib/asn1/gen_copy.c index 95646d0a3c..abf11859d5 100644 --- a/source4/heimdal/lib/asn1/gen_copy.c +++ b/source4/heimdal/lib/asn1/gen_copy.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_copy.c,v 1.19 2006/12/28 17:14:42 lha Exp $"); +RCSID("$Id: gen_copy.c 19539 2006-12-28 17:15:05Z lha $"); static int used_fail; diff --git a/source4/heimdal/lib/asn1/gen_decode.c b/source4/heimdal/lib/asn1/gen_decode.c index 19ddbb46db..7ebef6cdce 100644 --- a/source4/heimdal/lib/asn1/gen_decode.c +++ b/source4/heimdal/lib/asn1/gen_decode.c @@ -34,7 +34,7 @@ #include "gen_locl.h" #include "lex.h" -RCSID("$Id: gen_decode.c,v 1.32 2006/12/29 17:30:32 lha Exp $"); +RCSID("$Id: gen_decode.c 19572 2006-12-29 17:30:32Z lha $"); static void decode_primitive (const char *typename, const char *name, const char *forwstr) diff --git a/source4/heimdal/lib/asn1/gen_encode.c b/source4/heimdal/lib/asn1/gen_encode.c index bc2aff86e5..b5337b1c43 100644 --- a/source4/heimdal/lib/asn1/gen_encode.c +++ b/source4/heimdal/lib/asn1/gen_encode.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_encode.c,v 1.22 2006/12/29 17:30:03 lha Exp $"); +RCSID("$Id: gen_encode.c 19572 2006-12-29 17:30:32Z lha $"); static void encode_primitive (const char *typename, const char *name) diff --git a/source4/heimdal/lib/asn1/gen_free.c b/source4/heimdal/lib/asn1/gen_free.c index 26e02e39dd..d667c5d31a 100644 --- a/source4/heimdal/lib/asn1/gen_free.c +++ b/source4/heimdal/lib/asn1/gen_free.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_free.c,v 1.17 2006/12/28 17:14:54 lha Exp $"); +RCSID("$Id: gen_free.c 19539 2006-12-28 17:15:05Z lha $"); static void free_primitive (const char *typename, const char *name) diff --git a/source4/heimdal/lib/asn1/gen_glue.c b/source4/heimdal/lib/asn1/gen_glue.c index 2f3e283ad6..8d8bd152a3 100644 --- a/source4/heimdal/lib/asn1/gen_glue.c +++ b/source4/heimdal/lib/asn1/gen_glue.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_glue.c,v 1.9 2005/07/12 06:27:29 lha Exp $"); +RCSID("$Id: gen_glue.c 15617 2005-07-12 06:27:42Z lha $"); static void generate_2int (const Type *t, const char *gen_name) diff --git a/source4/heimdal/lib/asn1/gen_length.c b/source4/heimdal/lib/asn1/gen_length.c index 7f9dc7257b..a1f7cc6644 100644 --- a/source4/heimdal/lib/asn1/gen_length.c +++ b/source4/heimdal/lib/asn1/gen_length.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_length.c,v 1.22 2006/12/28 17:14:57 lha Exp $"); +RCSID("$Id: gen_length.c 19539 2006-12-28 17:15:05Z lha $"); static void length_primitive (const char *typename, diff --git a/source4/heimdal/lib/asn1/gen_locl.h b/source4/heimdal/lib/asn1/gen_locl.h index c9ea714c5f..8cd4dbad5a 100644 --- a/source4/heimdal/lib/asn1/gen_locl.h +++ b/source4/heimdal/lib/asn1/gen_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gen_locl.h,v 1.14 2006/09/05 12:29:18 lha Exp $ */ +/* $Id: gen_locl.h 18008 2006-09-05 12:29:18Z lha $ */ #ifndef __GEN_LOCL_H__ #define __GEN_LOCL_H__ diff --git a/source4/heimdal/lib/asn1/gen_seq.c b/source4/heimdal/lib/asn1/gen_seq.c index fa3813fd61..54776752c2 100644 --- a/source4/heimdal/lib/asn1/gen_seq.c +++ b/source4/heimdal/lib/asn1/gen_seq.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen_seq.c,v 1.4 2006/10/04 10:18:10 lha Exp $"); +RCSID("$Id: gen_seq.c 20561 2007-04-24 16:14:30Z lha $"); void generate_type_seq (const Symbol *s) @@ -111,7 +111,7 @@ generate_type_seq (const Symbol *s) "\t\tsizeof(data->val[0]) * data->len);\n" /* resize but don't care about failures since it doesn't matter */ "ptr = realloc(data->val, data->len * sizeof(data->val[0]));\n" - "if (ptr) data->val = ptr;\n" + "if (ptr != NULL || data->len == 0) data->val = ptr;\n" "return 0;\n", subname); diff --git a/source4/heimdal/lib/asn1/hash.c b/source4/heimdal/lib/asn1/hash.c index f03d6b856b..eeb6b6d63d 100644 --- a/source4/heimdal/lib/asn1/hash.c +++ b/source4/heimdal/lib/asn1/hash.c @@ -37,7 +37,7 @@ #include "gen_locl.h" -RCSID("$Id: hash.c,v 1.11 2006/04/07 22:16:00 lha Exp $"); +RCSID("$Id: hash.c 17016 2006-04-07 22:16:00Z lha $"); static Hashentry *_search(Hashtab * htab, /* The hash table */ void *ptr); /* And key */ diff --git a/source4/heimdal/lib/asn1/hash.h b/source4/heimdal/lib/asn1/hash.h index b54e10234a..10d8ce99b0 100644 --- a/source4/heimdal/lib/asn1/hash.h +++ b/source4/heimdal/lib/asn1/hash.h @@ -35,7 +35,7 @@ * hash.h. Header file for hash table functions */ -/* $Id: hash.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */ +/* $Id: hash.h 7464 1999-12-02 17:05:13Z joda $ */ struct hashentry { /* Entry in bucket */ struct hashentry **prev; diff --git a/source4/heimdal/lib/asn1/k5.asn1 b/source4/heimdal/lib/asn1/k5.asn1 index a86df38a99..0c7021f87f 100644 --- a/source4/heimdal/lib/asn1/k5.asn1 +++ b/source4/heimdal/lib/asn1/k5.asn1 @@ -1,4 +1,4 @@ --- $Id: k5.asn1,v 1.51 2006/11/21 05:17:47 lha Exp $ +-- $Id: k5.asn1 21004 2007-06-08 01:53:10Z lha $ KERBEROS5 DEFINITIONS ::= BEGIN @@ -59,6 +59,7 @@ PADATA-TYPE ::= INTEGER { KRB5-PADATA-PA-PK-OCSP-RESPONSE(18), KRB5-PADATA-ETYPE-INFO2(19), KRB5-PADATA-USE-SPECIFIED-KVNO(20), + KRB5-PADATA-SVR-REFERRAL-INFO(20), --- old ms referral number KRB5-PADATA-SAM-REDIRECT(21), -- (sam/otp) KRB5-PADATA-GET-FROM-TYPED-DATA(22), KRB5-PADATA-SAM-ETYPE-INFO(23), @@ -71,10 +72,11 @@ PADATA-TYPE ::= INTEGER { KRB5-PADATA-TD-REQ-SEQ(108), -- INTEGER KRB5-PADATA-PA-PAC-REQUEST(128), -- jbrezak@exchange.microsoft.com KRB5-PADATA-S4U2SELF(129), - KRB5-PADATA-PK-AS-09-BINDING(132) -- client send this to + KRB5-PADATA-PK-AS-09-BINDING(132), -- client send this to -- tell KDC that is supports -- the asCheckSum in the -- PK-AS-REP + KRB5-PADATA-CLIENT-CANONICALIZED(133) -- } AUTHDATA-TYPE ::= INTEGER { @@ -229,6 +231,7 @@ KDCOptions ::= BIT STRING { unused11(11), request-anonymous(14), canonicalize(15), + constrained-delegation(16), -- ms extension disable-transited-check(26), renewable-ok(27), enc-tkt-in-skey(28), @@ -409,7 +412,8 @@ EncKDCRepPart ::= SEQUENCE { renew-till[8] KerberosTime OPTIONAL, srealm[9] Realm, sname[10] PrincipalName, - caddr[11] HostAddresses OPTIONAL + caddr[11] HostAddresses OPTIONAL, + encrypted-pa-data[12] METHOD-DATA OPTIONAL } EncASRepPart ::= [APPLICATION 25] EncKDCRepPart @@ -624,6 +628,27 @@ KRB5SignedPath ::= SEQUENCE { delegated[2] KRB5SignedPathPrincipals OPTIONAL } +PA-ClientCanonicalizedNames ::= SEQUENCE{ + requested-name [0] PrincipalName, + real-name [1] PrincipalName +} + +PA-ClientCanonicalized ::= SEQUENCE { + names [0] PA-ClientCanonicalizedNames, + canon-checksum [1] Checksum +} + +AD-LoginAlias ::= SEQUENCE { -- ad-type number TBD -- + login-alias [0] PrincipalName, + checksum [1] Checksum +} + +-- old ms referral +PA-SvrReferralData ::= SEQUENCE { + referred-name [1] PrincipalName OPTIONAL, + referred-realm [0] Realm +} + END -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1 diff --git a/source4/heimdal/lib/asn1/kx509.asn1 b/source4/heimdal/lib/asn1/kx509.asn1 index 9706b061c3..fc6a696dab 100644 --- a/source4/heimdal/lib/asn1/kx509.asn1 +++ b/source4/heimdal/lib/asn1/kx509.asn1 @@ -1,4 +1,4 @@ --- $Id: kx509.asn1,v 1.1 2006/12/28 21:05:23 lha Exp $ +-- $Id: kx509.asn1 19546 2006-12-28 21:05:23Z lha $ KX509 DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/asn1/lex.c b/source4/heimdal/lib/asn1/lex.c index 10b4d65a7e..d628e4696f 100644 --- a/source4/heimdal/lib/asn1/lex.c +++ b/source4/heimdal/lib/asn1/lex.c @@ -1,31 +1,92 @@ -/* A lexical scanner generated by flex*/ -/* Scanner skeleton version: - * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ - */ +#line 3 "lex.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 33 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ #include <stdio.h> -#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +/* end standard C headers. */ -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 #endif +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ -#ifdef __cplusplus +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif -#include <stdlib.h> +#endif /* ! FLEXINT_H */ -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS +#ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST @@ -34,34 +95,17 @@ #if __STDC__ -#define YY_USE_PROTOS #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - /* Returned upon end-of-file. */ #define YY_NULL 0 @@ -76,80 +120,75 @@ * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ -#define BEGIN yy_start = 1 + 2 * +#define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ -#define YY_START ((yy_start - 1) / 2) +#define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) +#define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ +#ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 +#endif +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif extern int yyleng; + extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) -#define unput(c) yyunput( c, yytext_ptr ) - -/* Some routines like yy_flex_realloc() are emitted as static but are - not called by all lexers. This generates warnings in some compilers, - notably GCC. Arrange to suppress these. */ -#ifdef __GNUC__ -#define YY_MAY_BE_UNUSED __attribute__((unused)) -#else -#define YY_MAY_BE_UNUSED -#endif +#define unput(c) yyunput( c, (yytext_ptr) ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ -typedef unsigned int yy_size_t; +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; @@ -186,12 +225,16 @@ struct yy_buffer_state */ int yy_at_bol; + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; + #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process @@ -205,28 +248,38 @@ struct yy_buffer_state * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ -static YY_BUFFER_STATE yy_current_buffer = 0; +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". + * + * Returns the top of the stack, or NULL. */ -#define YY_CURRENT_BUFFER yy_current_buffer +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; - static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ +static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches @@ -234,66 +287,92 @@ static int yy_start = 0; /* start state number */ */ static int yy_did_buffer_switch_on_eof; -void yyrestart YY_PROTO(( FILE *input_file )); +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED; -static void yy_flex_free YY_PROTO(( void * )); +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ typedef unsigned char YY_CHAR; + FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + extern char *yytext; #define yytext_ptr yytext -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 95 #define YY_END_OF_BUFFER 96 -static yyconst short int yy_accept[568] = +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[568] = { 0, 0, 0, 96, 94, 90, 91, 87, 81, 81, 94, 94, 88, 88, 94, 89, 89, 89, 89, 89, 89, @@ -359,7 +438,7 @@ static yyconst short int yy_accept[568] = 32, 89, 59, 70, 77, 53, 0 } ; -static yyconst int yy_ec[256] = +static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -391,7 +470,7 @@ static yyconst int yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst int yy_meta[70] = +static yyconst flex_int32_t yy_meta[70] = { 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, @@ -402,7 +481,7 @@ static yyconst int yy_meta[70] = 2, 2, 2, 2, 2, 2, 2, 2, 2 } ; -static yyconst short int yy_base[570] = +static yyconst flex_int16_t yy_base[570] = { 0, 0, 0, 636, 637, 637, 637, 637, 637, 63, 627, 628, 70, 77, 616, 74, 72, 76, 609, 65, 81, @@ -468,7 +547,7 @@ static yyconst short int yy_base[570] = 0, 101, 0, 0, 0, 0, 637, 223, 69 } ; -static yyconst short int yy_def[570] = +static yyconst flex_int16_t yy_def[570] = { 0, 567, 1, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 568, 568, 568, 568, 568, 568, @@ -534,7 +613,7 @@ static yyconst short int yy_def[570] = 568, 568, 568, 568, 568, 568, 0, 567, 567 } ; -static yyconst short int yy_nxt[707] = +static yyconst flex_int16_t yy_nxt[707] = { 0, 4, 5, 6, 7, 8, 4, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 14, 4, 15, 16, @@ -616,7 +695,7 @@ static yyconst short int yy_nxt[707] = 567, 567, 567, 567, 567, 567 } ; -static yyconst short int yy_chk[707] = +static yyconst flex_int16_t yy_chk[707] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -701,6 +780,9 @@ static yyconst short int yy_chk[707] = static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; +extern int yy_flex_debug; +int yy_flex_debug = 0; + /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ @@ -710,7 +792,6 @@ static char *yy_last_accepting_cpos; #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "lex.l" -#define INITIAL 0 #line 2 "lex.l" /* * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan @@ -745,7 +826,7 @@ char *yytext; * SUCH DAMAGE. */ -/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */ +/* $Id: lex.l 18738 2006-10-21 11:57:22Z lha $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -770,7 +851,23 @@ static unsigned lineno = 1; static void unterminated(const char *, unsigned); /* This is for broken old lexes (solaris 10 and hpux) */ -#line 774 "lex.c" +#line 855 "lex.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -778,65 +875,30 @@ static void unterminated(const char *, unsigned); #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); +extern "C" int yywrap (void ); #else -extern int yywrap YY_PROTO(( void )); +extern int yywrap (void ); #endif #endif -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - + static void yyunput (int c,char *buf_ptr ); + #ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); +static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif +#ifdef __cplusplus +static int yyinput (void ); #else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 +static int input (void ); #endif -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif #endif /* Amount of stuff to slurp up with each read. */ @@ -845,7 +907,6 @@ YY_MALLOC_DECL #endif /* Copy whatever the last rule matched to the standard output. */ - #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). @@ -858,9 +919,10 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ - int c = '*', n; \ + int c = '*'; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -870,9 +932,22 @@ YY_MALLOC_DECL YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -893,12 +968,18 @@ YY_MALLOC_DECL #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif +/* end tables serialization structures and prototypes */ + /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. @@ -915,26 +996,28 @@ YY_MALLOC_DECL #define YY_RULE_SETUP \ YY_USER_ACTION +/** The main scanner function which does all the work. + */ YY_DECL - { +{ register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; + register char *yy_cp, *yy_bp; register int yy_act; - + #line 68 "lex.l" -#line 927 "lex.c" +#line 1010 "lex.c" - if ( yy_init ) + if ( !(yy_init) ) { - yy_init = 0; + (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; @@ -942,34 +1025,36 @@ YY_DECL if ( ! yyout ) yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } - yy_load_buffer_state(); + yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { - yy_cp = yy_c_buf_p; + yy_cp = (yy_c_buf_p); /* Support of yytext. */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { @@ -986,24 +1071,22 @@ yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; - do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: @@ -1567,6 +1650,7 @@ YY_RULE_SETUP ; YY_BREAK case 91: +/* rule 91 can match eol */ YY_RULE_SETUP #line 270 "lex.l" { ++lineno; } @@ -1591,33 +1675,33 @@ YY_RULE_SETUP #line 274 "lex.l" ECHO; YY_BREAK -#line 1595 "lex.c" +#line 1679 "lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our + * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position @@ -1627,13 +1711,13 @@ case YY_STATE_EOF(INITIAL): * end-of-buffer state). Contrast this with the test * in input(). */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have @@ -1646,30 +1730,30 @@ case YY_STATE_EOF(INITIAL): yy_next_state = yy_try_NUL_trans( yy_current_state ); - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; + yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { - yy_cp = yy_c_buf_p; + yy_cp = (yy_c_buf_p); goto yy_find_action; } } - else switch ( yy_get_next_buffer() ) + else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { - yy_did_buffer_switch_on_eof = 0; + (yy_did_buffer_switch_on_eof) = 0; - if ( yywrap() ) + if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up @@ -1680,7 +1764,7 @@ case YY_STATE_EOF(INITIAL): * YY_NULL, it'll still work - another * YY_NULL will get returned. */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; @@ -1688,30 +1772,30 @@ case YY_STATE_EOF(INITIAL): else { - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; @@ -1722,8 +1806,7 @@ case YY_STATE_EOF(INITIAL): "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ - } /* end of yylex */ - +} /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * @@ -1732,21 +1815,20 @@ case YY_STATE_EOF(INITIAL): * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); - if ( yy_current_buffer->yy_fill_buffer == 0 ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. @@ -1766,34 +1848,30 @@ static int yy_get_next_buffer() /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { @@ -1806,8 +1884,7 @@ static int yy_get_next_buffer() b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ @@ -1817,35 +1894,35 @@ static int yy_get_next_buffer() YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; -#endif + } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } - if ( yy_n_chars == 0 ) + if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); + yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } @@ -1853,32 +1930,31 @@ static int yy_get_next_buffer() else ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; - } - +} /* yy_get_previous_state - get the state just before the EOB char was reached */ -static yy_state_type yy_get_previous_state() - { + static yy_state_type yy_get_previous_state (void) +{ register yy_state_type yy_current_state; register char *yy_cp; + + yy_current_state = (yy_start); - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { @@ -1890,30 +1966,23 @@ static yy_state_type yy_get_previous_state() } return yy_current_state; - } - +} /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; + register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { @@ -1925,81 +1994,73 @@ yy_state_type yy_current_state; yy_is_jam = (yy_current_state == 567); return yy_is_jam ? 0 : yy_current_state; - } - +} -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} #ifndef YY_NO_INPUT #ifdef __cplusplus -static int yyinput() + static int yyinput (void) #else -static int input() + static int input (void) #endif - { - int c; - *yy_c_buf_p = yy_hold_char; +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ - *yy_c_buf_p = '\0'; + *(yy_c_buf_p) = '\0'; else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); - switch ( yy_get_next_buffer() ) + switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() @@ -2013,16 +2074,16 @@ static int input() */ /* Reset buffer status. */ - yyrestart( yyin ); + yyrestart(yyin ); - /* fall through */ + /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { - if ( yywrap() ) + if ( yywrap( ) ) return EOF; - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); @@ -2032,90 +2093,92 @@ static int input() } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; + (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); return c; - } -#endif /* YY_NO_INPUT */ - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); +} +#endif /* ifndef YY_NO_INPUT */ - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); } + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) return; - if ( yy_current_buffer ) + if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } + (yy_did_buffer_switch_on_eof) = 1; +} +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); @@ -2124,75 +2187,75 @@ int size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer(b,file ); return b; - } - +} -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + yyfree((void *) b->yy_ch_buf ); - yy_flex_free( (void *) b ); - } - - - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif + yyfree((void *) b ); +} +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - { - yy_flush_buffer( b ); +{ + int oerrno = errno; + + yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} - { - if ( ! b ) +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) return; b->yy_n_chars = 0; @@ -2209,29 +2272,121 @@ YY_BUFFER_STATE b; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; } +} +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); @@ -2245,56 +2400,51 @@ yy_size_t size; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer(b ); return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif +} +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param str a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; - + /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); + b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); @@ -2304,148 +2454,196 @@ int len; b->yy_is_our_buffer = 1; return b; - } +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 #endif +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); +/* Accessor methods (get/set functions) to struct members. */ - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} - yy_start_stack[yy_start_stack_ptr++] = YY_START; +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} - BEGIN(new_state); - } -#endif +/** Get the current token. + * + */ +char *yyget_text (void) +{ + return yytext; +} -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif +int yyget_debug (void) +{ + return yy_flex_debug; +} -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; #else -static void yy_fatal_error( msg ) -char msg[]; + yyin = (FILE *) 0; + yyout = (FILE *) 0; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } -/* Redefine yyless() so it works in section 3 code. */ + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + return 0; +} -/* Internal utility routines. */ +/* + * Internal utility routines. + */ #ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; - } +} #endif #ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { +static int yy_flex_strlen (yyconst char * s ) +{ register int n; for ( n = 0; s[n]; ++n ) ; return n; - } +} #endif - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { +void *yyalloc (yy_size_t size ) +{ return (void *) malloc( size ); - } +} -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { +void *yyrealloc (void * ptr, yy_size_t size ) +{ /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter @@ -2454,28 +2652,19 @@ yy_size_t size; * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); - } +} -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif #line 274 "lex.l" + #ifndef yywrap /* XXX */ int yywrap () @@ -2501,3 +2690,4 @@ unterminated(const char *type, unsigned start_lineno) { error_message("unterminated %s, possibly started on line %d\n", type, start_lineno); } + diff --git a/source4/heimdal/lib/asn1/lex.h b/source4/heimdal/lib/asn1/lex.h index 2d9e6745c5..7aececf6d7 100644 --- a/source4/heimdal/lib/asn1/lex.h +++ b/source4/heimdal/lib/asn1/lex.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: lex.h,v 1.6 2005/07/12 06:27:33 lha Exp $ */ +/* $Id: lex.h 15617 2005-07-12 06:27:42Z lha $ */ #include <roken.h> diff --git a/source4/heimdal/lib/asn1/libasn1.h b/source4/heimdal/lib/asn1/libasn1.h index 8ccde9a36a..64f554f2c8 100644 --- a/source4/heimdal/lib/asn1/libasn1.h +++ b/source4/heimdal/lib/asn1/libasn1.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: libasn1.h,v 1.11 2005/07/12 06:27:34 lha Exp $ */ +/* $Id: libasn1.h 15617 2005-07-12 06:27:42Z lha $ */ #ifndef __LIBASN1_H__ #define __LIBASN1_H__ diff --git a/source4/heimdal/lib/asn1/main.c b/source4/heimdal/lib/asn1/main.c index bba79b1e4e..3b4a8122ca 100644 --- a/source4/heimdal/lib/asn1/main.c +++ b/source4/heimdal/lib/asn1/main.c @@ -35,7 +35,7 @@ #include <getarg.h> #include "lex.h" -RCSID("$Id: main.c,v 1.16 2006/09/05 12:27:29 lha Exp $"); +RCSID("$Id: main.c 20858 2007-06-03 18:56:41Z lha $"); extern FILE *yyin; @@ -127,5 +127,7 @@ main(int argc, char **argv) if(ret != 0 || error_flag != 0) exit(1); close_generate (); + if (argc != optidx) + fclose(yyin); return 0; } diff --git a/source4/heimdal/lib/asn1/parse.c b/source4/heimdal/lib/asn1/parse.c index affe4f2a9c..31361c7492 100644 --- a/source4/heimdal/lib/asn1/parse.c +++ b/source4/heimdal/lib/asn1/parse.c @@ -248,7 +248,7 @@ /* Copy the first part of user declarations. */ -#line 36 "heimdal/lib/asn1/parse.y" +#line 36 "parse.y" #ifdef HAVE_CONFIG_H #include <config.h> @@ -261,7 +261,7 @@ #include "gen_locl.h" #include "der.h" -RCSID("$Id: parse.y,v 1.29 2006/12/28 17:15:02 lha Exp $"); +RCSID("$Id: parse.y 19539 2006-12-28 17:15:05Z lha $"); static Type *new_type (Typetype t); static struct constraint_spec *new_constraint_spec(enum ctype); @@ -280,7 +280,7 @@ struct string_list { /* Enabling traces. */ #ifndef YYDEBUG -# define YYDEBUG 0 +# define YYDEBUG 1 #endif /* Enabling verbose error messages. */ @@ -298,7 +298,7 @@ struct string_list { #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 65 "heimdal/lib/asn1/parse.y" +#line 65 "parse.y" { int constant; struct value *value; @@ -314,7 +314,7 @@ typedef union YYSTYPE struct constraint_spec *constraint_spec; } /* Line 187 of yacc.c. */ -#line 318 "heimdal/lib/asn1/parse.y" +#line 318 "parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -327,7 +327,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 331 "heimdal/lib/asn1/parse.y" +#line 331 "parse.c" #ifdef short # undef short @@ -1750,29 +1750,29 @@ yyreduce: switch (yyn) { case 2: -#line 233 "heimdal/lib/asn1/parse.y" +#line 233 "parse.y" { checkundefined(); } break; case 4: -#line 240 "heimdal/lib/asn1/parse.y" +#line 240 "parse.y" { error_message("implicit tagging is not supported"); } break; case 5: -#line 242 "heimdal/lib/asn1/parse.y" +#line 242 "parse.y" { error_message("automatic tagging is not supported"); } break; case 7: -#line 247 "heimdal/lib/asn1/parse.y" +#line 247 "parse.y" { error_message("no extensibility options supported"); } break; case 17: -#line 268 "heimdal/lib/asn1/parse.y" +#line 268 "parse.y" { struct string_list *sl; for(sl = (yyvsp[(1) - (4)].sl); sl != NULL; sl = sl->next) { @@ -1784,7 +1784,7 @@ yyreduce: break; case 22: -#line 287 "heimdal/lib/asn1/parse.y" +#line 287 "parse.y" { (yyval.sl) = emalloc(sizeof(*(yyval.sl))); (yyval.sl)->string = (yyvsp[(1) - (3)].name); @@ -1793,7 +1793,7 @@ yyreduce: break; case 23: -#line 293 "heimdal/lib/asn1/parse.y" +#line 293 "parse.y" { (yyval.sl) = emalloc(sizeof(*(yyval.sl))); (yyval.sl)->string = (yyvsp[(1) - (1)].name); @@ -1802,7 +1802,7 @@ yyreduce: break; case 24: -#line 301 "heimdal/lib/asn1/parse.y" +#line 301 "parse.y" { Symbol *s = addsym ((yyvsp[(1) - (3)].name)); s->stype = Stype; @@ -1813,7 +1813,7 @@ yyreduce: break; case 42: -#line 332 "heimdal/lib/asn1/parse.y" +#line 332 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_Boolean, TE_EXPLICIT, new_type(TBoolean)); @@ -1821,7 +1821,7 @@ yyreduce: break; case 43: -#line 339 "heimdal/lib/asn1/parse.y" +#line 339 "parse.y" { if((yyvsp[(2) - (5)].value)->type != integervalue || (yyvsp[(4) - (5)].value)->type != integervalue) @@ -1832,7 +1832,7 @@ yyreduce: break; case 44: -#line 349 "heimdal/lib/asn1/parse.y" +#line 349 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, new_type(TInteger)); @@ -1840,7 +1840,7 @@ yyreduce: break; case 45: -#line 354 "heimdal/lib/asn1/parse.y" +#line 354 "parse.y" { (yyval.type) = new_type(TInteger); (yyval.type)->range = emalloc(sizeof(*(yyval.type)->range)); @@ -1850,7 +1850,7 @@ yyreduce: break; case 46: -#line 361 "heimdal/lib/asn1/parse.y" +#line 361 "parse.y" { (yyval.type) = new_type(TInteger); (yyval.type)->members = (yyvsp[(3) - (4)].members); @@ -1859,7 +1859,7 @@ yyreduce: break; case 47: -#line 369 "heimdal/lib/asn1/parse.y" +#line 369 "parse.y" { (yyval.members) = emalloc(sizeof(*(yyval.members))); ASN1_TAILQ_INIT((yyval.members)); @@ -1868,7 +1868,7 @@ yyreduce: break; case 48: -#line 375 "heimdal/lib/asn1/parse.y" +#line 375 "parse.y" { ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members); (yyval.members) = (yyvsp[(1) - (3)].members); @@ -1876,12 +1876,12 @@ yyreduce: break; case 49: -#line 380 "heimdal/lib/asn1/parse.y" +#line 380 "parse.y" { (yyval.members) = (yyvsp[(1) - (3)].members); } break; case 50: -#line 384 "heimdal/lib/asn1/parse.y" +#line 384 "parse.y" { (yyval.member) = emalloc(sizeof(*(yyval.member))); (yyval.member)->name = (yyvsp[(1) - (4)].name); @@ -1895,7 +1895,7 @@ yyreduce: break; case 51: -#line 397 "heimdal/lib/asn1/parse.y" +#line 397 "parse.y" { (yyval.type) = new_type(TInteger); (yyval.type)->members = (yyvsp[(3) - (4)].members); @@ -1904,7 +1904,7 @@ yyreduce: break; case 53: -#line 408 "heimdal/lib/asn1/parse.y" +#line 408 "parse.y" { (yyval.type) = new_type(TBitString); (yyval.type)->members = emalloc(sizeof(*(yyval.type)->members)); @@ -1914,7 +1914,7 @@ yyreduce: break; case 54: -#line 415 "heimdal/lib/asn1/parse.y" +#line 415 "parse.y" { (yyval.type) = new_type(TBitString); (yyval.type)->members = (yyvsp[(4) - (5)].members); @@ -1923,7 +1923,7 @@ yyreduce: break; case 55: -#line 423 "heimdal/lib/asn1/parse.y" +#line 423 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_OID, TE_EXPLICIT, new_type(TOID)); @@ -1931,7 +1931,7 @@ yyreduce: break; case 56: -#line 429 "heimdal/lib/asn1/parse.y" +#line 429 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_OctetString, TE_EXPLICIT, new_type(TOctetString)); @@ -1939,7 +1939,7 @@ yyreduce: break; case 57: -#line 436 "heimdal/lib/asn1/parse.y" +#line 436 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_Null, TE_EXPLICIT, new_type(TNull)); @@ -1947,7 +1947,7 @@ yyreduce: break; case 58: -#line 443 "heimdal/lib/asn1/parse.y" +#line 443 "parse.y" { (yyval.type) = new_type(TSequence); (yyval.type)->members = (yyvsp[(3) - (4)].members); @@ -1956,7 +1956,7 @@ yyreduce: break; case 59: -#line 449 "heimdal/lib/asn1/parse.y" +#line 449 "parse.y" { (yyval.type) = new_type(TSequence); (yyval.type)->members = NULL; @@ -1965,7 +1965,7 @@ yyreduce: break; case 60: -#line 457 "heimdal/lib/asn1/parse.y" +#line 457 "parse.y" { (yyval.type) = new_type(TSequenceOf); (yyval.type)->subtype = (yyvsp[(3) - (3)].type); @@ -1974,7 +1974,7 @@ yyreduce: break; case 61: -#line 465 "heimdal/lib/asn1/parse.y" +#line 465 "parse.y" { (yyval.type) = new_type(TSet); (yyval.type)->members = (yyvsp[(3) - (4)].members); @@ -1983,7 +1983,7 @@ yyreduce: break; case 62: -#line 471 "heimdal/lib/asn1/parse.y" +#line 471 "parse.y" { (yyval.type) = new_type(TSet); (yyval.type)->members = NULL; @@ -1992,7 +1992,7 @@ yyreduce: break; case 63: -#line 479 "heimdal/lib/asn1/parse.y" +#line 479 "parse.y" { (yyval.type) = new_type(TSetOf); (yyval.type)->subtype = (yyvsp[(3) - (3)].type); @@ -2001,7 +2001,7 @@ yyreduce: break; case 64: -#line 487 "heimdal/lib/asn1/parse.y" +#line 487 "parse.y" { (yyval.type) = new_type(TChoice); (yyval.type)->members = (yyvsp[(3) - (4)].members); @@ -2009,7 +2009,7 @@ yyreduce: break; case 67: -#line 498 "heimdal/lib/asn1/parse.y" +#line 498 "parse.y" { Symbol *s = addsym((yyvsp[(1) - (1)].name)); (yyval.type) = new_type(TType); @@ -2021,7 +2021,7 @@ yyreduce: break; case 68: -#line 509 "heimdal/lib/asn1/parse.y" +#line 509 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, TE_EXPLICIT, new_type(TGeneralizedTime)); @@ -2029,7 +2029,7 @@ yyreduce: break; case 69: -#line 514 "heimdal/lib/asn1/parse.y" +#line 514 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTCTime, TE_EXPLICIT, new_type(TUTCTime)); @@ -2037,7 +2037,7 @@ yyreduce: break; case 70: -#line 521 "heimdal/lib/asn1/parse.y" +#line 521 "parse.y" { /* if (Constraint.type == contentConstrant) { assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too @@ -2053,14 +2053,14 @@ yyreduce: break; case 71: -#line 537 "heimdal/lib/asn1/parse.y" +#line 537 "parse.y" { (yyval.constraint_spec) = (yyvsp[(2) - (3)].constraint_spec); } break; case 75: -#line 550 "heimdal/lib/asn1/parse.y" +#line 550 "parse.y" { (yyval.constraint_spec) = new_constraint_spec(CT_CONTENTS); (yyval.constraint_spec)->u.content.type = (yyvsp[(2) - (2)].type); @@ -2069,7 +2069,7 @@ yyreduce: break; case 76: -#line 556 "heimdal/lib/asn1/parse.y" +#line 556 "parse.y" { if ((yyvsp[(3) - (3)].value)->type != objectidentifiervalue) error_message("Non-OID used in ENCODED BY constraint"); @@ -2080,7 +2080,7 @@ yyreduce: break; case 77: -#line 564 "heimdal/lib/asn1/parse.y" +#line 564 "parse.y" { if ((yyvsp[(5) - (5)].value)->type != objectidentifiervalue) error_message("Non-OID used in ENCODED BY constraint"); @@ -2091,14 +2091,14 @@ yyreduce: break; case 78: -#line 574 "heimdal/lib/asn1/parse.y" +#line 574 "parse.y" { (yyval.constraint_spec) = new_constraint_spec(CT_USER); } break; case 79: -#line 580 "heimdal/lib/asn1/parse.y" +#line 580 "parse.y" { (yyval.type) = new_type(TTag); (yyval.type)->tag = (yyvsp[(1) - (3)].tag); @@ -2112,7 +2112,7 @@ yyreduce: break; case 80: -#line 593 "heimdal/lib/asn1/parse.y" +#line 593 "parse.y" { (yyval.tag).tagclass = (yyvsp[(2) - (4)].constant); (yyval.tag).tagvalue = (yyvsp[(3) - (4)].constant); @@ -2121,56 +2121,56 @@ yyreduce: break; case 81: -#line 601 "heimdal/lib/asn1/parse.y" +#line 601 "parse.y" { (yyval.constant) = ASN1_C_CONTEXT; } break; case 82: -#line 605 "heimdal/lib/asn1/parse.y" +#line 605 "parse.y" { (yyval.constant) = ASN1_C_UNIV; } break; case 83: -#line 609 "heimdal/lib/asn1/parse.y" +#line 609 "parse.y" { (yyval.constant) = ASN1_C_APPL; } break; case 84: -#line 613 "heimdal/lib/asn1/parse.y" +#line 613 "parse.y" { (yyval.constant) = ASN1_C_PRIVATE; } break; case 85: -#line 619 "heimdal/lib/asn1/parse.y" +#line 619 "parse.y" { (yyval.constant) = TE_EXPLICIT; } break; case 86: -#line 623 "heimdal/lib/asn1/parse.y" +#line 623 "parse.y" { (yyval.constant) = TE_EXPLICIT; } break; case 87: -#line 627 "heimdal/lib/asn1/parse.y" +#line 627 "parse.y" { (yyval.constant) = TE_IMPLICIT; } break; case 88: -#line 634 "heimdal/lib/asn1/parse.y" +#line 634 "parse.y" { Symbol *s; s = addsym ((yyvsp[(1) - (4)].name)); @@ -2182,7 +2182,7 @@ yyreduce: break; case 90: -#line 648 "heimdal/lib/asn1/parse.y" +#line 648 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralString, TE_EXPLICIT, new_type(TGeneralString)); @@ -2190,7 +2190,7 @@ yyreduce: break; case 91: -#line 653 "heimdal/lib/asn1/parse.y" +#line 653 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTF8String, TE_EXPLICIT, new_type(TUTF8String)); @@ -2198,7 +2198,7 @@ yyreduce: break; case 92: -#line 658 "heimdal/lib/asn1/parse.y" +#line 658 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_PrintableString, TE_EXPLICIT, new_type(TPrintableString)); @@ -2206,7 +2206,7 @@ yyreduce: break; case 93: -#line 663 "heimdal/lib/asn1/parse.y" +#line 663 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_VisibleString, TE_EXPLICIT, new_type(TVisibleString)); @@ -2214,7 +2214,7 @@ yyreduce: break; case 94: -#line 668 "heimdal/lib/asn1/parse.y" +#line 668 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_IA5String, TE_EXPLICIT, new_type(TIA5String)); @@ -2222,7 +2222,7 @@ yyreduce: break; case 95: -#line 673 "heimdal/lib/asn1/parse.y" +#line 673 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_BMPString, TE_EXPLICIT, new_type(TBMPString)); @@ -2230,7 +2230,7 @@ yyreduce: break; case 96: -#line 678 "heimdal/lib/asn1/parse.y" +#line 678 "parse.y" { (yyval.type) = new_tag(ASN1_C_UNIV, UT_UniversalString, TE_EXPLICIT, new_type(TUniversalString)); @@ -2238,7 +2238,7 @@ yyreduce: break; case 97: -#line 686 "heimdal/lib/asn1/parse.y" +#line 686 "parse.y" { (yyval.members) = emalloc(sizeof(*(yyval.members))); ASN1_TAILQ_INIT((yyval.members)); @@ -2247,7 +2247,7 @@ yyreduce: break; case 98: -#line 692 "heimdal/lib/asn1/parse.y" +#line 692 "parse.y" { ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members); (yyval.members) = (yyvsp[(1) - (3)].members); @@ -2255,7 +2255,7 @@ yyreduce: break; case 99: -#line 697 "heimdal/lib/asn1/parse.y" +#line 697 "parse.y" { struct member *m = ecalloc(1, sizeof(*m)); m->name = estrdup("..."); @@ -2267,7 +2267,7 @@ yyreduce: break; case 100: -#line 708 "heimdal/lib/asn1/parse.y" +#line 708 "parse.y" { (yyval.member) = emalloc(sizeof(*(yyval.member))); (yyval.member)->name = (yyvsp[(1) - (2)].name); @@ -2279,7 +2279,7 @@ yyreduce: break; case 101: -#line 719 "heimdal/lib/asn1/parse.y" +#line 719 "parse.y" { (yyval.member) = (yyvsp[(1) - (1)].member); (yyval.member)->optional = 0; @@ -2288,7 +2288,7 @@ yyreduce: break; case 102: -#line 725 "heimdal/lib/asn1/parse.y" +#line 725 "parse.y" { (yyval.member) = (yyvsp[(1) - (2)].member); (yyval.member)->optional = 1; @@ -2297,7 +2297,7 @@ yyreduce: break; case 103: -#line 731 "heimdal/lib/asn1/parse.y" +#line 731 "parse.y" { (yyval.member) = (yyvsp[(1) - (3)].member); (yyval.member)->optional = 0; @@ -2306,7 +2306,7 @@ yyreduce: break; case 104: -#line 739 "heimdal/lib/asn1/parse.y" +#line 739 "parse.y" { (yyval.members) = emalloc(sizeof(*(yyval.members))); ASN1_TAILQ_INIT((yyval.members)); @@ -2315,7 +2315,7 @@ yyreduce: break; case 105: -#line 745 "heimdal/lib/asn1/parse.y" +#line 745 "parse.y" { ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members); (yyval.members) = (yyvsp[(1) - (3)].members); @@ -2323,7 +2323,7 @@ yyreduce: break; case 106: -#line 752 "heimdal/lib/asn1/parse.y" +#line 752 "parse.y" { (yyval.member) = emalloc(sizeof(*(yyval.member))); (yyval.member)->name = (yyvsp[(1) - (4)].name); @@ -2337,26 +2337,26 @@ yyreduce: break; case 108: -#line 765 "heimdal/lib/asn1/parse.y" +#line 765 "parse.y" { (yyval.objid) = NULL; } break; case 109: -#line 769 "heimdal/lib/asn1/parse.y" +#line 769 "parse.y" { (yyval.objid) = (yyvsp[(2) - (3)].objid); } break; case 110: -#line 775 "heimdal/lib/asn1/parse.y" +#line 775 "parse.y" { (yyval.objid) = NULL; } break; case 111: -#line 779 "heimdal/lib/asn1/parse.y" +#line 779 "parse.y" { if ((yyvsp[(2) - (2)].objid)) { (yyval.objid) = (yyvsp[(2) - (2)].objid); @@ -2368,14 +2368,14 @@ yyreduce: break; case 112: -#line 790 "heimdal/lib/asn1/parse.y" +#line 790 "parse.y" { (yyval.objid) = new_objid((yyvsp[(1) - (4)].name), (yyvsp[(3) - (4)].constant)); } break; case 113: -#line 794 "heimdal/lib/asn1/parse.y" +#line 794 "parse.y" { Symbol *s = addsym((yyvsp[(1) - (1)].name)); if(s->stype != SValue || @@ -2389,14 +2389,14 @@ yyreduce: break; case 114: -#line 805 "heimdal/lib/asn1/parse.y" +#line 805 "parse.y" { (yyval.objid) = new_objid(NULL, (yyvsp[(1) - (1)].constant)); } break; case 124: -#line 828 "heimdal/lib/asn1/parse.y" +#line 828 "parse.y" { Symbol *s = addsym((yyvsp[(1) - (1)].name)); if(s->stype != SValue) @@ -2408,7 +2408,7 @@ yyreduce: break; case 125: -#line 839 "heimdal/lib/asn1/parse.y" +#line 839 "parse.y" { (yyval.value) = emalloc(sizeof(*(yyval.value))); (yyval.value)->type = stringvalue; @@ -2417,7 +2417,7 @@ yyreduce: break; case 126: -#line 847 "heimdal/lib/asn1/parse.y" +#line 847 "parse.y" { (yyval.value) = emalloc(sizeof(*(yyval.value))); (yyval.value)->type = booleanvalue; @@ -2426,7 +2426,7 @@ yyreduce: break; case 127: -#line 853 "heimdal/lib/asn1/parse.y" +#line 853 "parse.y" { (yyval.value) = emalloc(sizeof(*(yyval.value))); (yyval.value)->type = booleanvalue; @@ -2435,7 +2435,7 @@ yyreduce: break; case 128: -#line 861 "heimdal/lib/asn1/parse.y" +#line 861 "parse.y" { (yyval.value) = emalloc(sizeof(*(yyval.value))); (yyval.value)->type = integervalue; @@ -2444,13 +2444,13 @@ yyreduce: break; case 130: -#line 872 "heimdal/lib/asn1/parse.y" +#line 872 "parse.y" { } break; case 131: -#line 877 "heimdal/lib/asn1/parse.y" +#line 877 "parse.y" { (yyval.value) = emalloc(sizeof(*(yyval.value))); (yyval.value)->type = objectidentifiervalue; @@ -2460,7 +2460,7 @@ yyreduce: /* Line 1267 of yacc.c. */ -#line 2464 "heimdal/lib/asn1/parse.y" +#line 2464 "parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2674,7 +2674,7 @@ yyreturn: } -#line 884 "heimdal/lib/asn1/parse.y" +#line 884 "parse.y" void diff --git a/source4/heimdal/lib/asn1/parse.h b/source4/heimdal/lib/asn1/parse.h index 868bb2543a..a2a9a3a335 100644 --- a/source4/heimdal/lib/asn1/parse.h +++ b/source4/heimdal/lib/asn1/parse.h @@ -222,7 +222,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 65 "heimdal/lib/asn1/parse.y" +#line 65 "parse.y" { int constant; struct value *value; @@ -238,7 +238,7 @@ typedef union YYSTYPE struct constraint_spec *constraint_spec; } /* Line 1489 of yacc.c. */ -#line 242 "heimdal/lib/asn1/parse.y" +#line 242 "parse.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/source4/heimdal/lib/asn1/pkcs12.asn1 b/source4/heimdal/lib/asn1/pkcs12.asn1 index ff512e8255..37fe03e58e 100644 --- a/source4/heimdal/lib/asn1/pkcs12.asn1 +++ b/source4/heimdal/lib/asn1/pkcs12.asn1 @@ -1,4 +1,4 @@ --- $Id: pkcs12.asn1,v 1.3 2005/07/23 11:07:39 lha Exp $ -- +-- $Id: pkcs12.asn1 15715 2005-07-23 11:08:47Z lha $ -- PKCS12 DEFINITIONS ::= diff --git a/source4/heimdal/lib/asn1/pkcs8.asn1 b/source4/heimdal/lib/asn1/pkcs8.asn1 index dc52511bf4..911e727c70 100644 --- a/source4/heimdal/lib/asn1/pkcs8.asn1 +++ b/source4/heimdal/lib/asn1/pkcs8.asn1 @@ -1,4 +1,4 @@ --- $Id: pkcs8.asn1,v 1.3 2005/09/13 19:41:29 lha Exp $ -- +-- $Id: pkcs8.asn1 16060 2005-09-13 19:41:29Z lha $ -- PKCS8 DEFINITIONS ::= diff --git a/source4/heimdal/lib/asn1/pkcs9.asn1 b/source4/heimdal/lib/asn1/pkcs9.asn1 index e6df32f65d..d985e91f3c 100644 --- a/source4/heimdal/lib/asn1/pkcs9.asn1 +++ b/source4/heimdal/lib/asn1/pkcs9.asn1 @@ -1,4 +1,4 @@ --- $Id: pkcs9.asn1,v 1.5 2006/04/24 08:59:10 lha Exp $ -- +-- $Id: pkcs9.asn1 17202 2006-04-24 08:59:10Z lha $ -- PKCS9 DEFINITIONS ::= diff --git a/source4/heimdal/lib/asn1/pkinit.asn1 b/source4/heimdal/lib/asn1/pkinit.asn1 index 56d6611677..e89a7217af 100644 --- a/source4/heimdal/lib/asn1/pkinit.asn1 +++ b/source4/heimdal/lib/asn1/pkinit.asn1 @@ -21,9 +21,15 @@ id-pkinit-san OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2) x509-sanan(2) } +id-pkinit-ms-eku OBJECT IDENTIFIER ::= + { iso(1) org(3) dod(6) internet(1) private(4) + enterprise(1) microsoft(311) 20 2 2 } + id-pkinit-ms-san OBJECT IDENTIFIER ::= - { iso(1) org(3) dod(6) internet(1) foo1(4) - foo2(1) foo3(311) foo4(20) foo5(2) foo6(3) } + { iso(1) org(3) dod(6) internet(1) private(4) + enterprise(1) microsoft(311) 20 2 3 } + +MS-UPN-SAN ::= UTF8String pa-pk-as-req INTEGER ::= 16 pa-pk-as-rep INTEGER ::= 17 diff --git a/source4/heimdal/lib/asn1/rfc2459.asn1 b/source4/heimdal/lib/asn1/rfc2459.asn1 index 430674a5ee..71f197eba7 100644 --- a/source4/heimdal/lib/asn1/rfc2459.asn1 +++ b/source4/heimdal/lib/asn1/rfc2459.asn1 @@ -87,6 +87,7 @@ id-at-serialNumber OBJECT IDENTIFIER ::= { id-x520-at 5 } id-at-countryName OBJECT IDENTIFIER ::= { id-x520-at 6 } id-at-localityName OBJECT IDENTIFIER ::= { id-x520-at 7 } id-at-stateOrProvinceName OBJECT IDENTIFIER ::= { id-x520-at 8 } +id-at-streetAddress OBJECT IDENTIFIER ::= { id-x520-at 9 } id-at-organizationName OBJECT IDENTIFIER ::= { id-x520-at 10 } id-at-organizationalUnitName OBJECT IDENTIFIER ::= { id-x520-at 11 } id-at-name OBJECT IDENTIFIER ::= { id-x520-at 41 } @@ -306,6 +307,32 @@ id-x509-ce-invalidityDate OBJECT IDENTIFIER ::= { id-x509-ce 24 } id-x509-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-x509-ce 29 } id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-x509-ce 54 } +DistributionPointReasonFlags ::= BIT STRING { + unused (0), + keyCompromise (1), + cACompromise (2), + affiliationChanged (3), + superseded (4), + cessationOfOperation (5), + certificateHold (6), + privilegeWithdrawn (7), + aACompromise (8) +} + +DistributionPointName ::= CHOICE { + fullName [0] IMPLICIT -- GeneralNames -- SEQUENCE -- SIZE (1..MAX) -- OF GeneralName, + nameRelativeToCRLIssuer [1] RelativeDistinguishedName +} + +DistributionPoint ::= SEQUENCE { + distributionPoint [0] IMPLICIT heim_any -- DistributionPointName -- OPTIONAL, + reasons [1] IMPLICIT heim_any -- DistributionPointReasonFlags -- OPTIONAL, + cRLIssuer [2] IMPLICIT heim_any -- GeneralNames -- OPTIONAL +} + +CRLDistributionPoints ::= SEQUENCE -- SIZE (1..MAX) -- OF DistributionPoint + + -- rfc3279 DSASigValue ::= SEQUENCE { @@ -406,10 +433,13 @@ CRLReason ::= ENUMERATED { aACompromise (10) } +PKIXXmppAddr ::= UTF8String + id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) } id-pkix-on OBJECT IDENTIFIER ::= { id-pkix 8 } +id-pkix-on-xmppAddr OBJECT IDENTIFIER ::= { id-pkix-on 5 } id-pkix-on-dnsSRV OBJECT IDENTIFIER ::= { id-pkix-on 7 } id-pkix-kp OBJECT IDENTIFIER ::= { id-pkix 3 } @@ -441,4 +471,25 @@ ProxyCertInfo ::= SEQUENCE { proxyPolicy ProxyPolicy } +--- U.S. Federal PKI Common Policy Framework +-- Card Authentication key +id-uspkicommon-card-id OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 6 } +id-uspkicommon-piv-interim OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 9 1 } + +--- Netscape extentions + +id-netscape OBJECT IDENTIFIER ::= + { joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) } +id-netscape-cert-comment OBJECT IDENTIFIER ::= { id-netscape 1 13 } + +--- MS extentions + +id-ms-cert-enroll-domaincontroller OBJECT IDENTIFIER ::= + { 1 3 6 1 4 1 311 20 2 } + +id-ms-client-authentication OBJECT IDENTIFIER ::= + { 1 3 6 1 5 5 7 3 2 } + +-- DER:1e:20:00:44:00:6f:00:6d:00:61:00:69:00:6e:00:43:00:6f:00:6e:00:74:00:72:00:6f:00:6c:00:6c:00:65:00:72 + END diff --git a/source4/heimdal/lib/asn1/symbol.c b/source4/heimdal/lib/asn1/symbol.c index a4e1ed4884..9407915c19 100644 --- a/source4/heimdal/lib/asn1/symbol.c +++ b/source4/heimdal/lib/asn1/symbol.c @@ -34,7 +34,7 @@ #include "gen_locl.h" #include "lex.h" -RCSID("$Id: symbol.c,v 1.10 2005/07/12 06:27:39 lha Exp $"); +RCSID("$Id: symbol.c 15617 2005-07-12 06:27:42Z lha $"); static Hashtab *htab; diff --git a/source4/heimdal/lib/asn1/symbol.h b/source4/heimdal/lib/asn1/symbol.h index 436bd043a1..d07caf5590 100644 --- a/source4/heimdal/lib/asn1/symbol.h +++ b/source4/heimdal/lib/asn1/symbol.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: symbol.h,v 1.14 2006/12/28 17:15:05 lha Exp $ */ +/* $Id: symbol.h 19539 2006-12-28 17:15:05Z lha $ */ #ifndef _SYMBOL_H #define _SYMBOL_H diff --git a/source4/heimdal/lib/asn1/test.asn1 b/source4/heimdal/lib/asn1/test.asn1 index 1a1179bc30..98b507a4da 100644 --- a/source4/heimdal/lib/asn1/test.asn1 +++ b/source4/heimdal/lib/asn1/test.asn1 @@ -1,4 +1,4 @@ --- $Id: test.asn1,v 1.9 2006/09/05 14:00:44 lha Exp $ -- +-- $Id: test.asn1 18013 2006-09-05 14:00:44Z lha $ -- TEST DEFINITIONS ::= diff --git a/source4/heimdal/lib/asn1/timegm.c b/source4/heimdal/lib/asn1/timegm.c index 86df58d700..a6776458cf 100644 --- a/source4/heimdal/lib/asn1/timegm.c +++ b/source4/heimdal/lib/asn1/timegm.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: timegm.c,v 1.11 2006/10/19 16:19:32 lha Exp $"); +RCSID("$Id: timegm.c 18607 2006-10-19 16:19:32Z lha $"); static int is_leap(unsigned y) diff --git a/source4/heimdal/lib/com_err/com_err.c b/source4/heimdal/lib/com_err/com_err.c index 0462fdcc03..faf4294cdd 100644 --- a/source4/heimdal/lib/com_err/com_err.c +++ b/source4/heimdal/lib/com_err/com_err.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: com_err.c,v 1.19 2005/04/24 19:42:39 lha Exp $"); +RCSID("$Id: com_err.c 14930 2005-04-24 19:43:06Z lha $"); #endif #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/com_err/com_err.h b/source4/heimdal/lib/com_err/com_err.h index fe7441108a..bdd764f7e9 100644 --- a/source4/heimdal/lib/com_err/com_err.h +++ b/source4/heimdal/lib/com_err/com_err.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: com_err.h,v 1.11 2005/07/07 14:58:07 lha Exp $ */ +/* $Id: com_err.h 15566 2005-07-07 14:58:07Z lha $ */ /* MIT compatible com_err library */ diff --git a/source4/heimdal/lib/com_err/com_right.h b/source4/heimdal/lib/com_err/com_right.h index 7e7d342e2c..4d929da866 100644 --- a/source4/heimdal/lib/com_err/com_right.h +++ b/source4/heimdal/lib/com_err/com_right.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: com_right.h,v 1.12 2005/02/03 08:43:01 lha Exp $ */ +/* $Id: com_right.h 14551 2005-02-03 08:45:13Z lha $ */ #ifndef __COM_RIGHT_H__ #define __COM_RIGHT_H__ diff --git a/source4/heimdal/lib/com_err/compile_et.c b/source4/heimdal/lib/com_err/compile_et.c index 1b472d8e0f..1057654822 100644 --- a/source4/heimdal/lib/com_err/compile_et.c +++ b/source4/heimdal/lib/com_err/compile_et.c @@ -35,7 +35,7 @@ #include "compile_et.h" #include <getarg.h> -RCSID("$Id: compile_et.c,v 1.19 2005/06/16 19:21:00 lha Exp $"); +RCSID("$Id: compile_et.c 15426 2005-06-16 19:21:42Z lha $"); #include <roken.h> #include <err.h> diff --git a/source4/heimdal/lib/com_err/compile_et.h b/source4/heimdal/lib/com_err/compile_et.h index 6da8c59322..1c7de5a08b 100644 --- a/source4/heimdal/lib/com_err/compile_et.h +++ b/source4/heimdal/lib/com_err/compile_et.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: compile_et.h,v 1.8 2005/06/16 19:21:26 lha Exp $ */ +/* $Id: compile_et.h 15426 2005-06-16 19:21:42Z lha $ */ #ifndef __COMPILE_ET_H__ #define __COMPILE_ET_H__ diff --git a/source4/heimdal/lib/com_err/error.c b/source4/heimdal/lib/com_err/error.c index b22f25b41a..051078025c 100644 --- a/source4/heimdal/lib/com_err/error.c +++ b/source4/heimdal/lib/com_err/error.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: error.c,v 1.15 2001/02/28 20:00:13 joda Exp $"); +RCSID("$Id: error.c 9724 2001-02-28 20:00:13Z joda $"); #endif #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/com_err/lex.c b/source4/heimdal/lib/com_err/lex.c index 4697d0a3fd..c5af2ead5c 100644 --- a/source4/heimdal/lib/com_err/lex.c +++ b/source4/heimdal/lib/com_err/lex.c @@ -1,6 +1,5 @@ -#include "config.h" -#line 3 "lex.yy.c" +#line 3 "lex.c" #define YY_INT_ALIGNED short int @@ -524,7 +523,7 @@ char *yytext; #include "parse.h" #include "lex.h" -RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $"); +RCSID("$Id: lex.l 15143 2005-05-16 08:52:54Z lha $"); static unsigned lineno = 1; static int getstring(void); @@ -533,7 +532,7 @@ static int getstring(void); #undef ECHO -#line 536 "lex.yy.c" +#line 536 "lex.c" #define INITIAL 0 @@ -688,7 +687,7 @@ YY_DECL #line 59 "lex.l" -#line 691 "lex.yy.c" +#line 691 "lex.c" if ( !(yy_init) ) { @@ -852,7 +851,7 @@ YY_RULE_SETUP #line 75 "lex.l" ECHO; YY_BREAK -#line 855 "lex.yy.c" +#line 855 "lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1083,7 +1082,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -1584,7 +1583,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan + * @param str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use diff --git a/source4/heimdal/lib/com_err/lex.h b/source4/heimdal/lib/com_err/lex.h index 9912bf4f09..89f0387655 100644 --- a/source4/heimdal/lib/com_err/lex.h +++ b/source4/heimdal/lib/com_err/lex.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: lex.h,v 1.1 2000/06/22 00:42:52 assar Exp $ */ +/* $Id: lex.h 8451 2000-06-22 00:42:52Z assar $ */ void error_message (const char *, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/source4/heimdal/lib/com_err/parse.c b/source4/heimdal/lib/com_err/parse.c index 9fb19b33ce..4bacb721ca 100644 --- a/source4/heimdal/lib/com_err/parse.c +++ b/source4/heimdal/lib/com_err/parse.c @@ -90,7 +90,7 @@ /* Copy the first part of user declarations. */ -#line 1 "./heimdal/lib/com_err/parse.y" +#line 1 "parse.y" /* * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan @@ -128,7 +128,7 @@ #include "compile_et.h" #include "lex.h" -RCSID("$Id: parse.y,v 1.15 2005/06/16 19:21:42 lha Exp $"); +RCSID("$Id: parse.y 15426 2005-06-16 19:21:42Z lha $"); void yyerror (char *s); static long name2number(const char *str); @@ -163,13 +163,13 @@ extern char *yytext; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 53 "./heimdal/lib/com_err/parse.y" +#line 53 "parse.y" { char *string; int number; } /* Line 187 of yacc.c. */ -#line 173 "./heimdal/lib/com_err/parse.y" +#line 173 "parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -182,7 +182,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 186 "./heimdal/lib/com_err/parse.y" +#line 186 "parse.c" #ifdef short # undef short @@ -1381,14 +1381,14 @@ yyreduce: switch (yyn) { case 6: -#line 73 "./heimdal/lib/com_err/parse.y" +#line 73 "parse.y" { id_str = (yyvsp[(2) - (2)].string); } break; case 7: -#line 79 "./heimdal/lib/com_err/parse.y" +#line 79 "parse.y" { base_id = name2number((yyvsp[(2) - (2)].string)); strlcpy(name, (yyvsp[(2) - (2)].string), sizeof(name)); @@ -1397,7 +1397,7 @@ yyreduce: break; case 8: -#line 85 "./heimdal/lib/com_err/parse.y" +#line 85 "parse.y" { base_id = name2number((yyvsp[(2) - (3)].string)); strlcpy(name, (yyvsp[(3) - (3)].string), sizeof(name)); @@ -1407,14 +1407,14 @@ yyreduce: break; case 11: -#line 98 "./heimdal/lib/com_err/parse.y" +#line 98 "parse.y" { number = (yyvsp[(2) - (2)].number); } break; case 12: -#line 102 "./heimdal/lib/com_err/parse.y" +#line 102 "parse.y" { free(prefix); asprintf (&prefix, "%s_", (yyvsp[(2) - (2)].string)); @@ -1425,7 +1425,7 @@ yyreduce: break; case 13: -#line 110 "./heimdal/lib/com_err/parse.y" +#line 110 "parse.y" { prefix = realloc(prefix, 1); if (prefix == NULL) @@ -1435,7 +1435,7 @@ yyreduce: break; case 14: -#line 117 "./heimdal/lib/com_err/parse.y" +#line 117 "parse.y" { struct error_code *ec = malloc(sizeof(*ec)); @@ -1458,7 +1458,7 @@ yyreduce: break; case 15: -#line 137 "./heimdal/lib/com_err/parse.y" +#line 137 "parse.y" { YYACCEPT; } @@ -1466,7 +1466,7 @@ yyreduce: /* Line 1267 of yacc.c. */ -#line 1470 "./heimdal/lib/com_err/parse.y" +#line 1470 "parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1680,7 +1680,7 @@ yyreturn: } -#line 142 "./heimdal/lib/com_err/parse.y" +#line 142 "parse.y" static long diff --git a/source4/heimdal/lib/com_err/parse.h b/source4/heimdal/lib/com_err/parse.h index cb1d09276c..4c9681ff34 100644 --- a/source4/heimdal/lib/com_err/parse.h +++ b/source4/heimdal/lib/com_err/parse.h @@ -64,13 +64,13 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 53 "./heimdal/lib/com_err/parse.y" +#line 53 "parse.y" { char *string; int number; } /* Line 1489 of yacc.c. */ -#line 74 "./heimdal/lib/com_err/parse.y" +#line 74 "parse.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 8077aeb223..fbc638c48f 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h,v 1.7 2006/12/15 20:02:54 lha Exp $ */ +/* $Id: gssapi.h 21004 2007-06-08 01:53:10Z lha $ */ #ifndef GSSAPI_GSSAPI_H_ #define GSSAPI_GSSAPI_H_ @@ -715,6 +715,23 @@ gss_inquire_cred_by_oid(OM_uint32 *minor_status, gss_buffer_set_t *data_set); /* + * RFC 4401 + */ + +#define GSS_C_PRF_KEY_FULL 0 +#define GSS_C_PRF_KEY_PARTIAL 1 + +OM_uint32 +gss_pseudo_random + (OM_uint32 *minor_status, + gss_ctx_id_t context, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out + ); + +/* * The following routines are obsolete variants of gss_get_mic, * gss_verify_mic, gss_wrap and gss_unwrap. They should be * provided by GSSAPI V2 implementations for backwards diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h index ecd90a6656..cca529fe26 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_krb5.h,v 1.17 2006/11/10 01:05:34 lha Exp $ */ +/* $Id: gssapi_krb5.h 20385 2007-04-18 08:51:32Z lha $ */ #ifndef GSSAPI_KRB5_H_ #define GSSAPI_KRB5_H_ @@ -65,6 +65,7 @@ extern gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X; extern gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X; extern gss_OID GSS_KRB5_SEND_TO_KDC_X; extern gss_OID GSS_KRB5_SET_DEFAULT_REALM_X; +extern gss_OID GSS_KRB5_CCACHE_NAME_X; /* Extensions inquire context */ extern gss_OID GSS_KRB5_GET_TKT_FLAGS_X; extern gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X; diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h index 0a856e39aa..fbb7906369 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_spnego.h,v 1.1 2006/10/07 22:26:21 lha Exp $ */ +/* $Id: gssapi_spnego.h 18335 2006-10-07 22:26:21Z lha $ */ #ifndef GSSAPI_SPNEGO_H_ #define GSSAPI_SPNEGO_H_ diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h index 2bb5ecedf5..403990ad47 100644 --- a/source4/heimdal/lib/gssapi/gssapi_mech.h +++ b/source4/heimdal/lib/gssapi/gssapi_mech.h @@ -298,6 +298,15 @@ typedef OM_uint32 _gss_set_cred_option ( ); +typedef OM_uint32 _gss_pseudo_random( + OM_uint32 *minor_status, + gss_ctx_id_t context, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out + ); + #define GMI_VERSION 1 typedef struct gssapi_mech_interface_desc { @@ -337,6 +346,7 @@ typedef struct gssapi_mech_interface_desc { _gss_inquire_cred_by_oid *gm_inquire_cred_by_oid; _gss_set_sec_context_option *gm_set_sec_context_option; _gss_set_cred_option *gm_set_cred_option; + _gss_pseudo_random *gm_pseudo_random; } gssapi_mech_interface_desc, *gssapi_mech_interface; gssapi_mech_interface diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c index 0123f67e09..619cbf97fc 100644 --- a/source4/heimdal/lib/gssapi/krb5/8003.c +++ b/source4/heimdal/lib/gssapi/krb5/8003.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: 8003.c,v 1.20 2006/10/07 22:13:51 lha Exp $"); +RCSID("$Id: 8003.c 18334 2006-10-07 22:16:04Z lha $"); krb5_error_code _gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p) diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 434fbee352..73b93ceba4 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: accept_sec_context.c,v 1.66 2006/11/13 18:00:54 lha Exp $"); +RCSID("$Id: accept_sec_context.c 20199 2007-02-07 22:36:39Z lha $"); HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab _gsskrb5_keytab; @@ -187,6 +187,7 @@ gsskrb5_accept_delegated_token out: if (ccache) { + /* Don't destroy the default cred cache */ if (delegated_cred_handle == NULL) krb5_cc_close(context, ccache); else diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index e811a99a8b..42b57cdadd 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: acquire_cred.c,v 1.33 2006/11/20 18:09:30 lha Exp $"); +RCSID("$Id: acquire_cred.c 20688 2007-05-17 18:44:31Z lha $"); OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, @@ -301,8 +301,8 @@ OM_uint32 _gsskrb5_acquire_cred if (desired_mechs) { int present = 0; - ret = _gsskrb5_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - desired_mechs, &present); + ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + desired_mechs, &present); if (ret) return ret; if (!present) { @@ -352,16 +352,16 @@ OM_uint32 _gsskrb5_acquire_cred return (ret); } } - ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); + ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) - ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - &handle->mechanisms); + ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); if (ret == GSS_S_COMPLETE) ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)handle, NULL, time_rec, NULL, actual_mechs); if (ret != GSS_S_COMPLETE) { if (handle->mechanisms != NULL) - _gsskrb5_release_oid_set(NULL, &handle->mechanisms); + gss_release_oid_set(NULL, &handle->mechanisms); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); krb5_free_principal(context, handle->principal); free(handle); diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c index 3b0272af80..9a1045a889 100644 --- a/source4/heimdal/lib/gssapi/krb5/add_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: add_cred.c,v 1.10 2006/11/13 18:01:01 lha Exp $"); +RCSID("$Id: add_cred.c 20688 2007-05-17 18:44:31Z lha $"); OM_uint32 _gsskrb5_add_cred ( OM_uint32 *minor_status, @@ -204,12 +204,12 @@ OM_uint32 _gsskrb5_add_cred ( } } } - ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); + ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret) goto failure; - ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - &handle->mechanisms); + ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); if (ret) goto failure; } @@ -243,7 +243,7 @@ OM_uint32 _gsskrb5_add_cred ( if (handle->ccache) krb5_cc_destroy(context, handle->ccache); if (handle->mechanisms) - _gsskrb5_release_oid_set(NULL, &handle->mechanisms); + gss_release_oid_set(NULL, &handle->mechanisms); free(handle); } if (output_cred_handle) diff --git a/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c b/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c deleted file mode 100644 index b0ec2c60d8..0000000000 --- a/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "krb5/gsskrb5_locl.h" - -RCSID("$Id: add_oid_set_member.c,v 1.10 2006/10/07 22:14:00 lha Exp $"); - -OM_uint32 _gsskrb5_add_oid_set_member ( - OM_uint32 * minor_status, - const gss_OID member_oid, - gss_OID_set * oid_set - ) -{ - gss_OID tmp; - size_t n; - OM_uint32 res; - int present; - - res = _gsskrb5_test_oid_set_member(minor_status, member_oid, - *oid_set, &present); - if (res != GSS_S_COMPLETE) - return res; - - if (present) { - *minor_status = 0; - return GSS_S_COMPLETE; - } - - n = (*oid_set)->count + 1; - tmp = realloc ((*oid_set)->elements, n * sizeof(gss_OID_desc)); - if (tmp == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - (*oid_set)->elements = tmp; - (*oid_set)->count = n; - (*oid_set)->elements[n-1] = *member_oid; - *minor_status = 0; - return GSS_S_COMPLETE; -} diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index d1bdbb641f..032da36ebc 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: arcfour.c,v 1.31 2006/11/13 18:01:08 lha Exp $"); +RCSID("$Id: arcfour.c 19031 2006-11-13 18:02:57Z lha $"); /* * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c index f69300b590..c1744abd3b 100644 --- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: canonicalize_name.c,v 1.4 2006/10/07 22:14:08 lha Exp $"); +RCSID("$Id: canonicalize_name.c 18334 2006-10-07 22:16:04Z lha $"); OM_uint32 _gsskrb5_canonicalize_name ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c index e75fe5da9d..6452f802ab 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.c +++ b/source4/heimdal/lib/gssapi/krb5/cfx.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: cfx.c,v 1.25 2006/11/13 18:01:14 lha Exp $"); +RCSID("$Id: cfx.c 19031 2006-11-13 18:02:57Z lha $"); /* * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.h b/source4/heimdal/lib/gssapi/krb5/cfx.h index ce021aa099..672704a841 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.h +++ b/source4/heimdal/lib/gssapi/krb5/cfx.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: cfx.h,v 1.8 2006/11/13 18:01:17 lha Exp $ */ +/* $Id: cfx.h 19031 2006-11-13 18:02:57Z lha $ */ #ifndef GSSAPI_CFX_H_ #define GSSAPI_CFX_H_ 1 diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c index 6b537468df..3f3b59d116 100644 --- a/source4/heimdal/lib/gssapi/krb5/compare_name.c +++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: compare_name.c,v 1.8 2006/11/13 18:01:20 lha Exp $"); +RCSID("$Id: compare_name.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_compare_name (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c index 3e64df03db..a0f075621a 100644 --- a/source4/heimdal/lib/gssapi/krb5/compat.c +++ b/source4/heimdal/lib/gssapi/krb5/compat.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: compat.c,v 1.14 2006/11/13 18:01:23 lha Exp $"); +RCSID("$Id: compat.c 19031 2006-11-13 18:02:57Z lha $"); static krb5_error_code diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c index 9012dd0b7f..b57ac7854e 100644 --- a/source4/heimdal/lib/gssapi/krb5/context_time.c +++ b/source4/heimdal/lib/gssapi/krb5/context_time.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: context_time.c,v 1.14 2006/11/13 18:01:26 lha Exp $"); +RCSID("$Id: context_time.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_lifetime_left(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index 4387a4e6ef..66d797c199 100644 --- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: copy_ccache.c,v 1.17 2006/11/13 18:01:29 lha Exp $"); +RCSID("$Id: copy_ccache.c 20688 2007-05-17 18:44:31Z lha $"); #if 0 OM_uint32 @@ -166,10 +166,10 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, if (id || keytab) { - ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); + ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) - ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - &handle->mechanisms); + ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); if (ret != GSS_S_COMPLETE) { kret = *minor_status; goto out; @@ -181,6 +181,11 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, return GSS_S_COMPLETE; out: + gss_release_oid_set(minor_status, &handle->mechanisms); + if (handle->ccache) + krb5_cc_close(context, handle->ccache); + if (handle->keytab) + krb5_kt_close(context, handle->keytab); if (handle->principal) krb5_free_principal(context, handle->principal); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); diff --git a/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c b/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c deleted file mode 100644 index 550995125a..0000000000 --- a/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "krb5/gsskrb5_locl.h" - -RCSID("$Id: create_emtpy_oid_set.c,v 1.7 2006/10/07 22:14:24 lha Exp $"); - -OM_uint32 _gsskrb5_create_empty_oid_set ( - OM_uint32 * minor_status, - gss_OID_set * oid_set - ) -{ - *oid_set = malloc(sizeof(**oid_set)); - if (*oid_set == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - (*oid_set)->count = 0; - (*oid_set)->elements = NULL; - *minor_status = 0; - return GSS_S_COMPLETE; -} diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c index eadec1ef03..39176faff4 100644 --- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: decapsulate.c,v 1.16 2006/10/07 22:14:26 lha Exp $"); +RCSID("$Id: decapsulate.c 18334 2006-10-07 22:16:04Z lha $"); /* * return the length of the mechanism in token or -1 diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index c7f2ee262d..abad986550 100644 --- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: delete_sec_context.c,v 1.20 2006/11/13 18:01:32 lha Exp $"); +RCSID("$Id: delete_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_delete_sec_context(OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c index 4956c2d77f..93fac8d67b 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_name.c +++ b/source4/heimdal/lib/gssapi/krb5/display_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_name.c,v 1.13 2006/11/13 18:01:36 lha Exp $"); +RCSID("$Id: display_name.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_display_name (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index b0155a7fdf..c0192522a7 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_status.c,v 1.17 2006/11/13 18:01:38 lha Exp $"); +RCSID("$Id: display_status.c 19031 2006-11-13 18:02:57Z lha $"); static const char * calling_error(OM_uint32 v) diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c index 8375257180..7337f1ab72 100644 --- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c +++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: duplicate_name.c,v 1.11 2006/11/13 18:01:42 lha Exp $"); +RCSID("$Id: duplicate_name.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_duplicate_name ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c index a015a95103..58dcb5c9c4 100644 --- a/source4/heimdal/lib/gssapi/krb5/encapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: encapsulate.c,v 1.12 2006/10/14 10:02:56 lha Exp $"); +RCSID("$Id: encapsulate.c 18459 2006-10-14 10:12:16Z lha $"); void _gssapi_encap_length (size_t data_len, diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c index 646fdafb7c..efa45a2638 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_name.c +++ b/source4/heimdal/lib/gssapi/krb5/export_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: export_name.c,v 1.9 2006/11/13 18:01:50 lha Exp $"); +RCSID("$Id: export_name.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_export_name (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c index ffa671a4a1..00218617a0 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: export_sec_context.c,v 1.12 2006/11/13 18:01:55 lha Exp $"); +RCSID("$Id: export_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_export_sec_context ( diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index bf7f64cf20..d4c1bc4db2 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,7 +34,7 @@ #include "krb5/gsskrb5_locl.h" #include <gssapi_mech.h> -RCSID("$Id: external.c,v 1.23 2006/11/13 18:01:57 lha Exp $"); +RCSID("$Id: external.c 20386 2007-04-18 08:52:08Z lha $"); /* * The implementation must reserve static storage for a @@ -358,6 +358,11 @@ static gss_OID_desc gss_krb5_set_default_realm_x_desc = gss_OID GSS_KRB5_SET_DEFAULT_REALM_X = &gss_krb5_set_default_realm_x_desc; +/* 1.2.752.43.13.16 */ +static gss_OID_desc gss_krb5_ccache_name_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")}; + +gss_OID GSS_KRB5_CCACHE_NAME_X = &gss_krb5_ccache_name_x_desc; /* 1.2.752.43.14.1 */ static gss_OID_desc gss_sasl_digest_md5_mechanism_desc = @@ -411,7 +416,8 @@ static gssapi_mech_interface_desc krb5_mech = { _gsskrb5_inquire_sec_context_by_oid, _gsskrb5_inquire_cred_by_oid, _gsskrb5_set_sec_context_option, - _gsskrb5_set_cred_option + _gsskrb5_set_cred_option, + _gsskrb5_pseudo_random }; gssapi_mech_interface diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 790c9b6166..133481ffe1 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: get_mic.c,v 1.35 2006/11/13 18:02:00 lha Exp $"); +RCSID("$Id: get_mic.c 19031 2006-11-13 18:02:57Z lha $"); static OM_uint32 mic_des diff --git a/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et b/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et index 97e98c5e1e..dbfdbdf2f1 100644 --- a/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et +++ b/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et @@ -2,7 +2,7 @@ # extended gss krb5 error messages # -id "$Id: gkrb5_err.et,v 1.1 2006/11/09 23:52:17 lha Exp $" +id "$Id: gkrb5_err.et 20049 2007-01-24 00:14:24Z lha $" error_table gk5 @@ -28,3 +28,4 @@ error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established" error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token" error_code KG_BAD_LENGTH, "Invalid field length in token" error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context" +error_code KG_INPUT_TOO_LONG, "Input too long" diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h index 15bd5c77da..c2239f1346 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h @@ -240,12 +240,6 @@ _gsskrb5_add_cred ( OM_uint32 */*acceptor_time_rec*/); OM_uint32 -_gsskrb5_add_oid_set_member ( - OM_uint32 * /*minor_status*/, - const gss_OID /*member_oid*/, - gss_OID_set * oid_set ); - -OM_uint32 _gsskrb5_canonicalize_name ( OM_uint32 * /*minor_status*/, const gss_name_t /*input_name*/, @@ -285,11 +279,6 @@ _gsskrb5_create_ctx ( enum gss_ctx_id_t_state /*state*/); OM_uint32 -_gsskrb5_create_empty_oid_set ( - OM_uint32 * /*minor_status*/, - gss_OID_set * oid_set ); - -OM_uint32 _gsskrb5_decapsulate ( OM_uint32 */*minor_status*/, gss_buffer_t /*input_token_buffer*/, @@ -521,6 +510,15 @@ _gsskrb5_process_context_token ( const gss_buffer_t token_buffer ); OM_uint32 +_gsskrb5_pseudo_random ( + OM_uint32 */*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*prf_key*/, + const gss_buffer_t /*prf_in*/, + ssize_t /*desired_output_len*/, + gss_buffer_t /*prf_out*/); + +OM_uint32 _gsskrb5_register_acceptor_identity (const char */*identity*/); OM_uint32 @@ -539,11 +537,6 @@ _gsskrb5_release_name ( gss_name_t * input_name ); OM_uint32 -_gsskrb5_release_oid_set ( - OM_uint32 * /*minor_status*/, - gss_OID_set * set ); - -OM_uint32 _gsskrb5_seal ( OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, @@ -581,13 +574,6 @@ _gsskrb5_sign ( gss_buffer_t message_token ); OM_uint32 -_gsskrb5_test_oid_set_member ( - OM_uint32 * /*minor_status*/, - const gss_OID /*member*/, - const gss_OID_set /*set*/, - int * present ); - -OM_uint32 _gsskrb5_unseal ( OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 1983a9b8e4..6ffb607035 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gsskrb5_locl.h,v 1.9 2006/11/13 18:02:03 lha Exp $ */ +/* $Id: gsskrb5_locl.h 20324 2007-04-12 16:46:01Z lha $ */ #ifndef GSSKRB5_LOCL_H #define GSSKRB5_LOCL_H @@ -92,6 +92,7 @@ typedef struct { gss_OID_set mechanisms; struct krb5_ccache_data *ccache; HEIMDAL_MUTEX cred_id_mutex; + krb5_enctype *enctypes; } *gsskrb5_cred; typedef struct Principal *gsskrb5_name; diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index 15311b4614..bf31db9232 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_name.c,v 1.18 2006/11/13 18:02:06 lha Exp $"); +RCSID("$Id: import_name.c 19031 2006-11-13 18:02:57Z lha $"); static OM_uint32 parse_krb5_name (OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c index bbdc1d36d0..3300036a81 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_sec_context.c,v 1.18 2006/11/13 18:02:09 lha Exp $"); +RCSID("$Id: import_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_import_sec_context ( diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c index 3827533219..eb886c24d3 100644 --- a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c +++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: indicate_mechs.c,v 1.9 2006/10/07 22:14:56 lha Exp $"); +RCSID("$Id: indicate_mechs.c 20688 2007-05-17 18:44:31Z lha $"); OM_uint32 _gsskrb5_indicate_mechs (OM_uint32 * minor_status, @@ -42,14 +42,13 @@ OM_uint32 _gsskrb5_indicate_mechs { OM_uint32 ret, junk; - ret = _gsskrb5_create_empty_oid_set(minor_status, mech_set); + ret = gss_create_empty_oid_set(minor_status, mech_set); if (ret) return ret; - ret = _gsskrb5_add_oid_set_member(minor_status, - GSS_KRB5_MECHANISM, mech_set); + ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set); if (ret) { - _gsskrb5_release_oid_set(&junk, mech_set); + gss_release_oid_set(&junk, mech_set); return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/init.c b/source4/heimdal/lib/gssapi/krb5/init.c index 3eece8e086..3bbdcc8ff1 100644 --- a/source4/heimdal/lib/gssapi/krb5/init.c +++ b/source4/heimdal/lib/gssapi/krb5/init.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init.c,v 1.10 2006/11/13 18:02:12 lha Exp $"); +RCSID("$Id: init.c 19031 2006-11-13 18:02:57Z lha $"); static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; static int created_key; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index d5f183b0ba..4d1ae0daa9 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init_sec_context.c,v 1.75 2006/12/13 10:33:20 lha Exp $"); +RCSID("$Id: init_sec_context.c 20326 2007-04-12 16:49:57Z lha $"); /* * copy the addresses from `input_chan_bindings' (if any) to @@ -391,6 +391,20 @@ init_auth goto failure; + /* + * This is hideous glue for (NFS) clients that wants to limit the + * available enctypes to what it can support (encryption in + * kernel). If there is no enctypes selected for this credential, + * reset it to the default set of enctypes. + */ + { + krb5_enctype *enctypes = NULL; + + if (initiator_cred_handle && initiator_cred_handle->enctypes) + enctypes = initiator_cred_handle->enctypes; + krb5_set_default_in_tkt_etypes(context, enctypes); + } + ret = gsskrb5_get_creds(minor_status, context, ccache, @@ -476,11 +490,8 @@ init_auth if (req_flags & GSS_C_EXTENDED_ERROR_FLAG) flags |= GSS_C_EXTENDED_ERROR_FLAG; - if (req_flags & GSS_C_CONF_FLAG) - flags |= GSS_C_CONF_FLAG; - if (req_flags & GSS_C_INTEG_FLAG) - flags |= GSS_C_INTEG_FLAG; - + flags |= GSS_C_CONF_FLAG; + flags |= GSS_C_INTEG_FLAG; flags |= GSS_C_TRANS_FLAG; if (ret_flags) diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c index bdaa01b108..41430568b0 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_context.c,v 1.11 2006/11/13 18:02:18 lha Exp $"); +RCSID("$Id: inquire_context.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_inquire_context ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c index 74018559a0..47bf71e686 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_cred.c,v 1.13 2006/11/13 18:02:21 lha Exp $"); +RCSID("$Id: inquire_cred.c 20688 2007-05-17 18:44:31Z lha $"); OM_uint32 _gsskrb5_inquire_cred (OM_uint32 * minor_status, @@ -80,7 +80,7 @@ OM_uint32 _gsskrb5_inquire_cred NULL, NULL); if (ret == GSS_S_COMPLETE) - acred = (gsskrb5_cred)aqcred_init; + icred = (gsskrb5_cred)aqcred_init; if (icred == NULL && acred == NULL) { *minor_status = 0; @@ -98,7 +98,7 @@ OM_uint32 _gsskrb5_inquire_cred if (icred && icred->principal != NULL) { gss_name_t name; - if (acred) + if (acred && acred->principal) name = (gss_name_t)acred->principal; else name = (gss_name_t)icred->principal; @@ -152,17 +152,17 @@ OM_uint32 _gsskrb5_inquire_cred } if (mechanisms != NULL) { - ret = _gsskrb5_create_empty_oid_set(minor_status, mechanisms); + ret = gss_create_empty_oid_set(minor_status, mechanisms); if (ret) goto out; if (acred) - ret = _gsskrb5_add_oid_set_member(minor_status, - &acred->mechanisms->elements[0], - mechanisms); + ret = gss_add_oid_set_member(minor_status, + &acred->mechanisms->elements[0], + mechanisms); if (ret == GSS_S_COMPLETE && icred) - ret = _gsskrb5_add_oid_set_member(minor_status, - &icred->mechanisms->elements[0], - mechanisms); + ret = gss_add_oid_set_member(minor_status, + &icred->mechanisms->elements[0], + mechanisms); if (ret) goto out; } diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c index 954a5e3119..a8af2145be 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Kungliga Tekniska Högskolan + * Copyright (c) 2003, 2006, 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_cred_by_mech.c,v 1.4 2006/10/07 22:15:08 lha Exp $"); +RCSID("$Id: inquire_cred_by_mech.c 20634 2007-05-09 15:33:01Z lha $"); OM_uint32 _gsskrb5_inquire_cred_by_mech ( OM_uint32 * minor_status, @@ -45,39 +45,32 @@ OM_uint32 _gsskrb5_inquire_cred_by_mech ( gss_cred_usage_t * cred_usage ) { - OM_uint32 ret; + gss_cred_usage_t usage; + OM_uint32 maj_stat; OM_uint32 lifetime; - if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 && - gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) { - *minor_status = EINVAL; - return GSS_S_BAD_MECH; - } + maj_stat = + _gsskrb5_inquire_cred (minor_status, cred_handle, + name, &lifetime, &usage, NULL); + if (maj_stat) + return maj_stat; - ret = _gsskrb5_inquire_cred (minor_status, - cred_handle, - name, - &lifetime, - cred_usage, - NULL); - - if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) { - gsskrb5_cred cred = (gsskrb5_cred)cred_handle; - gss_cred_usage_t usage; - - HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); - usage = cred->usage; - HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); - - if (initiator_lifetime) { - if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) - *initiator_lifetime = lifetime; - } - if (acceptor_lifetime) { - if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH) - *acceptor_lifetime = lifetime; - } + if (initiator_lifetime) { + if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) + *initiator_lifetime = lifetime; + else + *initiator_lifetime = 0; } + + if (acceptor_lifetime) { + if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH) + *acceptor_lifetime = lifetime; + else + *acceptor_lifetime = 0; + } + + if (cred_usage) + *cred_usage = usage; - return ret; + return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c index 1a36896019..da50b11d93 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_cred_by_oid.c,v 1.5 2006/11/13 18:02:24 lha Exp $"); +RCSID("$Id: inquire_cred_by_oid.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c index 5c1f082f45..0ce051f19c 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_mechs_for_name.c,v 1.3 2006/10/07 22:15:13 lha Exp $"); +RCSID("$Id: inquire_mechs_for_name.c 20688 2007-05-17 18:44:31Z lha $"); OM_uint32 _gsskrb5_inquire_mechs_for_name ( OM_uint32 * minor_status, @@ -43,15 +43,15 @@ OM_uint32 _gsskrb5_inquire_mechs_for_name ( { OM_uint32 ret; - ret = _gsskrb5_create_empty_oid_set(minor_status, mech_types); + ret = gss_create_empty_oid_set(minor_status, mech_types); if (ret) return ret; - ret = _gsskrb5_add_oid_set_member(minor_status, - GSS_KRB5_MECHANISM, - mech_types); + ret = gss_add_oid_set_member(minor_status, + GSS_KRB5_MECHANISM, + mech_types); if (ret) - _gsskrb5_release_oid_set(NULL, mech_types); + gss_release_oid_set(NULL, mech_types); return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c index 5d8aefab1c..64abd3c34a 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_names_for_mech.c,v 1.3 2006/10/07 22:15:15 lha Exp $"); +RCSID("$Id: inquire_names_for_mech.c 20688 2007-05-17 18:44:31Z lha $"); static gss_OID *name_list[] = { @@ -61,20 +61,20 @@ OM_uint32 _gsskrb5_inquire_names_for_mech ( return GSS_S_BAD_MECH; } - ret = _gsskrb5_create_empty_oid_set(minor_status, name_types); + ret = gss_create_empty_oid_set(minor_status, name_types); if (ret != GSS_S_COMPLETE) return ret; for (i = 0; name_list[i] != NULL; i++) { - ret = _gsskrb5_add_oid_set_member(minor_status, - *(name_list[i]), - name_types); + ret = gss_add_oid_set_member(minor_status, + *(name_list[i]), + name_types); if (ret != GSS_S_COMPLETE) break; } if (ret != GSS_S_COMPLETE) - _gsskrb5_release_oid_set(NULL, name_types); + gss_release_oid_set(NULL, name_types); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c index 97e86a95c7..5ca7536e6a 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_sec_context_by_oid.c,v 1.12 2006/11/13 18:02:27 lha Exp $"); +RCSID("$Id: inquire_sec_context_by_oid.c 19031 2006-11-13 18:02:57Z lha $"); static int oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c new file mode 100644 index 0000000000..3eb90d279f --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/prf.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: prf.c 20679 2007-05-14 03:12:05Z lha $"); + +OM_uint32 +_gsskrb5_pseudo_random(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out) +{ + gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle; + krb5_context context; + krb5_error_code ret; + krb5_crypto crypto; + krb5_data input, output; + uint32_t num; + unsigned char *p; + krb5_keyblock *key = NULL; + + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + if (desired_output_len <= 0) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + GSSAPI_KRB5_INIT (&context); + + switch(prf_key) { + case GSS_C_PRF_KEY_FULL: + _gsskrb5i_get_acceptor_subkey(ctx, context, &key); + case GSS_C_PRF_KEY_PARTIAL: + _gsskrb5i_get_initiator_subkey(ctx, context, &key); + break; + default: + _gsskrb5_set_status("unknown kerberos prf_key"); + *minor_status = 0; + return GSS_S_FAILURE; + } + + if (key == NULL) { + _gsskrb5_set_status("no prf_key found"); + *minor_status = 0; + return GSS_S_FAILURE; + } + + ret = krb5_crypto_init(context, key, 0, &crypto); + krb5_free_keyblock (context, key); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + prf_out->value = malloc(desired_output_len); + if (prf_out->value == NULL) { + _gsskrb5_set_status("Out of memory"); + *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG; + krb5_crypto_destroy(context, crypto); + return GSS_S_FAILURE; + } + prf_out->length = desired_output_len; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + input.length = prf_in->length + 4; + input.data = malloc(prf_in->length + 4); + if (input.data == NULL) { + OM_uint32 junk; + _gsskrb5_set_status("Out of memory"); + *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG; + gss_release_buffer(&junk, prf_out); + krb5_crypto_destroy(context, crypto); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_FAILURE; + } + memcpy(((unsigned char *)input.data) + 4, prf_in->value, prf_in->length); + + num = 0; + p = prf_out->value; + while(desired_output_len > 0) { + _gsskrb5_encode_om_uint32(num, input.data); + ret = krb5_crypto_prf(context, crypto, &input, &output); + if (ret) { + OM_uint32 junk; + *minor_status = ret; + free(input.data); + gss_release_buffer(&junk, prf_out); + krb5_crypto_destroy(context, crypto); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_FAILURE; + } + memcpy(p, output.data, min(desired_output_len, output.length)); + p += output.length; + desired_output_len -= output.length; + krb5_data_free(&output); + num++; + } + + krb5_crypto_destroy(context, crypto); + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c index 411d689635..15638f57fc 100644 --- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c +++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: process_context_token.c,v 1.5 2006/11/13 18:02:30 lha Exp $"); +RCSID("$Id: process_context_token.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_process_context_token ( OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c index b62ad02117..5dff62631a 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_buffer.c +++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_buffer.c,v 1.7 2006/10/07 22:15:22 lha Exp $"); +RCSID("$Id: release_buffer.c 18334 2006-10-07 22:16:04Z lha $"); OM_uint32 _gsskrb5_release_buffer (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c index f6d98b29c6..ab5695b097 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_cred.c,v 1.14 2006/11/13 18:02:34 lha Exp $"); +RCSID("$Id: release_cred.c 20753 2007-05-31 22:50:06Z lha $"); OM_uint32 _gsskrb5_release_cred (OM_uint32 * minor_status, @@ -42,6 +42,7 @@ OM_uint32 _gsskrb5_release_cred { krb5_context context; gsskrb5_cred cred; + OM_uint32 junk; *minor_status = 0; @@ -67,7 +68,9 @@ OM_uint32 _gsskrb5_release_cred else krb5_cc_close(context, cred->ccache); } - _gsskrb5_release_oid_set(NULL, &cred->mechanisms); + gss_release_oid_set(&junk, &cred->mechanisms); + if (cred->enctypes) + free(cred->enctypes); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); HEIMDAL_MUTEX_destroy(&cred->cred_id_mutex); memset(cred, 0, sizeof(*cred)); diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c index cc9c0934f7..a01a9a2a62 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_name.c +++ b/source4/heimdal/lib/gssapi/krb5/release_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_name.c,v 1.11 2006/11/13 18:02:37 lha Exp $"); +RCSID("$Id: release_name.c 19031 2006-11-13 18:02:57Z lha $"); OM_uint32 _gsskrb5_release_name (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/release_oid_set.c b/source4/heimdal/lib/gssapi/krb5/release_oid_set.c deleted file mode 100644 index a9f79a3082..0000000000 --- a/source4/heimdal/lib/gssapi/krb5/release_oid_set.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1997 - 2000, 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "krb5/gsskrb5_locl.h" - -RCSID("$Id: release_oid_set.c,v 1.7 2006/10/07 22:15:30 lha Exp $"); - -OM_uint32 _gsskrb5_release_oid_set - (OM_uint32 * minor_status, - gss_OID_set * set - ) -{ - if (minor_status) - *minor_status = 0; - free ((*set)->elements); - free (*set); - *set = GSS_C_NO_OID_SET; - return GSS_S_COMPLETE; -} diff --git a/source4/heimdal/lib/gssapi/krb5/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c index 3014edd04d..677a3c8d07 100755 --- a/source4/heimdal/lib/gssapi/krb5/sequence.c +++ b/source4/heimdal/lib/gssapi/krb5/sequence.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: sequence.c,v 1.8 2006/10/07 22:15:32 lha Exp $"); +RCSID("$Id: sequence.c 18334 2006-10-07 22:16:04Z lha $"); #define DEFAULT_JITTER_WINDOW 20 diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 849760ee4a..d0ca1c4d95 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_cred_option.c,v 1.5 2006/11/13 18:02:39 lha Exp $"); +RCSID("$Id: set_cred_option.c 20325 2007-04-12 16:49:17Z lha $"); static gss_OID_desc gss_krb5_import_cred_x_oid_desc = {9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */ @@ -130,6 +130,78 @@ out: } +static OM_uint32 +allowed_enctypes(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + OM_uint32 major_stat; + krb5_error_code ret; + size_t len, i; + krb5_enctype *enctypes = NULL; + krb5_storage *sp = NULL; + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + + if ((value->length % 4) != 0) { + *minor_status = 0; + major_stat = GSS_S_FAILURE; + goto out; + } + + len = value->length / 4; + enctypes = malloc((len + 1) * 4); + if (enctypes == NULL) { + *minor_status = ENOMEM; + major_stat = GSS_S_FAILURE; + goto out; + } + + sp = krb5_storage_from_mem(value->value, value->length); + if (sp == NULL) { + *minor_status = ENOMEM; + major_stat = GSS_S_FAILURE; + goto out; + } + + for (i = 0; i < len; i++) { + uint32_t e; + + ret = krb5_ret_uint32(sp, &e); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + enctypes[i] = e; + } + enctypes[i] = 0; + + if (cred->enctypes) + free(cred->enctypes); + cred->enctypes = enctypes; + + krb5_storage_free(sp); + + return GSS_S_COMPLETE; + +out: + if (sp) + krb5_storage_free(sp); + if (enctypes) + free(enctypes); + + return major_stat; +} + + OM_uint32 _gsskrb5_set_cred_option (OM_uint32 *minor_status, @@ -146,9 +218,11 @@ _gsskrb5_set_cred_option return GSS_S_FAILURE; } - if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) { + if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) return import_cred(minor_status, context, cred_handle, value); - } + + if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X)) + return allowed_enctypes(minor_status, context, cred_handle, value); *minor_status = EINVAL; return GSS_S_FAILURE; diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c index 4a5f60ce94..50441a11ad 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -36,7 +36,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_sec_context_option.c,v 1.10 2006/12/14 11:02:16 lha Exp $"); +RCSID("$Id: set_sec_context_option.c 20384 2007-04-18 08:51:06Z lha $"); static OM_uint32 get_bool(OM_uint32 *minor_status, @@ -51,6 +51,25 @@ get_bool(OM_uint32 *minor_status, return GSS_S_COMPLETE; } +static OM_uint32 +get_string(OM_uint32 *minor_status, + const gss_buffer_t value, + char **str) +{ + if (value == NULL || value->length == 0) { + *str = NULL; + } else { + *str = malloc(value->length + 1); + if (*str == NULL) { + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + memcpy(*str, value->value, value->length); + (*str)[value->length] = '\0'; + } + return GSS_S_COMPLETE; +} + OM_uint32 _gsskrb5_set_sec_context_option (OM_uint32 *minor_status, @@ -103,17 +122,9 @@ _gsskrb5_set_sec_context_option } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { char *str; - if (value == NULL || value->length == 0) { - str = NULL; - } else { - str = malloc(value->length + 1); - if (str) { - *minor_status = 0; - return GSS_S_UNAVAILABLE; - } - memcpy(str, value->value, value->length); - str[value->length] = '\0'; - } + maj_stat = get_string(minor_status, value, &str); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; _gsskrb5_register_acceptor_identity(str); free(str); @@ -124,17 +135,13 @@ _gsskrb5_set_sec_context_option } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) { char *str; - if (value == NULL || value->length == 0) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_READ; - } - str = malloc(value->length + 1); + maj_stat = get_string(minor_status, value, &str); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; if (str == NULL) { *minor_status = 0; - return GSS_S_UNAVAILABLE; + return GSS_S_CALL_INACCESSIBLE_READ; } - memcpy(str, value->value, value->length); - str[value->length] = '\0'; krb5_set_default_realm(context, str); free(str); @@ -161,8 +168,24 @@ _gsskrb5_set_sec_context_option *minor_status = 0; return GSS_S_COMPLETE; - } + } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) { + char *str; + + maj_stat = get_string(minor_status, value, &str); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + if (str == NULL) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_READ; + } + *minor_status = krb5_cc_set_default_name(context, str); + free(str); + if (*minor_status) + return GSS_S_FAILURE; + + return GSS_S_COMPLETE; + } *minor_status = EINVAL; return GSS_S_FAILURE; diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index 3dd7618561..d0a33d86fb 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: unwrap.c,v 1.39 2006/11/13 18:02:51 lha Exp $"); +RCSID("$Id: unwrap.c 19031 2006-11-13 18:02:57Z lha $"); static OM_uint32 unwrap_des diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 29b3a7f4bb..52381afcc2 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: verify_mic.c,v 1.37 2006/11/13 18:02:54 lha Exp $"); +RCSID("$Id: verify_mic.c 19031 2006-11-13 18:02:57Z lha $"); static OM_uint32 verify_mic_des diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index 79cfb48ed2..d41379870a 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: wrap.c,v 1.39 2006/11/14 09:49:56 lha Exp $"); +RCSID("$Id: wrap.c 19035 2006-11-14 09:49:56Z lha $"); /* * Return initiator subkey, or if that doesn't exists, the subkey. diff --git a/source4/heimdal/lib/gssapi/mech/context.c b/source4/heimdal/lib/gssapi/mech/context.c new file mode 100644 index 0000000000..1691fd9401 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/context.c @@ -0,0 +1,141 @@ +#include "mech/mech_locl.h" +#include "heim_threads.h" + +RCSID("$Id: context.c 19924 2007-01-16 10:17:01Z lha $"); + +struct mg_thread_ctx { + gss_OID mech; + OM_uint32 maj_stat; + OM_uint32 min_stat; + gss_buffer_desc maj_error; + gss_buffer_desc min_error; +}; + +static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static int created_key; +static HEIMDAL_thread_key context_key; + + +static void +destroy_context(void *ptr) +{ + struct mg_thread_ctx *mg = ptr; + OM_uint32 junk; + + if (mg == NULL) + return; + + gss_release_buffer(&junk, &mg->maj_error); + gss_release_buffer(&junk, &mg->min_error); + free(mg); +} + + +static struct mg_thread_ctx * +_gss_mechglue_thread(void) +{ + struct mg_thread_ctx *ctx; + int ret = 0; + + HEIMDAL_MUTEX_lock(&context_mutex); + + if (!created_key) { + HEIMDAL_key_create(&context_key, destroy_context, ret); + if (ret) { + HEIMDAL_MUTEX_unlock(&context_mutex); + return NULL; + } + created_key = 1; + } + HEIMDAL_MUTEX_unlock(&context_mutex); + + ctx = HEIMDAL_getspecific(context_key); + if (ctx == NULL) { + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + HEIMDAL_setspecific(context_key, ctx, ret); + if (ret) { + free(ctx); + return NULL; + } + } + return ctx; +} + +OM_uint32 +_gss_mg_get_error(const gss_OID mech, OM_uint32 type, + OM_uint32 value, gss_buffer_t string) +{ + struct mg_thread_ctx *mg; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return GSS_S_BAD_STATUS; + + if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0) + return GSS_S_BAD_STATUS; + + switch (type) { + case GSS_C_GSS_CODE: { + if (value != mg->maj_stat) + break; + string->value = malloc(mg->maj_error.length); + string->length = mg->maj_error.length; + memcpy(string->value, mg->maj_error.value, mg->maj_error.length); + return GSS_S_COMPLETE; + } + case GSS_C_MECH_CODE: { + if (value != mg->min_stat) + break; + string->value = malloc(mg->min_error.length); + string->length = mg->min_error.length; + memcpy(string->value, mg->min_error.value, mg->min_error.length); + return GSS_S_COMPLETE; + } + } + string->value = NULL; + string->length = 0; + return GSS_S_BAD_STATUS; +} + +void +_gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min) +{ + OM_uint32 major_status, minor_status; + OM_uint32 message_content; + struct mg_thread_ctx *mg; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return; + + gss_release_buffer(&minor_status, &mg->maj_error); + gss_release_buffer(&minor_status, &mg->min_error); + + mg->mech = &m->gm_mech_oid; + mg->maj_stat = maj; + mg->min_stat = min; + + major_status = m->gm_display_status(&minor_status, + maj, + GSS_C_GSS_CODE, + &m->gm_mech_oid, + &message_content, + &mg->maj_error); + if (GSS_ERROR(major_status)) { + mg->maj_error.value = NULL; + mg->maj_error.length = 0; + } + major_status = m->gm_display_status(&minor_status, + min, + GSS_C_MECH_CODE, + &m->gm_mech_oid, + &message_content, + &mg->min_error); + if (GSS_ERROR(major_status)) { + mg->min_error.value = NULL; + mg->min_error.length = 0; + } +} diff --git a/source4/heimdal/lib/gssapi/mech/context.h b/source4/heimdal/lib/gssapi/mech/context.h index 7a215dd7d8..24e529864d 100644 --- a/source4/heimdal/lib/gssapi/mech/context.h +++ b/source4/heimdal/lib/gssapi/mech/context.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/context.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: context.h,v 1.2 2006/06/28 09:00:25 lha Exp $ + * $Id: context.h 19925 2007-01-16 10:19:27Z lha $ */ #include <gssapi_mech.h> @@ -33,3 +33,9 @@ struct _gss_context { gssapi_mech_interface gc_mech; gss_ctx_id_t gc_ctx; }; + +void +_gss_mg_error(gssapi_mech_interface, OM_uint32, OM_uint32); + +OM_uint32 +_gss_mg_get_error(const gss_OID, OM_uint32, OM_uint32, gss_buffer_t); diff --git a/source4/heimdal/lib/gssapi/mech/cred.h b/source4/heimdal/lib/gssapi/mech/cred.h index df89e79727..7f77b8a68e 100644 --- a/source4/heimdal/lib/gssapi/mech/cred.h +++ b/source4/heimdal/lib/gssapi/mech/cred.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/cred.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: cred.h,v 1.3 2006/10/05 18:26:54 lha Exp $ + * $Id: cred.h 20626 2007-05-08 13:56:49Z lha $ */ struct _gss_mechanism_cred { @@ -36,7 +36,6 @@ struct _gss_mechanism_cred { SLIST_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred); struct _gss_cred { - gss_cred_usage_t gc_usage; struct _gss_mechanism_cred_list gc_mc; }; diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index 7df8a3483e..8c5f4d0b08 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_accept_sec_context.c,v 1.9 2006/12/15 20:12:20 lha Exp $"); +RCSID("$Id: gss_accept_sec_context.c 20626 2007-05-08 13:56:49Z lha $"); static OM_uint32 parse_header(const gss_buffer_t input_token, gss_OID mech_oid) @@ -127,10 +127,10 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid) return GSS_S_COMPLETE; } else if (input->length == 0) { /* - * There is the a wiered mode of SPNEGO (in CIFS and + * There is the a wierd mode of SPNEGO (in CIFS and * SASL GSS-SPENGO where the first token is zero * length and the acceptor returns a mech_list, lets - * home that is what is happening now. + * hope that is what is happening now. */ *mech_oid = spnego_mechanism; return GSS_S_COMPLETE; @@ -161,13 +161,18 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, int allocated_ctx; *minor_status = 0; - if (src_name) *src_name = 0; - if (mech_type) *mech_type = 0; - if (ret_flags) *ret_flags = 0; - if (time_rec) *time_rec = 0; - if (delegated_cred_handle) *delegated_cred_handle = 0; - output_token->length = 0; - output_token->value = 0; + if (src_name) + *src_name = GSS_C_NO_NAME; + if (mech_type) + *mech_type = GSS_C_NO_OID; + if (ret_flags) + *ret_flags = 0; + if (time_rec) + *time_rec = 0; + if (delegated_cred_handle) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + _mg_buffer_zero(output_token); + /* * If this is the first call (*context_handle is NULL), we must @@ -227,7 +232,10 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, &delegated_mc); if (major_status != GSS_S_COMPLETE && major_status != GSS_S_CONTINUE_NEEDED) + { + _gss_mg_error(m, major_status, *minor_status); return (major_status); + } if (!src_name) { m->gm_release_name(minor_status, &src_mn); @@ -264,8 +272,6 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, *minor_status = ENOMEM; return (GSS_S_FAILURE); } - m->gm_inquire_cred(minor_status, delegated_mc, - 0, 0, &dcred->gc_usage, 0); dmc->gmc_mech = m; dmc->gmc_mech_oid = &m->gm_mech_oid; dmc->gmc_cred = delegated_mc; diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c index 0b3554c0fa..d6e448a223 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_acquire_cred.c,v 1.4 2006/10/25 00:44:55 lha Exp $"); +RCSID("$Id: gss_acquire_cred.c 20626 2007-05-08 13:56:49Z lha $"); OM_uint32 gss_acquire_cred(OM_uint32 *minor_status, @@ -49,6 +49,14 @@ gss_acquire_cred(OM_uint32 *minor_status, OM_uint32 min_time, cred_time; int i; + *minor_status = 0; + if (actual_mechs) + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; + if (time_rec) + *time_rec = 0; + _gss_load_mech(); /* @@ -64,7 +72,6 @@ gss_acquire_cred(OM_uint32 *minor_status, break; } if (i == mechs->count) { - *output_cred_handle = 0; *minor_status = 0; return (GSS_S_BAD_MECH); } @@ -84,7 +91,6 @@ gss_acquire_cred(OM_uint32 *minor_status, *minor_status = ENOMEM; return (GSS_S_FAILURE); } - cred->gc_usage = cred_usage; SLIST_INIT(&cred->gc_mc); if (mechs == GSS_C_NO_OID_SET) @@ -109,7 +115,6 @@ gss_acquire_cred(OM_uint32 *minor_status, if (!mc) { continue; } - SLIST_INIT(&cred->gc_mc); mc->gmc_mech = m; mc->gmc_mech_oid = &m->gm_mech_oid; @@ -151,7 +156,6 @@ gss_acquire_cred(OM_uint32 *minor_status, free(cred); if (actual_mechs) gss_release_oid_set(minor_status, actual_mechs); - *output_cred_handle = 0; *minor_status = 0; return (GSS_S_NO_CRED); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c index beffd54e29..4947c5c30e 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_add_cred.c,v 1.3 2006/06/29 08:23:53 lha Exp $"); +RCSID("$Id: gss_add_cred.c 20626 2007-05-08 13:56:49Z lha $"); static struct _gss_mechanism_cred * _gss_copy_cred(struct _gss_mechanism_cred *mc) @@ -43,8 +43,10 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc) major_status = m->gm_inquire_cred_by_mech(&minor_status, mc->gmc_cred, mc->gmc_mech_oid, &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage); - if (major_status) + if (major_status) { + _gss_mg_error(m, major_status, minor_status); return (0); + } major_status = m->gm_add_cred(&minor_status, GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, @@ -52,8 +54,10 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc) &cred, 0, 0, 0); m->gm_release_name(&minor_status, &name); - if (major_status) + if (major_status) { + _gss_mg_error(m, major_status, minor_status); return (0); + } new_mc = malloc(sizeof(struct _gss_mechanism_cred)); if (!new_mc) { @@ -89,15 +93,20 @@ gss_add_cred(OM_uint32 *minor_status, struct _gss_mechanism_name *mn; OM_uint32 junk; - *output_cred_handle = 0; *minor_status = 0; + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (initiator_time_rec) + *initiator_time_rec = 0; + if (acceptor_time_rec) + *acceptor_time_rec = 0; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; new_cred = malloc(sizeof(struct _gss_cred)); if (!new_cred) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } - new_cred->gc_usage = cred_usage; SLIST_INIT(&new_cred->gc_mc); /* @@ -162,6 +171,7 @@ gss_add_cred(OM_uint32 *minor_status, acceptor_time_rec); if (major_status) { + _gss_mg_error(m, major_status, *minor_status); release_cred = (gss_cred_id_t)new_cred; gss_release_cred(&junk, &release_cred); free(mc); diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c index 5806cec009..87d1ab3725 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c @@ -32,7 +32,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_add_oid_set_member.c,v 1.3 2006/10/22 09:36:13 lha Exp $"); +RCSID("$Id: gss_add_oid_set_member.c 18817 2006-10-22 09:36:13Z lha $"); OM_uint32 gss_add_oid_set_member (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c index 9e9bd5e790..56e0039379 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_buffer_set.c,v 1.2 2006/10/24 21:53:02 lha Exp $"); +RCSID("$Id: gss_buffer_set.c 18885 2006-10-24 21:53:02Z lha $"); OM_uint32 gss_create_empty_buffer_set diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c index 38a464be46..1437a9bc7b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_canonicalize_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_canonicalize_name.c 19928 2007-01-16 10:37:54Z lha $"); OM_uint32 gss_canonicalize_name(OM_uint32 *minor_status, @@ -52,8 +52,10 @@ gss_canonicalize_name(OM_uint32 *minor_status, m = mn->gmn_mech; major_status = m->gm_canonicalize_name(minor_status, mn->gmn_name, mech_type, &new_canonical_name); - if (major_status) + if (major_status) { + _gss_mg_error(m, major_status, *minor_status); return (major_status); + } /* * Now we make a new name and mark it as an MN. diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c index 1068bfabf6..147ad60c94 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_compare_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_compare_name.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_compare_name(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c index 4b17381776..47999f35cf 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_context_time.c +++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_context_time.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_context_time.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_context_time(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c index 7298ec9e83..841271b1fd 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_create_empty_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_create_empty_oid_set.c 19951 2007-01-17 10:14:58Z lha $"); OM_uint32 gss_create_empty_oid_set(OM_uint32 *minor_status, @@ -36,7 +36,7 @@ gss_create_empty_oid_set(OM_uint32 *minor_status, gss_OID_set set; *minor_status = 0; - *oid_set = 0; + *oid_set = GSS_C_NO_OID_SET; set = malloc(sizeof(gss_OID_set_desc)); if (!set) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c index 8ebb848188..e8b86e4d22 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c @@ -32,7 +32,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_decapsulate_token.c,v 1.2 2006/10/14 10:04:45 lha Exp $"); +RCSID("$Id: gss_decapsulate_token.c 19951 2007-01-17 10:14:58Z lha $"); OM_uint32 gss_decapsulate_token(gss_buffer_t input_token, @@ -45,8 +45,7 @@ gss_decapsulate_token(gss_buffer_t input_token, int ret; size_t size; - output_token->length = 0; - output_token->value = NULL; + _mg_buffer_zero(output_token); ret = der_get_oid (oid->elements, oid->length, &o, &size); if (ret) diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c index 06ef8e6d09..8c40994739 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_delete_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_delete_sec_context.c 19951 2007-01-17 10:14:58Z lha $"); OM_uint32 gss_delete_sec_context(OM_uint32 *minor_status, @@ -37,6 +37,9 @@ gss_delete_sec_context(OM_uint32 *minor_status, OM_uint32 major_status; struct _gss_context *ctx = (struct _gss_context *) *context_handle; + if (output_token) + _mg_buffer_zero(output_token); + *minor_status = 0; if (ctx) { /* @@ -46,12 +49,9 @@ gss_delete_sec_context(OM_uint32 *minor_status, if (ctx->gc_ctx) { major_status = ctx->gc_mech->gm_delete_sec_context( minor_status, &ctx->gc_ctx, output_token); - } else if (output_token != GSS_C_NO_BUFFER) { - output_token->length = 0; - output_token->value = 0; } free(ctx); - *context_handle = 0; + *context_handle = GSS_C_NO_CONTEXT; } return (GSS_S_COMPLETE); diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c index 79f62a7a4f..e57e5dd795 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_display_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_display_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_display_name.c 19952 2007-01-17 10:16:15Z lha $"); OM_uint32 gss_display_name(OM_uint32 *minor_status, @@ -39,6 +39,10 @@ gss_display_name(OM_uint32 *minor_status, struct _gss_name *name = (struct _gss_name *) input_name; struct _gss_mechanism_name *mn; + _mg_buffer_zero(output_name_buffer); + if (output_name_type) + *output_name_type = GSS_C_NO_OID; + /* * If we know it, copy the buffer used to import the name in * the first place. Otherwise, ask all the MNs in turn if diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c index 7871f5338b..c316c26fd7 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_display_status.c +++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c @@ -59,7 +59,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_display_status.c,v 1.4 2006/07/19 11:02:33 lha Exp $"); +RCSID("$Id: gss_display_status.c 20084 2007-01-31 12:12:08Z lha $"); static const char * calling_error(OM_uint32 v) @@ -148,6 +148,18 @@ gss_display_status(OM_uint32 *minor_status, { OM_uint32 major_status; + _mg_buffer_zero(status_string); + *message_content = 0; + + major_status = _gss_mg_get_error(mech_type, status_type, + status_value, status_string); + if (major_status == GSS_S_COMPLETE) { + + *message_content = 0; + *minor_status = 0; + return GSS_S_COMPLETE; + } + *minor_status = 0; switch (status_type) { case GSS_C_GSS_CODE: { @@ -161,24 +173,40 @@ gss_display_status(OM_uint32 *minor_status, calling_error(GSS_CALLING_ERROR(status_value)), routine_error(GSS_ROUTINE_ERROR(status_value))); + if (buf == NULL) + break; + status_string->length = strlen(buf); status_string->value = buf; return GSS_S_COMPLETE; } case GSS_C_MECH_CODE: { - gssapi_mech_interface m; - m = __gss_get_mechanism(mech_type); - if (m) { - major_status = m->gm_display_status(minor_status, - status_value, status_type, mech_type, - message_content, status_string); - if (major_status == GSS_S_COMPLETE) - return (GSS_S_COMPLETE); + OM_uint32 maj_junk, min_junk; + gss_buffer_desc oid; + char *buf; + + maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid); + if (maj_junk != GSS_S_COMPLETE) { + oid.value = rk_UNCONST("unknown"); + oid.length = 7; } + + asprintf (&buf, "unknown mech-code %lu for mech %.*s", + (unsigned long)status_value, + (int)oid.length, (char *)oid.value); + if (maj_junk == GSS_S_COMPLETE) + gss_release_buffer(&min_junk, &oid); + + if (buf == NULL) + break; + + status_string->length = strlen(buf); + status_string->value = buf; + + return GSS_S_COMPLETE; } } - status_string->value = NULL; - status_string->length = 0; + _mg_buffer_zero(status_string); return (GSS_S_BAD_STATUS); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c index 5ef828f472..3aab0b9bbc 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_duplicate_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_duplicate_name.c 19953 2007-01-17 11:16:35Z lha $"); OM_uint32 gss_duplicate_name(OM_uint32 *minor_status, const gss_name_t src_name, @@ -39,6 +39,7 @@ OM_uint32 gss_duplicate_name(OM_uint32 *minor_status, struct _gss_mechanism_name *mn; *minor_status = 0; + *dest_name = GSS_C_NO_NAME; /* * If this name has a value (i.e. it didn't come from diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c index bfb0e75315..d111a0ed61 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c @@ -32,7 +32,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_duplicate_oid.c,v 1.1 2006/06/28 09:07:07 lha Exp $"); +RCSID("$Id: gss_duplicate_oid.c 19954 2007-01-17 11:50:23Z lha $"); OM_uint32 gss_duplicate_oid ( OM_uint32 *minor_status, @@ -56,6 +56,7 @@ OM_uint32 gss_duplicate_oid ( (*dest_oid)->elements = malloc(src_oid->length); if ((*dest_oid)->elements == NULL) { free(*dest_oid); + *dest_oid = GSS_C_NO_OID; *minor_status = ENOMEM; return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c index d1285815ee..476d451375 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c @@ -32,7 +32,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_encapsulate_token.c,v 1.2 2006/10/14 10:05:12 lha Exp $"); +RCSID("$Id: gss_encapsulate_token.c 19954 2007-01-17 11:50:23Z lha $"); OM_uint32 gss_encapsulate_token(gss_buffer_t input_token, @@ -45,8 +45,7 @@ gss_encapsulate_token(gss_buffer_t input_token, ret = der_get_oid (oid->elements, oid->length, &ct.thisMech, &size); if (ret) { - output_token->value = NULL; - output_token->length = 0; + _mg_buffer_zero(output_token); return GSS_S_FAILURE; } @@ -58,8 +57,7 @@ gss_encapsulate_token(gss_buffer_t input_token, &ct, &size, ret); der_free_oid(&ct.thisMech); if (ret) { - output_token->length = 0; - output_token->value = NULL; + _mg_buffer_zero(output_token); return GSS_S_FAILURE; } if (output_token->length != size) diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c index bc1c39c8ee..11c9dd2db5 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_export_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_export_name.c,v 1.3 2006/07/05 22:41:57 lha Exp $"); +RCSID("$Id: gss_export_name.c 19954 2007-01-17 11:50:23Z lha $"); OM_uint32 gss_export_name(OM_uint32 *minor_status, @@ -37,8 +37,7 @@ gss_export_name(OM_uint32 *minor_status, struct _gss_name *name = (struct _gss_name *) input_name; struct _gss_mechanism_name *mn; - exported_name->value = NULL; - exported_name->length = 0; + _mg_buffer_zero(exported_name); /* * If this name already has any attached MNs, export the first diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c index 1acc72b33d..cf13bc0cd3 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_export_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_export_sec_context.c 19954 2007-01-17 11:50:23Z lha $"); OM_uint32 gss_export_sec_context(OM_uint32 *minor_status, @@ -39,6 +39,8 @@ gss_export_sec_context(OM_uint32 *minor_status, gssapi_mech_interface m = ctx->gc_mech; gss_buffer_desc buf; + _mg_buffer_zero(interprocess_token); + major_status = m->gm_export_sec_context(minor_status, &ctx->gc_ctx, &buf); @@ -58,6 +60,7 @@ gss_export_sec_context(OM_uint32 *minor_status, * GSS_C_NO_CONTEXT, which we did above. * Return GSS_S_FAILURE. */ + _mg_buffer_zero(interprocess_token); *minor_status = ENOMEM; return (GSS_S_FAILURE); } @@ -67,6 +70,8 @@ gss_export_sec_context(OM_uint32 *minor_status, memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length); memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length); gss_release_buffer(minor_status, &buf); + } else { + _gss_mg_error(m, major_status, *minor_status); } return (major_status); diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c index e9a8f294a4..496dd2065c 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_get_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_get_mic.c 19954 2007-01-17 11:50:23Z lha $"); OM_uint32 gss_get_mic(OM_uint32 *minor_status, @@ -39,6 +39,12 @@ gss_get_mic(OM_uint32 *minor_status, struct _gss_context *ctx = (struct _gss_context *) context_handle; gssapi_mech_interface m = ctx->gc_mech; + _mg_buffer_zero(message_token); + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req, message_buffer, message_token)); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c index 9684301ba4..6f55a1d61c 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_import_name.c,v 1.3 2006/06/29 21:23:13 lha Exp $"); +RCSID("$Id: gss_import_name.c 19954 2007-01-17 11:50:23Z lha $"); static OM_uint32 _gss_import_export_name(OM_uint32 *minor_status, @@ -119,6 +119,10 @@ _gss_import_export_name(OM_uint32 *minor_status, */ major_status = m->gm_import_name(minor_status, input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, *minor_status); + return major_status; + } /* * Now we make a new name and mark it as an MN. @@ -145,9 +149,10 @@ gss_import_name(OM_uint32 *minor_status, OM_uint32 major_status; struct _gss_name *name; + *output_name = GSS_C_NO_NAME; + if (input_name_buffer->length == 0) { *minor_status = 0; - *output_name = 0; return (GSS_S_BAD_NAME); } @@ -180,7 +185,6 @@ gss_import_name(OM_uint32 *minor_status, && !gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS) && !gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) { *minor_status = 0; - *output_name = 0; return (GSS_S_BAD_NAMETYPE); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c index 5466f97cf4..44ca1b2677 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_import_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_import_sec_context.c 19956 2007-01-17 12:04:16Z lha $"); OM_uint32 gss_import_sec_context(OM_uint32 *minor_status, @@ -43,7 +43,7 @@ gss_import_sec_context(OM_uint32 *minor_status, size_t len; *minor_status = 0; - *context_handle = 0; + *context_handle = GSS_C_NO_CONTEXT; /* * We added an oid to the front of the token in @@ -73,6 +73,7 @@ gss_import_sec_context(OM_uint32 *minor_status, major_status = m->gm_import_sec_context(minor_status, &buf, &ctx->gc_ctx); if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, *minor_status); free(ctx); } else { *context_handle = (gss_ctx_id_t) ctx; diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c index 0da6c48834..00c6ed28ee 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c +++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_indicate_mechs.c,v 1.3 2006/07/05 22:36:49 lha Exp $"); +RCSID("$Id: gss_indicate_mechs.c 17803 2006-07-05 22:36:49Z lha $"); OM_uint32 gss_indicate_mechs(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c index 0d50bbd92b..c1c058d146 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_init_sec_context.c,v 1.4 2006/11/14 12:33:11 lha Exp $"); +RCSID("$Id: gss_init_sec_context.c 19957 2007-01-17 13:48:11Z lha $"); static gss_cred_id_t _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type) @@ -71,6 +71,14 @@ gss_init_sec_context(OM_uint32 * minor_status, *minor_status = 0; + _mg_buffer_zero(output_token); + if (actual_mech_type) + *actual_mech_type = GSS_C_NO_OID; + if (ret_flags) + *ret_flags = 0; + if (time_rec) + *time_rec = 0; + /* * If we haven't allocated a context yet, do so now and lookup * the mechanism switch table. If we have one already, make @@ -131,6 +139,8 @@ gss_init_sec_context(OM_uint32 * minor_status, && major_status != GSS_S_CONTINUE_NEEDED) { if (allocated_ctx) free(ctx); + _mg_buffer_zero(output_token); + _gss_mg_error(m, major_status, *minor_status); } else { *context_handle = (gss_ctx_id_t) ctx; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c index 88bbb3941f..5cce30c6bd 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_inquire_context.c 19958 2007-01-17 13:56:18Z lha $"); OM_uint32 gss_inquire_context(OM_uint32 *minor_status, @@ -46,27 +46,42 @@ gss_inquire_context(OM_uint32 *minor_status, struct _gss_name *name; gss_name_t src_mn, targ_mn; + if (locally_initiated) + *locally_initiated = 0; + if (open) + *open = 0; + if (lifetime_rec) + *lifetime_rec = 0; + + if (src_name) + *src_name = GSS_C_NO_NAME; + if (targ_name) + *targ_name = GSS_C_NO_NAME; + if (mech_type) + *mech_type = GSS_C_NO_OID; + src_mn = targ_mn = GSS_C_NO_NAME; + major_status = m->gm_inquire_context(minor_status, ctx->gc_ctx, - src_name ? &src_mn : 0, - targ_name ? &targ_mn : 0, + src_name ? &src_mn : NULL, + targ_name ? &targ_mn : NULL, lifetime_rec, mech_type, ctx_flags, locally_initiated, open); - if (src_name) *src_name = 0; - if (targ_name) *targ_name = 0; - if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, *minor_status); return (major_status); } if (src_name) { name = _gss_make_name(m, src_mn); if (!name) { - minor_status = 0; + *mech_type = GSS_C_NO_OID; + m->gm_release_name(minor_status, &src_mn); + *minor_status = 0; return (GSS_S_FAILURE); } *src_name = (gss_name_t) name; @@ -75,7 +90,10 @@ gss_inquire_context(OM_uint32 *minor_status, if (targ_name) { name = _gss_make_name(m, targ_mn); if (!name) { - minor_status = 0; + *mech_type = GSS_C_NO_OID; + gss_release_name(minor_status, src_name); + m->gm_release_name(minor_status, &targ_mn); + *minor_status = 0; return (GSS_S_FAILURE); } *targ_name = (gss_name_t) name; diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c index 223140205d..97c3628225 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c @@ -27,7 +27,21 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred.c,v 1.5 2006/07/20 02:03:18 lha Exp $"); +RCSID("$Id: gss_inquire_cred.c 20626 2007-05-08 13:56:49Z lha $"); + +#define AUSAGE 1 +#define IUSAGE 2 + +static void +updateusage(gss_cred_usage_t usage, int *usagemask) +{ + if (usage == GSS_C_BOTH) + *usagemask |= AUSAGE | IUSAGE; + else if (usage == GSS_C_ACCEPT) + *usagemask |= AUSAGE; + else if (usage == GSS_C_INITIATE) + *usagemask |= IUSAGE; +} OM_uint32 gss_inquire_cred(OM_uint32 *minor_status, @@ -44,27 +58,30 @@ gss_inquire_cred(OM_uint32 *minor_status, struct _gss_mechanism_name *mn; OM_uint32 min_lifetime; int found = 0; + int usagemask = 0; + gss_cred_usage_t usage; _gss_load_mech(); *minor_status = 0; if (name_ret) - *name_ret = 0; + *name_ret = GSS_C_NO_NAME; if (lifetime) *lifetime = 0; if (cred_usage) *cred_usage = 0; + if (mechanisms) + *mechanisms = GSS_C_NO_OID_SET; if (name_ret) { - name = malloc(sizeof(struct _gss_name)); - if (!name) { + name = calloc(1, sizeof(*name)); + if (name == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } - memset(name, 0, sizeof(struct _gss_name)); SLIST_INIT(&name->gn_mn); } else { - name = 0; + name = NULL; } if (mechanisms) { @@ -85,10 +102,11 @@ gss_inquire_cred(OM_uint32 *minor_status, OM_uint32 mc_lifetime; major_status = mc->gmc_mech->gm_inquire_cred(minor_status, - mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL); + mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL); if (major_status) continue; + updateusage(usage, &usagemask); if (name) { mn = malloc(sizeof(struct _gss_mechanism_name)); if (!mn) { @@ -120,10 +138,11 @@ gss_inquire_cred(OM_uint32 *minor_status, major_status = m->gm_mech.gm_inquire_cred(minor_status, GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime, - cred_usage, NULL); + &usage, NULL); if (major_status) continue; + updateusage(usage, &usagemask); if (name && mc_name) { mn = malloc( sizeof(struct _gss_mechanism_name)); @@ -152,6 +171,9 @@ gss_inquire_cred(OM_uint32 *minor_status, } if (found == 0) { + gss_name_t n = (gss_name_t)name; + if (n) + gss_release_name(minor_status, &n); gss_release_oid_set(minor_status, mechanisms); *minor_status = 0; return (GSS_S_NO_CRED); @@ -162,7 +184,13 @@ gss_inquire_cred(OM_uint32 *minor_status, *name_ret = (gss_name_t) name; if (lifetime) *lifetime = min_lifetime; - if (cred && cred_usage) - *cred_usage = cred->gc_usage; + if (cred_usage) { + if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE)) + *cred_usage = GSS_C_BOTH; + else if (usagemask & IUSAGE) + *cred_usage = GSS_C_INITIATE; + else if (usagemask & AUSAGE) + *cred_usage = GSS_C_ACCEPT; + } return (GSS_S_COMPLETE); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c index 771a6956a5..a4ace9e9e9 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred_by_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_inquire_cred_by_mech.c 19960 2007-01-17 15:09:24Z lha $"); OM_uint32 gss_inquire_cred_by_mech(OM_uint32 *minor_status, @@ -46,6 +46,14 @@ gss_inquire_cred_by_mech(OM_uint32 *minor_status, struct _gss_name *name; *minor_status = 0; + if (cred_name) + *cred_name = GSS_C_NO_NAME; + if (initiator_lifetime) + *initiator_lifetime = 0; + if (acceptor_lifetime) + *acceptor_lifetime = 0; + if (cred_usage) + *cred_usage = 0; m = __gss_get_mechanism(mech_type); if (!m) @@ -65,8 +73,10 @@ gss_inquire_cred_by_mech(OM_uint32 *minor_status, major_status = m->gm_inquire_cred_by_mech(minor_status, mc, mech_type, &mn, initiator_lifetime, acceptor_lifetime, cred_usage); - if (major_status != GSS_S_COMPLETE) + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, *minor_status); return (major_status); + } name = _gss_make_name(m, mn); if (!name) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c index 3cfe89af21..7b53a2ff4a 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred_by_oid.c,v 1.2 2006/06/28 16:20:41 lha Exp $"); +RCSID("$Id: gss_inquire_cred_by_oid.c 19960 2007-01-17 15:09:24Z lha $"); OM_uint32 gss_inquire_cred_by_oid (OM_uint32 *minor_status, @@ -46,6 +46,7 @@ gss_inquire_cred_by_oid (OM_uint32 *minor_status, gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; if (cred == NULL) return GSS_S_NO_CRED; @@ -55,8 +56,11 @@ gss_inquire_cred_by_oid (OM_uint32 *minor_status, int i; m = mc->gmc_mech; - if (m == NULL) + if (m == NULL) { + gss_release_buffer_set(minor_status, &set); + *minor_status = 0; return GSS_S_BAD_MECH; + } if (m->gm_inquire_cred_by_oid == NULL) continue; @@ -77,6 +81,7 @@ gss_inquire_cred_by_oid (OM_uint32 *minor_status, if (set == GSS_C_NO_BUFFER_SET) status = GSS_S_FAILURE; *data_set = set; + *minor_status = 0; return status; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c index 7052bf8b72..5330a747a6 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_mechs_for_name.c,v 1.3 2006/07/20 02:04:00 lha Exp $"); +RCSID("$Id: gss_inquire_mechs_for_name.c 17844 2006-07-20 02:04:00Z lha $"); OM_uint32 gss_inquire_mechs_for_name(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c index 2293163b03..65b52cbbc3 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_names_for_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_inquire_names_for_mech.c 19960 2007-01-17 15:09:24Z lha $"); OM_uint32 gss_inquire_names_for_mech(OM_uint32 *minor_status, @@ -38,6 +38,7 @@ gss_inquire_names_for_mech(OM_uint32 *minor_status, gssapi_mech_interface m = __gss_get_mechanism(mechanism); *minor_status = 0; + *name_types = GSS_C_NO_OID_SET; if (!m) return (GSS_S_BAD_MECH); @@ -56,15 +57,15 @@ gss_inquire_names_for_mech(OM_uint32 *minor_status, major_status = gss_add_oid_set_member(minor_status, GSS_C_NT_HOSTBASED_SERVICE, name_types); if (major_status) { - OM_uint32 ms; - gss_release_oid_set(&ms, name_types); + OM_uint32 junk; + gss_release_oid_set(&junk, name_types); return (major_status); } major_status = gss_add_oid_set_member(minor_status, GSS_C_NT_USER_NAME, name_types); if (major_status) { - OM_uint32 ms; - gss_release_oid_set(&ms, name_types); + OM_uint32 junk; + gss_release_oid_set(&junk, name_types); return (major_status); } } diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c index 7f5632ac55..fd8219ce02 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_sec_context_by_oid.c,v 1.1 2006/06/28 09:07:08 lha Exp $"); +RCSID("$Id: gss_inquire_sec_context_by_oid.c 19961 2007-01-17 15:57:51Z lha $"); OM_uint32 gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, @@ -44,7 +44,7 @@ gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, gssapi_mech_interface m; *minor_status = 0; - + *data_set = GSS_C_NO_BUFFER_SET; if (ctx == NULL) return GSS_S_NO_CONTEXT; @@ -58,10 +58,12 @@ gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, if (m == NULL) return GSS_S_BAD_MECH; - if (m->gm_inquire_sec_context_by_oid != NULL) + if (m->gm_inquire_sec_context_by_oid != NULL) { major_status = m->gm_inquire_sec_context_by_oid(minor_status, ctx->gc_ctx, desired_object, data_set); - else + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, major_status, *minor_status); + } else major_status = GSS_S_BAD_MECH; return major_status; diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c index 76a2c2b637..2500928baf 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_krb5.c,v 1.21 2006/11/10 00:57:27 lha Exp $"); +RCSID("$Id: gss_krb5.c 20383 2007-04-18 08:49:53Z lha $"); #include <krb5.h> #include <roken.h> @@ -164,7 +164,12 @@ gss_krb5_import_cred(OM_uint32 *minor_status, goto out; } - krb5_storage_to_data(sp, &data); + ret = krb5_storage_to_data(sp, &data); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } buffer.value = data.data; buffer.length = data.length; @@ -421,37 +426,49 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) */ OM_uint32 -gss_krb5_set_allowable_enctypes(OM_uint32 *min_status, +gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, gss_cred_id_t cred, OM_uint32 num_enctypes, int32_t *enctypes) { + krb5_error_code ret; OM_uint32 maj_status; gss_buffer_desc buffer; krb5_storage *sp; krb5_data data; + int i; sp = krb5_storage_emem(); if (sp == NULL) { - *min_status = ENOMEM; + *minor_status = ENOMEM; maj_status = GSS_S_FAILURE; goto out; } - while(*enctypes) { - krb5_store_int32(sp, *enctypes); - enctypes++; + for (i = 0; i < num_enctypes; i++) { + ret = krb5_store_int32(sp, enctypes[i]); + if (ret) { + *minor_status = ret; + maj_status = GSS_S_FAILURE; + goto out; + } } - krb5_storage_to_data(sp, &data); + ret = krb5_storage_to_data(sp, &data); + if (ret) { + *minor_status = ret; + maj_status = GSS_S_FAILURE; + goto out; + } buffer.value = data.data; buffer.length = data.length; - maj_status = gss_set_cred_option(min_status, + maj_status = gss_set_cred_option(minor_status, &cred, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X, &buffer); + krb5_data_free(&data); out: if (sp) krb5_storage_free(sp); @@ -494,6 +511,38 @@ gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c) */ OM_uint32 +gss_krb5_ccache_name(OM_uint32 *minor_status, + const char *name, + const char **out_name) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + if (out_name) + *out_name = NULL; + + buffer.value = rk_UNCONST(name); + buffer.length = strlen(name); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_CCACHE_NAME_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + + +/* + * + */ + +OM_uint32 gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, gss_ctx_id_t context_handle, time_t *authtime) diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c index b8fdefdca1..604027490e 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -28,7 +28,7 @@ #include "mech_locl.h" #include <heim_threads.h> -RCSID("$Id: gss_mech_switch.c,v 1.8 2006/12/15 20:05:43 lha Exp $"); +RCSID("$Id: gss_mech_switch.c 20625 2007-05-08 13:55:03Z lha $"); #ifndef _PATH_GSS_MECH #define _PATH_GSS_MECH "/etc/gss/mech" @@ -50,6 +50,9 @@ _gss_string_to_oid(const char* s, gss_OID oid) const char *p, *q; char *res; + oid->length = 0; + oid->elements = NULL; + /* * First figure out how many numbers in the oid, then * calculate the compiled oid size. @@ -169,8 +172,10 @@ add_builtin(gssapi_mech_interface mech) { struct _gss_mech_switch *m; OM_uint32 minor_status; - if (!mech) - return 0; + + /* not registering any mech is ok */ + if (mech == NULL) + return 0; m = malloc(sizeof(*m)); if (m == NULL) @@ -299,6 +304,7 @@ _gss_load_mech(void) OPTSYM(inquire_sec_context_by_oid); OPTSYM(set_sec_context_option); OPTSYM(set_cred_option); + OPTSYM(pseudo_random); SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); continue; diff --git a/source4/heimdal/lib/gssapi/mech/gss_names.c b/source4/heimdal/lib/gssapi/mech/gss_names.c index 833c582006..3ab609c192 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_names.c +++ b/source4/heimdal/lib/gssapi/mech/gss_names.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_names.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_names.c 19928 2007-01-16 10:37:54Z lha $"); struct _gss_mechanism_name * _gss_find_mn(struct _gss_name *name, gss_OID mech) @@ -62,7 +62,8 @@ _gss_find_mn(struct _gss_name *name, gss_OID mech) (name->gn_type.elements ? &name->gn_type : GSS_C_NO_OID), &mn->gmn_name); - if (major_status) { + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, minor_status); free(mn); return (0); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c index 1a8b811f37..8c75410cc1 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c @@ -32,7 +32,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_oid_equal.c,v 1.1 2006/06/28 09:07:08 lha Exp $"); +RCSID("$Id: gss_oid_equal.c 17702 2006-06-28 09:07:08Z lha $"); int gss_oid_equal(const gss_OID a, const gss_OID b) diff --git a/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c index 5a0ac4418f..3195370b77 100644 --- a/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan + * Copyright (c) 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,25 +31,35 @@ * SUCH DAMAGE. */ -#include "krb5/gsskrb5_locl.h" +#include "mech_locl.h" +RCSID("$Id: gss_oid_to_str.c 19963 2007-01-17 16:01:22Z lha $"); -RCSID("$Id: test_oid_set_member.c,v 1.7 2006/10/07 22:15:50 lha Exp $"); - -OM_uint32 _gsskrb5_test_oid_set_member - (OM_uint32 * minor_status, - const gss_OID member, - const gss_OID_set set, - int * present - ) +OM_uint32 +gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str) { - size_t i; + int ret; + size_t size; + heim_oid o; + char *p; + + _mg_buffer_zero(oid_str); + + ret = der_get_oid (oid->elements, oid->length, &o, &size); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = der_print_heim_oid(&o, ' ', &p); + der_free_oid(&o); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + oid_str->value = p; + oid_str->length = strlen(p); *minor_status = 0; - *present = 0; - for (i = 0; i < set->count; ++i) - if (gss_oid_equal(member, &set->elements[i]) != 0) { - *present = 1; - break; - } return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c index 1e6f39979f..dff6b04f14 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_process_context_token.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_process_context_token.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_process_context_token(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c index 66705bb40e..fc55cae030 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_buffer.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_release_buffer.c 19962 2007-01-17 15:59:04Z lha $"); OM_uint32 gss_release_buffer(OM_uint32 *minor_status, @@ -37,8 +37,7 @@ gss_release_buffer(OM_uint32 *minor_status, *minor_status = 0; if (buffer->value) free(buffer->value); - buffer->length = 0; - buffer->value = 0; + _mg_buffer_zero(buffer); return (GSS_S_COMPLETE); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c index 760621c861..b26dbd7865 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_cred.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_release_cred.c 19963 2007-01-17 16:01:22Z lha $"); OM_uint32 gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) @@ -47,6 +47,6 @@ gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) free(cred); *minor_status = 0; - *cred_handle = 0; + *cred_handle = GSS_C_NO_CREDENTIAL; return (GSS_S_COMPLETE); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c index 1286cd3b79..313eab8245 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_name.c,v 1.3 2006/10/22 07:59:06 lha Exp $"); +RCSID("$Id: gss_release_name.c 18812 2006-10-22 07:59:06Z lha $"); OM_uint32 gss_release_name(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c index fc84fabd29..7754787fa8 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c @@ -33,7 +33,7 @@ #include "mech_locl.h" -RCSID("$Id: gss_release_oid.c,v 1.1 2006/06/30 09:34:54 lha Exp $"); +RCSID("$Id: gss_release_oid.c 17747 2006-06-30 09:34:54Z lha $"); OM_uint32 gss_release_oid(OM_uint32 *minor_status, gss_OID *oid) diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c index 101657e4fb..4372e62294 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_release_oid_set.c 19963 2007-01-17 16:01:22Z lha $"); OM_uint32 gss_release_oid_set(OM_uint32 *minor_status, @@ -39,7 +39,7 @@ gss_release_oid_set(OM_uint32 *minor_status, if ((*set)->elements) free((*set)->elements); free(*set); - *set = 0; + *set = GSS_C_NO_OID_SET; } return (GSS_S_COMPLETE); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c index 2f66f90d4f..71c5e70dc7 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_seal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_seal.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_seal.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_seal.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_seal(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c index f813d72ac8..78c8cc79c1 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c +++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_set_cred_option.c,v 1.8 2006/11/13 08:59:43 lha Exp $"); +RCSID("$Id: gss_set_cred_option.c 20626 2007-05-08 13:56:49Z lha $"); OM_uint32 gss_set_cred_option (OM_uint32 *minor_status, @@ -55,7 +55,6 @@ gss_set_cred_option (OM_uint32 *minor_status, if (cred == NULL) return GSS_S_FAILURE; - cred->gc_usage = GSS_C_BOTH; /* XXX */ SLIST_INIT(&cred->gc_mc); SLIST_FOREACH(m, &_gss_mechs, gm_link) { @@ -104,6 +103,9 @@ gss_set_cred_option (OM_uint32 *minor_status, &mc->gmc_cred, object, value); if (major_status == GSS_S_COMPLETE) one_ok = 1; + else + _gss_mg_error(m, major_status, *minor_status); + } } if (one_ok) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c index aa562a23b6..d312251f53 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_set_sec_context_option.c,v 1.2 2006/06/28 14:39:00 lha Exp $"); +RCSID("$Id: gss_set_sec_context_option.c 19928 2007-01-16 10:37:54Z lha $"); OM_uint32 gss_set_sec_context_option (OM_uint32 *minor_status, @@ -58,10 +58,12 @@ gss_set_sec_context_option (OM_uint32 *minor_status, if (m == NULL) return GSS_S_BAD_MECH; - if (m->gm_set_sec_context_option != NULL) + if (m->gm_set_sec_context_option != NULL) { major_status = m->gm_set_sec_context_option(minor_status, &ctx->gc_ctx, object, value); - else + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, major_status, *minor_status); + } else major_status = GSS_S_BAD_MECH; return major_status; diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c index 8c854e5e43..5268197c61 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_sign.c +++ b/source4/heimdal/lib/gssapi/mech/gss_sign.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_sign.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_sign.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_sign(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c index a71a8b7c92..fc3c5ddeef 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_test_oid_set_member.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_test_oid_set_member.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_test_oid_set_member(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c index 128dc7883c..205cc6e326 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_unseal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_unseal.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_unseal.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_unseal(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c index 1c9484b18d..69c125356b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_unwrap.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_unwrap.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_unwrap(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_utils.c b/source4/heimdal/lib/gssapi/mech/gss_utils.c index d674fb163b..22217a9d62 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_utils.c +++ b/source4/heimdal/lib/gssapi/mech/gss_utils.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_utils.c,v 1.3 2006/12/18 13:01:25 lha Exp $"); +RCSID("$Id: gss_utils.c 19965 2007-01-17 16:23:47Z lha $"); OM_uint32 _gss_copy_oid(OM_uint32 *minor_status, @@ -38,6 +38,7 @@ _gss_copy_oid(OM_uint32 *minor_status, *minor_status = 0; to_oid->elements = malloc(len); if (!to_oid->elements) { + to_oid->length = 0; *minor_status = ENOMEM; return GSS_S_FAILURE; } @@ -68,6 +69,7 @@ _gss_copy_buffer(OM_uint32 *minor_status, to_buf->value = malloc(len); if (!to_buf->value) { *minor_status = ENOMEM; + to_buf->length = 0; return GSS_S_FAILURE; } to_buf->length = len; diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c index a99d17e2d7..f11cac7d2e 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_verify.c +++ b/source4/heimdal/lib/gssapi/mech/gss_verify.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_verify.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_verify.c 17700 2006-06-28 09:00:26Z lha $"); OM_uint32 gss_verify(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c index b51ed7a8c4..118f50735f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_verify_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_verify_mic.c 19965 2007-01-17 16:23:47Z lha $"); OM_uint32 gss_verify_mic(OM_uint32 *minor_status, @@ -39,6 +39,13 @@ gss_verify_mic(OM_uint32 *minor_status, struct _gss_context *ctx = (struct _gss_context *) context_handle; gssapi_mech_interface m = ctx->gc_mech; + if (qop_state) + *qop_state = 0; + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + return (m->gm_verify_mic(minor_status, ctx->gc_ctx, message_buffer, token_buffer, qop_state)); } diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c index a97ec1308f..0eb9dfbc6d 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_wrap.c,v 1.2 2006/06/28 09:00:26 lha Exp $"); +RCSID("$Id: gss_wrap.c 19965 2007-01-17 16:23:47Z lha $"); OM_uint32 gss_wrap(OM_uint32 *minor_status, @@ -41,6 +41,14 @@ gss_wrap(OM_uint32 *minor_status, struct _gss_context *ctx = (struct _gss_context *) context_handle; gssapi_mech_interface m = ctx->gc_mech; + if (conf_state) + *conf_state = 0; + _mg_buffer_zero(output_message_buffer); + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + return (m->gm_wrap(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer)); diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c index 27493aa90d..35b3ad723d 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_wrap_size_limit.c,v 1.2 2006/06/28 09:00:26 lha Exp $"); +RCSID("$Id: gss_wrap_size_limit.c 19965 2007-01-17 16:23:47Z lha $"); OM_uint32 gss_wrap_size_limit(OM_uint32 *minor_status, @@ -39,6 +39,12 @@ gss_wrap_size_limit(OM_uint32 *minor_status, { struct _gss_context *ctx = (struct _gss_context *) context_handle; gssapi_mech_interface m = ctx->gc_mech; + + *max_input_size = 0; + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, req_output_size, max_input_size)); diff --git a/source4/heimdal/lib/gssapi/mech/gssapi.asn1 b/source4/heimdal/lib/gssapi/mech/gssapi.asn1 index 544618b7d4..44b30bfa7e 100644 --- a/source4/heimdal/lib/gssapi/mech/gssapi.asn1 +++ b/source4/heimdal/lib/gssapi/mech/gssapi.asn1 @@ -1,4 +1,4 @@ --- $Id: gssapi.asn1,v 1.3 2006/10/18 21:08:19 lha Exp $ +-- $Id: gssapi.asn1 18565 2006-10-18 21:08:19Z lha $ GSS-API DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/gssapi/mech/mech_locl.h b/source4/heimdal/lib/gssapi/mech/mech_locl.h index f5db15c5fa..4399fa78a6 100644 --- a/source4/heimdal/lib/gssapi/mech/mech_locl.h +++ b/source4/heimdal/lib/gssapi/mech/mech_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: mech_locl.h,v 1.4 2006/10/07 18:25:27 lha Exp $ */ +/* $Id: mech_locl.h 19948 2007-01-17 10:03:07Z lha $ */ #include <config.h> @@ -61,3 +61,6 @@ #include "mech_switch.h" #include "name.h" #include "utils.h" + +#define _mg_buffer_zero(buffer) \ + do { (buffer)->value = NULL; (buffer)->length = 0; } while(0) diff --git a/source4/heimdal/lib/gssapi/mech/mech_switch.h b/source4/heimdal/lib/gssapi/mech/mech_switch.h index 0984d36ef3..14e6d7978c 100644 --- a/source4/heimdal/lib/gssapi/mech/mech_switch.h +++ b/source4/heimdal/lib/gssapi/mech/mech_switch.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: mech_switch.h,v 1.3 2006/10/05 18:31:53 lha Exp $ + * $Id: mech_switch.h 18246 2006-10-05 18:36:07Z lha $ */ #include <gssapi_mech.h> diff --git a/source4/heimdal/lib/gssapi/mech/name.h b/source4/heimdal/lib/gssapi/mech/name.h index 3e7443ba20..2252150a06 100644 --- a/source4/heimdal/lib/gssapi/mech/name.h +++ b/source4/heimdal/lib/gssapi/mech/name.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/name.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: name.h,v 1.4 2006/10/05 18:36:07 lha Exp $ + * $Id: name.h 18246 2006-10-05 18:36:07Z lha $ */ struct _gss_mechanism_name { diff --git a/source4/heimdal/lib/gssapi/mech/utils.h b/source4/heimdal/lib/gssapi/mech/utils.h index 42e92c3f42..908203557e 100644 --- a/source4/heimdal/lib/gssapi/mech/utils.h +++ b/source4/heimdal/lib/gssapi/mech/utils.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/utils.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: utils.h,v 1.4 2006/12/18 13:01:40 lha Exp $ + * $Id: utils.h 19398 2006-12-18 13:01:40Z lha $ */ OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID); diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index 2c86b3f794..106897b9b0 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: accept_sec_context.c,v 1.16 2006/12/19 12:10:35 lha Exp $"); +RCSID("$Id: accept_sec_context.c 20929 2007-06-05 21:19:22Z lha $"); static OM_uint32 send_reject (OM_uint32 *minor_status, @@ -92,7 +92,7 @@ send_supported_mechs (OM_uint32 *minor_status, gss_buffer_t output_token) { NegotiationTokenWin nt; - char hostname[MAXHOSTNAMELEN], *p; + char hostname[MAXHOSTNAMELEN + 1], *p; gss_buffer_desc name_buf; gss_OID name_type; gss_name_t target_princ; @@ -117,11 +117,12 @@ send_supported_mechs (OM_uint32 *minor_status, } memset(&target_princ, 0, sizeof(target_princ)); - if (gethostname(hostname, sizeof(hostname) - 1) != 0) { + if (gethostname(hostname, sizeof(hostname) - 2) != 0) { *minor_status = errno; free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } + hostname[sizeof(hostname) - 1] = '\0'; /* Send the constructed SAM name for this host */ for (p = hostname; *p != '\0' && *p != '.'; p++) { @@ -662,6 +663,11 @@ acceptor_start &ctx->mech_time_rec, &mech_delegated_cred); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { + ctx->preferred_mech_type = preferred_mech_type; + ctx->negotiated_mech_type = preferred_mech_type; + if (ret == GSS_S_COMPLETE) + ctx->open = 1; + if (delegated_cred_handle) ret = _gss_spnego_alloc_cred(minor_status, mech_delegated_cred, @@ -669,11 +675,6 @@ acceptor_start else gss_release_cred(&ret2, &mech_delegated_cred); - ctx->preferred_mech_type = preferred_mech_type; - ctx->negotiated_mech_type = preferred_mech_type; - if (ret == GSS_S_COMPLETE) - ctx->open = 1; - ret = acceptor_complete(minor_status, ctx, &get_mic, diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c index 786eac1340..bc7da9410e 100644 --- a/source4/heimdal/lib/gssapi/spnego/compat.c +++ b/source4/heimdal/lib/gssapi/spnego/compat.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: compat.c,v 1.9 2006/12/18 17:52:26 lha Exp $"); +RCSID("$Id: compat.c 19415 2006-12-18 17:52:26Z lha $"); /* * Apparently Microsoft got the OID wrong, and used diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c index 57bc45a492..3535c7bb35 100644 --- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: context_stubs.c,v 1.9 2006/12/18 12:59:44 lha Exp $"); +RCSID("$Id: context_stubs.c 21035 2007-06-09 15:32:47Z lha $"); static OM_uint32 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) @@ -310,7 +310,7 @@ OM_uint32 _gss_spnego_display_name *minor_status = 0; - if (name->mech == GSS_C_NO_NAME) + if (name == NULL || name->mech == GSS_C_NO_NAME) return GSS_S_FAILURE; return gss_display_name(minor_status, name->mech, diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c index 8f8edab15e..2362e99019 100644 --- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: cred_stubs.c,v 1.5 2006/10/07 22:27:04 lha Exp $"); +RCSID("$Id: cred_stubs.c 20619 2007-05-08 13:43:45Z lha $"); OM_uint32 _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) @@ -97,6 +97,8 @@ OM_uint32 _gss_spnego_acquire_cred OM_uint32 * time_rec ) { + const spnego_name dname = (const spnego_name)desired_name; + gss_name_t name = GSS_C_NO_NAME; OM_uint32 ret, tmp; gss_OID_set_desc actual_desired_mechs; gss_OID_set mechs; @@ -106,9 +108,18 @@ OM_uint32 _gss_spnego_acquire_cred *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (dname) { + ret = gss_import_name(minor_status, &dname->value, &dname->type, &name); + if (ret) { + return ret; + } + } + ret = gss_indicate_mechs(minor_status, &mechs); - if (ret != GSS_S_COMPLETE) + if (ret != GSS_S_COMPLETE) { + gss_release_name(minor_status, &name); return ret; + } /* Remove ourselves from this list */ actual_desired_mechs.count = mechs->count; @@ -135,7 +146,7 @@ OM_uint32 _gss_spnego_acquire_cred goto out; cred = (gssspnego_cred)cred_handle; - ret = gss_acquire_cred(minor_status, desired_name, + ret = gss_acquire_cred(minor_status, name, time_req, &actual_desired_mechs, cred_usage, &cred->negotiated_cred_id, @@ -146,6 +157,7 @@ OM_uint32 _gss_spnego_acquire_cred *output_cred_handle = cred_handle; out: + gss_release_name(minor_status, &name); gss_release_oid_set(&tmp, &mechs); if (actual_desired_mechs.elements != NULL) { free(actual_desired_mechs.elements); @@ -167,6 +179,7 @@ OM_uint32 _gss_spnego_inquire_cred ) { gssspnego_cred cred; + spnego_name sname = NULL; OM_uint32 ret; if (cred_handle == GSS_C_NO_CREDENTIAL) { @@ -174,14 +187,29 @@ OM_uint32 _gss_spnego_inquire_cred return GSS_S_NO_CRED; } + if (name) { + sname = calloc(1, sizeof(*sname)); + if (sname == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + } + cred = (gssspnego_cred)cred_handle; ret = gss_inquire_cred(minor_status, cred->negotiated_cred_id, - name, + sname ? &sname->mech : NULL, lifetime, cred_usage, mechanisms); + if (ret) { + if (sname) + free(sname); + return ret; + } + if (name) + *name = (gss_name_t)sname; return ret; } @@ -246,6 +274,7 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech ( ) { gssspnego_cred cred; + spnego_name sname = NULL; OM_uint32 ret; if (cred_handle == GSS_C_NO_CREDENTIAL) { @@ -253,17 +282,33 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech ( return GSS_S_NO_CRED; } + if (name) { + sname = calloc(1, sizeof(*sname)); + if (sname == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + } + cred = (gssspnego_cred)cred_handle; ret = gss_inquire_cred_by_mech(minor_status, cred->negotiated_cred_id, mech_type, - name, + sname ? &sname->mech : NULL, initiator_lifetime, acceptor_lifetime, cred_usage); - return ret; + if (ret) { + if (sname) + free(sname); + return ret; + } + if (name) + *name = (gss_name_t)sname; + + return GSS_S_COMPLETE; } OM_uint32 _gss_spnego_inquire_cred_by_oid diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c index b7e02a55e1..fbc231f3ae 100644 --- a/source4/heimdal/lib/gssapi/spnego/external.c +++ b/source4/heimdal/lib/gssapi/spnego/external.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" #include <gssapi_mech.h> -RCSID("$Id: external.c,v 1.7 2006/10/07 22:27:06 lha Exp $"); +RCSID("$Id: external.c 18336 2006-10-07 22:27:13Z lha $"); /* * RFC2478, SPNEGO: diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c index a221281a70..7c74981e66 100644 --- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: init_sec_context.c,v 1.11 2006/12/18 15:42:03 lha Exp $"); +RCSID("$Id: init_sec_context.c 19411 2006-12-18 15:42:03Z lha $"); /* * Is target_name an sane target for `mech´. diff --git a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 index 76fafa356c..aed67dc4ae 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 +++ b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 @@ -1,4 +1,4 @@ --- $Id: spnego.asn1,v 1.3 2006/12/18 18:28:49 lha Exp $ +-- $Id: spnego.asn1 19420 2006-12-18 18:28:49Z lha $ SPNEGO DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h index 45dff04313..44b24688e1 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: spnego_locl.h,v 1.15 2006/12/18 15:42:03 lha Exp $ */ +/* $Id: spnego_locl.h 19411 2006-12-18 15:42:03Z lha $ */ #ifndef SPNEGO_LOCL_H #define SPNEGO_LOCL_H diff --git a/source4/heimdal/lib/des/aes.c b/source4/heimdal/lib/hcrypto/aes.c index 5e0069de9d..a36459a457 100755 --- a/source4/heimdal/lib/des/aes.c +++ b/source4/heimdal/lib/hcrypto/aes.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: aes.c,v 1.5 2005/06/18 22:46:35 lha Exp $"); +RCSID("$Id: aes.c 15495 2005-06-18 22:47:33Z lha $"); #endif #ifdef KRB5 diff --git a/source4/heimdal/lib/des/aes.h b/source4/heimdal/lib/hcrypto/aes.h index 3ea1c141be..e91d8e73e1 100755 --- a/source4/heimdal/lib/des/aes.h +++ b/source4/heimdal/lib/hcrypto/aes.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: aes.h,v 1.6 2006/05/05 11:06:35 lha Exp $ */ +/* $Id: aes.h 17450 2006-05-05 11:11:43Z lha $ */ #ifndef HEIM_AES_H #define HEIM_AES_H 1 diff --git a/source4/heimdal/lib/des/bn.c b/source4/heimdal/lib/hcrypto/bn.c index c4230b6abc..698da2fe0b 100644 --- a/source4/heimdal/lib/des/bn.c +++ b/source4/heimdal/lib/hcrypto/bn.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: bn.c,v 1.9 2006/10/14 09:21:09 lha Exp $"); +RCSID("$Id: bn.c 18449 2006-10-14 09:21:09Z lha $"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/des/bn.h b/source4/heimdal/lib/hcrypto/bn.h index b0c90d36fc..82c9991c2c 100644 --- a/source4/heimdal/lib/des/bn.h +++ b/source4/heimdal/lib/hcrypto/bn.h @@ -32,7 +32,7 @@ */ /* - * $Id: bn.h,v 1.3 2006/01/13 08:27:50 lha Exp $ + * $Id: bn.h 16536 2006-01-13 08:27:50Z lha $ */ #ifndef _HEIM_BN_H diff --git a/source4/heimdal/lib/des/des-tables.h b/source4/heimdal/lib/hcrypto/des-tables.h index 03854ec174..03854ec174 100644 --- a/source4/heimdal/lib/des/des-tables.h +++ b/source4/heimdal/lib/hcrypto/des-tables.h diff --git a/source4/heimdal/lib/des/des.c b/source4/heimdal/lib/hcrypto/des.c index 5b1f5c29f4..a4444a8a7c 100644 --- a/source4/heimdal/lib/des/des.c +++ b/source4/heimdal/lib/hcrypto/des.c @@ -45,7 +45,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: des.c,v 1.18 2006/04/24 14:26:19 lha Exp $"); +RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $"); #endif #include <stdio.h> diff --git a/source4/heimdal/lib/des/des.h b/source4/heimdal/lib/hcrypto/des.h index 890fab462d..ac8deb8ab8 100644 --- a/source4/heimdal/lib/des/des.h +++ b/source4/heimdal/lib/hcrypto/des.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: des.h,v 1.25 2006/01/08 21:47:28 lha Exp $ */ +/* $Id: des.h 16480 2006-01-08 21:47:29Z lha $ */ #ifndef _DESperate_H #define _DESperate_H 1 diff --git a/source4/heimdal/lib/des/dh-imath.c b/source4/heimdal/lib/hcrypto/dh-imath.c index ebf02c72be..17592bbdf6 100644 --- a/source4/heimdal/lib/des/dh-imath.c +++ b/source4/heimdal/lib/hcrypto/dh-imath.c @@ -43,7 +43,7 @@ #include "imath/imath.h" -RCSID("$Id: dh-imath.c,v 1.6 2006/10/20 06:56:57 lha Exp $"); +RCSID("$Id: dh-imath.c 18645 2006-10-20 06:56:57Z lha $"); static void BN2mpz(mpz_t *s, const BIGNUM *bn) diff --git a/source4/heimdal/lib/des/dh.c b/source4/heimdal/lib/hcrypto/dh.c index 66d611f6d4..b558eb901c 100644 --- a/source4/heimdal/lib/des/dh.c +++ b/source4/heimdal/lib/hcrypto/dh.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: dh.c,v 1.10 2006/10/19 17:31:51 lha Exp $"); +RCSID("$Id: dh.c 18618 2006-10-19 17:31:51Z lha $"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/des/dh.h b/source4/heimdal/lib/hcrypto/dh.h index 105d298bc3..e34390dc99 100644 --- a/source4/heimdal/lib/des/dh.h +++ b/source4/heimdal/lib/hcrypto/dh.h @@ -32,7 +32,7 @@ */ /* - * $Id: dh.h,v 1.6 2006/05/06 13:11:15 lha Exp $ + * $Id: dh.h 17483 2006-05-06 13:11:15Z lha $ */ #ifndef _HEIM_DH_H diff --git a/source4/heimdal/lib/des/dsa.c b/source4/heimdal/lib/hcrypto/dsa.c index 411597b1c6..0dc59dac61 100644 --- a/source4/heimdal/lib/des/dsa.c +++ b/source4/heimdal/lib/hcrypto/dsa.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: dsa.c,v 1.2 2006/05/07 11:31:58 lha Exp $"); +RCSID("$Id: dsa.c 17496 2006-05-07 11:31:58Z lha $"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/des/dsa.h b/source4/heimdal/lib/hcrypto/dsa.h index 18859effc8..0544b80118 100644 --- a/source4/heimdal/lib/des/dsa.h +++ b/source4/heimdal/lib/hcrypto/dsa.h @@ -32,7 +32,7 @@ */ /* - * $Id: dsa.h,v 1.2 2006/01/13 15:26:52 lha Exp $ + * $Id: dsa.h 16564 2006-01-13 15:26:52Z lha $ */ #ifndef _HEIM_DSA_H diff --git a/source4/heimdal/lib/des/engine.c b/source4/heimdal/lib/hcrypto/engine.c index b72339c362..1a754909c5 100644 --- a/source4/heimdal/lib/des/engine.c +++ b/source4/heimdal/lib/hcrypto/engine.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: engine.c,v 1.11 2006/10/19 14:23:00 lha Exp $"); +RCSID("$Id: engine.c 20828 2007-06-03 05:10:20Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -322,24 +322,4 @@ ENGINE_by_id(const char *id) void ENGINE_add_conf_module(void) { - ENGINE *engine; - - /* - * XXX Parse configuration file instead - */ - - engine = ENGINE_by_dso("/usr/heimdal/lib/hc-modules/hc-gmp.so", NULL); - if (engine == NULL) - return; - { - const RSA_METHOD *method = ENGINE_get_RSA(engine); - if (method) - RSA_set_default_method(method); - } - { - const DH_METHOD *method = ENGINE_get_DH(engine); - if (method) - DH_set_default_method(method); - } - } diff --git a/source4/heimdal/lib/des/engine.h b/source4/heimdal/lib/hcrypto/engine.h index 65588f7d78..547a2d1324 100644 --- a/source4/heimdal/lib/des/engine.h +++ b/source4/heimdal/lib/hcrypto/engine.h @@ -32,7 +32,7 @@ */ /* - * $Id: engine.h,v 1.6 2006/05/06 12:34:36 lha Exp $ + * $Id: engine.h 17475 2006-05-06 12:34:36Z lha $ */ #ifndef _HEIM_ENGINE_H diff --git a/source4/heimdal/lib/des/evp.c b/source4/heimdal/lib/hcrypto/evp.c index 34480dbe7e..34480dbe7e 100644 --- a/source4/heimdal/lib/des/evp.c +++ b/source4/heimdal/lib/hcrypto/evp.c diff --git a/source4/heimdal/lib/des/evp.h b/source4/heimdal/lib/hcrypto/evp.h index 2fdf8d0765..a3fbc4c9ca 100644 --- a/source4/heimdal/lib/des/evp.h +++ b/source4/heimdal/lib/hcrypto/evp.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: evp.h,v 1.11 2006/10/07 17:21:24 lha Exp $ */ +/* $Id: evp.h 18312 2006-10-07 17:21:48Z lha $ */ #ifndef HEIM_EVP_H #define HEIM_EVP_H 1 diff --git a/source4/heimdal/lib/des/hash.h b/source4/heimdal/lib/hcrypto/hash.h index b6da9bd8e0..d19f0c0ae1 100644 --- a/source4/heimdal/lib/des/hash.h +++ b/source4/heimdal/lib/hcrypto/hash.h @@ -30,7 +30,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: hash.h,v 1.4 2006/05/05 11:06:49 lha Exp $ */ +/* $Id: hash.h 17450 2006-05-05 11:11:43Z lha $ */ /* stuff in common between md4, md5, and sha1 */ diff --git a/source4/heimdal/lib/des/hmac.c b/source4/heimdal/lib/hcrypto/hmac.c index 848b987a90..848b987a90 100644 --- a/source4/heimdal/lib/des/hmac.c +++ b/source4/heimdal/lib/hcrypto/hmac.c diff --git a/source4/heimdal/lib/des/hmac.h b/source4/heimdal/lib/hcrypto/hmac.h index a72ab574e7..5bdae0a369 100644 --- a/source4/heimdal/lib/des/hmac.h +++ b/source4/heimdal/lib/hcrypto/hmac.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hmac.h,v 1.3 2006/01/13 15:26:52 lha Exp $ */ +/* $Id: hmac.h 16564 2006-01-13 15:26:52Z lha $ */ #ifndef HEIM_HMAC_H #define HEIM_HMAC_H 1 diff --git a/source4/heimdal/lib/des/imath/LICENSE b/source4/heimdal/lib/hcrypto/imath/LICENSE index cecfb11404..cecfb11404 100644 --- a/source4/heimdal/lib/des/imath/LICENSE +++ b/source4/heimdal/lib/hcrypto/imath/LICENSE diff --git a/source4/heimdal/lib/des/imath/imath.c b/source4/heimdal/lib/hcrypto/imath/imath.c index 0a124fa13f..376425788b 100755 --- a/source4/heimdal/lib/des/imath/imath.c +++ b/source4/heimdal/lib/hcrypto/imath/imath.c @@ -2,9 +2,9 @@ Name: imath.c Purpose: Arbitrary precision integer arithmetic routines. Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: imath.c,v 1.6 2007/01/08 10:17:31 lha Exp $ + Info: $Id: imath.c 20854 2007-06-03 18:04:10Z lha $ - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -34,12 +34,15 @@ #endif #include <stdlib.h> -#include <stdio.h> #include <string.h> #include <ctype.h> #include <assert.h> +#if DEBUG +#define static +#endif + /* {{{ Constants */ const mp_result MP_OK = 0; /* no error, all is well */ @@ -183,15 +186,13 @@ static const mp_size multiply_threshold = MP_MULT_THRESH; /* Allocate a buffer of (at least) num digits, or return NULL if that couldn't be done. */ static mp_digit *s_alloc(mp_size num); -#if TRACEABLE_FREE + +/* Release a buffer of digits allocated by s_alloc(). */ static void s_free(void *ptr); -#else -#define s_free(P) free(P) -#endif /* Insure that z has at least min digits allocated, resizing if necessary. Returns true if successful, false if out of memory. */ -int s_pad(mp_int z, mp_size min); +static int s_pad(mp_int z, mp_size min); /* Normalize by removing leading zeroes (except when z = 0) */ #if TRACEABLE_CLAMP @@ -284,7 +285,7 @@ static mp_result s_brmu(mp_int z, mp_int m); static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2); /* Modular exponentiation, using Barrett reduction */ -mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); +static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); /* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; overwrites a with quotient, b with remainder. */ @@ -457,7 +458,7 @@ void mp_int_free(mp_int z) NRCHECK(z != NULL); mp_int_clear(z); - free(z); + free(z); /* note: NOT s_free() */ } /* }}} */ @@ -724,10 +725,11 @@ mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) /* Output is positive if inputs have same sign, otherwise negative */ osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; - /* If the output is not equal to any of the inputs, we'll write the - results there directly; otherwise, allocate a temporary space. */ + /* If the output is not identical to any of the inputs, we'll write + the results directly; otherwise, allocate a temporary space. */ ua = MP_USED(a); ub = MP_USED(b); - osize = ua + ub; + osize = MAX(ua, ub); + osize = 4 * ((osize + 1) / 2); if(c == a || c == b) { p = ROUND_PREC(osize); @@ -808,7 +810,7 @@ mp_result mp_int_sqr(mp_int a, mp_int c) CHECK(a != NULL && c != NULL); /* Get a temporary buffer big enough to hold the result */ - osize = (mp_size) 2 * MP_USED(a); + osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); if(a == c) { p = ROUND_PREC(osize); p = MAX(p, default_precision); @@ -977,7 +979,6 @@ mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) /* }}} */ - /* {{{ mp_int_div_value(a, value, q, r) */ mp_result mp_int_div_value(mp_int a, int value, mp_int q, int *r) @@ -2018,20 +2019,38 @@ static mp_digit *s_alloc(mp_size num) mp_digit *out = malloc(num * sizeof(mp_digit)); assert(out != NULL); /* for debugging */ +#if DEBUG > 1 + { + mp_digit v = (mp_digit) 0xdeadbeef; + int ix; + + for(ix = 0; ix < num; ++ix) + out[ix] = v; + } +#endif return out; } /* }}} */ -/* {{{ s_realloc(old, num) */ +/* {{{ s_realloc(old, osize, nsize) */ -static mp_digit *s_realloc(mp_digit *old, mp_size num) +static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize) { - mp_digit *new = realloc(old, num * sizeof(mp_digit)); +#if DEBUG > 1 + mp_digit *new = s_alloc(nsize); + int ix; - assert(new != NULL); /* for debugging */ + for(ix = 0; ix < nsize; ++ix) + new[ix] = (mp_digit) 0xdeadbeef; + + memcpy(new, old, osize * sizeof(mp_digit)); +#else + mp_digit *new = realloc(old, nsize * sizeof(mp_digit)); + assert(new != NULL); /* for debugging */ +#endif return new; } @@ -2039,18 +2058,16 @@ static mp_digit *s_realloc(mp_digit *old, mp_size num) /* {{{ s_free(ptr) */ -#if TRACEABLE_FREE static void s_free(void *ptr) { free(ptr); } -#endif /* }}} */ /* {{{ s_pad(z, min) */ -int s_pad(mp_int z, mp_size min) +static int s_pad(mp_int z, mp_size min) { if(MP_ALLOC(z) < min) { mp_size nsize = ROUND_PREC(min); @@ -2062,7 +2079,7 @@ int s_pad(mp_int z, mp_size min) COPY(MP_DIGITS(z), tmp, MP_USED(z)); } - else if((tmp = s_realloc(MP_DIGITS(z), nsize)) == NULL) + else if((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) return 0; MP_DIGITS(z) = tmp; @@ -2292,26 +2309,26 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, product; twice the space is plenty. */ if((t1 = s_alloc(4 * buf_size)) == NULL) return 0; - t2 = t1 + buf_size; + t2 = t1 + buf_size; t3 = t2 + buf_size; ZERO(t1, 4 * buf_size); /* t1 and t2 are initially used as temporaries to compute the inner product (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 */ - carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ + carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ t1[bot_size] = carry; - carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ + carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ t2[bot_size] = carry; - (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */ + (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */ /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that we're left with only the pieces we want: t3 = a1b0 + a0b1 */ - ZERO(t1, bot_size + 1); - ZERO(t2, bot_size + 1); + ZERO(t1, buf_size); + ZERO(t2, buf_size); (void) s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ (void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ @@ -2321,11 +2338,13 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, /* Assemble the output value */ COPY(t1, dc, buf_size); - (void) s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size + 1); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); - (void) s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, - buf_size, buf_size); + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); s_free(t1); /* note t2 and t3 are just internal pointers to t1 */ } @@ -2374,7 +2393,7 @@ static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) if(multiply_threshold && size_a > multiply_threshold) { mp_size bot_size = (size_a + 1) / 2; mp_digit *a_top = da + bot_size; - mp_digit *t1, *t2, *t3; + mp_digit *t1, *t2, *t3, carry; mp_size at_size = size_a - bot_size; mp_size buf_size = 2 * bot_size; @@ -2404,13 +2423,15 @@ static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) /* Assemble the output value */ COPY(t1, dc, 2 * bot_size); - (void) s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size + 1); - - (void) s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, - buf_size, buf_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); + + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); - free(t1); /* note that t2 and t2 are internal pointers only */ + s_free(t1); /* note that t2 and t2 are internal pointers only */ } else { @@ -2707,7 +2728,9 @@ static int s_qmul(mp_int z, mp_size p2) /* {{{ s_qsub(z, p2) */ -/* Subtract |z| from 2^p2, assuming 2^p2 > |z|, and set z to be positive */ +/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| + The sign of the result is always zero/positive. + */ static int s_qsub(mp_int z, mp_size p2) { mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp; @@ -2885,10 +2908,11 @@ static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) /* If x > m, we need to back it off until it is in range. This will be required at most twice. */ - if(mp_int_compare(x, m) >= 0) - (void) mp_int_sub(x, m, x); - if(mp_int_compare(x, m) >= 0) + if(mp_int_compare(x, m) >= 0) { (void) mp_int_sub(x, m, x); + if(mp_int_compare(x, m) >= 0) + (void) mp_int_sub(x, m, x); + } /* At this point, x has been properly reduced. */ return 1; @@ -2900,7 +2924,7 @@ static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) /* Perform modular exponentiation using Barrett's method, where mu is the reduction constant for m. Assumes a < m, b > 0. */ -mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) +static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) { mp_digit *db, *dbt, umu, d; mpz_t temp[3]; @@ -2909,8 +2933,10 @@ mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1; - while(last < 3) + while(last < 3) { SETUP(mp_int_init_size(TEMP(last), 4 * umu), last); + ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1))); + } (void) mp_int_set_value(c, 1); @@ -3006,22 +3032,13 @@ static mp_result s_udiv(mp_int a, mp_int b) /* Solve for quotient digits, store in q.digits in reverse order */ while(r.digits >= da) { - if (qpos > q.alloc) { - char buf[1024]; - printf("qpos = %d q.alloc = %d da = %d ua = %d\n", - (int)qpos, (int)q.alloc, (int)da, (int)ua); - mp_int_to_string(a, 10, buf, sizeof(buf)); - printf("a = %s\n", buf); - mp_int_to_string(b, 10, buf, sizeof(buf)); - printf("b = %s\n", buf); - assert(qpos <= q.alloc); - } + assert(qpos <= q.alloc); if(s_ucmp(b, &r) > 0) { r.digits -= 1; r.used += 1; - if(++skip > 1) + if(++skip > 1 && qpos > 0) q.digits[qpos++] = 0; CLAMP(&r); @@ -3030,15 +3047,19 @@ static mp_result s_udiv(mp_int a, mp_int b) mp_word pfx = r.digits[r.used - 1]; mp_word qdigit; - if(r.used > 1 && (pfx < btop || r.digits[r.used - 2] == 0)) { + if(r.used > 1 && pfx <= btop) { pfx <<= MP_DIGIT_BIT / 2; pfx <<= MP_DIGIT_BIT / 2; pfx |= r.digits[r.used - 2]; } qdigit = pfx / btop; - if(qdigit > MP_DIGIT_MAX) - qdigit = 1; + if(qdigit > MP_DIGIT_MAX) { + if(qdigit & MP_DIGIT_MAX) + qdigit = MP_DIGIT_MAX; + else + qdigit = 1; + } s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub); t.used = ub + 1; CLAMP(&t); @@ -3055,7 +3076,7 @@ static mp_result s_udiv(mp_int a, mp_int b) skip = 0; } } - + /* Put quotient digits in the correct order, and discard extra zeroes */ q.used = qpos; REV(mp_digit, q.digits, qpos); diff --git a/source4/heimdal/lib/des/imath/imath.h b/source4/heimdal/lib/hcrypto/imath/imath.h index 93cc35654d..f13c09d1a2 100755 --- a/source4/heimdal/lib/des/imath/imath.h +++ b/source4/heimdal/lib/hcrypto/imath/imath.h @@ -2,9 +2,9 @@ Name: imath.h Purpose: Arbitrary precision integer arithmetic routines. Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: imath.h,v 1.3 2006/10/21 16:32:15 lha Exp $ + Info: $Id: imath.h 20764 2007-06-01 03:55:14Z lha $ - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -94,7 +94,7 @@ extern const mp_result MP_BADARG; standard multiplication algorithm; otherwise, a recursive algorithm is used. Choose a value to suit your platform. */ -#define MP_MULT_THRESH 32 +#define MP_MULT_THRESH 22 #define MP_DEFAULT_PREC 8 /* default memory allocation, in digits */ diff --git a/source4/heimdal/lib/des/imath/iprime.c b/source4/heimdal/lib/hcrypto/imath/iprime.c index 582ade0f54..6313bab1b7 100755 --- a/source4/heimdal/lib/des/imath/iprime.c +++ b/source4/heimdal/lib/hcrypto/imath/iprime.c @@ -2,7 +2,7 @@ Name: iprime.c Purpose: Pseudoprimality testing routines Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: iprime.c,v 1.5 2007/01/05 21:01:48 lha Exp $ + Info: $Id: iprime.c 19737 2007-01-05 21:01:48Z lha $ Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. diff --git a/source4/heimdal/lib/des/imath/iprime.h b/source4/heimdal/lib/hcrypto/imath/iprime.h index cd54a73127..c935cdc111 100755 --- a/source4/heimdal/lib/des/imath/iprime.h +++ b/source4/heimdal/lib/hcrypto/imath/iprime.h @@ -2,7 +2,7 @@ Name: iprime.h Purpose: Pseudoprimality testing routines Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: iprime.h,v 1.3 2006/10/21 16:32:30 lha Exp $ + Info: $Id: iprime.h 18759 2006-10-21 16:32:36Z lha $ Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. diff --git a/source4/heimdal/lib/des/md2.c b/source4/heimdal/lib/hcrypto/md2.c index 91d7afd125..84b66c225f 100644 --- a/source4/heimdal/lib/des/md2.c +++ b/source4/heimdal/lib/hcrypto/md2.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md2.c,v 1.1 2006/01/08 21:47:28 lha Exp $"); +RCSID("$Id: md2.c 16480 2006-01-08 21:47:29Z lha $"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/des/md2.h b/source4/heimdal/lib/hcrypto/md2.h index f305d943aa..cf3960b935 100644 --- a/source4/heimdal/lib/des/md2.h +++ b/source4/heimdal/lib/hcrypto/md2.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md2.h,v 1.1 2006/01/08 21:47:28 lha Exp $ */ +/* $Id: md2.h 16480 2006-01-08 21:47:29Z lha $ */ #ifndef HEIM_MD2_H #define HEIM_MD2_H 1 diff --git a/source4/heimdal/lib/des/md4.c b/source4/heimdal/lib/hcrypto/md4.c index ded4fe12e8..95ab340b48 100644 --- a/source4/heimdal/lib/des/md4.c +++ b/source4/heimdal/lib/hcrypto/md4.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md4.c,v 1.18 2006/05/05 10:22:04 lha Exp $"); +RCSID("$Id: md4.c 17445 2006-05-05 10:37:46Z lha $"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/des/md4.h b/source4/heimdal/lib/hcrypto/md4.h index f8c011b9b7..8725209d02 100644 --- a/source4/heimdal/lib/des/md4.h +++ b/source4/heimdal/lib/hcrypto/md4.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md4.h,v 1.11 2006/05/05 11:07:01 lha Exp $ */ +/* $Id: md4.h 17450 2006-05-05 11:11:43Z lha $ */ #ifndef HEIM_MD4_H #define HEIM_MD4_H 1 diff --git a/source4/heimdal/lib/des/md5.c b/source4/heimdal/lib/hcrypto/md5.c index e23d6c8fd7..b145fd2ac7 100644 --- a/source4/heimdal/lib/des/md5.c +++ b/source4/heimdal/lib/hcrypto/md5.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md5.c,v 1.18 2006/05/05 10:22:35 lha Exp $"); +RCSID("$Id: md5.c 17445 2006-05-05 10:37:46Z lha $"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/des/md5.h b/source4/heimdal/lib/hcrypto/md5.h index 54c34fe572..de6bd3a0a6 100644 --- a/source4/heimdal/lib/des/md5.h +++ b/source4/heimdal/lib/hcrypto/md5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md5.h,v 1.11 2006/05/05 11:07:11 lha Exp $ */ +/* $Id: md5.h 17450 2006-05-05 11:11:43Z lha $ */ #ifndef HEIM_MD5_H #define HEIM_MD5_H 1 diff --git a/source4/heimdal/lib/des/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index cc92285754..dcfbdfad42 100644 --- a/source4/heimdal/lib/des/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs12.c,v 1.1 2006/01/13 08:26:49 lha Exp $"); +RCSID("$Id: pkcs12.c 20661 2007-05-10 21:57:58Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -77,7 +77,12 @@ PKCS12_key_gen(const void *key, size_t keylen, I[i] = ((unsigned char*)salt)[i % saltlen]; size_I += vlen; } - if (key && keylen > 0) { + /* + * There is a diffrence between the no password string and the + * empty string, in the empty string the UTF16 NUL terminator is + * included into the string. + */ + if (key && keylen >= 0) { 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/des/pkcs12.h b/source4/heimdal/lib/hcrypto/pkcs12.h index b55f1fced5..eb28b05467 100644 --- a/source4/heimdal/lib/des/pkcs12.h +++ b/source4/heimdal/lib/hcrypto/pkcs12.h @@ -32,7 +32,7 @@ */ /* - * $Id: pkcs12.h,v 1.2 2006/01/13 15:26:52 lha Exp $ + * $Id: pkcs12.h 16564 2006-01-13 15:26:52Z lha $ */ #ifndef _HEIM_PKCS12_H diff --git a/source4/heimdal/lib/des/pkcs5.c b/source4/heimdal/lib/hcrypto/pkcs5.c index 9ed494ef6f..85b8713cba 100644 --- a/source4/heimdal/lib/des/pkcs5.c +++ b/source4/heimdal/lib/hcrypto/pkcs5.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs5.c,v 1.3 2006/05/05 10:23:11 lha Exp $"); +RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $"); #ifdef KRB5 #include <krb5-types.h> diff --git a/source4/heimdal/lib/hcrypto/rand-egd.c b/source4/heimdal/lib/hcrypto/rand-egd.c new file mode 100644 index 0000000000..d1b024b535 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/rand-egd.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +RCSID("$Id: rand-egd.c 20093 2007-01-31 12:44:28Z lha $"); + +#include <sys/types.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <assert.h> + +#include <rand.h> +#include <randi.h> + +#include <roken.h> + +static const char *egd_path = "/var/run/egd-pool"; + +#define MAX_EGD_DATA 255 + +static int +connect_egd(const char *path) +{ + struct sockaddr_un addr; + int fd; + + memset(&addr, 0, sizeof(addr)); + + if (strlen(path) > sizeof(addr.sun_path)) + return -1; + + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { + close(fd); + return -1; + } + + return fd; +} + +static int +get_entropy(int fd, void *data, size_t len) +{ + unsigned char msg[2]; + + assert(len <= MAX_EGD_DATA); + + msg[0] = 0x02; /* read blocking data */ + msg[1] = len; /* wanted length */ + + if (net_write(fd, msg, sizeof(msg)) != sizeof(msg)) + return 0; + + if (net_read(fd, data, len) != len) + return 0; + + return 1; +} + +static int +put_entropy(int fd, const void *data, size_t len) +{ + unsigned char msg[4]; + + assert (len <= MAX_EGD_DATA); + + msg[0] = 0x03; /* write data */ + msg[1] = 0; /* dummy */ + msg[2] = 0; /* entropy */ + msg[3] = len; /* length */ + + if (net_write(fd, msg, sizeof(msg)) != sizeof(msg)) + return 0; + if (net_write(fd, data, len) != len) + return 0; + + return 1; +} + +/* + * + */ + +static void +egd_seed(const void *indata, int size) +{ + size_t len; + int fd, ret = 1; + + fd = connect_egd(egd_path); + if (fd < 0) + return; + + while(size) { + len = size; + if (len > MAX_EGD_DATA) + len = MAX_EGD_DATA; + ret = put_entropy(fd, indata, len); + if (ret != 1) + break; + indata = ((unsigned char *)indata) + len; + size -= len; + } + close(fd); +} + +static int +get_bytes(const char *path, unsigned char *outdata, int size) +{ + size_t len; + int fd, ret = 1; + + if (path == NULL) + path = egd_path; + + fd = connect_egd(path); + if (fd < 0) + return 0; + + while(size) { + len = size; + if (len > MAX_EGD_DATA) + len = MAX_EGD_DATA; + ret = get_entropy(fd, outdata, len); + if (ret != 1) + break; + outdata += len; + size -= len; + } + close(fd); + + return ret; +} + +static int +egd_bytes(unsigned char *outdata, int size) +{ + return get_bytes(NULL, outdata, size); +} + +static void +egd_cleanup(void) +{ +} + +static void +egd_add(const void *indata, int size, double entropi) +{ + egd_seed(indata, size); +} + +static int +egd_pseudorand(unsigned char *outdata, int size) +{ + return get_bytes(NULL, outdata, size); +} + +static int +egd_status(void) +{ + int fd; + fd = connect_egd(egd_path); + if (fd < 0) + return 0; + close(fd); + return 1; +} + +const RAND_METHOD hc_rand_egd_method = { + egd_seed, + egd_bytes, + egd_cleanup, + egd_add, + egd_pseudorand, + egd_status +}; + +const RAND_METHOD * +RAND_egd_method(void) +{ + return &hc_rand_egd_method; +} + + +int +RAND_egd(const char *filename) +{ + return RAND_egd_bytes(filename, 128); +} + +int +RAND_egd_bytes(const char *filename, int size) +{ + void *data; + int ret; + + if (size <= 0) + return 0; + + data = malloc(size); + if (data == NULL) + return 0; + + ret = get_bytes(filename, data, size); + if (ret != 1) { + free(data); + return ret; + } + + RAND_seed(data, size); + + memset(data, 0, sizeof(data)); + free(data); + + return 1; +} diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c new file mode 100644 index 0000000000..6cc4267c13 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c @@ -0,0 +1,563 @@ +/* + * fortuna.c + * Fortuna-like PRNG. + * + * Copyright (c) 2005 Marko Kreen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.8 2006/10/04 00:29:46 momjian Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +RCSID("$Id: rand-fortuna.c 20029 2007-01-21 09:55:42Z lha $"); + +#include <stdio.h> +#include <stdlib.h> +#include <rand.h> + +#include <roken.h> + +#include "randi.h" +#include "aes.h" +#include "sha.h" + +/* + * Why Fortuna-like: There does not seem to be any definitive reference + * on Fortuna in the net. Instead this implementation is based on + * following references: + * + * http://en.wikipedia.org/wiki/Fortuna_(PRNG) + * - Wikipedia article + * http://jlcooke.ca/random/ + * - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux. + */ + +/* + * There is some confusion about whether and how to carry forward + * the state of the pools. Seems like original Fortuna does not + * do it, resetting hash after each request. I guess expecting + * feeding to happen more often that requesting. This is absolutely + * unsuitable for pgcrypto, as nothing asynchronous happens here. + * + * J.L. Cooke fixed this by feeding previous hash to new re-initialized + * hash context. + * + * Fortuna predecessor Yarrow requires ability to query intermediate + * 'final result' from hash, without affecting it. + * + * This implementation uses the Yarrow method - asking intermediate + * results, but continuing with old state. + */ + + +/* + * Algorithm parameters + */ + +#define NUM_POOLS 32 + +/* in microseconds */ +#define RESEED_INTERVAL 100000 /* 0.1 sec */ + +/* for one big request, reseed after this many bytes */ +#define RESEED_BYTES (1024*1024) + +/* + * Skip reseed if pool 0 has less than this many + * bytes added since last reseed. + */ +#define POOL0_FILL (256/8) + +/* + * Algorithm constants + */ + +/* Both cipher key size and hash result size */ +#define BLOCK 32 + +/* cipher block size */ +#define CIPH_BLOCK 16 + +/* for internal wrappers */ +#define MD_CTX SHA256_CTX +#define CIPH_CTX AES_KEY + +struct fortuna_state +{ + unsigned char counter[CIPH_BLOCK]; + unsigned char result[CIPH_BLOCK]; + unsigned char key[BLOCK]; + MD_CTX pool[NUM_POOLS]; + CIPH_CTX ciph; + unsigned reseed_count; + struct timeval last_reseed_time; + unsigned pool0_bytes; + unsigned rnd_pos; + int tricks_done; +}; +typedef struct fortuna_state FState; + + +/* + * Use our own wrappers here. + * - Need to get intermediate result from digest, without affecting it. + * - Need re-set key on a cipher context. + * - Algorithms are guaranteed to exist. + * - No memory allocations. + */ + +static void +ciph_init(CIPH_CTX * ctx, const unsigned char *key, int klen) +{ + AES_set_encrypt_key(key, klen * 8, ctx); +} + +static void +ciph_encrypt(CIPH_CTX * ctx, const unsigned char *in, unsigned char *out) +{ + AES_encrypt(in, out, ctx); +} + +static void +md_init(MD_CTX * ctx) +{ + SHA256_Init(ctx); +} + +static void +md_update(MD_CTX * ctx, const unsigned char *data, int len) +{ + SHA256_Update(ctx, data, len); +} + +static void +md_result(MD_CTX * ctx, unsigned char *dst) +{ + SHA256_CTX tmp; + + memcpy(&tmp, ctx, sizeof(*ctx)); + SHA256_Final(dst, &tmp); + memset(&tmp, 0, sizeof(tmp)); +} + +/* + * initialize state + */ +static void +init_state(FState * st) +{ + int i; + + memset(st, 0, sizeof(*st)); + for (i = 0; i < NUM_POOLS; i++) + md_init(&st->pool[i]); +} + +/* + * Endianess does not matter. + * It just needs to change without repeating. + */ +static void +inc_counter(FState * st) +{ + uint32_t *val = (uint32_t *) st->counter; + + if (++val[0]) + return; + if (++val[1]) + return; + if (++val[2]) + return; + ++val[3]; +} + +/* + * This is called 'cipher in counter mode'. + */ +static void +encrypt_counter(FState * st, unsigned char *dst) +{ + ciph_encrypt(&st->ciph, st->counter, dst); + inc_counter(st); +} + + +/* + * The time between reseed must be at least RESEED_INTERVAL + * microseconds. + */ +static int +enough_time_passed(FState * st) +{ + int ok; + struct timeval tv; + struct timeval *last = &st->last_reseed_time; + + gettimeofday(&tv, NULL); + + /* check how much time has passed */ + ok = 0; + if (tv.tv_sec > last->tv_sec + 1) + ok = 1; + else if (tv.tv_sec == last->tv_sec + 1) + { + if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL) + ok = 1; + } + else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL) + ok = 1; + + /* reseed will happen, update last_reseed_time */ + if (ok) + memcpy(last, &tv, sizeof(tv)); + + memset(&tv, 0, sizeof(tv)); + + return ok; +} + +/* + * generate new key from all the pools + */ +static void +reseed(FState * st) +{ + unsigned k; + unsigned n; + MD_CTX key_md; + unsigned char buf[BLOCK]; + + /* set pool as empty */ + st->pool0_bytes = 0; + + /* + * Both #0 and #1 reseed would use only pool 0. Just skip #0 then. + */ + n = ++st->reseed_count; + + /* + * The goal: use k-th pool only 1/(2^k) of the time. + */ + md_init(&key_md); + for (k = 0; k < NUM_POOLS; k++) + { + md_result(&st->pool[k], buf); + md_update(&key_md, buf, BLOCK); + + if (n & 1 || !n) + break; + n >>= 1; + } + + /* add old key into mix too */ + md_update(&key_md, st->key, BLOCK); + + /* now we have new key */ + md_result(&key_md, st->key); + + /* use new key */ + ciph_init(&st->ciph, st->key, BLOCK); + + memset(&key_md, 0, sizeof(key_md)); + memset(buf, 0, BLOCK); +} + +/* + * Pick a random pool. This uses key bytes as random source. + */ +static unsigned +get_rand_pool(FState * st) +{ + unsigned rnd; + + /* + * This slightly prefers lower pools - thats OK. + */ + rnd = st->key[st->rnd_pos] % NUM_POOLS; + + st->rnd_pos++; + if (st->rnd_pos >= BLOCK) + st->rnd_pos = 0; + + return rnd; +} + +/* + * update pools + */ +static void +add_entropy(FState * st, const unsigned char *data, unsigned len) +{ + unsigned pos; + unsigned char hash[BLOCK]; + MD_CTX md; + + /* hash given data */ + md_init(&md); + md_update(&md, data, len); + md_result(&md, hash); + + /* + * Make sure the pool 0 is initialized, then update randomly. + */ + if (st->reseed_count == 0) + pos = 0; + else + pos = get_rand_pool(st); + md_update(&st->pool[pos], hash, BLOCK); + + if (pos == 0) + st->pool0_bytes += len; + + memset(hash, 0, BLOCK); + memset(&md, 0, sizeof(md)); +} + +/* + * Just take 2 next blocks as new key + */ +static void +rekey(FState * st) +{ + encrypt_counter(st, st->key); + encrypt_counter(st, st->key + CIPH_BLOCK); + ciph_init(&st->ciph, st->key, BLOCK); +} + +/* + * Hide public constants. (counter, pools > 0) + * + * This can also be viewed as spreading the startup + * entropy over all of the components. + */ +static void +startup_tricks(FState * st) +{ + int i; + unsigned char buf[BLOCK]; + + /* Use next block as counter. */ + encrypt_counter(st, st->counter); + + /* Now shuffle pools, excluding #0 */ + for (i = 1; i < NUM_POOLS; i++) + { + encrypt_counter(st, buf); + encrypt_counter(st, buf + CIPH_BLOCK); + md_update(&st->pool[i], buf, BLOCK); + } + memset(buf, 0, BLOCK); + + /* Hide the key. */ + rekey(st); + + /* This can be done only once. */ + st->tricks_done = 1; +} + +static void +extract_data(FState * st, unsigned count, unsigned char *dst) +{ + unsigned n; + unsigned block_nr = 0; + + /* Should we reseed? */ + if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0) + if (enough_time_passed(st)) + reseed(st); + + /* Do some randomization on first call */ + if (!st->tricks_done) + startup_tricks(st); + + while (count > 0) + { + /* produce bytes */ + encrypt_counter(st, st->result); + + /* copy result */ + if (count > CIPH_BLOCK) + n = CIPH_BLOCK; + else + n = count; + memcpy(dst, st->result, n); + dst += n; + count -= n; + + /* must not give out too many bytes with one key */ + block_nr++; + if (block_nr > (RESEED_BYTES / CIPH_BLOCK)) + { + rekey(st); + block_nr = 0; + } + } + /* Set new key for next request. */ + rekey(st); +} + +/* + * public interface + */ + +static FState main_state; +static int init_done; +static int have_entropy; + +/* + * Try our best to do an inital seed + */ +#define INIT_BYTES 128 + +static int +fortuna_reseed(void) +{ + int entropy_p = 0; + + if (!init_done) + abort(); + + { + unsigned char buf[INIT_BYTES]; + if ((*hc_rand_unix_method.bytes)(buf, sizeof(buf)) == 1) { + add_entropy(&main_state, buf, sizeof(buf)); + entropy_p = 1; + memset(buf, 0, sizeof(buf)); + } + } +#ifdef HAVE_ARC4RANDOM + { + uint32_t buf[INIT_BYTES / sizeof(uint32_t)]; + int i; + + for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++) + buf[i] = arc4random(); + add_entropy(&main_state, (void *)buf, sizeof(buf)); + entropy_p = 1; + } +#endif + /* + * Only to get egd entropy if /dev/random or arc4rand failed since + * it can be horribly slow to generate new bits. + */ + if (!entropy_p) { + unsigned char buf[INIT_BYTES]; + if ((*hc_rand_egd_method.bytes)(buf, sizeof(buf)) == 1) { + add_entropy(&main_state, buf, sizeof(buf)); + entropy_p = 1; + memset(buf, 0, sizeof(buf)); + } + } + { + pid_t pid = getpid(); + add_entropy(&main_state, (void *)&pid, sizeof(pid)); + } + { + struct timeval tv; + gettimeofday(&tv, NULL); + add_entropy(&main_state, (void *)&tv, sizeof(tv)); + } + { + uid_t u = getuid(); + add_entropy(&main_state, (void *)&u, sizeof(u)); + } + return entropy_p; +} + +static int +fortuna_init(void) +{ + if (!init_done) + { + init_state(&main_state); + init_done = 1; + } + if (!have_entropy) + have_entropy = fortuna_reseed(); + return (init_done && have_entropy); +} + + + +static void +fortuna_seed(const void *indata, int size) +{ + fortuna_init(); + add_entropy(&main_state, indata, size); + if (size >= INIT_BYTES) + have_entropy = 1; +} + +static int +fortuna_bytes(unsigned char *outdata, int size) +{ + if (!fortuna_init()) + return 0; + extract_data(&main_state, size, outdata); + return 1; +} + +static void +fortuna_cleanup(void) +{ + init_done = 0; + have_entropy = 0; + memset(&main_state, 0, sizeof(main_state)); +} + +static void +fortuna_add(const void *indata, int size, double entropi) +{ + fortuna_seed(indata, size); +} + +static int +fortuna_pseudorand(unsigned char *outdata, int size) +{ + return fortuna_bytes(outdata, size); +} + +static int +fortuna_status(void) +{ + return fortuna_init() ? 1 : 0; +} + +const RAND_METHOD hc_rand_fortuna_method = { + fortuna_seed, + fortuna_bytes, + fortuna_cleanup, + fortuna_add, + fortuna_pseudorand, + fortuna_status +}; + +const RAND_METHOD * +RAND_fortuna_method(void) +{ + return &hc_rand_fortuna_method; +} diff --git a/source4/heimdal/lib/des/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c index a51c6c0c0d..354492fb3d 100644 --- a/source4/heimdal/lib/des/rand-unix.c +++ b/source4/heimdal/lib/hcrypto/rand-unix.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand-unix.c,v 1.2 2006/10/21 21:09:14 lha Exp $"); +RCSID("$Id: rand-unix.c 20028 2007-01-21 09:54:56Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -43,6 +43,8 @@ RCSID("$Id: rand-unix.c,v 1.2 2006/10/21 21:09:14 lha Exp $"); #include <roken.h> +#include "randi.h" + /* * Unix /dev/random */ @@ -151,3 +153,9 @@ const RAND_METHOD hc_rand_unix_method = { unix_pseudorand, unix_status }; + +const RAND_METHOD * +RAND_unix_method(void) +{ + return &hc_rand_unix_method; +} diff --git a/source4/heimdal/lib/des/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 6eb959b724..29f2d46dba 100644 --- a/source4/heimdal/lib/des/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,50 +35,73 @@ #include <config.h> #endif -RCSID("$Id: rand.c,v 1.7 2006/10/16 10:23:01 lha Exp $"); +RCSID("$Id: rand.c 20126 2007-02-01 22:08:41Z lha $"); #include <stdio.h> #include <stdlib.h> #include <rand.h> +#include <randi.h> #include <roken.h> -extern RAND_METHOD hc_rand_unix_method; -static const RAND_METHOD *selected_meth = &hc_rand_unix_method; +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + +const static RAND_METHOD *selected_meth = NULL; + +static void +init_method(void) +{ + if (selected_meth != NULL) + return; + + if ((*hc_rand_unix_method.status)() == 1) + selected_meth = &hc_rand_unix_method; + else + selected_meth = &hc_rand_fortuna_method; +} void RAND_seed(const void *indata, size_t size) { + init_method(); (*selected_meth->seed)(indata, size); } int RAND_bytes(void *outdata, size_t size) { + init_method(); return (*selected_meth->bytes)(outdata, size); } void RAND_cleanup(void) { + init_method(); (*selected_meth->cleanup)(); } void RAND_add(const void *indata, size_t size, double entropi) { + init_method(); (*selected_meth->add)(indata, size, entropi); } int RAND_pseudo_bytes(void *outdata, size_t size) { + init_method(); return (*selected_meth->pseudorand)(outdata, size); } int RAND_status(void) { + init_method(); return (*selected_meth->status)(); } @@ -101,20 +124,92 @@ RAND_set_rand_engine(ENGINE *engine) return 1; } +#define RAND_FILE_SIZE 1024 + int RAND_load_file(const char *filename, size_t size) { - return 1; + unsigned char buf[128]; + size_t len; + ssize_t slen; + int fd; + + fd = open(filename, O_RDONLY | O_BINARY, 0600); + if (fd < 0) + return 0; + + len = 0; + while(len < size) { + slen = read(fd, buf, sizeof(buf)); + if (slen <= 0) + break; + RAND_seed(buf, slen); + len += slen; + } + close(fd); + + return len ? 1 : 0; } int RAND_write_file(const char *filename) { - return 1; + unsigned char buf[128]; + size_t len; + int res = 0, fd; + + fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600); + if (fd < 0) + return 0; + + len = 0; + while(len < RAND_FILE_SIZE) { + res = RAND_bytes(buf, sizeof(buf)); + if (res != 1) + break; + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { + res = 0; + break; + } + len += sizeof(buf); + } + + close(fd); + + return res; } -int -RAND_egd(const char *filename) +const char * +RAND_file_name(char *filename, size_t size) { - return 1; + const char *e = NULL; + int pathp = 0, ret; + + if (!issuid()) { + e = getenv("RANDFILE"); + if (e == NULL) { + e = getenv("HOME"); + if (e) + pathp = 1; + } + } + if (e == NULL) { + struct passwd *pw = getpwuid(getuid()); + if (pw) { + e = pw->pw_dir; + pathp = 1; + } + } + if (e == NULL) + return NULL; + + if (pathp) + ret = snprintf(filename, size, "%s/.rnd", e); + else + ret = snprintf(filename, size, "%s", e); + + if (ret <= 0 || ret >= size) + return NULL; + + return filename; } diff --git a/source4/heimdal/lib/des/rand.h b/source4/heimdal/lib/hcrypto/rand.h index a57da53928..c8ba2d9a7b 100644 --- a/source4/heimdal/lib/des/rand.h +++ b/source4/heimdal/lib/hcrypto/rand.h @@ -33,7 +33,7 @@ */ /* - * $Id: rand.h,v 1.4 2006/04/17 13:23:04 lha Exp $ + * $Id: rand.h 20063 2007-01-30 18:30:36Z lha $ */ #ifndef _HEIM_RAND_H @@ -53,10 +53,15 @@ typedef struct RAND_METHOD RAND_METHOD; #define RAND_set_rand_method hc_RAND_set_rand_method #define RAND_get_rand_method hc_RAND_get_rand_method #define RAND_set_rand_engine hc_RAND_set_rand_engine +#define RAND_file_name hc_RAND_file_name #define RAND_load_file hc_RAND_load_file #define RAND_write_file hc_RAND_write_file #define RAND_status hc_RAND_status #define RAND_egd hc_RAND_egd +#define RAND_egd_bytes hc_RAND_egd_bytes +#define RAND_fortuna_method hc_RAND_fortuna_method +#define RAND_egd_method hc_RAND_egd_method +#define RAND_unix_method hc_RAND_unix_method /* * @@ -87,10 +92,17 @@ const RAND_METHOD * RAND_get_rand_method(void); int RAND_set_rand_engine(ENGINE *); +const char * + RAND_file_name(char *, size_t); int RAND_load_file(const char *, size_t); int RAND_write_file(const char *); int RAND_status(void); int RAND_egd(const char *); +int RAND_egd_bytes(const char *, int); +const RAND_METHOD * RAND_fortuna_method(void); +const RAND_METHOD * RAND_unix_method(void); +const RAND_METHOD * RAND_egd_method(void); + #endif /* _HEIM_RAND_H */ diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/hcrypto/randi.h index 340b35377d..b9b9b5309c 100644 --- a/source4/heimdal/lib/gssapi/gssapi.h +++ b/source4/heimdal/lib/hcrypto/randi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,11 +31,15 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h,v 1.50 2006/10/07 20:57:15 lha Exp $ */ +/* + * $Id: randi.h 20027 2007-01-21 09:54:00Z lha $ + */ -#ifndef GSSAPI_H_ -#define GSSAPI_H_ +#ifndef _HEIM_RANDI_H +#define _HEIM_RANDI_H 1 -#include <gssapi/gssapi.h> +extern const RAND_METHOD hc_rand_fortuna_method; +extern const RAND_METHOD hc_rand_unix_method; +extern const RAND_METHOD hc_rand_egd_method; -#endif +#endif /* _HEIM_RANDI_H */ diff --git a/source4/heimdal/lib/des/rc2.c b/source4/heimdal/lib/hcrypto/rc2.c index ed43c70605..63992be9a9 100755 --- a/source4/heimdal/lib/des/rc2.c +++ b/source4/heimdal/lib/hcrypto/rc2.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: rc2.c,v 1.7 2006/04/09 17:03:21 lha Exp $"); +RCSID("$Id: rc2.c 17022 2006-04-09 17:03:21Z lha $"); #endif #include "rc2.h" diff --git a/source4/heimdal/lib/des/rc2.h b/source4/heimdal/lib/hcrypto/rc2.h index b2cd50b880..5a2dd2d705 100755 --- a/source4/heimdal/lib/des/rc2.h +++ b/source4/heimdal/lib/hcrypto/rc2.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: rc2.h,v 1.2 2006/01/08 21:47:29 lha Exp $ */ +/* $Id: rc2.h 16480 2006-01-08 21:47:29Z lha $ */ /* symbol renaming */ #define RC2_set_key hc_RC2_set_key diff --git a/source4/heimdal/lib/des/rc4.c b/source4/heimdal/lib/hcrypto/rc4.c index 17d4b021ff..edaf37ddc4 100755 --- a/source4/heimdal/lib/des/rc4.c +++ b/source4/heimdal/lib/hcrypto/rc4.c @@ -36,7 +36,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rc4.c,v 1.1 2004/03/25 16:40:59 lha Exp $"); +RCSID("$Id: rc4.c 13640 2004-03-25 16:40:59Z lha $"); #endif #include <rc4.h> diff --git a/source4/heimdal/lib/des/rc4.h b/source4/heimdal/lib/hcrypto/rc4.h index 3c359dc72a..1ab25f59e6 100644 --- a/source4/heimdal/lib/des/rc4.h +++ b/source4/heimdal/lib/hcrypto/rc4.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: rc4.h,v 1.4 2006/01/08 21:47:29 lha Exp $ */ +/* $Id: rc4.h 16480 2006-01-08 21:47:29Z lha $ */ /* symbol renaming */ #define RC4_set_key hc_RC4_set_key diff --git a/source4/heimdal/lib/des/resource.h b/source4/heimdal/lib/hcrypto/resource.h index 02c6a7c6d9..02c6a7c6d9 100644 --- a/source4/heimdal/lib/des/resource.h +++ b/source4/heimdal/lib/hcrypto/resource.h diff --git a/source4/heimdal/lib/des/rijndael-alg-fst.c b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c index d6e4f45c18..c6330d27e4 100755 --- a/source4/heimdal/lib/des/rijndael-alg-fst.c +++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c @@ -31,7 +31,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rijndael-alg-fst.c,v 1.3 2006/05/05 10:23:41 lha Exp $"); +RCSID("$Id: rijndael-alg-fst.c 17445 2006-05-05 10:37:46Z lha $"); #endif #ifdef KRB5 diff --git a/source4/heimdal/lib/des/rijndael-alg-fst.h b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h index 7e2e1935fd..7e2e1935fd 100755 --- a/source4/heimdal/lib/des/rijndael-alg-fst.h +++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h diff --git a/source4/heimdal/lib/des/rnd_keys.c b/source4/heimdal/lib/hcrypto/rnd_keys.c index e58faefcb0..a035b890b8 100644 --- a/source4/heimdal/lib/des/rnd_keys.c +++ b/source4/heimdal/lib/hcrypto/rnd_keys.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rnd_keys.c,v 1.71 2006/05/05 10:24:31 lha Exp $"); +RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $"); #endif #ifdef KRB5 diff --git a/source4/heimdal/lib/des/rsa-imath.c b/source4/heimdal/lib/hcrypto/rsa-imath.c index 298affadfe..e05ead1e66 100644 --- a/source4/heimdal/lib/des/rsa-imath.c +++ b/source4/heimdal/lib/hcrypto/rsa-imath.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rsa-imath.c,v 1.23 2007/01/06 13:45:25 lha Exp $"); +RCSID("$Id: rsa-imath.c 19750 2007-01-06 13:45:25Z lha $"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/des/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c index 241afb2e46..a7b4371e4d 100644 --- a/source4/heimdal/lib/des/rsa.c +++ b/source4/heimdal/lib/hcrypto/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rsa.c,v 1.19 2007/01/09 10:04:20 lha Exp $"); +RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -110,6 +110,7 @@ RSA_free(RSA *rsa) free_if(rsa->q); free_if(rsa->dmp1); free_if(rsa->dmq1); + free_if(rsa->iqmp); #undef free_if memset(rsa, 0, sizeof(*rsa)); @@ -234,7 +235,7 @@ RSA_verify(int type, const unsigned char *from, unsigned int flen, /* * A NULL RSA_METHOD that returns failure for all operations. This is - * used as the default RSA method is we don't have any native + * used as the default RSA method if we don't have any native * support. */ diff --git a/source4/heimdal/lib/des/rsa.h b/source4/heimdal/lib/hcrypto/rsa.h index 0aceb9f9da..575774dbde 100644 --- a/source4/heimdal/lib/des/rsa.h +++ b/source4/heimdal/lib/hcrypto/rsa.h @@ -32,7 +32,7 @@ */ /* - * $Id: rsa.h,v 1.9 2007/01/05 20:26:23 lha Exp $ + * $Id: rsa.h 19734 2007-01-05 20:26:23Z lha $ */ #ifndef _HEIM_RSA_H diff --git a/source4/heimdal/lib/des/sha.c b/source4/heimdal/lib/hcrypto/sha.c index fae0fe01cb..a264f53f33 100644 --- a/source4/heimdal/lib/des/sha.c +++ b/source4/heimdal/lib/hcrypto/sha.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: sha.c,v 1.19 2006/05/05 10:25:00 lha Exp $"); +RCSID("$Id: sha.c 17445 2006-05-05 10:37:46Z lha $"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/des/sha.h b/source4/heimdal/lib/hcrypto/sha.h index 977b9f7bb2..70fc20e222 100644 --- a/source4/heimdal/lib/des/sha.h +++ b/source4/heimdal/lib/hcrypto/sha.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: sha.h,v 1.11 2006/05/05 11:06:21 lha Exp $ */ +/* $Id: sha.h 17450 2006-05-05 11:11:43Z lha $ */ #ifndef HEIM_SHA_H #define HEIM_SHA_H 1 diff --git a/source4/heimdal/lib/des/sha256.c b/source4/heimdal/lib/hcrypto/sha256.c index 58fb92815a..b95442eff6 100644 --- a/source4/heimdal/lib/des/sha256.c +++ b/source4/heimdal/lib/hcrypto/sha256.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: sha256.c,v 1.2 2006/05/05 10:25:37 lha Exp $"); +RCSID("$Id: sha256.c 17445 2006-05-05 10:37:46Z lha $"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/des/ui.c b/source4/heimdal/lib/hcrypto/ui.c index 25b0ad293c..3e651998b5 100644 --- a/source4/heimdal/lib/des/ui.c +++ b/source4/heimdal/lib/hcrypto/ui.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: ui.c,v 1.6 2006/09/22 15:45:57 lha Exp $"); +RCSID("$Id: ui.c 18158 2006-09-22 15:45:57Z lha $"); #endif #include <stdio.h> diff --git a/source4/heimdal/lib/des/ui.h b/source4/heimdal/lib/hcrypto/ui.h index d6e68e12cc..53926cc1f7 100644 --- a/source4/heimdal/lib/des/ui.h +++ b/source4/heimdal/lib/hcrypto/ui.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: ui.h,v 1.1 2006/01/08 21:47:29 lha Exp $ */ +/* $Id: ui.h 16480 2006-01-08 21:47:29Z lha $ */ #ifndef _HEIM_UI_H #define _HEIM_UI_H 1 diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c index 0bbf6f2210..870f0431cf 100644 --- a/source4/heimdal/lib/hdb/db.c +++ b/source4/heimdal/lib/hdb/db.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: db.c,v 1.36 2006/09/12 18:12:37 lha Exp $"); +RCSID("$Id: db.c 20215 2007-02-09 21:59:53Z lha $"); #if HAVE_DB1 @@ -67,8 +67,11 @@ DB_lock(krb5_context context, HDB *db, int operation) { DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); - if(fd < 0) + if(fd < 0) { + krb5_set_error_string(context, + "Can't lock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; + } return hdb_lock(fd, operation); } @@ -77,8 +80,11 @@ DB_unlock(krb5_context context, HDB *db) { DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); - if(fd < 0) + if(fd < 0) { + krb5_set_error_string(context, + "Can't unlock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; + } return hdb_unlock(fd); } @@ -93,14 +99,22 @@ DB_seq(krb5_context context, HDB *db, int code; code = db->hdb_lock(context, db, HDB_RLOCK); - if(code == -1) + if(code == -1) { + krb5_set_error_string(context, "Database %s in use", db->hdb_name); return HDB_ERR_DB_INUSE; + } code = (*d->seq)(d, &key, &value, flag); db->hdb_unlock(context, db); /* XXX check value */ - if(code == -1) - return errno; - if(code == 1) + if(code == -1) { + code = errno; + krb5_set_error_string(context, "Database %s seq error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_NOENTRY; + } key_data.data = key.data; key_data.length = key.size; @@ -174,10 +188,16 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) return code; code = (*d->get)(d, &k, &v, 0); db->hdb_unlock(context, db); - if(code < 0) - return errno; - if(code == 1) + if(code < 0) { + code = errno; + krb5_set_error_string(context, "Database %s get error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_NOENTRY; + } krb5_data_copy(reply, v.data, v.size); return 0; @@ -200,10 +220,16 @@ DB__put(krb5_context context, HDB *db, int replace, return code; code = (*d->put)(d, &k, &v, replace ? 0 : R_NOOVERWRITE); db->hdb_unlock(context, db); - if(code < 0) - return errno; - if(code == 1) + if(code < 0) { + code = errno; + krb5_set_error_string(context, "Database %s put error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_EXISTS; + } return 0; } @@ -220,8 +246,12 @@ DB__del(krb5_context context, HDB *db, krb5_data key) return code; code = (*d->del)(d, &k, 0); db->hdb_unlock(context, db); - if(code == 1) - return HDB_ERR_NOENTRY; + if(code == 1) { + code = errno; + krb5_set_error_string(context, "Database %s put error: %s", + db->hdb_name, strerror(code)); + return code; + } if(code < 0) return errno; return 0; diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c index 141c63a8ac..aac0ff5367 100644 --- a/source4/heimdal/lib/hdb/ext.c +++ b/source4/heimdal/lib/hdb/ext.c @@ -34,7 +34,7 @@ #include "hdb_locl.h" #include <der.h> -RCSID("$Id: ext.c,v 1.6 2006/10/14 10:13:03 lha Exp $"); +RCSID("$Id: ext.c 20236 2007-02-16 23:52:29Z lha $"); krb5_error_code hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) @@ -394,3 +394,17 @@ hdb_entry_get_ConstrainedDelegACL(const hdb_entry *entry, return 0; } + +krb5_error_code +hdb_entry_get_aliases(const hdb_entry *entry, const HDB_Ext_Aliases **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_aliases); + if (ext) + *a = &ext->data.u.aliases; + else + *a = NULL; + + return 0; +} diff --git a/source4/heimdal/lib/hdb/hdb-protos.h b/source4/heimdal/lib/hdb/hdb-protos.h index de0545a037..6d679fd48f 100644 --- a/source4/heimdal/lib/hdb/hdb-protos.h +++ b/source4/heimdal/lib/hdb/hdb-protos.h @@ -42,6 +42,41 @@ hdb_db_create ( HDB **/*db*/, const char */*filename*/); +const char * +hdb_dbinfo_get_acl_file ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const krb5_config_binding * +hdb_dbinfo_get_binding ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_dbname ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_label ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_mkey_file ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +struct hdb_dbinfo * +hdb_dbinfo_get_next ( + struct hdb_dbinfo */*dbp*/, + struct hdb_dbinfo */*dbprevp*/); + +const char * +hdb_dbinfo_get_realm ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + krb5_error_code hdb_enctype2key ( krb5_context /*context*/, @@ -58,7 +93,13 @@ hdb_entry2string ( int hdb_entry2value ( krb5_context /*context*/, - hdb_entry */*ent*/, + const hdb_entry */*ent*/, + krb5_data */*value*/); + +int +hdb_entry_alias2value ( + krb5_context /*context*/, + const hdb_entry_alias */*alias*/, krb5_data */*value*/); krb5_error_code @@ -76,6 +117,11 @@ hdb_entry_get_ConstrainedDelegACL ( const hdb_entry */*entry*/, const HDB_Ext_Constrained_delegation_acl **/*a*/); +krb5_error_code +hdb_entry_get_aliases ( + const hdb_entry */*entry*/, + const HDB_Ext_Aliases **/*a*/); + int hdb_entry_get_password ( krb5_context /*context*/, @@ -125,6 +171,11 @@ hdb_foreach ( void */*data*/); void +hdb_free_dbinfo ( + krb5_context /*context*/, + struct hdb_dbinfo **/*dbp*/); + +void hdb_free_entry ( krb5_context /*context*/, hdb_entry_ex */*ent*/); @@ -159,6 +210,11 @@ hdb_generate_key_set_password ( Key **/*keys*/, size_t */*num_keys*/); +int +hdb_get_dbinfo ( + krb5_context /*context*/, + struct hdb_dbinfo **/*dbp*/); + krb5_error_code hdb_init_db ( krb5_context /*context*/, @@ -314,6 +370,12 @@ hdb_value2entry ( krb5_data */*value*/, hdb_entry */*ent*/); +int +hdb_value2entry_alias ( + krb5_context /*context*/, + krb5_data */*value*/, + hdb_entry_alias */*ent*/); + krb5_error_code hdb_write_master_key ( krb5_context /*context*/, diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1 index c8c276ff6e..acd8f61d7e 100644 --- a/source4/heimdal/lib/hdb/hdb.asn1 +++ b/source4/heimdal/lib/hdb/hdb.asn1 @@ -1,4 +1,4 @@ --- $Id: hdb.asn1,v 1.17 2006/08/24 10:45:19 lha Exp $ +-- $Id: hdb.asn1 20236 2007-02-16 23:52:29Z lha $ HDB DEFINITIONS ::= BEGIN @@ -120,4 +120,8 @@ hdb_entry ::= SEQUENCE { extensions[13] HDB-extensions OPTIONAL } +hdb_entry_alias ::= [APPLICATION 0] SEQUENCE { + principal[0] Principal OPTIONAL +} + END diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index cd4f24a732..f0731ed98e 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: hdb.c,v 1.64 2006/11/28 14:24:27 lha Exp $"); +RCSID("$Id: hdb.c 20214 2007-02-09 21:51:10Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> @@ -56,7 +56,7 @@ static struct hdb_method methods[] = { {"ldapi:", hdb_ldapi_create}, #endif #ifdef _SAMBA_BUILD_ - {"ldb:", hdb_ldb_create}, + {"ldb:", hdb_ldb_create}, #endif #ifdef HAVE_LDB /* Used for integrated samba build */ {"ldb:", hdb_ldb_create}, @@ -81,11 +81,15 @@ hdb_next_enctype2key(krb5_context context, for (k = *key ? (*key) + 1 : e->keys.val; k < e->keys.val + e->keys.len; - k++) + k++) + { if(k->key.keytype == enctype){ *key = k; return 0; } + } + krb5_set_error_string(context, "No next enctype %d for hdb-entry", + (int)enctype); return KRB5_PROG_ETYPE_NOSUPP; /* XXX */ } @@ -164,6 +168,8 @@ hdb_foreach(krb5_context context, krb5_error_code ret; hdb_entry_ex entry; ret = db->hdb_firstkey(context, db, flags, &entry); + if (ret == 0) + krb5_clear_error_string(context); while(ret == 0){ ret = (*func)(context, db, &entry, data); hdb_free_entry(context, &entry); @@ -228,8 +234,11 @@ hdb_init_db(krb5_context context, HDB *db) version.length = strlen(version.data) + 1; /* zero terminated */ ret = (*db->hdb__put)(context, db, 0, tag, version); ret2 = db->hdb_unlock(context, db); - if (ret) + if (ret) { + if (ret2) + krb5_clear_error_string(context); return ret; + } return ret2; } diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index dcfceb58f0..830589388f 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hdb.h,v 1.38 2006/04/28 07:37:11 lha Exp $ */ +/* $Id: hdb.h 20535 2007-04-23 07:49:16Z lha $ */ #ifndef __HDB_H__ #define __HDB_H__ @@ -41,6 +41,8 @@ #include <heim_asn1.h> #include <hdb_asn1.h> +struct hdb_dbinfo; + enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; /* flags for various functions */ @@ -50,6 +52,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_GET_SERVER 8 /* fetch server */ #define HDB_F_GET_KRBTGT 16 /* fetch krbtgt */ #define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ +#define HDB_F_CANON 32 /* want canonicalition */ /* key usage for master key */ #define HDB_KU_MKEY 0x484442 @@ -69,7 +72,7 @@ typedef struct HDB{ char *hdb_name; int hdb_master_key_set; hdb_master_key hdb_master_key; - void *hdb_openp; + int hdb_openp; krb5_error_code (*hdb_open)(krb5_context, struct HDB*, diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et index f2636b2fea..5c5b80bb36 100644 --- a/source4/heimdal/lib/hdb/hdb_err.et +++ b/source4/heimdal/lib/hdb/hdb_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: hdb_err.et,v 1.6 2005/08/11 13:17:22 lha Exp $" +id "$Id: hdb_err.et 15878 2005-08-11 13:17:22Z lha $" error_table hdb diff --git a/source4/heimdal/lib/hdb/hdb_locl.h b/source4/heimdal/lib/hdb/hdb_locl.h index 0bf4e8191c..ad16075b24 100644 --- a/source4/heimdal/lib/hdb/hdb_locl.h +++ b/source4/heimdal/lib/hdb/hdb_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hdb_locl.h,v 1.19 2003/09/10 21:54:58 lha Exp $ */ +/* $Id: hdb_locl.h 12820 2003-09-10 21:54:58Z lha $ */ #ifndef __HDB_LOCL_H__ #define __HDB_LOCL_H__ diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c index 8d4810f5c9..9b87050120 100644 --- a/source4/heimdal/lib/hdb/keys.c +++ b/source4/heimdal/lib/hdb/keys.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: keys.c,v 1.6 2006/10/22 09:40:12 lha Exp $"); +RCSID("$Id: keys.c 18819 2006-10-22 09:40:12Z lha $"); /* * free all the memory used by (len, keys) diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c index 7ae3ec3150..5c867daf20 100644 --- a/source4/heimdal/lib/hdb/keytab.c +++ b/source4/heimdal/lib/hdb/keytab.c @@ -35,7 +35,7 @@ /* keytab backend for HDB databases */ -RCSID("$Id: keytab.c,v 1.16 2006/10/09 12:36:40 lha Exp $"); +RCSID("$Id: keytab.c 18380 2006-10-09 12:36:40Z lha $"); struct hdb_data { char *dbname; diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c index 40569b29ad..02d87b6cf3 100644 --- a/source4/heimdal/lib/hdb/mkey.c +++ b/source4/heimdal/lib/hdb/mkey.c @@ -36,7 +36,7 @@ #define O_BINARY 0 #endif -RCSID("$Id: mkey.c,v 1.22 2006/05/05 10:27:59 lha Exp $"); +RCSID("$Id: mkey.c 17445 2006-05-05 10:37:46Z lha $"); struct hdb_master_key_data { krb5_keytab_entry keytab; diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c index 6c72ea78c5..6575b8a417 100644 --- a/source4/heimdal/lib/hdb/ndbm.c +++ b/source4/heimdal/lib/hdb/ndbm.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: ndbm.c,v 1.38 2005/12/13 11:54:10 lha Exp $"); +RCSID("$Id: ndbm.c 16395 2005-12-13 11:54:10Z lha $"); #if HAVE_NDBM diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c index 1a5b4947be..0e48269aa4 100644 --- a/source4/heimdal/lib/hx509/ca.c +++ b/source4/heimdal/lib/hx509/ca.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "hx_locl.h" #include <pkinit_asn1.h> -RCSID("$Id: ca.c,v 1.12 2007/01/05 18:40:46 lha Exp $"); +RCSID("$Id: ca.c 20904 2007-06-05 01:58:45Z lha $"); struct hx509_ca_tbs { hx509_name subject; @@ -47,10 +47,12 @@ struct hx509_ca_tbs { unsigned int ca:1; unsigned int key:1; unsigned int serial:1; + unsigned int domaincontroller:1; } flags; time_t notBefore; time_t notAfter; int pathLenConstraint; /* both for CA and Proxy */ + CRLDistributionPoints crldp; }; int @@ -66,6 +68,8 @@ hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs) (*tbs)->eku.len = 0; (*tbs)->eku.val = NULL; (*tbs)->pathLenConstraint = 0; + (*tbs)->crldp.len = 0; + (*tbs)->crldp.val = NULL; return 0; } @@ -80,6 +84,7 @@ hx509_ca_tbs_free(hx509_ca_tbs *tbs) free_GeneralNames(&(*tbs)->san); free_ExtKeyUsage(&(*tbs)->eku); der_free_heim_integer(&(*tbs)->serial); + free_CRLDistributionPoints(&(*tbs)->crldp); hx509_name_free(&(*tbs)->subject); @@ -114,6 +119,89 @@ hx509_ca_tbs_set_notAfter_lifetime(hx509_context context, return hx509_ca_tbs_set_notAfter(context, tbs, time(NULL) + delta); } +static const struct units templatebits[] = { + { "ExtendedKeyUsage", HX509_CA_TEMPLATE_EKU }, + { "KeyUsage", HX509_CA_TEMPLATE_KU }, + { "SPKI", HX509_CA_TEMPLATE_SPKI }, + { "notAfter", HX509_CA_TEMPLATE_NOTAFTER }, + { "notBefore", HX509_CA_TEMPLATE_NOTBEFORE }, + { "serial", HX509_CA_TEMPLATE_SERIAL }, + { "subject", HX509_CA_TEMPLATE_SUBJECT }, + { NULL, 0 } +}; + +const struct units * +hx509_ca_tbs_template_units(void) +{ + return templatebits; +} + +int +hx509_ca_tbs_set_template(hx509_context context, + hx509_ca_tbs tbs, + int flags, + hx509_cert cert) +{ + int ret; + + if (flags & HX509_CA_TEMPLATE_SUBJECT) { + if (tbs->subject) + hx509_name_free(&tbs->subject); + ret = hx509_cert_get_subject(cert, &tbs->subject); + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to get subject from template"); + return ret; + } + } + if (flags & HX509_CA_TEMPLATE_SERIAL) { + der_free_heim_integer(&tbs->serial); + ret = hx509_cert_get_serialnumber(cert, &tbs->serial); + tbs->flags.serial = !ret; + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to copy serial number"); + return ret; + } + } + if (flags & HX509_CA_TEMPLATE_NOTBEFORE) + tbs->notBefore = hx509_cert_get_notBefore(cert); + if (flags & HX509_CA_TEMPLATE_NOTAFTER) + tbs->notAfter = hx509_cert_get_notAfter(cert); + if (flags & HX509_CA_TEMPLATE_SPKI) { + free_SubjectPublicKeyInfo(&tbs->spki); + ret = hx509_cert_get_SPKI(cert, &tbs->spki); + tbs->flags.key = !ret; + if (ret) { + hx509_set_error_string(context, 0, ret, "Failed to copy SPKI"); + return ret; + } + } + if (flags & HX509_CA_TEMPLATE_KU) { + KeyUsage ku; + ret = _hx509_cert_get_keyusage(context, cert, &ku); + if (ret) + return ret; + tbs->key_usage = KeyUsage2int(ku); + } + if (flags & HX509_CA_TEMPLATE_EKU) { + ExtKeyUsage eku; + int i; + ret = _hx509_cert_get_eku(context, cert, &eku); + if (ret) + return ret; + for (i = 0; i < eku.len; i++) { + ret = hx509_ca_tbs_add_eku(context, tbs, &eku.val[i]); + if (ret) { + free_ExtKeyUsage(&eku); + return ret; + } + } + free_ExtKeyUsage(&eku); + } + return 0; +} + int hx509_ca_tbs_set_ca(hx509_context context, hx509_ca_tbs tbs, @@ -136,6 +224,14 @@ hx509_ca_tbs_set_proxy(hx509_context context, int +hx509_ca_tbs_set_domaincontroller(hx509_context context, + hx509_ca_tbs tbs) +{ + tbs->flags.domaincontroller = 1; + return 0; +} + +int hx509_ca_tbs_set_spki(hx509_context context, hx509_ca_tbs tbs, const SubjectPublicKeyInfo *spki) @@ -160,25 +256,123 @@ hx509_ca_tbs_set_serialnumber(hx509_context context, } int -hx509_ca_tbs_add_eku(hx509_context contex, +hx509_ca_tbs_add_eku(hx509_context context, hx509_ca_tbs tbs, const heim_oid *oid) { void *ptr; int ret; + unsigned i; + + /* search for duplicates */ + for (i = 0; i < tbs->eku.len; i++) { + if (der_heim_oid_cmp(oid, &tbs->eku.val[i]) == 0) + return 0; + } ptr = realloc(tbs->eku.val, sizeof(tbs->eku.val[0]) * (tbs->eku.len + 1)); - if (ptr == NULL) + if (ptr == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; + } tbs->eku.val = ptr; ret = der_copy_oid(oid, &tbs->eku.val[tbs->eku.len]); - if (ret) + if (ret) { + hx509_set_error_string(context, 0, ret, "out of memory"); return ret; + } tbs->eku.len += 1; return 0; } int +hx509_ca_tbs_add_crl_dp_uri(hx509_context context, + hx509_ca_tbs tbs, + const char *uri, + hx509_name issuername) +{ + DistributionPoint dp; + int ret; + + memset(&dp, 0, sizeof(dp)); + + dp.distributionPoint = ecalloc(1, sizeof(*dp.distributionPoint)); + + { + DistributionPointName name; + GeneralName gn; + size_t size; + + name.element = choice_DistributionPointName_fullName; + name.u.fullName.len = 1; + name.u.fullName.val = &gn; + + gn.element = choice_GeneralName_uniformResourceIdentifier; + gn.u.uniformResourceIdentifier = rk_UNCONST(uri); + + ASN1_MALLOC_ENCODE(DistributionPointName, + dp.distributionPoint->data, + dp.distributionPoint->length, + &name, &size, ret); + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to encoded DistributionPointName"); + goto out; + } + if (dp.distributionPoint->length != size) + _hx509_abort("internal ASN.1 encoder error"); + } + + if (issuername) { +#if 1 + hx509_set_error_string(context, 0, EINVAL, + "CRLDistributionPoints.name.issuername not yet supported"); + return EINVAL; +#else + GeneralNames *crlissuer; + GeneralName gn; + Name n; + + crlissuer = calloc(1, sizeof(*crlissuer)); + if (crlissuer == NULL) { + return ENOMEM; + } + memset(&gn, 0, sizeof(gn)); + + gn.element = choice_GeneralName_directoryName; + ret = hx509_name_to_Name(issuername, &n); + if (ret) { + hx509_set_error_string(context, 0, ret, "out of memory"); + goto out; + } + + gn.u.directoryName.element = n.element; + gn.u.directoryName.u.rdnSequence = n.u.rdnSequence; + + ret = add_GeneralNames(&crlissuer, &gn); + free_Name(&n); + if (ret) { + hx509_set_error_string(context, 0, ret, "out of memory"); + goto out; + } + + dp.cRLIssuer = &crlissuer; +#endif + } + + ret = add_CRLDistributionPoints(&tbs->crldp, &dp); + if (ret) { + hx509_set_error_string(context, 0, ret, "out of memory"); + goto out; + } + +out: + free_DistributionPoint(&dp); + + return ret; +} + +int hx509_ca_tbs_add_san_otherName(hx509_context context, hx509_ca_tbs tbs, const heim_oid *oid, @@ -282,6 +476,58 @@ out: return ret; } +/* + * + */ + +static int +add_utf8_san(hx509_context context, + hx509_ca_tbs tbs, + const heim_oid *oid, + const char *string) +{ + const PKIXXmppAddr ustring = (const PKIXXmppAddr)string; + heim_octet_string os; + size_t size; + int ret; + + os.length = 0; + os.data = NULL; + + ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + if (size != os.length) + _hx509_abort("internal ASN.1 encoder error"); + + ret = hx509_ca_tbs_add_san_otherName(context, + tbs, + oid, + &os); + free(os.data); +out: + return ret; +} + +int +hx509_ca_tbs_add_san_ms_upn(hx509_context context, + hx509_ca_tbs tbs, + const char *principal) +{ + return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal); +} + +int +hx509_ca_tbs_add_san_jid(hx509_context context, + hx509_ca_tbs tbs, + const char *jid) +{ + return add_utf8_san(context, tbs, oid_id_pkix_on_xmppAddr(), jid); +} + + int hx509_ca_tbs_add_san_hostname(hx509_context context, hx509_ca_tbs tbs, @@ -321,6 +567,14 @@ hx509_ca_tbs_set_subject(hx509_context context, return hx509_name_copy(context, subject, &tbs->subject); } +int +hx509_ca_tbs_subject_expand(hx509_context context, + hx509_ca_tbs tbs, + hx509_env env) +{ + return hx509_name_expand(context, tbs->subject, env); +} + static int add_extension(hx509_context context, TBSCertificate *tbsc, @@ -410,7 +664,7 @@ ca_sign(hx509_context context, time_t notAfter; unsigned key_usage; - sigalg = hx509_signature_rsa_with_sha1(); + sigalg = _hx509_crypto_default_sig_alg; memset(&c, 0, sizeof(c)); @@ -439,6 +693,7 @@ ca_sign(hx509_context context, KeyUsage ku; memset(&ku, 0, sizeof(ku)); ku.keyCertSign = 1; + ku.cRLSign = 1; key_usage |= KeyUsage2int(ku); } @@ -453,16 +708,25 @@ ca_sign(hx509_context context, hx509_set_error_string(context, 0, ret, "No public key set"); return ret; } - if (tbs->subject == NULL && !tbs->flags.proxy) { - ret = EINVAL; - hx509_set_error_string(context, 0, ret, "No subject name set"); - return ret; + /* + * Don't put restrictions on proxy certificate's subject name, it + * will be generated below. + */ + if (!tbs->flags.proxy) { + if (tbs->subject == NULL) { + hx509_set_error_string(context, 0, EINVAL, "No subject name set"); + return EINVAL; + } + if (hx509_name_is_null_p(tbs->subject) && tbs->san.len == 0) { + hx509_set_error_string(context, 0, EINVAL, + "NULL subject and no SubjectAltNames"); + return EINVAL; + } } if (tbs->flags.ca && tbs->flags.proxy) { - ret = EINVAL; - hx509_set_error_string(context, 0, ret, "Can't be proxy and CA " + hx509_set_error_string(context, 0, EINVAL, "Can't be proxy and CA " "at the same time"); - return ret; + return EINVAL; } if (tbs->flags.proxy) { if (tbs->san.len > 0) { @@ -549,6 +813,22 @@ ca_sign(hx509_context context, goto out; } + /* Add the text BMP string Domaincontroller to the cert */ + if (tbs->flags.domaincontroller) { + data.data = rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d" + "\x00\x61\x00\x69\x00\x6e\x00\x43" + "\x00\x6f\x00\x6e\x00\x74\x00\x72" + "\x00\x6f\x00\x6c\x00\x6c\x00\x65" + "\x00\x72"); + data.length = 34; + + ret = add_extension(context, tbsc, 0, + oid_id_ms_cert_enroll_domaincontroller(), + &data); + if (ret) + goto out; + } + /* add KeyUsage */ { KeyUsage ku; @@ -561,7 +841,7 @@ ca_sign(hx509_context context, } if (size != data.length) _hx509_abort("internal ASN.1 encoder error"); - ret = add_extension(context, tbsc, 1, + ret = add_extension(context, tbsc, 1, oid_id_x509_ce_keyUsage(), &data); free(data.data); if (ret) @@ -678,7 +958,8 @@ ca_sign(hx509_context context, } if (size != data.length) _hx509_abort("internal ASN.1 encoder error"); - ret = add_extension(context, tbsc, 0, + /* Critical if this is a CA */ + ret = add_extension(context, tbsc, tbs->flags.ca, oid_id_x509_ce_basicConstraints(), &data); free(data.data); @@ -728,6 +1009,23 @@ ca_sign(hx509_context context, goto out; } + if (tbs->crldp.len) { + + ASN1_MALLOC_ENCODE(CRLDistributionPoints, data.data, data.length, + &tbs->crldp, &size, ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + if (size != data.length) + _hx509_abort("internal ASN.1 encoder error"); + ret = add_extension(context, tbsc, FALSE, + oid_id_x509_ce_cRLDistributionPoints(), + &data); + free(data.data); + if (ret) + goto out; + } ASN1_MALLOC_ENCODE(TBSCertificate, data.data, data.length,tbsc, &size, ret); if (ret) { @@ -772,11 +1070,13 @@ get_AuthorityKeyIdentifier(hx509_context context, if (ret == 0) { ai->keyIdentifier = calloc(1, sizeof(*ai->keyIdentifier)); if (ai->keyIdentifier == NULL) { + free_SubjectKeyIdentifier(&si); ret = ENOMEM; hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } ret = der_copy_octet_string(&si, ai->keyIdentifier); + free_SubjectKeyIdentifier(&si); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; @@ -818,6 +1118,7 @@ get_AuthorityKeyIdentifier(hx509_context context, goto out; } + memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_directoryName; gn.u.directoryName.element = choice_GeneralName_directoryName_rdnSequence; diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c index f84c61a798..27b17a0204 100644 --- a/source4/heimdal/lib/hx509/cert.c +++ b/source4/heimdal/lib/hx509/cert.c @@ -32,8 +32,9 @@ */ #include "hx_locl.h" -RCSID("$Id: cert.c,v 1.82 2007/01/09 10:52:03 lha Exp $"); +RCSID("$Id: cert.c 20915 2007-06-05 03:58:56Z lha $"); #include "crypto-headers.h" +#include <rtbl.h> struct hx509_verify_ctx_data { hx509_certs trust_anchors; @@ -102,11 +103,13 @@ hx509_context_init(hx509_context *context) if (*context == NULL) return ENOMEM; + _hx509_ks_null_register(*context); _hx509_ks_mem_register(*context); _hx509_ks_file_register(*context); _hx509_ks_pkcs12_register(*context); _hx509_ks_pkcs11_register(*context); _hx509_ks_dir_register(*context); + _hx509_ks_keychain_register(*context); ENGINE_add_conf_module(); OpenSSL_add_all_algorithms(); @@ -116,6 +119,11 @@ hx509_context_init(hx509_context *context) initialize_hx_error_table_r(&(*context)->et_list); initialize_asn1_error_table_r(&(*context)->et_list); +#ifdef HX509_DEFAULT_ANCHORS + (void)hx509_certs_init(*context, HX509_DEFAULT_ANCHORS, 0, + NULL, &(*context)->default_trust_anchors); +#endif + return 0; } @@ -138,6 +146,9 @@ hx509_context_free(hx509_context *context) } (*context)->ks_num_ops = 0; free_error_table ((*context)->et_list); + if ((*context)->querystat) + free((*context)->querystat); + memset(*context, 0, sizeof(**context)); free(*context); *context = NULL; } @@ -836,7 +847,7 @@ find_parent(hx509_context context, hx509_set_error_string(context, 0, HX509_ISSUER_NOT_FOUND, "Failed to find issuer for " - "certificate with subject: %s", str); + "certificate with subject: '%s'", str); free(str); } return HX509_ISSUER_NOT_FOUND; @@ -847,7 +858,9 @@ find_parent(hx509_context context, */ static int -is_proxy_cert(hx509_context context, const Certificate *cert, ProxyCertInfo *rinfo) +is_proxy_cert(hx509_context context, + const Certificate *cert, + ProxyCertInfo *rinfo) { ProxyCertInfo info; const Extension *e; @@ -876,7 +889,9 @@ is_proxy_cert(hx509_context context, const Certificate *cert, ProxyCertInfo *rin hx509_clear_error_string(context); return HX509_EXTRA_DATA_AFTER_STRUCTURE; } - if (rinfo) + if (rinfo == NULL) + free_ProxyCertInfo(&info); + else *rinfo = info; return 0; @@ -969,8 +984,10 @@ _hx509_calculate_path(hx509_context context, current = parent; if (path->len > max_depth) { + hx509_cert_free(current); hx509_set_error_string(context, 0, HX509_PATH_TOO_LONG, - "Path too long while bulding certificate chain"); + "Path too long while bulding " + "certificate chain"); return HX509_PATH_TOO_LONG; } } @@ -1065,6 +1082,25 @@ hx509_cert_get_serialnumber(hx509_cert p, heim_integer *i) return der_copy_heim_integer(&p->data->tbsCertificate.serialNumber, i); } +time_t +hx509_cert_get_notBefore(hx509_cert p) +{ + return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notBefore); +} + +time_t +hx509_cert_get_notAfter(hx509_cert p) +{ + return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter); +} + +int +hx509_cert_get_SPKI(hx509_cert p, SubjectPublicKeyInfo *spki) +{ + return copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo, + spki); +} + hx509_private_key _hx509_cert_private_key(hx509_cert p) { @@ -1349,7 +1385,7 @@ match_tree(const GeneralSubtrees *t, const Certificate *c, int *match) { GeneralName certname; - + memset(&certname, 0, sizeof(certname)); certname.element = choice_GeneralName_directoryName; certname.u.directoryName.element = c->tbsCertificate.subject.element; @@ -1435,6 +1471,7 @@ hx509_verify_path(hx509_context context, int ret, i, proxy_cert_depth; enum certtype type; Name proxy_issuer; + hx509_certs anchors = NULL; memset(&proxy_issuer, 0, sizeof(proxy_issuer)); @@ -1449,11 +1486,24 @@ hx509_verify_path(hx509_context context, ctx->time_now = time(NULL); /* + * + */ + ret = hx509_certs_init(context, "MEMORY:trust-anchors", 0, NULL, &anchors); + if (ret) + goto out; + ret = hx509_certs_merge(context, anchors, ctx->trust_anchors); + if (ret) + goto out; + ret = hx509_certs_merge(context, anchors, context->default_trust_anchors); + if (ret) + goto out; + + /* * Calculate the path from the certificate user presented to the * to an anchor. */ ret = _hx509_calculate_path(context, 0, ctx->time_now, - ctx->trust_anchors, ctx->max_depth, + anchors, ctx->max_depth, cert, pool, &path); if (ret) goto out; @@ -1775,6 +1825,7 @@ hx509_verify_path(hx509_context context, } out: + hx509_certs_free(&anchors); free_Name(&proxy_issuer); free_name_constraints(&nc); _hx509_path_free(&path); @@ -2030,6 +2081,8 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert { Certificate *c = _hx509_get_cert(cert); + _hx509_query_statistic(context, 1, q); + if ((q->match & HX509_QUERY_FIND_ISSUER_CERT) && _hx509_cert_is_parent_cmp(q->subject, c, 0) != 0) return 0; @@ -2154,6 +2207,139 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert return 1; } +void +hx509_query_statistic_file(hx509_context context, const char *fn) +{ + if (context->querystat) + free(context->querystat); + context->querystat = strdup(fn); +} + +void +_hx509_query_statistic(hx509_context context, int type, const hx509_query *q) +{ + FILE *f; + if (context->querystat == NULL) + return; + f = fopen(context->querystat, "a"); + if (f == NULL) + return; + fprintf(f, "%d %d\n", type, q->match); + fclose(f); +} + +static const char *statname[] = { + "find issuer cert", + "match serialnumber", + "match issuer name", + "match subject name", + "match subject key id", + "match issuer id", + "private key", + "ku encipherment", + "ku digitalsignature", + "ku keycertsign", + "ku crlsign", + "ku nonrepudiation", + "ku keyagreement", + "ku dataencipherment", + "anchor", + "match certificate", + "match local key id", + "no match path", + "match friendly name", + "match function", + "match key hash sha1", + "match time" +}; + +struct stat_el { + unsigned long stats; + unsigned int index; +}; + + +static int +stat_sort(const void *a, const void *b) +{ + const struct stat_el *ae = a; + const struct stat_el *be = b; + return be->stats - ae->stats; +} + +void +hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out) +{ + rtbl_t t; + FILE *f; + int type, mask, i, num; + unsigned long multiqueries = 0, totalqueries = 0; + struct stat_el stats[32]; + + if (context->querystat == NULL) + return; + f = fopen(context->querystat, "r"); + if (f == NULL) { + fprintf(out, "No statistic file %s: %s.\n", + context->querystat, strerror(errno)); + return; + } + + for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) { + stats[i].index = i; + stats[i].stats = 0; + } + + while (fscanf(f, "%d %d\n", &type, &mask) == 2) { + if (type != printtype) + continue; + num = i = 0; + while (mask && i < sizeof(stats)/sizeof(stats[0])) { + if (mask & 1) { + stats[i].stats++; + num++; + } + mask = mask >>1 ; + i++; + } + if (num > 1) + multiqueries++; + totalqueries++; + } + fclose(f); + + qsort(stats, sizeof(stats)/sizeof(stats[0]), sizeof(stats[0]), stat_sort); + + t = rtbl_create(); + if (t == NULL) + errx(1, "out of memory"); + + rtbl_set_separator (t, " "); + + rtbl_add_column_by_id (t, 0, "Name", 0); + rtbl_add_column_by_id (t, 1, "Counter", 0); + + + for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) { + char str[10]; + + if (stats[i].index < sizeof(statname)/sizeof(statname[0])) + rtbl_add_column_entry_by_id (t, 0, statname[stats[i].index]); + else { + snprintf(str, sizeof(str), "%d", stats[i].index); + rtbl_add_column_entry_by_id (t, 0, str); + } + snprintf(str, sizeof(str), "%lu", stats[i].stats); + rtbl_add_column_entry_by_id (t, 1, str); + } + + rtbl_format(t, out); + rtbl_destroy(t); + + fprintf(out, "\nQueries: multi %lu total %lu\n", + multiqueries, totalqueries); +} + int hx509_cert_check_eku(hx509_context context, hx509_cert cert, const heim_oid *eku, int allow_any_eku) @@ -2212,3 +2398,39 @@ _hx509_cert_get_keyusage(hx509_context context, return ret; return 0; } + +int +_hx509_cert_get_eku(hx509_context context, + hx509_cert cert, + ExtKeyUsage *e) +{ + int ret; + + memset(e, 0, sizeof(*e)); + + ret = find_extension_eku(_hx509_get_cert(cert), e); + if (ret && ret != HX509_EXTENSION_NOT_FOUND) { + hx509_clear_error_string(context); + return ret; + } + return 0; +} + +int +hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os) +{ + size_t size; + int ret; + + os->data = NULL; + os->length = 0; + + ASN1_MALLOC_ENCODE(Certificate, os->data, os->length, + _hx509_get_cert(c), &size, ret); + if (ret) + return ret; + if (os->length != size) + _hx509_abort("internal ASN.1 encoder error"); + + return ret; +} diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c index 4ed70b8f84..29ca80e194 100644 --- a/source4/heimdal/lib/hx509/cms.c +++ b/source4/heimdal/lib/hx509/cms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: cms.c,v 1.48 2007/01/08 18:45:03 lha Exp $"); +RCSID("$Id: cms.c 20937 2007-06-06 20:50:55Z lha $"); #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) @@ -302,6 +302,11 @@ hx509_cms_unenvelope(hx509_context context, goto out; } enccontent = encryptedContent; + } else if (encryptedContent != NULL) { + ret = HX509_CMS_NO_DATA_AVAILABLE; + hx509_set_error_string(context, 0, ret, + "Both internal and external encrypted data"); + goto out; } cert = NULL; @@ -423,6 +428,7 @@ out: int hx509_cms_envelope_1(hx509_context context, + int flags, hx509_cert cert, const void *data, size_t length, @@ -621,6 +627,7 @@ hx509_cms_verify_signed(hx509_context context, hx509_verify_ctx ctx, const void *data, size_t length, + const heim_octet_string *signedContent, hx509_certs store, heim_oid *contentType, heim_octet_string *content, @@ -648,12 +655,20 @@ hx509_cms_verify_signed(hx509_context context, goto out; } - if (sd.encapContentInfo.eContent == NULL) { + if (sd.encapContentInfo.eContent == NULL && signedContent == NULL) { ret = HX509_CMS_NO_DATA_AVAILABLE; hx509_set_error_string(context, 0, ret, "No content data in SignedData"); goto out; } + if (sd.encapContentInfo.eContent && signedContent) { + ret = HX509_CMS_NO_DATA_AVAILABLE; + hx509_set_error_string(context, 0, ret, + "Both external and internal SignedData"); + goto out; + } + if (sd.encapContentInfo.eContent) + signedContent = sd.encapContentInfo.eContent; ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer", 0, NULL, &certs); @@ -739,7 +754,7 @@ hx509_cms_verify_signed(hx509_context context, ret = _hx509_verify_signature(context, NULL, &signer_info->digestAlgorithm, - sd.encapContentInfo.eContent, + signedContent, &os); der_free_octet_string(&os); if (ret) { @@ -801,7 +816,7 @@ hx509_cms_verify_signed(hx509_context context, _hx509_abort("internal ASN.1 encoder error"); } else { - signed_data = sd.encapContentInfo.eContent; + signed_data = rk_UNCONST(signedContent); match_oid = oid_id_pkcs7_data(); } @@ -824,7 +839,7 @@ hx509_cms_verify_signed(hx509_context context, "Failed to verify sigature in " "CMS SignedData"); } - if (signed_data != sd.encapContentInfo.eContent) { + if (signed_data != signedContent) { der_free_octet_string(signed_data); free(signed_data); } @@ -861,14 +876,14 @@ hx509_cms_verify_signed(hx509_context context, goto out; } - content->data = malloc(sd.encapContentInfo.eContent->length); + content->data = malloc(signedContent->length); if (content->data == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } - content->length = sd.encapContentInfo.eContent->length; - memcpy(content->data,sd.encapContentInfo.eContent->data,content->length); + content->length = signedContent->length; + memcpy(content->data, signedContent->data, content->length); out: free_SignedData(&sd); @@ -884,38 +899,6 @@ out: return ret; } -int -_hx509_set_digest_alg(DigestAlgorithmIdentifier *id, - const heim_oid *oid, - void *param, size_t length) -{ - int ret; - if (param) { - id->parameters = malloc(sizeof(*id->parameters)); - if (id->parameters == NULL) - return ENOMEM; - id->parameters->data = malloc(length); - if (id->parameters->data == NULL) { - free(id->parameters); - id->parameters = NULL; - return ENOMEM; - } - memcpy(id->parameters->data, param, length); - id->parameters->length = length; - } else - id->parameters = NULL; - ret = der_copy_oid(oid, &id->algorithm); - if (ret) { - if (id->parameters) { - free(id->parameters->data); - free(id->parameters); - id->parameters = NULL; - } - return ret; - } - return 0; -} - static int add_one_attribute(Attribute **attr, unsigned int *len, @@ -950,6 +933,7 @@ add_one_attribute(Attribute **attr, int hx509_cms_create_signed_1(hx509_context context, + int flags, const heim_oid *eContentType, const void *data, size_t length, const AlgorithmIdentifier *digest_alg, @@ -962,7 +946,7 @@ hx509_cms_create_signed_1(hx509_context context, AlgorithmIdentifier digest; hx509_name name; SignerInfo *signer_info; - heim_octet_string buf; + heim_octet_string buf, content, sigdata = { 0, NULL }; SignedData sd; int ret; size_t size; @@ -973,6 +957,9 @@ hx509_cms_create_signed_1(hx509_context context, memset(&path, 0, sizeof(path)); memset(&digest, 0, sizeof(digest)); + content.data = rk_UNCONST(data); + content.length = length; + if (_hx509_cert_private_key(cert) == NULL) { hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, "Private key missing for signing"); @@ -992,22 +979,29 @@ hx509_cms_create_signed_1(hx509_context context, sd.version = CMSVersion_v3; + if (eContentType == NULL) + eContentType = oid_id_pkcs7_data(); + der_copy_oid(eContentType, &sd.encapContentInfo.eContentType); - ALLOC(sd.encapContentInfo.eContent, 1); - if (sd.encapContentInfo.eContent == NULL) { - hx509_clear_error_string(context); - ret = ENOMEM; - goto out; - } - sd.encapContentInfo.eContent->data = malloc(length); - if (sd.encapContentInfo.eContent->data == NULL) { - hx509_clear_error_string(context); - ret = ENOMEM; - goto out; + /* */ + if ((flags & HX509_CMS_SIGATURE_DETACHED) == 0) { + ALLOC(sd.encapContentInfo.eContent, 1); + if (sd.encapContentInfo.eContent == NULL) { + hx509_clear_error_string(context); + ret = ENOMEM; + goto out; + } + + sd.encapContentInfo.eContent->data = malloc(length); + if (sd.encapContentInfo.eContent->data == NULL) { + hx509_clear_error_string(context); + ret = ENOMEM; + goto out; + } + memcpy(sd.encapContentInfo.eContent->data, data, length); + sd.encapContentInfo.eContent->length = length; } - memcpy(sd.encapContentInfo.eContent->data, data, length); - sd.encapContentInfo.eContent->length = length; ALLOC_SEQ(&sd.signerInfos, 1); if (sd.signerInfos.val == NULL) { @@ -1029,39 +1023,43 @@ hx509_cms_create_signed_1(hx509_context context, signer_info->signedAttrs = NULL; signer_info->unsignedAttrs = NULL; - ALLOC(signer_info->signedAttrs, 1); - if (signer_info->signedAttrs == NULL) { - ret = ENOMEM; + + ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm); + if (ret) { + hx509_clear_error_string(context); goto out; } - { - heim_octet_string data; + /* + * If its not pkcs7-data send signedAttributes + */ - ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm); - if (ret) { - hx509_clear_error_string(context); + if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) { + CMSAttributes sa; + heim_octet_string sig; + + ALLOC(signer_info->signedAttrs, 1); + if (signer_info->signedAttrs == NULL) { + ret = ENOMEM; goto out; } ret = _hx509_create_signature(context, NULL, &digest, - sd.encapContentInfo.eContent, + &content, NULL, - &data); - if (ret) { - hx509_clear_error_string(context); + &sig); + if (ret) goto out; - } ASN1_MALLOC_ENCODE(MessageDigest, buf.data, buf.length, - &data, + &sig, &size, ret); - der_free_octet_string(&data); + der_free_octet_string(&sig); if (ret) { hx509_clear_error_string(context); goto out; @@ -1078,9 +1076,6 @@ hx509_cms_create_signed_1(hx509_context context, goto out; } - } - - if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) { ASN1_MALLOC_ENCODE(ContentType, buf.data, @@ -1101,19 +1096,13 @@ hx509_cms_create_signed_1(hx509_context context, hx509_clear_error_string(context); goto out; } - } - - { - CMSAttributes sa; - heim_octet_string os; - sa.val = signer_info->signedAttrs->val; sa.len = signer_info->signedAttrs->len; ASN1_MALLOC_ENCODE(CMSAttributes, - os.data, - os.length, + sigdata.data, + sigdata.length, &sa, &size, ret); @@ -1121,21 +1110,32 @@ hx509_cms_create_signed_1(hx509_context context, hx509_clear_error_string(context); goto out; } - if (size != os.length) + if (size != sigdata.length) _hx509_abort("internal ASN.1 encoder error"); - + } else { + sigdata.data = content.data; + sigdata.length = content.length; + } + + + { + AlgorithmIdentifier sigalg; + + ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG, + _hx509_cert_private_key(cert), peer, + &sigalg); + if (ret) + goto out; + ret = _hx509_create_signature(context, _hx509_cert_private_key(cert), - hx509_signature_rsa_with_sha1(), - &os, + &sigalg, + &sigdata, &signer_info->signatureAlgorithm, &signer_info->signature); - - der_free_octet_string(&os); - if (ret) { - hx509_clear_error_string(context); + free_AlgorithmIdentifier(&sigalg); + if (ret) goto out; - } } ALLOC_SEQ(&sd.digestAlgorithms, 1); @@ -1184,17 +1184,12 @@ hx509_cms_create_signed_1(hx509_context context, } for (i = 0; i < path.len; i++) { - ASN1_MALLOC_ENCODE(Certificate, - sd.certificates->val[i].data, - sd.certificates->val[i].length, - _hx509_get_cert(path.val[i]), - &size, ret); + ret = hx509_cert_binary(context, path.val[i], + &sd.certificates->val[i]); if (ret) { hx509_clear_error_string(context); goto out; } - if (sd.certificates->val[i].length != size) - _hx509_abort("internal ASN.1 encoder error"); } } @@ -1209,6 +1204,8 @@ hx509_cms_create_signed_1(hx509_context context, _hx509_abort("internal ASN.1 encoder error"); out: + if (sigdata.data != content.data) + der_free_octet_string(&sigdata); free_AlgorithmIdentifier(&digest); _hx509_path_free(&path); free_SignedData(&sd); diff --git a/source4/heimdal/lib/hx509/collector.c b/source4/heimdal/lib/hx509/collector.c index ec172f46f4..8b6ffcb945 100644 --- a/source4/heimdal/lib/hx509/collector.c +++ b/source4/heimdal/lib/hx509/collector.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: collector.c,v 1.16 2007/01/09 10:52:04 lha Exp $"); +RCSID("$Id: collector.c 20778 2007-06-01 22:04:13Z lha $"); struct private_key { AlgorithmIdentifier alg; @@ -51,22 +51,26 @@ struct hx509_collector { }; -struct hx509_collector * -_hx509_collector_alloc(hx509_context context, hx509_lock lock) +int +_hx509_collector_alloc(hx509_context context, hx509_lock lock, struct hx509_collector **collector) { struct hx509_collector *c; int ret; + *collector = NULL; + c = calloc(1, sizeof(*c)); - if (c == NULL) - return NULL; + if (c == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } c->lock = lock; ret = hx509_certs_init(context, "MEMORY:collector-unenvelop-cert", 0,NULL, &c->unenvelop_certs); if (ret) { free(c); - return NULL; + return ret; } c->val.data = NULL; c->val.len = 0; @@ -75,10 +79,11 @@ _hx509_collector_alloc(hx509_context context, hx509_lock lock) if (ret) { hx509_certs_free(&c->unenvelop_certs); free(c); - return NULL; + return ret; } - return c; + *collector = c; + return 0; } hx509_lock diff --git a/source4/heimdal/lib/hx509/crmf.asn1 b/source4/heimdal/lib/hx509/crmf.asn1 index 4f02b26872..97ade264ae 100644 --- a/source4/heimdal/lib/hx509/crmf.asn1 +++ b/source4/heimdal/lib/hx509/crmf.asn1 @@ -1,4 +1,4 @@ --- $Id: crmf.asn1,v 1.1 2006/04/18 13:05:21 lha Exp $ +-- $Id: crmf.asn1 17102 2006-04-18 13:05:21Z lha $ PKCS10 DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c index dac0a8160b..96d9693cc2 100644 --- a/source4/heimdal/lib/hx509/crypto.c +++ b/source4/heimdal/lib/hx509/crypto.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: crypto.c,v 1.63 2007/01/09 10:52:05 lha Exp $"); +RCSID("$Id: crypto.c 20939 2007-06-06 20:53:02Z lha $"); struct hx509_crypto; @@ -42,6 +42,11 @@ enum crypto_op_type { COT_SIGN }; +struct hx509_generate_private_context { + const heim_oid *key_oid; + int isCA; + unsigned long num_bits; +}; struct hx509_private_key_ops { const char *pemtype; @@ -56,8 +61,9 @@ struct hx509_private_key_ops { const void *data, size_t len, hx509_private_key private_key); - int (*generate_private_key)(hx509_context context, - hx509_private_key private_key); + int (*generate_private_key)(hx509_context, + struct hx509_generate_private_context *, + hx509_private_key); int (*handle_alg)(const hx509_private_key, const AlgorithmIdentifier *, enum crypto_op_type); @@ -96,7 +102,7 @@ struct hx509_private_key { */ struct signature_alg { - char *name; + const char *name; const heim_oid *(*sig_oid)(void); const AlgorithmIdentifier *(*sig_alg)(void); const heim_oid *(*key_oid)(void); @@ -107,8 +113,7 @@ struct signature_alg { #define SIG_DIGEST 0x100 #define SIG_PUBLIC_SIG 0x200 -#define SIG_PUBLIC_ENC 0x400 -#define SIG_SECRET 0x800 +#define SIG_SECRET 0x400 int (*verify_signature)(hx509_context context, const struct signature_alg *, @@ -123,9 +128,6 @@ struct signature_alg { const heim_octet_string *, AlgorithmIdentifier *, heim_octet_string *); - int (*private_key2SPKI)(hx509_context, - hx509_private_key, - SubjectPublicKeyInfo *); }; /* @@ -142,6 +144,46 @@ heim_int2BN(const heim_integer *i) return bn; } +/* + * + */ + +static int +set_digest_alg(DigestAlgorithmIdentifier *id, + const heim_oid *oid, + const void *param, size_t length) +{ + int ret; + if (param) { + id->parameters = malloc(sizeof(*id->parameters)); + if (id->parameters == NULL) + return ENOMEM; + id->parameters->data = malloc(length); + if (id->parameters->data == NULL) { + free(id->parameters); + id->parameters = NULL; + return ENOMEM; + } + memcpy(id->parameters->data, param, length); + id->parameters->length = length; + } else + id->parameters = NULL; + ret = der_copy_oid(oid, &id->algorithm); + if (ret) { + if (id->parameters) { + free(id->parameters->data); + free(id->parameters); + id->parameters = NULL; + } + return ret; + } + return 0; +} + +/* + * + */ + static int rsa_verify_signature(hx509_context context, const struct signature_alg *sig_alg, @@ -280,12 +322,13 @@ rsa_create_signature(hx509_context context, digest_alg = hx509_signature_md5(); } else if (der_heim_oid_cmp(sig_oid, oid_id_dsa_with_sha1()) == 0) { digest_alg = hx509_signature_sha1(); + } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) { + digest_alg = hx509_signature_sha1(); } else return HX509_ALG_NOT_SUPP; if (signatureAlgorithm) { - ret = _hx509_set_digest_alg(signatureAlgorithm, - sig_oid, "\x05\x00", 2); + ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2); if (ret) { hx509_clear_error_string(context); return ret; @@ -380,9 +423,8 @@ rsa_private_key2SPKI(hx509_context context, } spki->subjectPublicKey.length = len * 8; - ret = _hx509_set_digest_alg(&spki->algorithm, - oid_id_pkcs1_rsaEncryption(), - "\x05\x00", 2); + ret = set_digest_alg(&spki->algorithm,oid_id_pkcs1_rsaEncryption(), + "\x05\x00", 2); if (ret) { hx509_set_error_string(context, 0, ret, "malloc - out of memory"); free(spki->subjectPublicKey.data); @@ -400,17 +442,13 @@ rsa_private_key2SPKI(hx509_context context, } static int -cb_func(int a, int b, BN_GENCB *c) +rsa_generate_private_key(hx509_context context, + struct hx509_generate_private_context *ctx, + hx509_private_key private_key) { - return 1; -} - -static int -rsa_generate_private_key(hx509_context context, hx509_private_key private_key) -{ - BN_GENCB cb; BIGNUM *e; int ret; + unsigned long bits; static const int default_rsa_e = 65537; static const int default_rsa_bits = 1024; @@ -425,9 +463,14 @@ rsa_generate_private_key(hx509_context context, hx509_private_key private_key) e = BN_new(); BN_set_word(e, default_rsa_e); - BN_GENCB_set(&cb, cb_func, NULL); - ret = RSA_generate_key_ex(private_key->private_key.rsa, - default_rsa_bits, e, &cb); + bits = default_rsa_bits; + + if (ctx->num_bits) + bits = ctx->num_bits; + else if (ctx->isCA) + bits *= 2; + + ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL); BN_free(e); if (ret != 1) { hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, @@ -642,8 +685,8 @@ sha256_create_signature(hx509_context context, if (signatureAlgorithm) { int ret; - ret = _hx509_set_digest_alg(signatureAlgorithm, - (*sig_alg->sig_oid)(), "\x05\x00", 2); + ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(), + "\x05\x00", 2); if (ret) return ret; } @@ -708,8 +751,8 @@ sha1_create_signature(hx509_context context, if (signatureAlgorithm) { int ret; - ret = _hx509_set_digest_alg(signatureAlgorithm, - (*sig_alg->sig_oid)(), "\x05\x00", 2); + ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(), + "\x05\x00", 2); if (ret) return ret; } @@ -789,7 +832,7 @@ md2_verify_signature(hx509_context context, return 0; } -static struct signature_alg pkcs1_rsa_sha1_alg = { +static const struct signature_alg pkcs1_rsa_sha1_alg = { "rsa", oid_id_pkcs1_rsaEncryption, hx509_signature_rsa_with_sha1, @@ -797,11 +840,10 @@ static struct signature_alg pkcs1_rsa_sha1_alg = { NULL, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, rsa_verify_signature, - rsa_create_signature, - rsa_private_key2SPKI + rsa_create_signature }; -static struct signature_alg rsa_with_sha256_alg = { +static const struct signature_alg rsa_with_sha256_alg = { "rsa-with-sha256", oid_id_pkcs1_sha256WithRSAEncryption, hx509_signature_rsa_with_sha256, @@ -809,11 +851,10 @@ static struct signature_alg rsa_with_sha256_alg = { oid_id_sha256, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, rsa_verify_signature, - rsa_create_signature, - rsa_private_key2SPKI + rsa_create_signature }; -static struct signature_alg rsa_with_sha1_alg = { +static const struct signature_alg rsa_with_sha1_alg = { "rsa-with-sha1", oid_id_pkcs1_sha1WithRSAEncryption, hx509_signature_rsa_with_sha1, @@ -821,11 +862,10 @@ static struct signature_alg rsa_with_sha1_alg = { oid_id_secsig_sha_1, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, rsa_verify_signature, - rsa_create_signature, - rsa_private_key2SPKI + rsa_create_signature }; -static struct signature_alg rsa_with_md5_alg = { +static const struct signature_alg rsa_with_md5_alg = { "rsa-with-md5", oid_id_pkcs1_md5WithRSAEncryption, hx509_signature_rsa_with_md5, @@ -833,11 +873,10 @@ static struct signature_alg rsa_with_md5_alg = { oid_id_rsa_digest_md5, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, rsa_verify_signature, - rsa_create_signature, - rsa_private_key2SPKI + rsa_create_signature }; -static struct signature_alg rsa_with_md2_alg = { +static const struct signature_alg rsa_with_md2_alg = { "rsa-with-md2", oid_id_pkcs1_md2WithRSAEncryption, hx509_signature_rsa_with_md2, @@ -845,11 +884,10 @@ static struct signature_alg rsa_with_md2_alg = { oid_id_rsa_digest_md2, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, rsa_verify_signature, - rsa_create_signature, - rsa_private_key2SPKI + rsa_create_signature }; -static struct signature_alg dsa_sha1_alg = { +static const struct signature_alg dsa_sha1_alg = { "dsa-with-sha1", oid_id_dsa_with_sha1, NULL, @@ -860,7 +898,7 @@ static struct signature_alg dsa_sha1_alg = { /* create_signature */ NULL, }; -static struct signature_alg sha256_alg = { +static const struct signature_alg sha256_alg = { "sha-256", oid_id_sha256, hx509_signature_sha256, @@ -871,7 +909,7 @@ static struct signature_alg sha256_alg = { sha256_create_signature }; -static struct signature_alg sha1_alg = { +static const struct signature_alg sha1_alg = { "sha1", oid_id_secsig_sha_1, hx509_signature_sha1, @@ -882,7 +920,7 @@ static struct signature_alg sha1_alg = { sha1_create_signature }; -static struct signature_alg md5_alg = { +static const struct signature_alg md5_alg = { "rsa-md5", oid_id_rsa_digest_md5, hx509_signature_md5, @@ -892,7 +930,7 @@ static struct signature_alg md5_alg = { md5_verify_signature }; -static struct signature_alg md2_alg = { +static const struct signature_alg md2_alg = { "rsa-md2", oid_id_rsa_digest_md2, hx509_signature_md2, @@ -907,12 +945,13 @@ static struct signature_alg md2_alg = { * compatible" type (type is RSA, DSA, none, etc) */ -static struct signature_alg *sig_algs[] = { +static const struct signature_alg *sig_algs[] = { &rsa_with_sha256_alg, &rsa_with_sha1_alg, &pkcs1_rsa_sha1_alg, &rsa_with_md5_alg, &rsa_with_md2_alg, + &pkcs1_rsa_sha1_alg, &dsa_sha1_alg, &sha256_alg, &sha1_alg, @@ -1235,8 +1274,56 @@ _hx509_private_key2SPKI(hx509_context context, } int +_hx509_generate_private_key_init(hx509_context context, + const heim_oid *oid, + struct hx509_generate_private_context **ctx) +{ + *ctx = NULL; + + if (der_heim_oid_cmp(oid, oid_id_pkcs1_rsaEncryption()) != 0) { + hx509_set_error_string(context, 0, EINVAL, + "private key not an RSA key"); + return EINVAL; + } + + *ctx = calloc(1, sizeof(**ctx)); + if (*ctx == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + (*ctx)->key_oid = oid; + + return 0; +} + +int +_hx509_generate_private_key_is_ca(hx509_context context, + struct hx509_generate_private_context *ctx) +{ + ctx->isCA = 1; + return 0; +} + +int +_hx509_generate_private_key_bits(hx509_context context, + struct hx509_generate_private_context *ctx, + unsigned long bits) +{ + ctx->num_bits = bits; + return 0; +} + + +void +_hx509_generate_private_key_free(struct hx509_generate_private_context **ctx) +{ + free(*ctx); + *ctx = NULL; +} + +int _hx509_generate_private_key(hx509_context context, - const heim_oid *key_oid, + struct hx509_generate_private_context *ctx, hx509_private_key *private_key) { struct hx509_private_key_ops *ops; @@ -1244,7 +1331,7 @@ _hx509_generate_private_key(hx509_context context, *private_key = NULL; - ops = find_private_alg(key_oid); + ops = find_private_alg(ctx->key_oid); if (ops == NULL) { hx509_clear_error_string(context); return HX509_SIG_ALG_NO_SUPPORTED; @@ -1256,7 +1343,7 @@ _hx509_generate_private_key(hx509_context context, return ret; } - ret = (*ops->generate_private_key)(context, *private_key); + ret = (*ops->generate_private_key)(context, ctx, *private_key); if (ret) _hx509_private_key_free(private_key); @@ -1268,21 +1355,21 @@ _hx509_generate_private_key(hx509_context context, * */ -static const heim_octet_string null_entry_oid = { 2, "\x05\x00" }; +static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") }; -static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 3 }; +static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 }; const AlgorithmIdentifier _hx509_signature_sha512_data = { - { 8, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid) + { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid) }; -static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2 }; +static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 }; const AlgorithmIdentifier _hx509_signature_sha384_data = { - { 8, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid) + { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid) }; static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }; const AlgorithmIdentifier _hx509_signature_sha256_data = { - { 8, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid) + { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid) }; static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 }; @@ -1335,6 +1422,20 @@ const AlgorithmIdentifier _hx509_signature_rsa_data = { { 7, rk_UNCONST(rsa_oid) }, NULL }; +static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 }; +const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = { + { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL +}; + +static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 }; +const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = { + { 9, rk_UNCONST(aes128_cbc_oid) }, NULL +}; + +static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 }; +const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = { + { 9, rk_UNCONST(aes256_cbc_oid) }, NULL +}; const AlgorithmIdentifier * hx509_signature_sha512(void) @@ -1388,6 +1489,33 @@ const AlgorithmIdentifier * hx509_signature_rsa(void) { return &_hx509_signature_rsa_data; } +const AlgorithmIdentifier * +hx509_crypto_des_rsdi_ede3_cbc(void) +{ return &_hx509_des_rsdi_ede3_cbc_oid; } + +const AlgorithmIdentifier * +hx509_crypto_aes128_cbc(void) +{ return &_hx509_crypto_aes128_cbc_data; } + +const AlgorithmIdentifier * +hx509_crypto_aes256_cbc(void) +{ return &_hx509_crypto_aes256_cbc_data; } + +/* + * + */ + +const AlgorithmIdentifier * _hx509_crypto_default_sig_alg = + &_hx509_signature_rsa_with_sha1_data; +const AlgorithmIdentifier * _hx509_crypto_default_digest_alg = + &_hx509_signature_sha1_data; +const AlgorithmIdentifier * _hx509_crypto_default_secret_alg = + &_hx509_crypto_aes128_cbc_data; + +/* + * + */ + int _hx509_private_key_init(hx509_private_key *key, hx509_private_key_ops *ops, @@ -1487,6 +1615,7 @@ _hx509_private_key_export(hx509_context context, struct hx509cipher { const char *name; const heim_oid *(*oid_func)(void); + const AlgorithmIdentifier *(*ai_func)(void); const EVP_CIPHER *(*evp_func)(void); int (*get_params)(hx509_context, const hx509_crypto, const heim_octet_string *, heim_octet_string *); @@ -1654,6 +1783,7 @@ static const struct hx509cipher ciphers[] = { { "rc2-cbc", oid_id_pkcs3_rc2_cbc, + NULL, EVP_rc2_cbc, CMSRC2CBCParam_get, CMSRC2CBCParam_set @@ -1661,6 +1791,7 @@ static const struct hx509cipher ciphers[] = { { "rc2-cbc", oid_id_rsadsi_rc2_cbc, + NULL, EVP_rc2_cbc, CMSRC2CBCParam_get, CMSRC2CBCParam_set @@ -1668,6 +1799,7 @@ static const struct hx509cipher ciphers[] = { { "rc2-40-cbc", oid_private_rc2_40, + NULL, EVP_rc2_40_cbc, CMSRC2CBCParam_get, CMSRC2CBCParam_set @@ -1675,6 +1807,7 @@ static const struct hx509cipher ciphers[] = { { "des-ede3-cbc", oid_id_pkcs3_des_ede3_cbc, + NULL, EVP_des_ede3_cbc, CMSCBCParam_get, CMSCBCParam_set @@ -1682,6 +1815,7 @@ static const struct hx509cipher ciphers[] = { { "des-ede3-cbc", oid_id_rsadsi_des_ede3_cbc, + hx509_crypto_des_rsdi_ede3_cbc, EVP_des_ede3_cbc, CMSCBCParam_get, CMSCBCParam_set @@ -1689,6 +1823,7 @@ static const struct hx509cipher ciphers[] = { { "aes-128-cbc", oid_id_aes_128_cbc, + hx509_crypto_aes128_cbc, EVP_aes_128_cbc, CMSCBCParam_get, CMSCBCParam_set @@ -1696,6 +1831,7 @@ static const struct hx509cipher ciphers[] = { { "aes-192-cbc", oid_id_aes_192_cbc, + NULL, EVP_aes_192_cbc, CMSCBCParam_get, CMSCBCParam_set @@ -1703,6 +1839,7 @@ static const struct hx509cipher ciphers[] = { { "aes-256-cbc", oid_id_aes_256_cbc, + hx509_crypto_aes256_cbc, EVP_aes_256_cbc, CMSCBCParam_get, CMSCBCParam_set @@ -2060,11 +2197,13 @@ PBE_string2key(hx509_context context, const EVP_MD *md) { PKCS12_PBEParams p12params; - int passwordlen = strlen(password); + int passwordlen; hx509_crypto c; int iter, saltlen, ret; unsigned char *salt; + passwordlen = password ? strlen(password) : 0; + if (parameters == NULL) return HX509_ALG_NOT_SUPP; @@ -2081,10 +2220,6 @@ PBE_string2key(hx509_context context, salt = p12params.salt.data; saltlen = p12params.salt.length; - /* XXX It needs to be here, but why ? */ - if (passwordlen == 0) - password = NULL; - if (!PKCS12_key_gen (password, passwordlen, salt, saltlen, PKCS12_KEY_ID, iter, key->length, key->data, md)) { ret = HX509_CRYPTO_INTERNAL_ERROR; @@ -2205,8 +2340,10 @@ _hx509_pbe_decrypt(hx509_context context, if (i < pw->len) password = pw->val[i]; - else + else if (i < pw->len + 1) password = ""; + else + password = NULL; ret = (*s2k)(context, password, ai->parameters, &crypto, &key, &iv, enc_oid, md); @@ -2314,7 +2451,6 @@ hx509_crypto_select(const hx509_context context, hx509_peer_info peer, AlgorithmIdentifier *selected) { - const heim_oid *keytype = NULL; const AlgorithmIdentifier *def; size_t i, j; int ret, bits; @@ -2323,20 +2459,25 @@ hx509_crypto_select(const hx509_context context, if (type == HX509_SELECT_DIGEST) { bits = SIG_DIGEST; - def = hx509_signature_sha1(); + def = _hx509_crypto_default_digest_alg; } else if (type == HX509_SELECT_PUBLIC_SIG) { bits = SIG_PUBLIC_SIG; /* XXX depend on `source´ and `peer´ */ - def = hx509_signature_rsa_with_sha1(); + def = _hx509_crypto_default_sig_alg; + } else if (type == HX509_SELECT_SECRET_ENC) { + bits = SIG_SECRET; + def = _hx509_crypto_default_secret_alg; } else { hx509_set_error_string(context, 0, EINVAL, "Unknown type %d of selection", type); return EINVAL; } - keytype = find_keytype(source); - if (peer) { + const heim_oid *keytype = NULL; + + keytype = find_keytype(source); + for (i = 0; i < peer->len; i++) { for (j = 0; sig_algs[j]; j++) { if ((sig_algs[j]->flags & bits) != bits) @@ -2354,6 +2495,19 @@ hx509_crypto_select(const hx509_context context, hx509_clear_error_string(context); return ret; } + if (bits & SIG_SECRET) { + const struct hx509cipher *cipher; + + cipher = find_cipher_by_oid(&peer->val[i].algorithm); + if (cipher == NULL) + continue; + if (cipher->ai_func == NULL) + continue; + ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected); + if (ret) + hx509_clear_error_string(context); + return ret; + } } } @@ -2379,7 +2533,7 @@ hx509_crypto_available(hx509_context context, *val = NULL; if (type == HX509_SELECT_ALL) { - bits = SIG_DIGEST | SIG_PUBLIC_SIG; + bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET; } else if (type == HX509_SELECT_DIGEST) { bits = SIG_DIGEST; } else if (type == HX509_SELECT_PUBLIC_SIG) { @@ -2415,6 +2569,26 @@ hx509_crypto_available(hx509_context context, len++; } + /* Add AES */ + if (bits & SIG_SECRET) { + + for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) { + + if (ciphers[i].ai_func == NULL) + continue; + + ptr = realloc(*val, sizeof(**val) * (len + 1)); + if (ptr == NULL) + goto out; + *val = ptr; + + ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]); + if (ret) + goto out; + len++; + } + } + *plen = len; return 0; diff --git a/source4/heimdal/lib/hx509/env.c b/source4/heimdal/lib/hx509/env.c new file mode 100644 index 0000000000..4cb2f9f4b1 --- /dev/null +++ b/source4/heimdal/lib/hx509/env.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hx_locl.h" +RCSID("$Id: env.c 19878 2007-01-13 00:58:39Z lha $"); + +struct hx509_env { + struct { + char *key; + char *value; + } *val; + size_t len; +}; + +int +hx509_env_init(hx509_context context, hx509_env *env) +{ + *env = calloc(1, sizeof(**env)); + if (*env == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + return 0; +} + +int +hx509_env_add(hx509_context context, hx509_env env, + const char *key, const char *value) +{ + void *ptr; + + ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1)); + if (ptr == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + env->val = ptr; + env->val[env->len].key = strdup(key); + if (env->val[env->len].key == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + env->val[env->len].value = strdup(value); + if (env->val[env->len].value == NULL) { + free(env->val[env->len].key); + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + env->len++; + return 0; +} + +const char * +hx509_env_lfind(hx509_context context, hx509_env env, + const char *key, size_t len) +{ + size_t i; + + for (i = 0; i < env->len; i++) { + char *s = env->val[i].key; + if (strncmp(key, s, len) == 0 && s[len] == '\0') + return env->val[i].value; + } + return NULL; +} + + +void +hx509_env_free(hx509_env *env) +{ + size_t i; + + for (i = 0; i < (*env)->len; i++) { + free((*env)->val[i].key); + free((*env)->val[i].value); + } + free((*env)->val); + free(*env); + *env = NULL; +} + diff --git a/source4/heimdal/lib/hx509/error.c b/source4/heimdal/lib/hx509/error.c index 770b71981a..9f3a014873 100644 --- a/source4/heimdal/lib/hx509/error.c +++ b/source4/heimdal/lib/hx509/error.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: error.c,v 1.4 2006/11/16 15:08:09 lha Exp $"); +RCSID("$Id: error.c 20912 2007-06-05 03:53:52Z lha $"); struct hx509_error_data { hx509_error next; @@ -87,7 +87,8 @@ hx509_set_error_stringv(hx509_context context, int flags, int code, } void -hx509_set_error_string(hx509_context context, int flags, int code, const char *fmt, ...) +hx509_set_error_string(hx509_context context, int flags, int code, + const char *fmt, ...) { va_list ap; @@ -100,9 +101,9 @@ char * hx509_get_error_string(hx509_context context, int error_code) { struct rk_strpool *p = NULL; - hx509_error msg; + hx509_error msg = context->error; - if (context->error == NULL) { + if (msg == NULL || msg->code != error_code) { const char *cstr; char *str; @@ -125,10 +126,12 @@ hx509_get_error_string(hx509_context context, int error_code) } void -hx509_err(hx509_context context, int exit_code, int error_code, char *fmt, ...) +hx509_err(hx509_context context, int exit_code, + int error_code, const char *fmt, ...) { va_list ap; - char *msg, *str; + const char *msg; + char *str; va_start(ap, fmt); vasprintf(&str, fmt, ap); diff --git a/source4/heimdal/lib/hx509/file.c b/source4/heimdal/lib/hx509/file.c index 39497fc3a9..1152af2423 100644 --- a/source4/heimdal/lib/hx509/file.c +++ b/source4/heimdal/lib/hx509/file.c @@ -35,6 +35,27 @@ RCSID("$ID$"); int +_hx509_map_file_os(const char *fn, heim_octet_string *os, struct stat *rsb) +{ + size_t length; + void *data; + int ret; + + ret = _hx509_map_file(fn, &data, &length, rsb); + + os->data = data; + os->length = length; + + return ret; +} + +void +_hx509_unmap_file_os(heim_octet_string *os) +{ + _hx509_unmap_file(os->data, os->length); +} + +int _hx509_map_file(const char *fn, void **data, size_t *length, struct stat *rsb) { struct stat sb; diff --git a/source4/heimdal/lib/hx509/hx509-private.h b/source4/heimdal/lib/hx509/hx509-private.h index 2db3f4f932..2763df957f 100644 --- a/source4/heimdal/lib/hx509/hx509-private.h +++ b/source4/heimdal/lib/hx509/hx509-private.h @@ -39,6 +39,12 @@ _hx509_cert_assign_key ( hx509_private_key /*private_key*/); int +_hx509_cert_get_eku ( + hx509_context /*context*/, + hx509_cert /*cert*/, + ExtKeyUsage */*e*/); + +int _hx509_cert_get_keyusage ( hx509_context /*context*/, hx509_cert /*c*/, @@ -105,10 +111,11 @@ _hx509_check_key_usage ( unsigned /*flags*/, int /*req_present*/); -struct hx509_collector * +int _hx509_collector_alloc ( hx509_context /*context*/, - hx509_lock /*lock*/); + hx509_lock /*lock*/, + struct hx509_collector **/*collector*/); int _hx509_collector_certs_add ( @@ -169,9 +176,29 @@ _hx509_find_extension_subject_key_id ( int _hx509_generate_private_key ( hx509_context /*context*/, - const heim_oid */*key_oid*/, + struct hx509_generate_private_context */*ctx*/, hx509_private_key */*private_key*/); +int +_hx509_generate_private_key_bits ( + hx509_context /*context*/, + struct hx509_generate_private_context */*ctx*/, + unsigned long /*bits*/); + +void +_hx509_generate_private_key_free (struct hx509_generate_private_context **/*ctx*/); + +int +_hx509_generate_private_key_init ( + hx509_context /*context*/, + const heim_oid */*oid*/, + struct hx509_generate_private_context **/*ctx*/); + +int +_hx509_generate_private_key_is_ca ( + hx509_context /*context*/, + struct hx509_generate_private_context */*ctx*/); + Certificate * _hx509_get_cert (hx509_cert /*cert*/); @@ -182,9 +209,15 @@ void _hx509_ks_file_register (hx509_context /*context*/); void +_hx509_ks_keychain_register (hx509_context /*context*/); + +void _hx509_ks_mem_register (hx509_context /*context*/); void +_hx509_ks_null_register (hx509_context /*context*/); + +void _hx509_ks_pkcs11_register (hx509_context /*context*/); void @@ -215,6 +248,12 @@ _hx509_map_file ( struct stat */*rsb*/); int +_hx509_map_file_os ( + const char */*fn*/, + heim_octet_string */*os*/, + struct stat */*rsb*/); + +int _hx509_match_keys ( hx509_cert /*c*/, hx509_private_key /*private_key*/); @@ -269,9 +308,9 @@ _hx509_pbe_decrypt ( void _hx509_pi_printf ( - int (*/*func*/)(void *, char *), + int (*/*func*/)(void *, const char *), void */*ctx*/, - char */*fmt*/, + const char */*fmt*/, ...); int @@ -340,6 +379,12 @@ _hx509_query_match_cert ( const hx509_query */*q*/, hx509_cert /*cert*/); +void +_hx509_query_statistic ( + hx509_context /*context*/, + int /*type*/, + const hx509_query */*q*/); + int _hx509_request_add_dns_name ( hx509_context /*context*/, @@ -392,18 +437,14 @@ _hx509_set_cert_attribute ( const heim_oid */*oid*/, const heim_octet_string */*attr*/); -int -_hx509_set_digest_alg ( - DigestAlgorithmIdentifier */*id*/, - const heim_oid */*oid*/, - void */*param*/, - size_t /*length*/); - void _hx509_unmap_file ( void */*data*/, size_t /*len*/); +void +_hx509_unmap_file_os (heim_octet_string */*os*/); + int _hx509_unparse_Name ( const Name */*aname*/, diff --git a/source4/heimdal/lib/hx509/hx509-protos.h b/source4/heimdal/lib/hx509/hx509-protos.h index 4fcab70ff8..ab312cdbdf 100644 --- a/source4/heimdal/lib/hx509/hx509-protos.h +++ b/source4/heimdal/lib/hx509/hx509-protos.h @@ -8,6 +8,14 @@ extern "C" { #endif +#ifndef HX509_LIB_FUNCTION +#if defined(_WIN32) +#define HX509_LIB_FUNCTION _stdcall +#else +#define HX509_LIB_FUNCTION +#endif +#endif + void hx509_bitstring_print ( const heim_bit_string */*b*/, @@ -29,8 +37,15 @@ hx509_ca_sign_self ( hx509_cert */*certificate*/); int +hx509_ca_tbs_add_crl_dp_uri ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/, + const char */*uri*/, + hx509_name /*issuername*/); + +int hx509_ca_tbs_add_eku ( - hx509_context /*contex*/, + hx509_context /*context*/, hx509_ca_tbs /*tbs*/, const heim_oid */*oid*/); @@ -41,6 +56,18 @@ hx509_ca_tbs_add_san_hostname ( const char */*dnsname*/); int +hx509_ca_tbs_add_san_jid ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/, + const char */*jid*/); + +int +hx509_ca_tbs_add_san_ms_upn ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/, + const char */*principal*/); + +int hx509_ca_tbs_add_san_otherName ( hx509_context /*context*/, hx509_ca_tbs /*tbs*/, @@ -74,6 +101,11 @@ hx509_ca_tbs_set_ca ( int /*pathLenConstraint*/); int +hx509_ca_tbs_set_domaincontroller ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/); + +int hx509_ca_tbs_set_notAfter ( hx509_context /*context*/, hx509_ca_tbs /*tbs*/, @@ -116,6 +148,28 @@ hx509_ca_tbs_set_subject ( hx509_name /*subject*/); int +hx509_ca_tbs_set_template ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/, + int /*flags*/, + hx509_cert /*cert*/); + +int +hx509_ca_tbs_subject_expand ( + hx509_context /*context*/, + hx509_ca_tbs /*tbs*/, + hx509_env /*env*/); + +const struct units * +hx509_ca_tbs_template_units (void); + +int +hx509_cert_binary ( + hx509_context /*context*/, + hx509_cert /*c*/, + heim_octet_string */*os*/); + +int hx509_cert_check_eku ( hx509_context /*context*/, hx509_cert /*cert*/, @@ -136,6 +190,11 @@ hx509_cert_find_subjectAltName_otherName ( void hx509_cert_free (hx509_cert /*cert*/); +int +hx509_cert_get_SPKI ( + hx509_cert /*p*/, + SubjectPublicKeyInfo */*spki*/); + hx509_cert_attribute hx509_cert_get_attribute ( hx509_cert /*cert*/, @@ -155,6 +214,12 @@ hx509_cert_get_issuer ( hx509_cert /*p*/, hx509_name */*name*/); +time_t +hx509_cert_get_notAfter (hx509_cert /*p*/); + +time_t +hx509_cert_get_notBefore (hx509_cert /*p*/); + int hx509_cert_get_serialnumber ( hx509_cert /*p*/, @@ -218,7 +283,7 @@ int hx509_certs_info ( hx509_context /*context*/, hx509_certs /*certs*/, - int (*/*func*/)(void *, char *), + int (*/*func*/)(void *, const char *), void */*ctx*/); int @@ -274,6 +339,7 @@ hx509_clear_error_string (hx509_context /*context*/); int hx509_cms_create_signed_1 ( hx509_context /*context*/, + int /*flags*/, const heim_oid */*eContentType*/, const void */*data*/, size_t /*length*/, @@ -296,6 +362,7 @@ hx509_cms_decrypt_encrypted ( int hx509_cms_envelope_1 ( hx509_context /*context*/, + int /*flags*/, hx509_cert /*cert*/, const void */*data*/, size_t /*length*/, @@ -327,6 +394,7 @@ hx509_cms_verify_signed ( hx509_verify_ctx /*ctx*/, const void */*data*/, size_t /*length*/, + const heim_octet_string */*signedContent*/, hx509_certs /*store*/, heim_oid */*contentType*/, heim_octet_string */*content*/, @@ -350,6 +418,41 @@ hx509_context_set_missing_revoke ( int /*flag*/); int +hx509_crl_add_revoked_certs ( + hx509_context /*context*/, + hx509_crl /*crl*/, + hx509_certs /*certs*/); + +int +hx509_crl_alloc ( + hx509_context /*context*/, + hx509_crl */*crl*/); + +void +hx509_crl_free ( + hx509_context /*context*/, + hx509_crl */*crl*/); + +int +hx509_crl_lifetime ( + hx509_context /*context*/, + hx509_crl /*crl*/, + int /*delta*/); + +int +hx509_crl_sign ( + hx509_context /*context*/, + hx509_cert /*signer*/, + hx509_crl /*crl*/, + heim_octet_string */*os*/); + +const AlgorithmIdentifier * +hx509_crypto_aes128_cbc (void); + +const AlgorithmIdentifier * +hx509_crypto_aes256_cbc (void); + +int hx509_crypto_available ( hx509_context /*context*/, int /*type*/, @@ -365,6 +468,9 @@ hx509_crypto_decrypt ( heim_octet_string */*ivec*/, heim_octet_string */*clear*/); +const AlgorithmIdentifier * +hx509_crypto_des_rsdi_ede3_cbc (void); + void hx509_crypto_destroy (hx509_crypto /*crypto*/); @@ -432,17 +538,44 @@ hx509_crypto_set_random_key ( hx509_crypto /*crypto*/, heim_octet_string */*key*/); +int +hx509_env_add ( + hx509_context /*context*/, + hx509_env /*env*/, + const char */*key*/, + const char */*value*/); + +void +hx509_env_free (hx509_env */*env*/); + +int +hx509_env_init ( + hx509_context /*context*/, + hx509_env */*env*/); + +const char * +hx509_env_lfind ( + hx509_context /*context*/, + hx509_env /*env*/, + const char */*key*/, + size_t /*len*/); + void hx509_err ( hx509_context /*context*/, int /*exit_code*/, int /*error_code*/, - char */*fmt*/, + const char */*fmt*/, ...); void hx509_free_octet_string_list (hx509_octet_string_list */*list*/); +int +hx509_general_name_unparse ( + GeneralName */*name*/, + char **/*str*/); + char * hx509_get_error_string ( hx509_context /*context*/, @@ -507,11 +640,22 @@ hx509_lock_set_prompter ( void */*data*/); int +hx509_name_cmp ( + hx509_name /*n1*/, + hx509_name /*n2*/); + +int hx509_name_copy ( hx509_context /*context*/, const hx509_name /*from*/, hx509_name */*to*/); +int +hx509_name_expand ( + hx509_context /*context*/, + hx509_name /*name*/, + hx509_env /*env*/); + void hx509_name_free (hx509_name */*name*/); @@ -519,6 +663,11 @@ int hx509_name_is_null_p (const hx509_name /*name*/); int +hx509_name_normalize ( + hx509_context /*context*/, + hx509_name /*name*/); + +int hx509_name_to_Name ( const hx509_name /*from*/, Name */*to*/); @@ -576,7 +725,7 @@ hx509_peer_info_alloc ( hx509_context /*context*/, hx509_peer_info */*peer*/); -int +void hx509_peer_info_free (hx509_peer_info /*peer*/); int @@ -639,6 +788,17 @@ hx509_query_match_option ( hx509_query */*q*/, hx509_query_option /*option*/); +void +hx509_query_statistic_file ( + hx509_context /*context*/, + const char */*fn*/); + +void +hx509_query_unparse_stats ( + hx509_context /*context*/, + int /*printtype*/, + FILE */*out*/); + int hx509_revoke_add_crl ( hx509_context /*context*/, diff --git a/source4/heimdal/lib/hx509/hx509.h b/source4/heimdal/lib/hx509/hx509.h index 70f29ea92d..664c12e045 100644 --- a/source4/heimdal/lib/hx509/hx509.h +++ b/source4/heimdal/lib/hx509/hx509.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hx509.h,v 1.16 2007/01/09 10:52:05 lha Exp $ */ +/* $Id: hx509.h 20798 2007-06-02 03:28:55Z lha $ */ typedef struct hx509_cert_attribute_data *hx509_cert_attribute; typedef struct hx509_cert_data *hx509_cert; @@ -50,6 +50,8 @@ typedef struct hx509_request_data *hx509_request; typedef struct hx509_error_data *hx509_error; typedef struct hx509_peer_info *hx509_peer_info; typedef struct hx509_ca_tbs *hx509_ca_tbs; +typedef struct hx509_env *hx509_env; +typedef struct hx509_crl *hx509_crl; typedef void (*hx509_vprint_func)(void *, const char *, va_list); @@ -107,5 +109,18 @@ typedef enum { #define HX509_SELECT_DIGEST 1 #define HX509_SELECT_PUBLIC_SIG 2 #define HX509_SELECT_PUBLIC_ENC 3 +#define HX509_SELECT_SECRET_ENC 4 + +/* flags to hx509_ca_tbs_set_template */ +#define HX509_CA_TEMPLATE_SUBJECT 1 +#define HX509_CA_TEMPLATE_SERIAL 2 +#define HX509_CA_TEMPLATE_NOTBEFORE 4 +#define HX509_CA_TEMPLATE_NOTAFTER 8 +#define HX509_CA_TEMPLATE_SPKI 16 +#define HX509_CA_TEMPLATE_KU 32 +#define HX509_CA_TEMPLATE_EKU 64 + +/* flags hx509_cms_create_signed* */ +#define HX509_CMS_SIGATURE_DETACHED 1 #include <hx509-protos.h> diff --git a/source4/heimdal/lib/hx509/hx509_err.et b/source4/heimdal/lib/hx509/hx509_err.et index 54ec177e47..90f3b3d907 100644 --- a/source4/heimdal/lib/hx509/hx509_err.et +++ b/source4/heimdal/lib/hx509/hx509_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: hx509_err.et,v 1.19 2006/12/30 23:05:39 lha Exp $" +id "$Id: hx509_err.et 20807 2007-06-03 03:11:20Z lha $" error_table hx prefix HX509 @@ -76,7 +76,8 @@ error_code CRL_CERT_REVOKED, "Certificate is included in CRL" error_code REVOKE_STATUS_MISSING, "No revoke status found for certificates" error_code CRL_UNKNOWN_EXTENSION, "Unknown extension" error_code REVOKE_WRONG_DATA, "Got wrong CRL/OCSP data from server" -error_code REVOKE_NOT_SAME_PARENT, "Doesn't have same parent as other certificaes" +error_code REVOKE_NOT_SAME_PARENT, "Doesn't have same parent as other certificates" +error_code CERT_NOT_IN_OCSP, "Certificates not in OCSP reply" # misc error index 108 diff --git a/source4/heimdal/lib/hx509/hx_locl.h b/source4/heimdal/lib/hx509/hx_locl.h index 78d158f8b1..bfbee0943e 100644 --- a/source4/heimdal/lib/hx509/hx_locl.h +++ b/source4/heimdal/lib/hx509/hx_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hx_locl.h,v 1.30 2007/01/09 10:52:06 lha Exp $ */ +/* $Id: hx_locl.h 20930 2007-06-06 00:23:42Z lha $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -71,6 +71,7 @@ struct hx509_keyset_ops; struct hx509_collector; +struct hx509_generate_private_context; typedef struct hx509_path hx509_path; #include <hx509.h> @@ -144,7 +145,7 @@ struct hx509_query_data { }; struct hx509_keyset_ops { - char *name; + const char *name; int flags; int (*init)(hx509_context, hx509_certs, void **, int, const char *, hx509_lock); @@ -157,7 +158,7 @@ struct hx509_keyset_ops { int (*iter)(hx509_context, hx509_certs, void *, void *, hx509_cert *); int (*iter_end)(hx509_context, hx509_certs, void *, void *); int (*printinfo)(hx509_context, hx509_certs, - void *, int (*)(void *, char *), void *); + void *, int (*)(void *, const char *), void *); int (*getkeys)(hx509_context, hx509_certs, void *, hx509_private_key **); int (*addkey)(hx509_context, hx509_certs, void *, hx509_private_key); }; @@ -178,7 +179,21 @@ struct hx509_context_data { #define HX509_DEFAULT_OCSP_TIME_DIFF (5*60) hx509_error error; struct et_list *et_list; + char *querystat; + hx509_certs default_trust_anchors; }; /* _hx509_calculate_path flag field */ #define HX509_CALCULATE_PATH_NO_ANCHOR 1 + +extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg; +extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg; +extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg; + +/* + * Configurable options + */ + +#if 0 /* fdef __APPLE__*/ +#define HX509_DEFAULT_ANCHORS "KEYCHAIN:system" +#endif diff --git a/source4/heimdal/lib/hx509/keyset.c b/source4/heimdal/lib/hx509/keyset.c index c3d5ee210c..475835b9b0 100644 --- a/source4/heimdal/lib/hx509/keyset.c +++ b/source4/heimdal/lib/hx509/keyset.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: keyset.c,v 1.18 2007/01/09 10:52:07 lha Exp $"); +RCSID("$Id: keyset.c 20911 2007-06-05 03:41:17Z lha $"); struct hx509_certs_data { struct hx509_keyset_ops *ops; @@ -276,6 +276,8 @@ hx509_certs_find(hx509_context context, *r = NULL; + _hx509_query_statistic(context, 0, q); + if (certs->ops->query) return (*certs->ops->query)(context, certs, certs->ops_data, q, r); @@ -317,6 +319,8 @@ certs_merge_func(hx509_context context, void *ctx, hx509_cert c) int hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from) { + if (from == NULL) + return 0; return hx509_certs_iter(context, from, certs_merge_func, to); } @@ -358,7 +362,7 @@ hx509_get_one_cert(hx509_context context, hx509_certs certs, hx509_cert *c) } static int -certs_info_stdio(void *ctx, char *str) +certs_info_stdio(void *ctx, const char *str) { FILE *f = ctx; fprintf(f, "%s\n", str); @@ -368,7 +372,7 @@ certs_info_stdio(void *ctx, char *str) int hx509_certs_info(hx509_context context, hx509_certs certs, - int (*func)(void *, char *), + int (*func)(void *, const char *), void *ctx) { if (func == NULL) { @@ -385,8 +389,8 @@ hx509_certs_info(hx509_context context, } void -_hx509_pi_printf(int (*func)(void *, char *), void *ctx, - char *fmt, ...) +_hx509_pi_printf(int (*func)(void *, const char *), void *ctx, + const char *fmt, ...) { va_list ap; char *str; diff --git a/source4/heimdal/lib/hx509/ks_dir.c b/source4/heimdal/lib/hx509/ks_dir.c index 01dcf5795b..a0bc875e5b 100644 --- a/source4/heimdal/lib/hx509/ks_dir.c +++ b/source4/heimdal/lib/hx509/ks_dir.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_dir.c,v 1.7 2007/01/09 10:52:08 lha Exp $"); +RCSID("$Id: ks_dir.c 19778 2007-01-09 10:52:13Z lha $"); #include <dirent.h> /* diff --git a/source4/heimdal/lib/hx509/ks_file.c b/source4/heimdal/lib/hx509/ks_file.c index db0f475129..f9a3580880 100644 --- a/source4/heimdal/lib/hx509/ks_file.c +++ b/source4/heimdal/lib/hx509/ks_file.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_file.c,v 1.31 2007/01/09 10:52:08 lha Exp $"); +RCSID("$Id: ks_file.c 20776 2007-06-01 22:02:01Z lha $"); struct ks_file { hx509_certs certs; @@ -542,12 +542,9 @@ file_init(hx509_context context, return 0; } - c = _hx509_collector_alloc(context, lock); - if (c == NULL) { - ret = ENOMEM; - hx509_set_error_string(context, 0, ret, "out of memory"); + ret = _hx509_collector_alloc(context, lock, &c); + if (ret) goto out; - } for (p = f->fn; p != NULL; p = pnext) { int found_data; @@ -678,16 +675,12 @@ static int store_func(hx509_context context, void *ctx, hx509_cert c) { FILE *f = (FILE *)ctx; - size_t size; heim_octet_string data; int ret; - ASN1_MALLOC_ENCODE(Certificate, data.data, data.length, - _hx509_get_cert(c), &size, ret); + ret = hx509_cert_binary(context, c, &data); if (ret) return ret; - if (data.length != size) - _hx509_abort("internal ASN.1 encoder error"); dump_pem_file(context, "CERTIFICATE", f, data.data, data.length); free(data.data); diff --git a/source4/heimdal/lib/hx509/ks_keychain.c b/source4/heimdal/lib/hx509/ks_keychain.c new file mode 100644 index 0000000000..2f0f72cd14 --- /dev/null +++ b/source4/heimdal/lib/hx509/ks_keychain.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hx_locl.h" +RCSID("$Id: ks_keychain.c 20945 2007-06-06 22:17:17Z lha $"); + +#ifdef HAVE_FRAMEWORK_SECURITY + +#include <Security/Security.h> + +/* Missing function decls */ +OSStatus SecKeyGetCSPHandle(SecKeyRef, CSSM_CSP_HANDLE *); +OSStatus SecKeyGetCredentials(SecKeyRef, CSSM_ACL_AUTHORIZATION_TAG, + int, const CSSM_ACCESS_CREDENTIALS **); +#define kSecCredentialTypeDefault 0 + + +static int +getAttribute(SecKeychainItemRef itemRef, SecItemAttr item, + SecKeychainAttributeList **attrs) +{ + SecKeychainAttributeInfo attrInfo; + uint32 attrFormat = 0; + OSStatus ret; + + *attrs = NULL; + + attrInfo.count = 1; + attrInfo.tag = &item; + attrInfo.format = &attrFormat; + + ret = SecKeychainItemCopyAttributesAndData(itemRef, &attrInfo, NULL, + attrs, NULL, NULL); + if (ret) + return EINVAL; + return 0; +} + + +/* + * + */ + +struct kc_rsa { + SecKeychainItemRef item; + size_t keysize; +}; + + +static int +kc_rsa_public_encrypt(int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) +{ + return -1; +} + +static int +kc_rsa_public_decrypt(int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) +{ + return -1; +} + + +static int +kc_rsa_private_encrypt(int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) +{ + struct kc_rsa *kc = RSA_get_app_data(rsa); + + CSSM_RETURN cret; + OSStatus ret; + const CSSM_ACCESS_CREDENTIALS *creds; + SecKeyRef privKeyRef = (SecKeyRef)kc->item; + CSSM_CSP_HANDLE cspHandle; + const CSSM_KEY *cssmKey; + CSSM_CC_HANDLE sigHandle = 0; + CSSM_DATA sig, in; + int fret = 0; + + + cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey); + if(cret) abort(); + + cret = SecKeyGetCSPHandle(privKeyRef, &cspHandle); + if(cret) abort(); + + ret = SecKeyGetCredentials(privKeyRef, CSSM_ACL_AUTHORIZATION_SIGN, + kSecCredentialTypeDefault, &creds); + if(ret) abort(); + + ret = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA, + creds, cssmKey, &sigHandle); + if(ret) abort(); + + in.Data = (uint8 *)from; + in.Length = flen; + + sig.Data = (uint8 *)to; + sig.Length = kc->keysize; + + cret = CSSM_SignData(sigHandle, &in, 1, CSSM_ALGID_NONE, &sig); + if(cret) { + /* cssmErrorString(cret); */ + fret = -1; + } else + fret = sig.Length; + + if(sigHandle) + CSSM_DeleteContext(sigHandle); + + return fret; +} + +static int +kc_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA * rsa, int padding) +{ + return -1; +} + +static int +kc_rsa_init(RSA *rsa) +{ + return 1; +} + +static int +kc_rsa_finish(RSA *rsa) +{ + struct kc_rsa *kc_rsa = RSA_get_app_data(rsa); + CFRelease(kc_rsa->item); + memset(kc_rsa, 0, sizeof(*kc_rsa)); + free(kc_rsa); + return 1; +} + +static const RSA_METHOD kc_rsa_pkcs1_method = { + "hx509 Keychain PKCS#1 RSA", + kc_rsa_public_encrypt, + kc_rsa_public_decrypt, + kc_rsa_private_encrypt, + kc_rsa_private_decrypt, + NULL, + NULL, + kc_rsa_init, + kc_rsa_finish, + 0, + NULL, + NULL, + NULL +}; + +static int +set_private_key(hx509_context context, + SecKeychainItemRef itemRef, + hx509_cert cert) +{ + struct kc_rsa *kc; + hx509_private_key key; + RSA *rsa; + int ret; + + ret = _hx509_private_key_init(&key, NULL, NULL); + if (ret) + return ret; + + kc = calloc(1, sizeof(*kc)); + if (kc == NULL) + _hx509_abort("out of memory"); + + kc->item = itemRef; + + rsa = RSA_new(); + if (rsa == NULL) + _hx509_abort("out of memory"); + + /* Argh, fake modulus since OpenSSL API is on crack */ + { + SecKeychainAttributeList *attrs = NULL; + uint32_t size; + void *data; + + rsa->n = BN_new(); + if (rsa->n == NULL) abort(); + + ret = getAttribute(itemRef, kSecKeyKeySizeInBits, &attrs); + if (ret) abort(); + + size = *(uint32_t *)attrs->attr[0].data; + SecKeychainItemFreeAttributesAndData(attrs, NULL); + + kc->keysize = (size + 7) / 8; + + data = malloc(kc->keysize); + memset(data, 0xe0, kc->keysize); + BN_bin2bn(data, kc->keysize, rsa->n); + free(data); + } + rsa->e = NULL; + + RSA_set_method(rsa, &kc_rsa_pkcs1_method); + ret = RSA_set_app_data(rsa, kc); + if (ret != 1) + _hx509_abort("RSA_set_app_data"); + + _hx509_private_key_assign_rsa(key, rsa); + _hx509_cert_assign_key(cert, key); + + return 0; +} + +/* + * + */ + +struct ks_keychain { + SecKeychainRef keychain; +}; + +static int +keychain_init(hx509_context context, + hx509_certs certs, void **data, int flags, + const char *residue, hx509_lock lock) +{ + struct ks_keychain *ctx; + OSStatus ret; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + hx509_clear_error_string(context); + return ENOMEM; + } + + if (residue) { + if (strcasecmp(residue, "system") == 0) + residue = "/System/Library/Keychains/X509Anchors"; + + ret = SecKeychainOpen(residue, &ctx->keychain); + if (ret != noErr) { + hx509_set_error_string(context, 0, ENOENT, + "Failed to open %s", residue); + return ENOENT; + } + } + + *data = ctx; + return 0; +} + +/* + * + */ + +static int +keychain_free(hx509_certs certs, void *data) +{ + struct ks_keychain *ctx = data; + if (ctx->keychain) + CFRelease(ctx->keychain); + memset(ctx, 0, sizeof(*ctx)); + free(ctx); + return 0; +} + +/* + * + */ + +struct iter { + SecKeychainSearchRef searchRef; +}; + +static int +keychain_iter_start(hx509_context context, + hx509_certs certs, void *data, void **cursor) +{ + struct ks_keychain *ctx = data; + struct iter *iter; + OSStatus ret; + + iter = calloc(1, sizeof(*iter)); + if (iter == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + + ret = SecKeychainSearchCreateFromAttributes(ctx->keychain, + kSecCertificateItemClass, + NULL, + &iter->searchRef); + if (ret) { + free(iter); + hx509_set_error_string(context, 0, ret, + "Failed to start search for attributes"); + return ENOMEM; + } + + *cursor = iter; + return 0; +} + +/* + * + */ + +static int +keychain_iter(hx509_context context, + hx509_certs certs, void *data, void *cursor, hx509_cert *cert) +{ + SecKeychainAttributeList *attrs = NULL; + SecKeychainAttributeInfo attrInfo; + uint32 attrFormat = 0; + SecKeychainItemRef itemRef; + SecItemAttr item; + struct iter *iter = cursor; + Certificate t; + OSStatus ret; + UInt32 len; + void *ptr = NULL; + size_t size; + + *cert = NULL; + + ret = SecKeychainSearchCopyNext(iter->searchRef, &itemRef); + if (ret == errSecItemNotFound) + return 0; + else if (ret != 0) + return EINVAL; + + /* + * Pick out certificate and matching "keyid" + */ + + item = kSecPublicKeyHashItemAttr; + + attrInfo.count = 1; + attrInfo.tag = &item; + attrInfo.format = &attrFormat; + + ret = SecKeychainItemCopyAttributesAndData(itemRef, &attrInfo, NULL, + &attrs, &len, &ptr); + if (ret) + return EINVAL; + + ret = decode_Certificate(ptr, len, &t, &size); + CFRelease(itemRef); + if (ret) { + hx509_set_error_string(context, 0, ret, "Failed to parse certificate"); + goto out; + } + + ret = hx509_cert_init(context, &t, cert); + free_Certificate(&t); + if (ret) + goto out; + + /* + * Find related private key if there is one by looking at + * kSecPublicKeyHashItemAttr == kSecKeyLabel + */ + { + SecKeychainSearchRef search; + SecKeychainAttribute attrKeyid; + SecKeychainAttributeList attrList; + + attrKeyid.tag = kSecKeyLabel; + attrKeyid.length = attrs->attr[0].length; + attrKeyid.data = attrs->attr[0].data; + + attrList.count = 1; + attrList.attr = &attrKeyid; + + ret = SecKeychainSearchCreateFromAttributes(NULL, + CSSM_DL_DB_RECORD_PRIVATE_KEY, + &attrList, + &search); + if (ret) { + ret = 0; + goto out; + } + + ret = SecKeychainSearchCopyNext(search, &itemRef); + CFRelease(search); + if (ret == errSecItemNotFound) { + ret = 0; + goto out; + } else if (ret) { + ret = EINVAL; + goto out; + } + set_private_key(context, itemRef, *cert); + } + +out: + SecKeychainItemFreeAttributesAndData(attrs, ptr); + + return ret; +} + +/* + * + */ + +static int +keychain_iter_end(hx509_context context, + hx509_certs certs, + void *data, + void *cursor) +{ + struct iter *iter = cursor; + + CFRelease(iter->searchRef); + memset(iter, 0, sizeof(*iter)); + free(iter); + return 0; +} + +/* + * + */ + +struct hx509_keyset_ops keyset_keychain = { + "KEYCHAIN", + 0, + keychain_init, + NULL, + keychain_free, + NULL, + NULL, + keychain_iter_start, + keychain_iter, + keychain_iter_end +}; + +#endif /* HAVE_FRAMEWORK_SECURITY */ + +/* + * + */ + +void +_hx509_ks_keychain_register(hx509_context context) +{ +#ifdef HAVE_FRAMEWORK_SECURITY + _hx509_ks_register(context, &keyset_keychain); +#endif +} diff --git a/source4/heimdal/lib/hx509/ks_mem.c b/source4/heimdal/lib/hx509/ks_mem.c index dd7b7166bc..efa19eb19c 100644 --- a/source4/heimdal/lib/hx509/ks_mem.c +++ b/source4/heimdal/lib/hx509/ks_mem.c @@ -80,6 +80,7 @@ mem_free(hx509_certs certs, void *data) free(mem->certs.val); for (i = 0; mem->keys && mem->keys[i]; i++) _hx509_private_key_free(&mem->keys[i]); + free(mem->keys); free(mem->name); free(mem); @@ -162,7 +163,7 @@ mem_getkeys(hx509_context context, for (i = 0; mem->keys && mem->keys[i]; i++) ; - *keys = calloc(i, sizeof(**keys)); + *keys = calloc(i + 1, sizeof(**keys)); for (i = 0; mem->keys && mem->keys[i]; i++) { (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); if ((*keys)[i] == NULL) { diff --git a/source4/heimdal/lib/hx509/ks_null.c b/source4/heimdal/lib/hx509/ks_null.c index 1e6c2ea3fb..3be259fc60 100644 --- a/source4/heimdal/lib/hx509/ks_null.c +++ b/source4/heimdal/lib/hx509/ks_null.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_null.c,v 1.5 2007/01/09 10:52:10 lha Exp $"); +RCSID("$Id: ks_null.c 20901 2007-06-04 23:14:08Z lha $"); static int @@ -90,3 +90,9 @@ struct hx509_keyset_ops keyset_null = { null_iter, null_iter_end }; + +void +_hx509_ks_null_register(hx509_context context) +{ + _hx509_ks_register(context, &keyset_null); +} diff --git a/source4/heimdal/lib/hx509/ks_p11.c b/source4/heimdal/lib/hx509/ks_p11.c index b103264b7a..90c716213f 100644 --- a/source4/heimdal/lib/hx509/ks_p11.c +++ b/source4/heimdal/lib/hx509/ks_p11.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_p11.c,v 1.45 2007/01/09 19:43:35 lha Exp $"); +RCSID("$Id: ks_p11.c 20920 2007-06-05 05:47:06Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif @@ -214,7 +214,7 @@ p11_rsa_finish(RSA *rsa) return 1; } -static const RSA_METHOD rsa_pkcs1_method = { +static const RSA_METHOD p11_rsa_pkcs1_method = { "hx509 PKCS11 PKCS#1 RSA", p11_rsa_public_encrypt, p11_rsa_public_decrypt, @@ -644,7 +644,7 @@ collect_private_key(hx509_context context, if (p->refcount == 0) _hx509_abort("pkcs11 refcount to high"); - RSA_set_method(rsa, &rsa_pkcs1_method); + RSA_set_method(rsa, &p11_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, p11rsa); if (ret != 1) _hx509_abort("RSA_set_app_data"); @@ -766,11 +766,9 @@ p11_list_keys(hx509_context context, if (lock == NULL) lock = _hx509_empty_lock; - collector = _hx509_collector_alloc(context, lock); - if (collector == NULL) { - hx509_set_error_string(context, 0, ENOMEM, "out of memory"); - return ENOMEM; - } + ret = _hx509_collector_alloc(context, lock, &collector); + if (ret) + return ret; key_class = CKO_PRIVATE_KEY; ret = iterate_entries(context, p, slot, session, @@ -1113,7 +1111,7 @@ static int p11_printinfo(hx509_context context, hx509_certs certs, void *data, - int (*func)(void *, char *), + int (*func)(void *, const char *), void *ctx) { struct p11_module *p = data; @@ -1140,6 +1138,17 @@ p11_printinfo(hx509_context context, MECHNAME(CKM_RSA_X_509, "rsa-x-509"); MECHNAME(CKM_MD5_RSA_PKCS, "md5-rsa-pkcs"); MECHNAME(CKM_SHA1_RSA_PKCS, "sha1-rsa-pkcs"); + MECHNAME(CKM_RIPEMD160_RSA_PKCS, "ripemd160-rsa-pkcs"); + MECHNAME(CKM_RSA_PKCS_OAEP, "rsa-pkcs-oaep"); + MECHNAME(CKM_SHA_1, "sha1"); + MECHNAME(CKM_MD5, "md5"); + MECHNAME(CKM_MD2, "md2"); + MECHNAME(CKM_RIPEMD160, "ripemd-160"); + MECHNAME(CKM_DES_ECB, "des-ecb"); + MECHNAME(CKM_DES_CBC, "des-cbc"); + MECHNAME(CKM_AES_ECB, "aes-ecb"); + MECHNAME(CKM_AES_CBC, "aes-cbc"); + MECHNAME(CKM_DH_PKCS_PARAMETER_GEN, "dh-pkcs-parameter-gen"); default: snprintf(unknownname, sizeof(unknownname), "unknown-mech-%lu", diff --git a/source4/heimdal/lib/hx509/ks_p12.c b/source4/heimdal/lib/hx509/ks_p12.c index 69dba802e5..5fddbd07de 100644 --- a/source4/heimdal/lib/hx509/ks_p12.c +++ b/source4/heimdal/lib/hx509/ks_p12.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_p12.c,v 1.18 2007/01/09 10:52:11 lha Exp $"); +RCSID("$Id: ks_p12.c 20909 2007-06-05 03:09:13Z lha $"); struct ks_pkcs12 { hx509_certs certs; @@ -341,39 +341,45 @@ p12_init(hx509_context context, if (lock == NULL) lock = _hx509_empty_lock; - c = _hx509_collector_alloc(context, lock); - if (c == NULL) - return ENOMEM; + ret = _hx509_collector_alloc(context, lock, &c); + if (ret) + return ret; p12 = calloc(1, sizeof(*p12)); if (p12 == NULL) { ret = ENOMEM; + hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } p12->fn = strdup(residue); if (p12->fn == NULL) { ret = ENOMEM; + hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } if (flags & HX509_CERTS_CREATE) { - ret = hx509_certs_init(context, "MEMORY:ks-file-create", + ret = hx509_certs_init(context, "MEMORY:ks-file-create", 0, lock, &p12->certs); - if (ret) - goto out; - *data = p12; - return 0; + if (ret == 0) + *data = p12; + goto out; } ret = _hx509_map_file(residue, &buf, &len, NULL); - if (ret) + if (ret) { + hx509_clear_error_string(context); goto out; + } ret = decode_PKCS12_PFX(buf, len, &pfx, NULL); _hx509_unmap_file(buf, len); - if (ret) + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to decode the PFX in %s", residue); goto out; + } if (der_heim_oid_cmp(&pfx.authSafe.contentType, oid_id_pkcs7_data()) != 0) { free_PKCS12_PFX(&pfx); @@ -452,15 +458,20 @@ addBag(hx509_context context, ptr = realloc(as->val, sizeof(as->val[0]) * (as->len + 1)); if (ptr == NULL) { - hx509_set_error_string(context, 0, ENOMEM, "malloc out of memory"); + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } as->val = ptr; ret = der_copy_oid(oid, &as->val[as->len].contentType); + if (ret) { + hx509_set_error_string(context, 0, ret, "out of memory"); + return ret; + } as->val[as->len].content = calloc(1, sizeof(*as->val[0].content)); if (as->val[as->len].content == NULL) { + der_free_oid(&as->val[as->len].contentType); hx509_set_error_string(context, 0, ENOMEM, "malloc out of memory"); return ENOMEM; } @@ -488,11 +499,11 @@ store_func(hx509_context context, void *ctx, hx509_cert c) os.data = NULL; os.length = 0; - ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, - _hx509_get_cert(c), &size, ret); + ret = hx509_cert_binary(context, c, &os); if (ret) - goto out; - ASN1_MALLOC_ENCODE(PKCS12_OctetString, + return ret; + + ASN1_MALLOC_ENCODE(PKCS12_OctetString, cb.certValue.data,cb.certValue.length, &os, &size, ret); free(os.data); @@ -505,7 +516,7 @@ store_func(hx509_context context, void *ctx, hx509_cert c) } ASN1_MALLOC_ENCODE(PKCS12_CertBag, os.data, os.length, &cb, &size, ret); - free(cb.certValue.data); + free_PKCS12_CertBag(&cb); if (ret) goto out; diff --git a/source4/heimdal/lib/hx509/lock.c b/source4/heimdal/lib/hx509/lock.c index 95fc0aa26d..de326f2e2d 100644 --- a/source4/heimdal/lib/hx509/lock.c +++ b/source4/heimdal/lib/hx509/lock.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: lock.c,v 1.13 2006/10/14 09:41:05 lha Exp $"); +RCSID("$Id: lock.c 18452 2006-10-14 09:41:05Z lha $"); struct hx509_lock_data { struct _hx509_password password; diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c index 92e9e6f974..5198633b1e 100644 --- a/source4/heimdal/lib/hx509/name.c +++ b/source4/heimdal/lib/hx509/name.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: name.c,v 1.33 2006/12/30 23:04:11 lha Exp $"); +RCSID("$Id: name.c 20891 2007-06-04 22:51:41Z lha $"); /* * name parsing from rfc2253 @@ -41,7 +41,7 @@ RCSID("$Id: name.c,v 1.33 2006/12/30 23:04:11 lha Exp $"); */ static const struct { - char *n; + const char *n; const heim_oid *(*o)(void); } no[] = { { "C", oid_id_at_countryName }, @@ -51,6 +51,7 @@ static const struct { { "O", oid_id_at_organizationName }, { "OU", oid_id_at_organizationalUnitName }, { "S", oid_id_at_stateOrProvinceName }, + { "STREET", oid_id_at_streetAddress }, { "UID", oid_id_Userid }, { "emailAddress", oid_id_pkcs9_emailAddress }, { "serialNumber", oid_id_at_serialNumber } @@ -81,25 +82,27 @@ quote_string(const char *f, size_t len, size_t *rlen) to[j++] = from[i]; } else { int l = snprintf(&to[j], tolen - j - 1, - "#%02x", (unsigned int)from[i]); + "#%02x", (unsigned char)from[i]); j += l; } } to[j] = '\0'; + assert(j < tolen); *rlen = j; return to; } static int -append_string(char **str, size_t *total_len, char *ss, size_t len, int quote) +append_string(char **str, size_t *total_len, const char *ss, + size_t len, int quote) { char *s, *qs; if (quote) qs = quote_string(ss, len, &len); else - qs = ss; + qs = rk_UNCONST(ss); s = realloc(*str, len + *total_len + 1); if (s == NULL) @@ -181,10 +184,10 @@ _hx509_Name_to_string(const Name *n, char **str) ss = ds->u.ia5String; break; case choice_DirectoryString_printableString: - ss = ds->u.ia5String; + ss = ds->u.printableString; break; case choice_DirectoryString_utf8String: - ss = ds->u.ia5String; + ss = ds->u.utf8String; break; case choice_DirectoryString_bmpString: { uint16_t *bmp = ds->u.bmpString.data; @@ -200,11 +203,25 @@ _hx509_Name_to_string(const Name *n, char **str) break; } case choice_DirectoryString_teletexString: - ss = "teletex-string"; /* XXX */ + ss = malloc(ds->u.teletexString.length + 1); + if (ss == NULL) + _hx509_abort("allocation failure"); /* XXX */ + memcpy(ss, ds->u.teletexString.data, ds->u.teletexString.length); + ss[ds->u.teletexString.length] = '\0'; break; - case choice_DirectoryString_universalString: - ss = "universalString"; /* XXX */ + case choice_DirectoryString_universalString: { + uint32_t *uni = ds->u.universalString.data; + size_t unilen = ds->u.universalString.length; + size_t k; + + ss = malloc(unilen + 1); + if (ss == NULL) + _hx509_abort("allocation failure"); /* XXX */ + for (k = 0; k < unilen; k++) + ss[k] = uni[k] & 0xff; /* XXX */ + ss[k] = '\0'; break; + } default: _hx509_abort("unknown directory type: %d", ds->element); exit(1); @@ -214,8 +231,12 @@ _hx509_Name_to_string(const Name *n, char **str) append_string(str, &total_len, "=", 1, 0); len = strlen(ss); append_string(str, &total_len, ss, len, 1); - if (ds->element == choice_DirectoryString_bmpString) + if (ds->element == choice_DirectoryString_universalString || + ds->element == choice_DirectoryString_bmpString || + ds->element == choice_DirectoryString_teletexString) + { free(ss); + } if (j + 1 < n->u.rdnSequence.val[i].len) append_string(str, &total_len, "+", 1, 0); } @@ -299,6 +320,13 @@ _hx509_name_cmp(const Name *n1, const Name *n2) } int +hx509_name_cmp(hx509_name n1, hx509_name n2) +{ + return _hx509_name_cmp(&n1->der_name, &n2->der_name); +} + + +int _hx509_name_from_Name(const Name *n, hx509_name *name) { int ret; @@ -487,6 +515,106 @@ hx509_name_to_Name(const hx509_name from, Name *to) return copy_Name(&from->der_name, to); } +int +hx509_name_normalize(hx509_context context, hx509_name name) +{ + return 0; +} + +int +hx509_name_expand(hx509_context context, + hx509_name name, + hx509_env env) +{ + Name *n = &name->der_name; + int i, j; + + if (env == NULL) + return 0; + + if (n->element != choice_Name_rdnSequence) { + hx509_set_error_string(context, 0, EINVAL, "RDN not of supported type"); + return EINVAL; + } + + for (i = 0 ; i < n->u.rdnSequence.len; i++) { + for (j = 0; j < n->u.rdnSequence.val[i].len; j++) { + /* + THIS SHOULD REALLY BE: + COMP = n->u.rdnSequence.val[i].val[j]; + normalize COMP to utf8 + check if there are variables + expand variables + convert back to orignal format, store in COMP + free normalized utf8 string + */ + DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value; + char *p, *p2; + struct rk_strpool *strpool = NULL; + + if (ds->element != choice_DirectoryString_utf8String) { + hx509_set_error_string(context, 0, EINVAL, "unsupported type"); + return EINVAL; + } + p = strstr(ds->u.utf8String, "${"); + if (p) { + strpool = rk_strpoolprintf(strpool, "%.*s", + (int)(p - ds->u.utf8String), + ds->u.utf8String); + if (strpool == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + } + while (p != NULL) { + /* expand variables */ + const char *value; + p2 = strchr(p, '}'); + if (p2 == NULL) { + hx509_set_error_string(context, 0, EINVAL, "missing }"); + rk_strpoolfree(strpool); + return EINVAL; + } + p += 2; + value = hx509_env_lfind(context, env, p, p2 - p); + if (value == NULL) { + hx509_set_error_string(context, 0, EINVAL, + "variable %.*s missing", + (int)(p2 - p), p); + rk_strpoolfree(strpool); + return EINVAL; + } + strpool = rk_strpoolprintf(strpool, "%s", value); + if (strpool == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + p2++; + + p = strstr(p2, "${"); + if (p) + strpool = rk_strpoolprintf(strpool, "%.*s", + (int)(p - p2), p2); + else + strpool = rk_strpoolprintf(strpool, "%s", p2); + if (strpool == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + } + if (strpool) { + free(ds->u.utf8String); + ds->u.utf8String = rk_strpoolcollect(strpool); + if (ds->u.utf8String == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + } + } + } + return 0; +} + void hx509_name_free(hx509_name *name) @@ -548,3 +676,91 @@ hx509_name_is_null_p(const hx509_name name) { return name->der_name.u.rdnSequence.len == 0; } + +int +hx509_general_name_unparse(GeneralName *name, char **str) +{ + struct rk_strpool *strpool = NULL; + + *str = NULL; + + switch (name->element) { + case choice_GeneralName_otherName: { + char *str; + hx509_oid_sprint(&name->u.otherName.type_id, &str); + if (str == NULL) + return ENOMEM; + strpool = rk_strpoolprintf(strpool, "otherName: %s", str); + free(str); + break; + } + case choice_GeneralName_rfc822Name: + strpool = rk_strpoolprintf(strpool, "rfc822Name: %s\n", + name->u.rfc822Name); + break; + case choice_GeneralName_dNSName: + strpool = rk_strpoolprintf(strpool, "dNSName: %s\n", + name->u.dNSName); + break; + case choice_GeneralName_directoryName: { + Name dir; + char *s; + int ret; + memset(&dir, 0, sizeof(dir)); + dir.element = name->u.directoryName.element; + dir.u.rdnSequence = name->u.directoryName.u.rdnSequence; + ret = _hx509_unparse_Name(&dir, &s); + if (ret) + return ret; + strpool = rk_strpoolprintf(strpool, "directoryName: %s", s); + free(s); + break; + } + case choice_GeneralName_uniformResourceIdentifier: + strpool = rk_strpoolprintf(strpool, "URI: %s", + name->u.uniformResourceIdentifier); + break; + case choice_GeneralName_iPAddress: { + unsigned char *a = name->u.iPAddress.data; + + strpool = rk_strpoolprintf(strpool, "IPAddress: "); + if (strpool == NULL) + break; + if (name->u.iPAddress.length == 4) + strpool = rk_strpoolprintf(strpool, "%d.%d.%d.%d", + a[0], a[1], a[2], a[3]); + else if (name->u.iPAddress.length == 16) + strpool = rk_strpoolprintf(strpool, + "%02X:%02X:%02X:%02X:" + "%02X:%02X:%02X:%02X:" + "%02X:%02X:%02X:%02X:" + "%02X:%02X:%02X:%02X", + a[0], a[1], a[2], a[3], + a[4], a[5], a[6], a[7], + a[8], a[9], a[10], a[11], + a[12], a[13], a[14], a[15]); + else + strpool = rk_strpoolprintf(strpool, + "unknown IP address of length %lu", + (unsigned long)name->u.iPAddress.length); + break; + } + case choice_GeneralName_registeredID: { + char *str; + hx509_oid_sprint(&name->u.registeredID, &str); + if (str == NULL) + return ENOMEM; + strpool = rk_strpoolprintf(strpool, "registeredID: %s", str); + free(str); + break; + } + default: + return EINVAL; + } + if (strpool == NULL) + return ENOMEM; + + *str = rk_strpoolcollect(strpool); + + return 0; +} diff --git a/source4/heimdal/lib/hx509/ocsp.asn1 b/source4/heimdal/lib/hx509/ocsp.asn1 index 62a2750b96..d8ecd66ccf 100644 --- a/source4/heimdal/lib/hx509/ocsp.asn1 +++ b/source4/heimdal/lib/hx509/ocsp.asn1 @@ -1,5 +1,5 @@ -- From rfc2560 --- $Id: ocsp.asn1,v 1.4 2006/12/30 12:38:44 lha Exp $ +-- $Id: ocsp.asn1 19576 2006-12-30 12:40:43Z lha $ OCSP DEFINITIONS EXPLICIT TAGS::= BEGIN diff --git a/source4/heimdal/lib/hx509/peer.c b/source4/heimdal/lib/hx509/peer.c index f82f2877f6..eccedf1043 100644 --- a/source4/heimdal/lib/hx509/peer.c +++ b/source4/heimdal/lib/hx509/peer.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: peer.c,v 1.1 2006/11/26 15:49:01 lha Exp $"); +RCSID("$Id: peer.c 20938 2007-06-06 20:51:34Z lha $"); int hx509_peer_info_alloc(hx509_context context, hx509_peer_info *peer) @@ -59,14 +59,16 @@ free_cms_alg(hx509_peer_info peer) } } -int +void hx509_peer_info_free(hx509_peer_info peer) { + if (peer == NULL) + return; if (peer->cert) hx509_cert_free(peer->cert); free_cms_alg(peer); memset(peer, 0, sizeof(*peer)); - return 0; + free(peer); } int diff --git a/source4/heimdal/lib/hx509/pkcs10.asn1 b/source4/heimdal/lib/hx509/pkcs10.asn1 index c33fd36cb2..518fe3bfa3 100644 --- a/source4/heimdal/lib/hx509/pkcs10.asn1 +++ b/source4/heimdal/lib/hx509/pkcs10.asn1 @@ -1,4 +1,4 @@ --- $Id: pkcs10.asn1,v 1.1 2006/04/01 09:46:57 lha Exp $ +-- $Id: pkcs10.asn1 16918 2006-04-01 09:46:57Z lha $ PKCS10 DEFINITIONS ::= BEGIN diff --git a/source4/heimdal/lib/hx509/print.c b/source4/heimdal/lib/hx509/print.c index 802ac12b4e..dc9d4cfa58 100644 --- a/source4/heimdal/lib/hx509/print.c +++ b/source4/heimdal/lib/hx509/print.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: print.c,v 1.15 2006/12/07 20:37:57 lha Exp $"); +RCSID("$Id: print.c 20908 2007-06-05 02:59:33Z lha $"); struct hx509_validate_ctx_data { @@ -41,6 +41,18 @@ struct hx509_validate_ctx_data { void *ctx; }; +struct cert_status { + unsigned int selfsigned:1; + unsigned int isca:1; + unsigned int isproxy:1; + unsigned int haveSAN:1; + unsigned int haveIAN:1; + unsigned int haveSKI:1; + unsigned int haveAKI:1; + unsigned int haveCRLDP:1; +}; + + /* * */ @@ -155,10 +167,16 @@ validate_print(hx509_validate_ctx ctx, int flags, const char *fmt, ...) va_end(va); } +/* + * Dont Care, SHOULD critical, SHOULD NOT critical, MUST critical, + * MUST NOT critical + */ enum critical_flag { D_C = 0, S_C, S_N_C, M_C, M_N_C }; static int -check_Null(hx509_validate_ctx ctx, enum critical_flag cf, const Extension *e) +check_Null(hx509_validate_ctx ctx, + struct cert_status *status, + enum critical_flag cf, const Extension *e) { switch(cf) { case D_C: @@ -191,13 +209,96 @@ check_Null(hx509_validate_ctx ctx, enum critical_flag cf, const Extension *e) static int check_subjectKeyIdentifier(hx509_validate_ctx ctx, + struct cert_status *status, enum critical_flag cf, const Extension *e) { - check_Null(ctx, cf, e); + SubjectKeyIdentifier si; + size_t size; + int ret; + + status->haveSKI = 1; + check_Null(ctx, status, cf, e); + + ret = decode_SubjectKeyIdentifier(e->extnValue.data, + e->extnValue.length, + &si, &size); + if (ret) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding SubjectKeyIdentifier failed: %d", ret); + return 1; + } + if (size != e->extnValue.length) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding SKI ahve extra bits on the end"); + return 1; + } + if (si.length == 0) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "SKI is too short (0 bytes)"); + if (si.length > 20) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "SKI is too long"); + + { + char *id; + hex_encode(si.data, si.length, &id); + if (id) { + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "\tsubject key id: %s\n", id); + free(id); + } + } + + free_SubjectKeyIdentifier(&si); + + return 0; +} + +static int +check_authorityKeyIdentifier(hx509_validate_ctx ctx, + struct cert_status *status, + enum critical_flag cf, + const Extension *e) +{ + AuthorityKeyIdentifier ai; + size_t size; + int ret; + + status->haveAKI = 1; + check_Null(ctx, status, cf, e); + + status->haveSKI = 1; + check_Null(ctx, status, cf, e); + + ret = decode_AuthorityKeyIdentifier(e->extnValue.data, + e->extnValue.length, + &ai, &size); + if (ret) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding AuthorityKeyIdentifier failed: %d", ret); + return 1; + } + if (size != e->extnValue.length) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding SKI ahve extra bits on the end"); + return 1; + } + + if (ai.keyIdentifier) { + char *id; + hex_encode(ai.keyIdentifier->data, ai.keyIdentifier->length, &id); + if (id) { + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "\tauthority key id: %s\n", id); + free(id); + } + } + return 0; } + static int check_pkinit_san(hx509_validate_ctx ctx, heim_any *a) { @@ -206,15 +307,16 @@ check_pkinit_san(hx509_validate_ctx ctx, heim_any *a) size_t size; int ret; - ret = decode_KRB5PrincipalName(a->data, a->length, - &kn, &size); + ret = decode_KRB5PrincipalName(a->data, a->length, &kn, &size); if (ret) { - printf("Decoding kerberos name in SAN failed: %d", ret); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding kerberos name in SAN failed: %d", ret); return 1; } if (size != a->length) { - printf("Decoding kerberos name have extra bits on the end"); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding kerberos name have extra bits on the end"); return 1; } @@ -233,22 +335,117 @@ check_pkinit_san(hx509_validate_ctx ctx, heim_any *a) } static int -check_dnssrv_san(hx509_validate_ctx ctx, heim_any *a) +check_utf8_string_san(hx509_validate_ctx ctx, heim_any *a) { + PKIXXmppAddr jid; + size_t size; + int ret; + + ret = decode_PKIXXmppAddr(a->data, a->length, &jid, &size); + if (ret) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding JID in SAN failed: %d", ret); + return 1; + } + + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "%s", jid); + free_PKIXXmppAddr(&jid); + return 0; } +static int +check_altnull(hx509_validate_ctx ctx, heim_any *a) +{ + return 0; +} + +static int +check_CRLDistributionPoints(hx509_validate_ctx ctx, + struct cert_status *status, + enum critical_flag cf, + const Extension *e) +{ + CRLDistributionPoints dp; + size_t size; + int ret, i; + + check_Null(ctx, status, cf, e); + + ret = decode_CRLDistributionPoints(e->extnValue.data, + e->extnValue.length, + &dp, &size); + if (ret) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Decoding CRL Distribution Points failed: %d\n", ret); + return 1; + } + + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "CRL Distribution Points:\n"); + for (i = 0 ; i < dp.len; i++) { + if (dp.val[i].distributionPoint) { + DistributionPointName dpname; + heim_any *data = dp.val[i].distributionPoint; + int j; + + ret = decode_DistributionPointName(data->data, data->length, + &dpname, NULL); + if (ret) { + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Failed to parse CRL Distribution Point Name: %d\n", ret); + continue; + } + + switch (dpname.element) { + case choice_DistributionPointName_fullName: + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "Fullname:\n"); + + for (j = 0 ; j < dpname.u.fullName.len; j++) { + char *s; + GeneralName *name = &dpname.u.fullName.val[j]; + + ret = hx509_general_name_unparse(name, &s); + if (ret == 0 && s != NULL) { + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, " %s\n", s); + free(s); + } + } + break; + case choice_DistributionPointName_nameRelativeToCRLIssuer: + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "Unknown nameRelativeToCRLIssuer"); + break; + default: + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Unknown DistributionPointName"); + break; + } + free_DistributionPointName(&dpname); + } + } + free_CRLDistributionPoints(&dp); + + status->haveCRLDP = 1; + + return 0; +} + + struct { const char *name; const heim_oid *(*oid)(void); int (*func)(hx509_validate_ctx, heim_any *); } check_altname[] = { { "pk-init", oid_id_pkinit_san, check_pkinit_san }, - { "dns-srv", oid_id_pkix_on_dnsSRV, check_dnssrv_san } + { "jabber", oid_id_pkix_on_xmppAddr, check_utf8_string_san }, + { "dns-srv", oid_id_pkix_on_dnsSRV, check_altnull }, + { "card-id", oid_id_uspkicommon_card_id, check_altnull }, + { "Microsoft NT-PRINCIPAL-NAME", oid_id_pkinit_ms_san, check_utf8_string_san } }; static int check_altName(hx509_validate_ctx ctx, + struct cert_status *status, const char *name, enum critical_flag cf, const Extension *e) @@ -257,20 +454,24 @@ check_altName(hx509_validate_ctx ctx, size_t size; int ret, i; - check_Null(ctx, cf, e); + check_Null(ctx, status, cf, e); if (e->extnValue.length == 0) { - printf("%sAltName empty, not allowed", name); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "%sAltName empty, not allowed", name); return 1; } ret = decode_GeneralNames(e->extnValue.data, e->extnValue.length, &gn, &size); if (ret) { - printf("\tret = %d while decoding %s GeneralNames\n", ret, name); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "\tret = %d while decoding %s GeneralNames\n", + ret, name); return 1; } if (gn.len == 0) { - printf("%sAltName generalName empty, not allowed", name); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "%sAltName generalName empty, not allowed\n", name); return 1; } @@ -278,7 +479,9 @@ check_altName(hx509_validate_ctx ctx, switch (gn.val[i].element) { case choice_GeneralName_otherName: { unsigned j; - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "%sAltName otherName ", name); + + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "%sAltName otherName ", name); for (j = 0; j < sizeof(check_altname)/sizeof(check_altname[0]); j++) { if (der_heim_oid_cmp((*check_altname[j].oid)(), @@ -298,41 +501,18 @@ check_altName(hx509_validate_ctx ctx, validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "\n"); break; } - case choice_GeneralName_rfc822Name: - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "rfc822Name: %s\n", - gn.val[i].u.rfc822Name); - break; - case choice_GeneralName_dNSName: - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "dNSName: %s\n", - gn.val[i].u.dNSName); - break; - case choice_GeneralName_directoryName: { - Name dir; + default: { char *s; - dir.element = gn.val[i].u.directoryName.element; - dir.u.rdnSequence = gn.val[i].u.directoryName.u.rdnSequence; - ret = _hx509_unparse_Name(&dir, &s); + ret = hx509_general_name_unparse(&gn.val[i], &s); if (ret) { - printf("unable to parse %sAltName directoryName\n", name); + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "ret = %d unparsing GeneralName\n", ret); return 1; } - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "directoryName: %s\n", s); + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "%s\n", s); free(s); break; } - case choice_GeneralName_uniformResourceIdentifier: - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "uri: %s\n", - gn.val[i].u.uniformResourceIdentifier); - break; - case choice_GeneralName_iPAddress: - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "ip address\n"); - break; - case choice_GeneralName_registeredID: - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "registered id: "); - hx509_oid_print(&gn.val[i].u.registeredID, - validate_vprint, ctx); - validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "\n"); - break; } } @@ -343,23 +523,28 @@ check_altName(hx509_validate_ctx ctx, static int check_subjectAltName(hx509_validate_ctx ctx, + struct cert_status *status, enum critical_flag cf, const Extension *e) { - return check_altName(ctx, "subject", cf, e); + status->haveSAN = 1; + return check_altName(ctx, status, "subject", cf, e); } static int check_issuerAltName(hx509_validate_ctx ctx, + struct cert_status *status, enum critical_flag cf, const Extension *e) { - return check_altName(ctx, "issuer", cf, e); + status->haveIAN = 1; + return check_altName(ctx, status, "issuer", cf, e); } static int check_basicConstraints(hx509_validate_ctx ctx, + struct cert_status *status, enum critical_flag cf, const Extension *e) { @@ -367,7 +552,7 @@ check_basicConstraints(hx509_validate_ctx ctx, size_t size; int ret; - check_Null(ctx, cf, e); + check_Null(ctx, status, cf, e); ret = decode_BasicConstraints(e->extnValue.data, e->extnValue.length, &b, &size); @@ -384,6 +569,30 @@ check_basicConstraints(hx509_validate_ctx ctx, validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "\tpathLenConstraint: %d\n", *b.pathLenConstraint); + if (b.cA) { + if (*b.cA) { + if (!e->critical) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Is a CA and not BasicConstraints CRITICAL\n"); + status->isca = 1; + } + else + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "cA is FALSE, not allowed to be\n"); + } + free_BasicConstraints(&b); + + return 0; +} + +static int +check_proxyCertInfo(hx509_validate_ctx ctx, + struct cert_status *status, + enum critical_flag cf, + const Extension *e) +{ + status->isproxy = 1; + return 0; } @@ -391,6 +600,7 @@ struct { const char *name; const heim_oid *(*oid)(void); int (*func)(hx509_validate_ctx ctx, + struct cert_status *status, enum critical_flag cf, const Extension *); enum critical_flag cf; @@ -401,7 +611,7 @@ struct { { ext(keyUsage, Null), S_C }, { ext(subjectAltName, subjectAltName), M_N_C }, { ext(issuerAltName, issuerAltName), S_N_C }, - { ext(basicConstraints, basicConstraints), M_C }, + { ext(basicConstraints, basicConstraints), D_C }, { ext(cRLNumber, Null), M_N_C }, { ext(cRLReason, Null), M_N_C }, { ext(holdInstructionCode, Null), M_N_C }, @@ -410,14 +620,20 @@ struct { { ext(issuingDistributionPoint, Null), M_C }, { ext(certificateIssuer, Null), M_C }, { ext(nameConstraints, Null), M_C }, - { ext(cRLDistributionPoints, Null), S_N_C }, + { ext(cRLDistributionPoints, CRLDistributionPoints), S_N_C }, { ext(certificatePolicies, Null) }, { ext(policyMappings, Null), M_N_C }, - { ext(authorityKeyIdentifier, Null), M_N_C }, + { ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C }, { ext(policyConstraints, Null), D_C }, { ext(extKeyUsage, Null), D_C }, { ext(freshestCRL, Null), M_N_C }, { ext(inhibitAnyPolicy, Null), M_C }, + { "proxyCertInfo", oid_id_pe_proxyCertInfo, + check_proxyCertInfo, M_C }, + { "US Fed PKI - PIV Interim", oid_id_uspkicommon_piv_interim, + check_Null, D_C }, + { "Netscape cert comment", oid_id_netscape_cert_comment, + check_Null, D_C }, { NULL } }; @@ -459,31 +675,45 @@ hx509_validate_cert(hx509_context context, { Certificate *c = _hx509_get_cert(cert); TBSCertificate *t = &c->tbsCertificate; - hx509_name name; + hx509_name issuer, subject; char *str; + struct cert_status status; + int ret; + + memset(&status, 0, sizeof(status)); if (_hx509_cert_get_version(c) != 3) validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "Not version 3 certificate\n"); - if (t->version && *t->version < 2 && t->extensions) + if ((t->version == NULL || *t->version < 2) && t->extensions) validate_print(ctx, HX509_VALIDATE_F_VALIDATE, "Not version 3 certificate with extensions\n"); - _hx509_name_from_Name(&t->subject, &name); - hx509_name_to_string(name, &str); - hx509_name_free(&name); + if (_hx509_cert_get_version(c) >= 3 && t->extensions == NULL) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Version 3 certificate without extensions\n"); + + ret = hx509_cert_get_subject(cert, &subject); + if (ret) abort(); + hx509_name_to_string(subject, &str); validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "subject name: %s\n", str); free(str); - _hx509_name_from_Name(&t->issuer, &name); - hx509_name_to_string(name, &str); - hx509_name_free(&name); + ret = hx509_cert_get_issuer(cert, &issuer); + if (ret) abort(); + hx509_name_to_string(issuer, &str); validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "issuer name: %s\n", str); free(str); + if (hx509_name_cmp(subject, issuer) == 0) { + status.selfsigned = 1; + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "\tis a self-signed certificate\n"); + } + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "Validity:\n"); @@ -528,11 +758,68 @@ hx509_validate_cert(hx509_context context, "checking extention: %s\n", check_extension[j].name); (*check_extension[j].func)(ctx, + &status, check_extension[j].cf, &t->extensions->val[i]); } } else validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "no extentions\n"); + if (status.isca) { + if (!status.haveSKI) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "CA certificate have no SubjectKeyIdentifier\n"); + + } else { + if (!status.haveAKI) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Is not CA and doesn't have " + "AuthorityKeyIdentifier\n"); + } + + + if (!status.haveSKI) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Doesn't have SubjectKeyIdentifier\n"); + + if (status.isproxy && status.isca) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Proxy and CA at the same time!\n"); + + if (status.isproxy) { + if (status.haveSAN) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Proxy and have SAN\n"); + if (status.haveIAN) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Proxy and have IAN\n"); + } + + if (hx509_name_is_null_p(subject) && !status.haveSAN) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "NULL subject DN and doesn't have a SAN\n"); + + if (!status.selfsigned && !status.haveCRLDP) + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Not a CA nor PROXY and doesn't have" + "CRL Dist Point\n"); + + if (status.selfsigned) { + ret = _hx509_verify_signature_bitstring(context, + c, + &c->signatureAlgorithm, + &c->tbsCertificate._save, + &c->signatureValue); + if (ret == 0) + validate_print(ctx, HX509_VALIDATE_F_VERBOSE, + "Self-signed certificate was self-signed\n"); + else + validate_print(ctx, HX509_VALIDATE_F_VALIDATE, + "Self-signed certificate NOT really self-signed!\n"); + } + + hx509_name_free(&subject); + hx509_name_free(&issuer); + return 0; } diff --git a/source4/heimdal/lib/hx509/req.c b/source4/heimdal/lib/hx509/req.c index ca7baa514b..34e3a4ea27 100644 --- a/source4/heimdal/lib/hx509/req.c +++ b/source4/heimdal/lib/hx509/req.c @@ -33,7 +33,7 @@ #include "hx_locl.h" #include <pkcs10_asn1.h> -RCSID("$Id: req.c,v 1.7 2007/01/04 20:20:11 lha Exp $"); +RCSID("$Id: req.c 20934 2007-06-06 15:30:02Z lha $"); struct hx509_request_data { hx509_name name; @@ -191,7 +191,7 @@ _hx509_request_to_pkcs10(hx509_context context, ret = _hx509_create_signature(context, signer, - hx509_signature_rsa_with_sha1(), + _hx509_crypto_default_sig_alg, &data, &r.signatureAlgorithm, &os); diff --git a/source4/heimdal/lib/hx509/revoke.c b/source4/heimdal/lib/hx509/revoke.c index 8067b29c10..0d477945c8 100644 --- a/source4/heimdal/lib/hx509/revoke.c +++ b/source4/heimdal/lib/hx509/revoke.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: revoke.c,v 1.32 2006/12/30 17:09:06 lha Exp $"); +RCSID("$Id: revoke.c 20871 2007-06-03 21:22:51Z lha $"); struct revoke_crl { char *path; @@ -281,8 +281,11 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp) ret = parse_ocsp_basic(data, length, &basic); _hx509_unmap_file(data, length); - if (ret) + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to parse OCSP response"); return ret; + } if (basic.certs) { int i; @@ -442,7 +445,8 @@ verify_crl(hx509_context context, &crl->tbsCertList._save, &crl->signatureValue); if (ret) { - hx509_set_error_string(context, HX509_ERROR_APPEND, ret, "CRL signature invalid"); + hx509_set_error_string(context, HX509_ERROR_APPEND, ret, + "CRL signature invalid"); goto out; } @@ -800,7 +804,7 @@ hx509_ocsp_request(hx509_context context, memset(&req, 0, sizeof(req)); if (digest == NULL) - digest = hx509_signature_sha1(); + digest = _hx509_crypto_default_digest_alg; ctx.req = &req.tbsRequest; ctx.certs = pool; @@ -922,7 +926,7 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out) fprintf(out, "replies: %d\n", ocsp.ocsp.tbsResponseData.responses.len); for (i = 0; i < ocsp.ocsp.tbsResponseData.responses.len; i++) { - char *status; + const char *status; switch (ocsp.ocsp.tbsResponseData.responses.val[i].certStatus.element) { case choice_OCSPCertStatus_good: status = "good"; @@ -955,6 +959,12 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out) return ret; } +/* + * Verify that the `cert' is part of the OCSP reply and its not + * expired. Doesn't verify signature the OCSP reply or its done by a + * authorized sender, that is assumed to be already done. + */ + int hx509_ocsp_verify(hx509_context context, time_t now, @@ -967,12 +977,17 @@ hx509_ocsp_verify(hx509_context context, OCSPBasicOCSPResponse basic; int ret, i; + if (now == 0) + now = time(NULL); + *expiration = 0; ret = parse_ocsp_basic(data, length, &basic); - if (ret) + if (ret) { + hx509_set_error_string(context, 0, ret, + "Failed to parse OCSP response"); return ret; - + } for (i = 0; i < basic.tbsResponseData.responses.len; i++) { @@ -1003,18 +1018,244 @@ hx509_ocsp_verify(hx509_context context, now + context->ocsp_time_diff) continue; - /* don't allow the next updte to be in the past */ + /* don't allow the next update to be in the past */ if (basic.tbsResponseData.responses.val[i].nextUpdate) { if (*basic.tbsResponseData.responses.val[i].nextUpdate < now) continue; + *expiration = *basic.tbsResponseData.responses.val[i].nextUpdate; } else - continue; - - *expiration = *basic.tbsResponseData.responses.val[i].nextUpdate; + *expiration = now; + free_OCSPBasicOCSPResponse(&basic); return 0; } + free_OCSPBasicOCSPResponse(&basic); + { + hx509_name name; + char *subject; + + ret = hx509_cert_get_subject(cert, &name); + if (ret) { + hx509_clear_error_string(context); + goto out; + } + ret = hx509_name_to_string(name, &subject); + hx509_name_free(&name); + if (ret) { + hx509_clear_error_string(context); + goto out; + } + hx509_set_error_string(context, 0, HX509_CERT_NOT_IN_OCSP, + "Certificate %s not in OCSP response " + "or not good", + subject); + free(subject); + } +out: + return HX509_CERT_NOT_IN_OCSP; +} + +struct hx509_crl { + hx509_certs revoked; + time_t expire; +}; + +int +hx509_crl_alloc(hx509_context context, hx509_crl *crl) +{ + int ret; + + *crl = calloc(1, sizeof(**crl)); + if (*crl == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + + ret = hx509_certs_init(context, "MEMORY:crl", 0, NULL, &(*crl)->revoked); + if (ret) { + free(*crl); + *crl = NULL; + } + (*crl)->expire = 0; + return ret; +} + +int +hx509_crl_add_revoked_certs(hx509_context context, + hx509_crl crl, + hx509_certs certs) +{ + return hx509_certs_merge(context, crl->revoked, certs); +} + +int +hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta) +{ + crl->expire = time(NULL) + delta; + return 0; +} + + +void +hx509_crl_free(hx509_context context, hx509_crl *crl) +{ + if (*crl == NULL) + return; + hx509_certs_free(&(*crl)->revoked); + memset(*crl, 0, sizeof(**crl)); + free(*crl); + *crl = NULL; +} + +static int +add_revoked(hx509_context context, void *ctx, hx509_cert cert) +{ + TBSCRLCertList *c = ctx; + unsigned int num; + void *ptr; + int ret; + + num = c->revokedCertificates->len; + ptr = realloc(c->revokedCertificates->val, + (num + 1) * sizeof(c->revokedCertificates->val[0])); + if (ptr == NULL) { + hx509_clear_error_string(context); + return ENOMEM; + } + c->revokedCertificates->val = ptr; + + ret = hx509_cert_get_serialnumber(cert, + &c->revokedCertificates->val[num].userCertificate); + if (ret) { + hx509_clear_error_string(context); + return ret; + } + c->revokedCertificates->val[num].revocationDate.element = + choice_Time_generalTime; + c->revokedCertificates->val[num].revocationDate.u.generalTime = + time(NULL) - 3600 * 24; + c->revokedCertificates->val[num].crlEntryExtensions = NULL; + + c->revokedCertificates->len++; + + return 0; +} + + +int +hx509_crl_sign(hx509_context context, + hx509_cert signer, + hx509_crl crl, + heim_octet_string *os) +{ + const AlgorithmIdentifier *sigalg = _hx509_crypto_default_sig_alg; + CRLCertificateList c; + size_t size; + int ret; + hx509_private_key signerkey; + + memset(&c, 0, sizeof(c)); + + signerkey = _hx509_cert_private_key(signer); + if (signerkey == NULL) { + ret = HX509_PRIVATE_KEY_MISSING; + hx509_set_error_string(context, 0, ret, + "Private key missing for CRL signing"); + return ret; + } + + c.tbsCertList.version = malloc(sizeof(*c.tbsCertList.version)); + if (c.tbsCertList.version == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + + *c.tbsCertList.version = 1; + + ret = copy_AlgorithmIdentifier(sigalg, &c.tbsCertList.signature); + if (ret) { + hx509_clear_error_string(context); + goto out; + } + + ret = copy_Name(&_hx509_get_cert(signer)->tbsCertificate.issuer, + &c.tbsCertList.issuer); + if (ret) { + hx509_clear_error_string(context); + goto out; + } + + c.tbsCertList.thisUpdate.element = choice_Time_generalTime; + c.tbsCertList.thisUpdate.u.generalTime = time(NULL) - 24 * 3600; + + c.tbsCertList.nextUpdate = malloc(sizeof(*c.tbsCertList.nextUpdate)); + if (c.tbsCertList.nextUpdate == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + ret = ENOMEM; + goto out; + } + + { + time_t next = crl->expire; + if (next == 0) + next = time(NULL) + 24 * 3600 * 365; + + c.tbsCertList.nextUpdate->element = choice_Time_generalTime; + c.tbsCertList.nextUpdate->u.generalTime = next; + } + + c.tbsCertList.revokedCertificates = + calloc(1, sizeof(*c.tbsCertList.revokedCertificates)); + if (c.tbsCertList.revokedCertificates == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + ret = ENOMEM; + goto out; + } + c.tbsCertList.crlExtensions = NULL; + + ret = hx509_certs_iter(context, crl->revoked, add_revoked, &c.tbsCertList); + if (ret) + goto out; + + /* if not revoked certs, remove OPTIONAL entry */ + if (c.tbsCertList.revokedCertificates->len == 0) { + free(c.tbsCertList.revokedCertificates); + c.tbsCertList.revokedCertificates = NULL; + } + + ASN1_MALLOC_ENCODE(TBSCRLCertList, os->data, os->length, + &c.tbsCertList, &size, ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "failed to encode tbsCRL"); + goto out; + } + if (size != os->length) + _hx509_abort("internal ASN.1 encoder error"); + + + ret = _hx509_create_signature_bitstring(context, + signerkey, + sigalg, + os, + &c.signatureAlgorithm, + &c.signatureValue); + free(os->data); + + ASN1_MALLOC_ENCODE(CRLCertificateList, os->data, os->length, + &c, &size, ret); + free_CRLCertificateList(&c); + if (ret) { + hx509_set_error_string(context, 0, ret, "failed to encode CRL"); + goto out; + } + if (size != os->length) + _hx509_abort("internal ASN.1 encoder error"); + return 0; + +out: + free_CRLCertificateList(&c); + return ret; } diff --git a/source4/heimdal/lib/hx509/test_name.c b/source4/heimdal/lib/hx509/test_name.c index 9017e54ab1..2c6dd516cb 100644 --- a/source4/heimdal/lib/hx509/test_name.c +++ b/source4/heimdal/lib/hx509/test_name.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: test_name.c,v 1.6 2006/12/30 23:04:54 lha Exp $"); +RCSID("$Id: test_name.c 19882 2007-01-13 01:02:57Z lha $"); static int test_name(hx509_context context, const char *name) @@ -69,6 +69,39 @@ test_name_fail(hx509_context context, const char *name) return 1; } +static int +test_expand(hx509_context context, const char *name, const char *expected) +{ + hx509_env env; + hx509_name n; + char *s; + int ret; + + hx509_env_init(context, &env); + hx509_env_add(context, env, "uid", "lha"); + + ret = hx509_parse_name(context, name, &n); + if (ret) + return 1; + + ret = hx509_name_expand(context, n, env); + hx509_env_free(&env); + if (ret) + return 1; + + ret = hx509_name_to_string(n, &s); + hx509_name_free(&n); + if (ret) + return 1; + + ret = strcmp(s, expected) != 0; + free(s); + if (ret) + return 1; + + return 0; +} + int main(int argc, char **argv) { @@ -86,6 +119,13 @@ main(int argc, char **argv) ret += test_name_fail(context, "CN=foo,=foo"); ret += test_name_fail(context, "CN=foo,really-unknown-type=foo"); + ret += test_expand(context, "UID=${uid},C=SE", "UID=lha,C=SE"); + ret += test_expand(context, "UID=foo${uid},C=SE", "UID=foolha,C=SE"); + ret += test_expand(context, "UID=${uid}bar,C=SE", "UID=lhabar,C=SE"); + ret += test_expand(context, "UID=f${uid}b,C=SE", "UID=flhab,C=SE"); + ret += test_expand(context, "UID=${uid}${uid},C=SE", "UID=lhalha,C=SE"); + ret += test_expand(context, "UID=${uid}{uid},C=SE", "UID=lha{uid},C=SE"); + hx509_context_free(&context); return ret; diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index d20c24699b..999ce7f120 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include <dlfcn.h> #endif -RCSID("$Id: acache.c,v 1.17 2007/01/08 15:31:01 lha Exp $"); +RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; diff --git a/source4/heimdal/lib/krb5/add_et_list.c b/source4/heimdal/lib/krb5/add_et_list.c index 3b9773bebb..a6005c6859 100644 --- a/source4/heimdal/lib/krb5/add_et_list.c +++ b/source4/heimdal/lib/krb5/add_et_list.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: add_et_list.c,v 1.3 2004/04/13 14:33:45 lha Exp $"); +RCSID("$Id: add_et_list.c 13713 2004-04-13 14:33:45Z lha $"); /* * Add a specified list of error messages to the et list in context. diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c index f68be423b0..8c31843058 100644 --- a/source4/heimdal/lib/krb5/addr_families.c +++ b/source4/heimdal/lib/krb5/addr_families.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c,v 1.53 2006/10/22 06:54:00 lha Exp $"); +RCSID("$Id: addr_families.c 18805 2006-10-22 06:54:00Z lha $"); struct addr_operations { int af; diff --git a/source4/heimdal/lib/krb5/appdefault.c b/source4/heimdal/lib/krb5/appdefault.c index 03fa933b6f..b0bb171f4a 100644 --- a/source4/heimdal/lib/krb5/appdefault.c +++ b/source4/heimdal/lib/krb5/appdefault.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: appdefault.c,v 1.10 2005/01/05 05:40:59 lukeh Exp $"); +RCSID("$Id: appdefault.c 14465 2005-01-05 05:40:59Z lukeh $"); void KRB5_LIB_FUNCTION krb5_appdefault_boolean(krb5_context context, const char *appname, diff --git a/source4/heimdal/lib/krb5/asn1_glue.c b/source4/heimdal/lib/krb5/asn1_glue.c index b07e058550..6b7d40d453 100644 --- a/source4/heimdal/lib/krb5/asn1_glue.c +++ b/source4/heimdal/lib/krb5/asn1_glue.c @@ -37,7 +37,7 @@ #include "krb5_locl.h" -RCSID("$Id: asn1_glue.c,v 1.10 2006/10/06 17:02:48 lha Exp $"); +RCSID("$Id: asn1_glue.c 18269 2006-10-06 17:02:48Z lha $"); krb5_error_code KRB5_LIB_FUNCTION _krb5_principal2principalname (PrincipalName *p, @@ -47,23 +47,14 @@ _krb5_principal2principalname (PrincipalName *p, } krb5_error_code KRB5_LIB_FUNCTION -_krb5_principalname2krb5_principal (krb5_context context, +_krb5_principalname2krb5_principal (krb5_context context, krb5_principal *principal, const PrincipalName from, const Realm realm) { - if (from.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { - if (from.name_string.len != 1) { - return KRB5_PARSE_MALFORMED; - } - return krb5_parse_name(context, - from.name_string.val[0], - principal); - } else { - krb5_principal p = malloc(sizeof(*p)); - copy_PrincipalName(&from, &p->name); - p->realm = strdup(realm); - *principal = p; - } + krb5_principal p = malloc(sizeof(*p)); + copy_PrincipalName(&from, &p->name); + p->realm = strdup(realm); + *principal = p; return 0; } diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c index b8ce65d9a5..5e08f15ad4 100644 --- a/source4/heimdal/lib/krb5/auth_context.c +++ b/source4/heimdal/lib/krb5/auth_context.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: auth_context.c,v 1.62 2005/01/05 02:34:08 lukeh Exp $"); +RCSID("$Id: auth_context.c 14452 2005-01-05 02:34:08Z lukeh $"); krb5_error_code KRB5_LIB_FUNCTION krb5_auth_con_init(krb5_context context, diff --git a/source4/heimdal/lib/krb5/build_ap_req.c b/source4/heimdal/lib/krb5/build_ap_req.c index e11744cc3a..b1968fe817 100644 --- a/source4/heimdal/lib/krb5/build_ap_req.c +++ b/source4/heimdal/lib/krb5/build_ap_req.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: build_ap_req.c,v 1.20 2004/05/25 21:18:17 lha Exp $"); +RCSID("$Id: build_ap_req.c 13863 2004-05-25 21:46:46Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_build_ap_req (krb5_context context, diff --git a/source4/heimdal/lib/krb5/build_auth.c b/source4/heimdal/lib/krb5/build_auth.c index 9eff09bb0a..f8739c044d 100644 --- a/source4/heimdal/lib/krb5/build_auth.c +++ b/source4/heimdal/lib/krb5/build_auth.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: build_auth.c,v 1.43 2006/04/10 08:53:21 lha Exp $"); +RCSID("$Id: build_auth.c 17033 2006-04-10 08:53:21Z lha $"); static krb5_error_code make_etypelist(krb5_context context, diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index a96870a7de..5be3935f2b 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: cache.c,v 1.82 2006/09/12 17:35:33 lha Exp $"); +RCSID("$Id: cache.c 20503 2007-04-21 22:03:56Z lha $"); /* * Add a new ccache type with operations `ops', overwriting any @@ -473,7 +473,8 @@ krb5_cc_store_cred(krb5_context context, /* * Retrieve the credential identified by `mcreds' (and `whichfields') - * from `id' in `creds'. + * from `id' in `creds'. 'creds' must be free by the caller using + * krb5_free_cred_contents. * Return 0 or an error code. */ diff --git a/source4/heimdal/lib/krb5/changepw.c b/source4/heimdal/lib/krb5/changepw.c index ba584a04a4..3ceb6df89c 100644 --- a/source4/heimdal/lib/krb5/changepw.c +++ b/source4/heimdal/lib/krb5/changepw.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: changepw.c,v 1.56 2006/05/05 09:26:47 lha Exp $"); +RCSID("$Id: changepw.c 17442 2006-05-05 09:31:15Z lha $"); static void str2data (krb5_data *d, diff --git a/source4/heimdal/lib/krb5/codec.c b/source4/heimdal/lib/krb5/codec.c index 080e8a6511..0d36b4b442 100644 --- a/source4/heimdal/lib/krb5/codec.c +++ b/source4/heimdal/lib/krb5/codec.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: codec.c,v 1.9 2004/05/25 21:19:37 lha Exp $"); +RCSID("$Id: codec.c 13863 2004-05-25 21:46:46Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_decode_EncTicketPart (krb5_context context, diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index bbd9cf4c78..ac5eba39dc 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: config_file.c,v 1.55 2006/12/04 23:35:54 lha Exp $"); +RCSID("$Id: config_file.c 19213 2006-12-04 23:36:36Z lha $"); #ifndef HAVE_NETINFO diff --git a/source4/heimdal/lib/krb5/config_file_netinfo.c b/source4/heimdal/lib/krb5/config_file_netinfo.c index 6e72509ab6..1e01e7c5ff 100644 --- a/source4/heimdal/lib/krb5/config_file_netinfo.c +++ b/source4/heimdal/lib/krb5/config_file_netinfo.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: config_file_netinfo.c,v 1.4 2004/05/25 21:20:18 lha Exp $"); +RCSID("$Id: config_file_netinfo.c 13863 2004-05-25 21:46:46Z lha $"); /* * Netinfo implementation from Luke Howard <lukeh@xedoc.com.au> diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index 89ebc34a1a..5188a1d3a8 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: constants.c,v 1.8 2004/09/23 07:57:37 joda Exp $"); +RCSID("$Id: constants.c 14253 2004-09-23 07:57:37Z joda $"); const char *krb5_config_file = #ifdef __APPLE__ diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index d0317da375..b54e293a60 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <com_err.h> -RCSID("$Id: context.c,v 1.112 2006/11/24 14:24:33 lha Exp $"); +RCSID("$Id: context.c 19107 2006-11-24 14:24:33Z lha $"); #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c index bff56a2602..1d1b4d7070 100644 --- a/source4/heimdal/lib/krb5/convert_creds.c +++ b/source4/heimdal/lib/krb5/convert_creds.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: convert_creds.c,v 1.32 2005/04/23 19:40:57 lha Exp $"); +RCSID("$Id: convert_creds.c 14897 2005-04-23 19:40:57Z lha $"); #include "krb5-v4compat.h" diff --git a/source4/heimdal/lib/krb5/copy_host_realm.c b/source4/heimdal/lib/krb5/copy_host_realm.c index eb77fba024..4e668c2a14 100644 --- a/source4/heimdal/lib/krb5/copy_host_realm.c +++ b/source4/heimdal/lib/krb5/copy_host_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: copy_host_realm.c,v 1.5 2004/05/25 21:21:17 lha Exp $"); +RCSID("$Id: copy_host_realm.c 13863 2004-05-25 21:46:46Z lha $"); /* * Copy the list of realms from `from' to `to'. diff --git a/source4/heimdal/lib/krb5/crc.c b/source4/heimdal/lib/krb5/crc.c index 4cfed75154..072c29d689 100644 --- a/source4/heimdal/lib/krb5/crc.c +++ b/source4/heimdal/lib/krb5/crc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: crc.c,v 1.10 2006/05/05 09:27:09 lha Exp $"); +RCSID("$Id: crc.c 17442 2006-05-05 09:31:15Z lha $"); static u_long table[256]; diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index 2afd0725f1..d4d83162f1 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: creds.c,v 1.20 2005/05/18 04:21:04 lha Exp $"); +RCSID("$Id: creds.c 15167 2005-05-18 04:21:57Z lha $"); /* keep this for compatibility with older code */ krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 6d4a81baa8..93f3e44ba1 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: crypto.c,v 1.146 2006/11/17 21:58:47 lha Exp $"); +RCSID("$Id: crypto.c 20981 2007-06-07 20:05:50Z lha $"); #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -57,8 +57,6 @@ struct krb5_crypto_data { struct key_usage *key_usage; }; -#define kcrypto_oid_enc(n) { sizeof(n)/sizeof(n[0]), n } - #define CRYPTO_ETYPE(C) ((C)->et->type) /* bits for `flags' below */ @@ -82,7 +80,6 @@ struct key_type { const char *name; size_t bits; size_t size; - size_t minsize; size_t schedule_size; #if 0 krb5_enctype best_etype; @@ -128,6 +125,9 @@ struct encryption_type { krb5_boolean encryptp, int usage, void *ivec); + size_t prf_length; + krb5_error_code (*prf)(krb5_context, + krb5_crypto, const krb5_data *, krb5_data *); }; #define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA) @@ -724,7 +724,6 @@ static struct key_type keytype_null = { 0, 0, 0, - 0, NULL, NULL, NULL @@ -735,7 +734,6 @@ static struct key_type keytype_des = { "des", 56, sizeof(DES_cblock), - sizeof(DES_cblock), sizeof(DES_key_schedule), krb5_DES_random_key, krb5_DES_schedule, @@ -748,7 +746,6 @@ static struct key_type keytype_des3 = { "des3", 168, 3 * sizeof(DES_cblock), - 3 * sizeof(DES_cblock), 3 * sizeof(DES_key_schedule), DES3_random_key, DES3_schedule, @@ -761,7 +758,6 @@ static struct key_type keytype_des3_derived = { "des3", 168, 3 * sizeof(DES_cblock), - 3 * sizeof(DES_cblock), 3 * sizeof(DES_key_schedule), DES3_random_key, DES3_schedule, @@ -774,7 +770,6 @@ static struct key_type keytype_aes128 = { "aes-128", 128, 16, - 16, sizeof(struct krb5_aes_schedule), NULL, AES_schedule, @@ -786,7 +781,6 @@ static struct key_type keytype_aes256 = { "aes-256", 256, 32, - 32, sizeof(struct krb5_aes_schedule), NULL, AES_schedule, @@ -798,7 +792,6 @@ static struct key_type keytype_arcfour = { "arcfour", 128, 16, - 16, sizeof(RC4_KEY), NULL, ARCFOUR_schedule, @@ -2451,6 +2444,58 @@ ARCFOUR_encrypt(krb5_context context, /* + * + */ + +static krb5_error_code +AES_PRF(krb5_context context, + krb5_crypto crypto, + const krb5_data *in, + krb5_data *out) +{ + struct checksum_type *ct = crypto->et->checksum; + krb5_error_code ret; + Checksum result; + krb5_keyblock *derived; + + result.cksumtype = ct->type; + ret = krb5_data_alloc(&result.checksum, ct->checksumsize); + if (ret) { + krb5_set_error_string(context, "out memory"); + return ret; + } + + (*ct->checksum)(context, NULL, in->data, in->length, 0, &result); + + if (result.checksum.length < crypto->et->blocksize) + krb5_abortx(context, "internal prf error"); + + derived = NULL; + ret = krb5_derive_key(context, crypto->key.key, + crypto->et->type, "prf", 3, &derived); + if (ret) + krb5_abortx(context, "krb5_derive_key"); + + ret = krb5_data_alloc(out, crypto->et->blocksize); + if (ret) + krb5_abortx(context, "malloc failed"); + + { + AES_KEY key; + + AES_set_encrypt_key(derived->keyvalue.data, + crypto->et->keytype->bits, &key); + AES_encrypt(result.checksum.data, out->data, &key); + memset(&key, 0, sizeof(key)); + } + + krb5_data_free(&result.checksum); + krb5_free_keyblock(context, derived); + + return ret; +} + +/* * these should currently be in reverse preference order. * (only relevant for !F_PSEUDO) */ @@ -2466,6 +2511,8 @@ static struct encryption_type enctype_null = { NULL, F_DISABLED, NULL_encrypt, + 0, + NULL }; static struct encryption_type enctype_des_cbc_crc = { ETYPE_DES_CBC_CRC, @@ -2479,6 +2526,8 @@ static struct encryption_type enctype_des_cbc_crc = { NULL, 0, DES_CBC_encrypt_key_ivec, + 0, + NULL }; static struct encryption_type enctype_des_cbc_md4 = { ETYPE_DES_CBC_MD4, @@ -2492,6 +2541,8 @@ static struct encryption_type enctype_des_cbc_md4 = { &checksum_rsa_md4_des, 0, DES_CBC_encrypt_null_ivec, + 0, + NULL }; static struct encryption_type enctype_des_cbc_md5 = { ETYPE_DES_CBC_MD5, @@ -2505,6 +2556,8 @@ static struct encryption_type enctype_des_cbc_md5 = { &checksum_rsa_md5_des, 0, DES_CBC_encrypt_null_ivec, + 0, + NULL }; static struct encryption_type enctype_arcfour_hmac_md5 = { ETYPE_ARCFOUR_HMAC_MD5, @@ -2517,7 +2570,9 @@ static struct encryption_type enctype_arcfour_hmac_md5 = { &checksum_hmac_md5, NULL, F_SPECIAL, - ARCFOUR_encrypt + ARCFOUR_encrypt, + 0, + NULL }; static struct encryption_type enctype_des3_cbc_md5 = { ETYPE_DES3_CBC_MD5, @@ -2531,6 +2586,8 @@ static struct encryption_type enctype_des3_cbc_md5 = { &checksum_rsa_md5_des3, 0, DES3_CBC_encrypt, + 0, + NULL }; static struct encryption_type enctype_des3_cbc_sha1 = { ETYPE_DES3_CBC_SHA1, @@ -2544,6 +2601,8 @@ static struct encryption_type enctype_des3_cbc_sha1 = { &checksum_hmac_sha1_des3, F_DERIVED, DES3_CBC_encrypt, + 0, + NULL }; static struct encryption_type enctype_old_des3_cbc_sha1 = { ETYPE_OLD_DES3_CBC_SHA1, @@ -2557,6 +2616,8 @@ static struct encryption_type enctype_old_des3_cbc_sha1 = { &checksum_hmac_sha1_des3, 0, DES3_CBC_encrypt, + 0, + NULL }; static struct encryption_type enctype_aes128_cts_hmac_sha1 = { ETYPE_AES128_CTS_HMAC_SHA1_96, @@ -2570,6 +2631,8 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = { &checksum_hmac_sha1_aes128, F_DERIVED, AES_CTS_encrypt, + 16, + AES_PRF }; static struct encryption_type enctype_aes256_cts_hmac_sha1 = { ETYPE_AES256_CTS_HMAC_SHA1_96, @@ -2583,6 +2646,8 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = { &checksum_hmac_sha1_aes256, F_DERIVED, AES_CTS_encrypt, + 16, + AES_PRF }; static struct encryption_type enctype_des_cbc_none = { ETYPE_DES_CBC_NONE, @@ -2596,6 +2661,8 @@ static struct encryption_type enctype_des_cbc_none = { NULL, F_PSEUDO, DES_CBC_encrypt_null_ivec, + 0, + NULL }; static struct encryption_type enctype_des_cfb64_none = { ETYPE_DES_CFB64_NONE, @@ -2609,6 +2676,8 @@ static struct encryption_type enctype_des_cfb64_none = { NULL, F_PSEUDO, DES_CFB64_encrypt_null_ivec, + 0, + NULL }; static struct encryption_type enctype_des_pcbc_none = { ETYPE_DES_PCBC_NONE, @@ -2622,6 +2691,8 @@ static struct encryption_type enctype_des_pcbc_none = { NULL, F_PSEUDO, DES_PCBC_encrypt_key_ivec, + 0, + NULL }; static struct encryption_type enctype_des3_cbc_none = { ETYPE_DES3_CBC_NONE, @@ -2635,6 +2706,8 @@ static struct encryption_type enctype_des3_cbc_none = { NULL, F_PSEUDO, DES3_CBC_encrypt, + 0, + NULL }; static struct encryption_type *etypes[] = { @@ -3090,8 +3163,8 @@ decrypt_internal_derived(krb5_context context, checksum_sz = CHECKSUMSIZE(et->keyed_checksum); if (len < checksum_sz) { - krb5_clear_error_string (context); - return EINVAL; /* XXX - better error code? */ + krb5_set_error_string(context, "Encrypted data shorter then checksum"); + return KRB5_BAD_MSIZE; } if (((len - checksum_sz) % et->padsize) != 0) { @@ -3357,11 +3430,8 @@ krb5_decrypt_EncryptedData(krb5_context context, * * ************************************************************/ -#ifdef HAVE_OPENSSL -#include <openssl/rand.h> +#define ENTROPY_NEEDED 128 -/* From openssl/crypto/rand/rand_lcl.h */ -#define ENTROPY_NEEDED 20 static int seed_something(void) { @@ -3417,7 +3487,8 @@ krb5_generate_random_block(void *buf, size_t len) HEIMDAL_MUTEX_lock(&crypto_mutex); if (!rng_initialized) { if (seed_something()) - krb5_abortx(NULL, "Fatal: could not seed the random number generator"); + krb5_abortx(NULL, "Fatal: could not seed the " + "random number generator"); rng_initialized = 1; } @@ -3426,38 +3497,6 @@ krb5_generate_random_block(void *buf, size_t len) krb5_abortx(NULL, "Failed to generate random block"); } -#else - -void KRB5_LIB_FUNCTION -krb5_generate_random_block(void *buf, size_t len) -{ - DES_cblock key, out; - static DES_cblock counter; - static DES_key_schedule schedule; - int i; - static int initialized = 0; - - HEIMDAL_MUTEX_lock(&crypto_mutex); - if(!initialized) { - DES_new_random_key(&key); - DES_set_key(&key, &schedule); - memset(&key, 0, sizeof(key)); - DES_new_random_key(&counter); - initialized = 1; - } - HEIMDAL_MUTEX_unlock(&crypto_mutex); - while(len > 0) { - DES_ecb_encrypt(&counter, &out, &schedule, DES_ENCRYPT); - for(i = 7; i >=0; i--) - if(counter[i]++) - break; - memcpy(buf, out, min(len, sizeof(out))); - len -= min(len, sizeof(out)); - buf = (char*)buf + sizeof(out); - } -} -#endif - static void DES3_postproc(krb5_context context, unsigned char *k, size_t len, struct key_data *key) @@ -3645,7 +3684,7 @@ krb5_crypto_init(krb5_context context, etype); return KRB5_PROG_ETYPE_NOSUPP; } - if((*crypto)->et->keytype->minsize > key->keyvalue.length) { + if((*crypto)->et->keytype->size != key->keyvalue.length) { free(*crypto); *crypto = NULL; krb5_set_error_string (context, "encryption key has bad length"); @@ -3844,6 +3883,50 @@ krb5_get_wrapped_length (krb5_context context, return wrapped_length (context, crypto, data_len); } +/* + * Return the size of an encrypted packet of length `data_len' + */ + +static size_t +crypto_overhead (krb5_context context, + krb5_crypto crypto) +{ + struct encryption_type *et = crypto->et; + size_t res; + + res = CHECKSUMSIZE(et->checksum); + res += et->confoundersize; + if (et->padsize > 1) + res += et->padsize; + return res; +} + +static size_t +crypto_overhead_dervied (krb5_context context, + krb5_crypto crypto) +{ + struct encryption_type *et = crypto->et; + size_t res; + + if (et->keyed_checksum) + res = CHECKSUMSIZE(et->keyed_checksum); + else + res = CHECKSUMSIZE(et->checksum); + res += et->confoundersize; + if (et->padsize > 1) + res += et->padsize; + return res; +} + +size_t +krb5_crypto_overhead (krb5_context context, krb5_crypto crypto) +{ + if (derived_crypto (context, crypto)) + return crypto_overhead_dervied (context, crypto); + else + return crypto_overhead (context, crypto); +} + krb5_error_code KRB5_LIB_FUNCTION krb5_random_to_key(krb5_context context, krb5_enctype type, @@ -3934,6 +4017,44 @@ _krb5_pk_octetstring2key(krb5_context context, return ret; } +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_prf_length(krb5_context context, + krb5_enctype type, + size_t *length) +{ + struct encryption_type *et = _find_enctype(type); + + if(et == NULL || et->prf_length == 0) { + krb5_set_error_string(context, "encryption type %d not supported", + type); + return KRB5_PROG_ETYPE_NOSUPP; + } + + *length = et->prf_length; + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_prf(krb5_context context, + const krb5_crypto crypto, + const krb5_data *input, + krb5_data *output) +{ + struct encryption_type *et = crypto->et; + + krb5_data_zero(output); + + if(et->prf == NULL) { + krb5_set_error_string(context, "kerberos prf for %s not supported", + et->name); + return KRB5_PROG_ETYPE_NOSUPP; + } + + return (*et->prf)(context, crypto, input, output); +} + + + #ifdef CRYPTO_DEBUG diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index f0c6d00abe..2ece85bdb3 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: data.c,v 1.21 2006/10/14 09:45:41 lha Exp $"); +RCSID("$Id: data.c 20039 2007-01-23 20:34:01Z lha $"); void KRB5_LIB_FUNCTION krb5_data_zero(krb5_data *p) @@ -118,3 +118,11 @@ krb5_copy_data(krb5_context context, } return ret; } + +int KRB5_LIB_FUNCTION +krb5_data_cmp(const krb5_data *data1, const krb5_data *data2) +{ + if (data1->length != data2->length) + return data1->length - data2->length; + return memcmp(data1->data, data2->data, data1->length); +} diff --git a/source4/heimdal/lib/krb5/eai_to_heim_errno.c b/source4/heimdal/lib/krb5/eai_to_heim_errno.c index f0d1f51033..c6b5cfb18b 100644 --- a/source4/heimdal/lib/krb5/eai_to_heim_errno.c +++ b/source4/heimdal/lib/krb5/eai_to_heim_errno.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: eai_to_heim_errno.c,v 1.5 2004/05/25 21:23:35 lha Exp $"); +RCSID("$Id: eai_to_heim_errno.c 13863 2004-05-25 21:46:46Z lha $"); /* * convert the getaddrinfo error code in `eai_errno' into a diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index b672fe74f9..1ba6494487 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: error_string.c,v 1.7 2006/02/16 07:49:23 lha Exp $"); +RCSID("$Id: error_string.c 16746 2006-02-16 07:49:23Z lha $"); #undef __attribute__ #define __attribute__(X) diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c index 46e784f561..b2b410269e 100644 --- a/source4/heimdal/lib/krb5/expand_hostname.c +++ b/source4/heimdal/lib/krb5/expand_hostname.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: expand_hostname.c,v 1.14 2006/11/04 03:34:57 lha Exp $"); +RCSID("$Id: expand_hostname.c 18906 2006-11-04 03:34:57Z lha $"); static krb5_error_code copy_hostname(krb5_context context, diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index 7441509e38..864efa8d7d 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: fcache.c,v 1.54 2006/12/15 21:35:52 lha Exp $"); +RCSID("$Id: fcache.c 19379 2006-12-15 21:35:52Z lha $"); typedef struct krb5_fcache{ char *filename; diff --git a/source4/heimdal/lib/krb5/free.c b/source4/heimdal/lib/krb5/free.c index 84aa6f8c2c..1b0bd05412 100644 --- a/source4/heimdal/lib/krb5/free.c +++ b/source4/heimdal/lib/krb5/free.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: free.c,v 1.8 2005/05/18 10:06:16 lha Exp $"); +RCSID("$Id: free.c 15175 2005-05-18 10:06:16Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *rep) diff --git a/source4/heimdal/lib/krb5/free_host_realm.c b/source4/heimdal/lib/krb5/free_host_realm.c index 27afcdbb23..6b13ce7d0e 100644 --- a/source4/heimdal/lib/krb5/free_host_realm.c +++ b/source4/heimdal/lib/krb5/free_host_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: free_host_realm.c,v 1.5 2004/05/25 21:25:02 lha Exp $"); +RCSID("$Id: free_host_realm.c 13863 2004-05-25 21:46:46Z lha $"); /* * Free all memory allocated by `realmlist' diff --git a/source4/heimdal/lib/krb5/generate_seq_number.c b/source4/heimdal/lib/krb5/generate_seq_number.c index 7f79e29858..8a04f048c8 100644 --- a/source4/heimdal/lib/krb5/generate_seq_number.c +++ b/source4/heimdal/lib/krb5/generate_seq_number.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: generate_seq_number.c,v 1.10 2006/05/05 09:28:06 lha Exp $"); +RCSID("$Id: generate_seq_number.c 17442 2006-05-05 09:31:15Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_generate_seq_number(krb5_context context, diff --git a/source4/heimdal/lib/krb5/generate_subkey.c b/source4/heimdal/lib/krb5/generate_subkey.c index df4828d097..fb99cbbf3f 100644 --- a/source4/heimdal/lib/krb5/generate_subkey.c +++ b/source4/heimdal/lib/krb5/generate_subkey.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: generate_subkey.c,v 1.11 2005/01/05 02:39:21 lukeh Exp $"); +RCSID("$Id: generate_subkey.c 14455 2005-01-05 02:39:21Z lukeh $"); krb5_error_code KRB5_LIB_FUNCTION krb5_generate_subkey(krb5_context context, diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 663b5e7f1b..761224b82c 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_cred.c,v 1.113 2006/11/21 05:14:01 lha Exp $"); +RCSID("$Id: get_cred.c 21004 2007-06-08 01:53:10Z lha $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -542,8 +542,8 @@ again: KRB5_KU_TGS_REP_ENC_PART_SESSION, &krbtgt->addresses, nonce, - TRUE, - TRUE /* flags.b.request_anonymous */, + EXTRACT_TICKET_ALLOW_CNAME_MISMATCH| + EXTRACT_TICKET_ALLOW_SERVER_MISMATCH, decrypt_tkt_with_subkey, subkey); krb5_free_kdc_rep(context, &rep); @@ -659,6 +659,20 @@ krb5_get_kdc_cred(krb5_context context, return ret; } +static void +not_found(krb5_context context, krb5_const_principal p) +{ + krb5_error_code ret; + char *str; + + ret = krb5_unparse_name(context, p, &str); + if(ret) { + krb5_clear_error_string(context); + return; + } + krb5_set_error_string(context, "Matching credential (%s) not found", str); + free(str); +} static krb5_error_code find_cred(krb5_context context, @@ -684,17 +698,7 @@ find_cred(krb5_context context, } tgts++; } - { - char *str; - ret = krb5_unparse_name(context, server, &str); - if(ret == 0) { - krb5_set_error_string(context, "Matching credential " - "(%s) not found", str); - free(str); - } else { - krb5_clear_error_string(context); - } - } + not_found(context, server); return KRB5_CC_NOTFOUND; } @@ -818,7 +822,7 @@ get_cred_from_kdc_flags(krb5_context context, } } if(krb5_realm_compare(context, in_creds->client, in_creds->server)) { - krb5_clear_error_string (context); + not_found(context, in_creds->server); return KRB5_CC_NOTFOUND; } /* XXX this can loop forever */ @@ -972,7 +976,7 @@ krb5_get_credentials_with_flags(krb5_context context, } free(res_creds); if(options & KRB5_GC_CACHED) { - krb5_clear_error_string (context); + not_found(context, in_creds->server); return KRB5_CC_NOTFOUND; } if(options & KRB5_GC_USER_USER) @@ -1175,7 +1179,7 @@ krb5_get_creds(krb5_context context, } free(res_creds); if(options & KRB5_GC_CACHED) { - krb5_clear_error_string (context); + not_found(context, in_creds.server); krb5_free_principal(context, in_creds.client); return KRB5_CC_NOTFOUND; } diff --git a/source4/heimdal/lib/krb5/get_default_principal.c b/source4/heimdal/lib/krb5/get_default_principal.c index 03e8f0a823..83fb2b0fa9 100644 --- a/source4/heimdal/lib/krb5/get_default_principal.c +++ b/source4/heimdal/lib/krb5/get_default_principal.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_principal.c,v 1.10 2005/04/20 20:53:29 lha Exp $"); +RCSID("$Id: get_default_principal.c 14870 2005-04-20 20:53:29Z lha $"); /* * Try to find out what's a reasonable default principal. diff --git a/source4/heimdal/lib/krb5/get_default_realm.c b/source4/heimdal/lib/krb5/get_default_realm.c index bb72daf373..09c8577b26 100644 --- a/source4/heimdal/lib/krb5/get_default_realm.c +++ b/source4/heimdal/lib/krb5/get_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_realm.c,v 1.13 2004/05/25 21:27:17 lha Exp $"); +RCSID("$Id: get_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); /* * Return a NULL-terminated list of default realms in `realms'. diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index 6eebf1fa80..1bb98737d1 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_for_creds.c,v 1.49 2006/04/10 09:28:15 lha Exp $"); +RCSID("$Id: get_for_creds.c 17036 2006-04-10 09:28:15Z lha $"); static krb5_error_code add_addrs(krb5_context context, diff --git a/source4/heimdal/lib/krb5/get_host_realm.c b/source4/heimdal/lib/krb5/get_host_realm.c index ffc646d98b..d709e4b38d 100644 --- a/source4/heimdal/lib/krb5/get_host_realm.c +++ b/source4/heimdal/lib/krb5/get_host_realm.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <resolve.h> -RCSID("$Id: get_host_realm.c,v 1.37 2006/10/17 19:28:36 lha Exp $"); +RCSID("$Id: get_host_realm.c 18541 2006-10-17 19:28:36Z lha $"); /* To automagically find the correct realm of a host (without * [domain_realm] in krb5.conf) add a text record for your domain with diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index e140011413..ec106bb7ec 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_in_tkt.c,v 1.119 2006/10/06 17:05:08 lha Exp $"); +RCSID("$Id: get_in_tkt.c 20226 2007-02-16 03:31:50Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_init_etype (krb5_context context, @@ -125,13 +125,12 @@ _krb5_extract_ticket(krb5_context context, krb5_key_usage key_usage, krb5_addresses *addrs, unsigned nonce, - krb5_boolean allow_server_mismatch, - krb5_boolean ignore_cname, + unsigned flags, krb5_decrypt_proc decrypt_proc, krb5_const_pointer decryptarg) { krb5_error_code ret; - krb5_principal tmp_principal, srv_principal = NULL; + krb5_principal tmp_principal; int tmp; size_t len; time_t tmp_time; @@ -143,8 +142,8 @@ _krb5_extract_ticket(krb5_context context, * as realm against windows KDC's, they always return the full realm * based on the DNS Name. */ -allow_server_mismatch = 1; -ignore_cname = 1; +flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; +flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; ret = _krb5_principalname2krb5_principal (context, &tmp_principal, @@ -155,7 +154,7 @@ ignore_cname = 1; /* compare client */ - if (!ignore_cname) { + if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0){ tmp = krb5_principal_compare (context, tmp_principal, creds->client); if (!tmp) { krb5_free_principal (context, tmp_principal); @@ -177,60 +176,49 @@ ignore_cname = 1; krb5_abortx(context, "internal error in ASN.1 encoder"); creds->second_ticket.length = 0; creds->second_ticket.data = NULL; - - /* decrypt */ - - if (decrypt_proc == NULL) - decrypt_proc = decrypt_tkt; - - ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); - if (ret) - goto out; - -#if 0 - /* XXX should this decode be here, or in the decrypt_proc? */ - ret = krb5_decode_keyblock(context, &rep->enc_part.key, 1); - if(ret) - goto out; -#endif /* compare server */ ret = _krb5_principalname2krb5_principal (context, - &srv_principal, + &tmp_principal, rep->kdc_rep.ticket.sname, rep->kdc_rep.ticket.realm); if (ret) goto out; + if(flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH){ + krb5_free_principal(context, creds->server); + creds->server = tmp_principal; + tmp_principal = NULL; + } else { + tmp = krb5_principal_compare (context, tmp_principal, + creds->server); + krb5_free_principal (context, tmp_principal); + if (!tmp) { + ret = KRB5KRB_AP_ERR_MODIFIED; + krb5_clear_error_string (context); + goto out; + } + } + + /* decrypt */ - ret = _krb5_principalname2krb5_principal (context, - &tmp_principal, - rep->enc_part.sname, - rep->enc_part.srealm); + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + + ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); if (ret) goto out; - /* - * see if the service principal matches in the ticket - * and in the enc_part - */ - tmp = krb5_principal_compare (context, tmp_principal, srv_principal); - krb5_free_principal (context, tmp_principal); - if (!tmp) { - ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_clear_error_string (context); - goto out; - } + /* verify names */ + if(flags & EXTRACT_TICKET_MATCH_REALM){ + const char *srealm = krb5_principal_get_realm(context, creds->server); + const char *crealm = krb5_principal_get_realm(context, creds->client); - if(allow_server_mismatch){ - krb5_free_principal(context, creds->server); - creds->server = srv_principal; - srv_principal = NULL; - }else{ - tmp = krb5_principal_compare (context, srv_principal, creds->server); - if (!tmp) { + if (strcmp(rep->enc_part.srealm, srealm) != 0 || + strcmp(rep->enc_part.srealm, crealm) != 0) + { ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_clear_error_string (context); + krb5_clear_error_string(context); goto out; } } @@ -329,8 +317,6 @@ ignore_cname = 1; out: memset (rep->enc_part.key.keyvalue.data, 0, rep->enc_part.key.keyvalue.length); - if (srv_principal) - krb5_free_principal (context, srv_principal); return ret; } @@ -792,18 +778,23 @@ krb5_get_in_cred(krb5_context context, if (ret) goto out; - ret = _krb5_extract_ticket(context, - &rep, - creds, - key, - keyseed, - KRB5_KU_AS_REP_ENC_PART, - NULL, - nonce, - FALSE, - opts.request_anonymous, - decrypt_proc, - decryptarg); + { + unsigned flags = 0; + if (opts.request_anonymous) + flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + + ret = _krb5_extract_ticket(context, + &rep, + creds, + key, + keyseed, + KRB5_KU_AS_REP_ENC_PART, + NULL, + nonce, + flags, + decrypt_proc, + decryptarg); + } memset (key->keyvalue.data, 0, key->keyvalue.length); krb5_free_keyblock_contents (context, key); free (key); diff --git a/source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c b/source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c index 69da6c5ea7..52f95c4bc4 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c +++ b/source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_in_tkt_with_keytab.c,v 1.9 2005/06/17 04:56:44 lha Exp $"); +RCSID("$Id: get_in_tkt_with_keytab.c 15477 2005-06-17 04:56:44Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_keytab_key_proc (krb5_context context, diff --git a/source4/heimdal/lib/krb5/get_port.c b/source4/heimdal/lib/krb5/get_port.c index ba76466e06..85587ea766 100644 --- a/source4/heimdal/lib/krb5/get_port.c +++ b/source4/heimdal/lib/krb5/get_port.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_port.c,v 1.9 2004/05/25 21:29:59 lha Exp $"); +RCSID("$Id: get_port.c 13863 2004-05-25 21:46:46Z lha $"); int KRB5_LIB_FUNCTION krb5_getportbyname (krb5_context context, diff --git a/source4/heimdal/lib/krb5/heim_err.et b/source4/heimdal/lib/krb5/heim_err.et index 3c4f06edb1..1b8ab49bc1 100644 --- a/source4/heimdal/lib/krb5/heim_err.et +++ b/source4/heimdal/lib/krb5/heim_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: heim_err.et,v 1.13 2004/02/13 16:23:40 lha Exp $" +id "$Id: heim_err.et 13352 2004-02-13 16:23:40Z lha $" error_table heim diff --git a/source4/heimdal/lib/krb5/heim_threads.h b/source4/heimdal/lib/krb5/heim_threads.h index 3ebe66beee..3c27d13d81 100755 --- a/source4/heimdal/lib/krb5/heim_threads.h +++ b/source4/heimdal/lib/krb5/heim_threads.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: heim_threads.h,v 1.11 2004/12/18 16:03:38 lha Exp $ */ +/* $Id: heim_threads.h 14409 2004-12-18 16:03:38Z lha $ */ /* * Provide wrapper macros for thread synchronization primitives so we diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c index a331524a7e..5bdf23d97f 100644 --- a/source4/heimdal/lib/krb5/init_creds.c +++ b/source4/heimdal/lib/krb5/init_creds.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds.c,v 1.30 2006/11/23 16:27:36 lha Exp $"); +RCSID("$Id: init_creds.c 20541 2007-04-23 12:19:14Z lha $"); void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) @@ -386,7 +386,7 @@ krb5_get_init_creds_opt_get_error(krb5_context context, return ENOMEM; } - ret = copy_KRB_ERROR(*error, opt->opt_private->error); + ret = copy_KRB_ERROR(opt->opt_private->error, *error); if (ret) krb5_clear_error_string(context); @@ -408,3 +408,36 @@ krb5_get_init_creds_opt_set_addressless(krb5_context context, opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_FALSE; return 0; } + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_canonicalize(krb5_context context, + krb5_get_init_creds_opt *opt, + krb5_boolean req) +{ + krb5_error_code ret; + ret = require_ext_opt(context, opt, "init_creds_opt_set_canonicalize"); + if (ret) + return ret; + if (req) + opt->opt_private->flags |= KRB5_INIT_CREDS_CANONICALIZE; + else + opt->opt_private->flags &= ~KRB5_INIT_CREDS_CANONICALIZE; + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_win2k(krb5_context context, + krb5_get_init_creds_opt *opt, + krb5_boolean req) +{ + krb5_error_code ret; + ret = require_ext_opt(context, opt, "init_creds_opt_set_win2k"); + if (ret) + return ret; + if (req) + opt->opt_private->flags |= KRB5_INIT_CREDS_NO_C_CANON_CHECK; + else + opt->opt_private->flags &= ~KRB5_INIT_CREDS_NO_C_CANON_CHECK; + return 0; +} + diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index f6f6eac7d5..a58435a9ea 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds_pw.c,v 1.105 2007/01/09 10:44:59 lha Exp $"); +RCSID("$Id: init_creds_pw.c 20262 2007-02-18 00:33:01Z lha $"); typedef struct krb5_get_init_creds_ctx { KDCOptions flags; @@ -55,6 +55,7 @@ typedef struct krb5_get_init_creds_ctx { krb5_get_init_creds_tristate req_pac; krb5_pk_init_ctx pk_init_ctx; + int ic_flags; } krb5_get_init_creds_ctx; static krb5_error_code @@ -285,12 +286,16 @@ get_init_creds_common(krb5_context context, ctx->key_proc = options->opt_private->key_proc; ctx->req_pac = options->opt_private->req_pac; ctx->pk_init_ctx = options->opt_private->pk_init_ctx; + ctx->ic_flags = options->opt_private->flags; } else ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET; if (ctx->key_proc == NULL) ctx->key_proc = default_s2k_func; + if (ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) + ctx->flags.canonicalize = 1; + ctx->pre_auth_types = NULL; ctx->addrs = NULL; ctx->etypes = NULL; @@ -834,6 +839,8 @@ static PA_DATA * find_pa_data(const METHOD_DATA *md, int type) { int i; + if (md == NULL) + return NULL; for (i = 0; i < md->len; i++) if (md->val[i].padata_type == type) return &md->val[i]; @@ -1347,6 +1354,15 @@ init_cred_loop(krb5_context context, { krb5_keyblock *key = NULL; + unsigned flags = 0; + + if (ctx->flags.request_anonymous) + flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + if (ctx->flags.canonicalize) { + flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; + flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + flags |= EXTRACT_TICKET_MATCH_REALM; + } ret = process_pa_data_to_key(context, ctx, creds, &ctx->as_req, &rep, hi, &key); @@ -1361,12 +1377,65 @@ init_cred_loop(krb5_context context, KRB5_KU_AS_REP_ENC_PART, NULL, ctx->nonce, - FALSE, - ctx->flags.request_anonymous, + flags, NULL, NULL); krb5_free_keyblock(context, key); } + /* + * Verify referral data + */ + if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) && + (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) == 0) + { + PA_ClientCanonicalized canon; + krb5_crypto crypto; + krb5_data data; + PA_DATA *pa; + size_t len; + + pa = find_pa_data(rep.kdc_rep.padata, KRB5_PADATA_CLIENT_CANONICALIZED); + if (pa == NULL) { + ret = EINVAL; + krb5_set_error_string(context, "Client canonicalizion not signed"); + goto out; + } + + ret = decode_PA_ClientCanonicalized(pa->padata_value.data, + pa->padata_value.length, + &canon, &len); + if (ret) { + krb5_set_error_string(context, "Failed to decode " + "PA_ClientCanonicalized"); + goto out; + } + + ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, + &canon.names, &len, ret); + if (ret) + goto out; + if (data.length != len) + krb5_abortx(context, "internal asn.1 error"); + + ret = krb5_crypto_init(context, &creds->session, 0, &crypto); + if (ret) { + free(data.data); + free_PA_ClientCanonicalized(&canon); + goto out; + } + + ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES, + data.data, data.length, + &canon.canon_checksum); + krb5_crypto_destroy(context, crypto); + free(data.data); + free_PA_ClientCanonicalized(&canon); + if (ret) { + krb5_set_error_string(context, "Failed to verify " + "client canonicalized data"); + goto out; + } + } out: krb5_data_free(&ctx->req_buffer); free_METHOD_DATA(&md); diff --git a/source4/heimdal/lib/krb5/k524_err.et b/source4/heimdal/lib/krb5/k524_err.et index 2dc60f46ae..0ca25f74d4 100644 --- a/source4/heimdal/lib/krb5/k524_err.et +++ b/source4/heimdal/lib/krb5/k524_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: k524_err.et,v 1.1 2001/06/20 02:44:11 joda Exp $" +id "$Id: k524_err.et 10141 2001-06-20 02:45:58Z joda $" error_table k524 diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index 8f2d9f7f86..c945a9ce13 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -43,7 +43,7 @@ #include "kcm.h" -RCSID("$Id: kcm.c,v 1.9 2006/05/05 09:28:48 lha Exp $"); +RCSID("$Id: kcm.c 17442 2006-05-05 09:31:15Z lha $"); typedef struct krb5_kcmcache { char *name; diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index 314d97978b..ff4f972e57 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keyblock.c,v 1.17 2005/05/18 04:21:31 lha Exp $"); +RCSID("$Id: keyblock.c 15167 2005-05-18 04:21:57Z lha $"); void KRB5_LIB_FUNCTION krb5_keyblock_zero(krb5_keyblock *keyblock) diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index 43fc21c1d1..f6c7858c12 100644 --- a/source4/heimdal/lib/krb5/keytab.c +++ b/source4/heimdal/lib/krb5/keytab.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab.c,v 1.63 2005/11/25 21:46:40 lha Exp $"); +RCSID("$Id: keytab.c 20211 2007-02-09 07:11:03Z lha $"); /* * Register a new keytab in `ops' @@ -364,11 +364,11 @@ krb5_kt_get_entry(krb5_context context, if (entry->vno) { return 0; } else { - char princ[256], kt_name[256], kvno_str[25]; + char princ[256], kvno_str[25], *kt_name; char *enctype_str = NULL; krb5_unparse_name_fixed (context, principal, princ, sizeof(princ)); - krb5_kt_get_name (context, id, kt_name, sizeof(kt_name)); + krb5_kt_get_full_name (context, id, &kt_name); krb5_enctype_to_string(context, enctype, &enctype_str); if (kvno) @@ -377,11 +377,12 @@ krb5_kt_get_entry(krb5_context context, kvno_str[0] = '\0'; krb5_set_error_string (context, - "failed to find %s%s in keytab %s (%s)", + "Failed to find %s%s in keytab %s (%s)", princ, kvno_str, - kt_name, + kt_name ? kt_name : "unknown keytab", enctype_str ? enctype_str : "unknown enctype"); + free(kt_name); free(enctype_str); return KRB5_KT_NOTFOUND; } diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c index d5130aaad8..54272d4845 100644 --- a/source4/heimdal/lib/krb5/keytab_any.c +++ b/source4/heimdal/lib/krb5/keytab_any.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_any.c,v 1.8 2006/04/10 09:20:13 lha Exp $"); +RCSID("$Id: keytab_any.c 17035 2006-04-10 09:20:13Z lha $"); struct any_data { krb5_keytab kt; diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index 1b06387339..4ada3a463e 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_file.c,v 1.23 2006/05/05 12:36:57 lha Exp $"); +RCSID("$Id: keytab_file.c 17457 2006-05-05 12:36:57Z lha $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c index d7f8a720e1..77455ba5f7 100644 --- a/source4/heimdal/lib/krb5/keytab_keyfile.c +++ b/source4/heimdal/lib/krb5/keytab_keyfile.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002, 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_keyfile.c,v 1.19 2006/04/24 15:06:57 lha Exp $"); +RCSID("$Id: keytab_keyfile.c 20695 2007-05-30 14:09:09Z lha $"); /* afs keyfile operations --------------------------------------- */ @@ -350,7 +350,7 @@ akf_add_entry(krb5_context context, for (i = 0; i < len; i++) { ret = krb5_ret_int32(sp, &kvno); if (ret) { - krb5_set_error_string (context, "Failed got get kvno "); + krb5_set_error_string (context, "Failed to get kvno "); goto out; } if(krb5_storage_seek(sp, 8, SEEK_CUR) < 0) { diff --git a/source4/heimdal/lib/krb5/keytab_krb4.c b/source4/heimdal/lib/krb5/keytab_krb4.c index 19e7f106bf..907836c144 100644 --- a/source4/heimdal/lib/krb5/keytab_krb4.c +++ b/source4/heimdal/lib/krb5/keytab_krb4.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_krb4.c,v 1.15 2006/04/10 17:10:53 lha Exp $"); +RCSID("$Id: keytab_krb4.c 17046 2006-04-10 17:10:53Z lha $"); struct krb4_kt_data { char *filename; diff --git a/source4/heimdal/lib/krb5/keytab_memory.c b/source4/heimdal/lib/krb5/keytab_memory.c index fa54ff43ce..0ad8720c3f 100644 --- a/source4/heimdal/lib/krb5/keytab_memory.c +++ b/source4/heimdal/lib/krb5/keytab_memory.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_memory.c,v 1.8 2005/12/05 18:39:46 lha Exp $"); +RCSID("$Id: keytab_memory.c 16352 2005-12-05 18:39:46Z lha $"); /* memory operations -------------------------------------------- */ diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index c3e5732753..be718f6714 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -4,14 +4,6 @@ #include <stdarg.h> -#ifndef KRB5_LIB_FUNCTION -#if defined(_WIN32) -#define KRB5_LIB_FUNCTION _stdcall -#else -#define KRB5_LIB_FUNCTION -#endif -#endif - void KRB5_LIB_FUNCTION _krb5_aes_cts_encrypt ( const unsigned char */*in*/, @@ -68,8 +60,7 @@ _krb5_extract_ticket ( krb5_key_usage /*key_usage*/, krb5_addresses */*addrs*/, unsigned /*nonce*/, - krb5_boolean /*allow_server_mismatch*/, - krb5_boolean /*ignore_cname*/, + unsigned /*flags*/, krb5_decrypt_proc /*decrypt_proc*/, krb5_const_pointer /*decryptarg*/); diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 9dfe487b0a..e852bffeb1 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -521,6 +521,19 @@ krb5_c_make_random_key ( krb5_keyblock */*random_key*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_c_prf ( + krb5_context /*context*/, + const krb5_keyblock */*key*/, + const krb5_data */*input*/, + krb5_data */*output*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_c_prf_length ( + krb5_context /*context*/, + krb5_enctype /*type*/, + size_t */*length*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_c_set_checksum ( krb5_context /*context*/, krb5_checksum */*cksum*/, @@ -1103,11 +1116,34 @@ krb5_crypto_init ( krb5_enctype /*etype*/, krb5_crypto */*crypto*/); +size_t +krb5_crypto_overhead ( + krb5_context /*context*/, + krb5_crypto /*crypto*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_prf ( + krb5_context /*context*/, + const krb5_crypto /*crypto*/, + const krb5_data */*input*/, + krb5_data */*output*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_prf_length ( + krb5_context /*context*/, + krb5_enctype /*type*/, + size_t */*length*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_data_alloc ( krb5_data */*p*/, int /*len*/); +int KRB5_LIB_FUNCTION +krb5_data_cmp ( + const krb5_data */*data1*/, + const krb5_data */*data2*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_data_copy ( krb5_data */*p*/, @@ -1248,12 +1284,6 @@ void krb5_digest_free (krb5_digest /*digest*/); krb5_error_code -krb5_digest_get_a1_hash ( - krb5_context /*context*/, - krb5_digest /*digest*/, - krb5_data */*data*/); - -krb5_error_code krb5_digest_get_client_binding ( krb5_context /*context*/, krb5_digest /*digest*/, @@ -1271,11 +1301,6 @@ krb5_digest_get_opaque ( krb5_digest /*digest*/); const char * -krb5_digest_get_responseData ( - krb5_context /*context*/, - krb5_digest /*digest*/); - -const char * krb5_digest_get_rsp ( krb5_context /*context*/, krb5_digest /*digest*/); @@ -1286,6 +1311,12 @@ krb5_digest_get_server_nonce ( krb5_digest /*digest*/); krb5_error_code +krb5_digest_get_session_key ( + krb5_context /*context*/, + krb5_digest /*digest*/, + krb5_data */*data*/); + +krb5_error_code krb5_digest_get_tickets ( krb5_context /*context*/, krb5_digest /*digest*/, @@ -1298,6 +1329,11 @@ krb5_digest_init_request ( krb5_realm /*realm*/, krb5_ccache /*ccache*/); +krb5_boolean +krb5_digest_rep_get_status ( + krb5_context /*context*/, + krb5_digest /*digest*/); + krb5_error_code krb5_digest_request ( krb5_context /*context*/, @@ -1371,6 +1407,12 @@ krb5_digest_set_realm ( krb5_digest /*digest*/, const char */*realm*/); +int +krb5_digest_set_responseData ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*response*/); + krb5_error_code krb5_digest_set_server_cb ( krb5_context /*context*/, @@ -2057,6 +2099,12 @@ krb5_get_init_creds_opt_set_anonymous ( krb5_get_init_creds_opt */*opt*/, int /*anonymous*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_canonicalize ( + krb5_context /*context*/, + krb5_get_init_creds_opt */*opt*/, + krb5_boolean /*req*/); + void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_set_default_flags ( krb5_context /*context*/, @@ -2129,6 +2177,12 @@ krb5_get_init_creds_opt_set_tkt_life ( krb5_deltat /*tkt_life*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_win2k ( + krb5_context /*context*/, + krb5_get_init_creds_opt */*opt*/, + krb5_boolean /*req*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_get_init_creds_password ( krb5_context /*context*/, krb5_creds */*creds*/, diff --git a/source4/heimdal/lib/krb5/krb5-v4compat.h b/source4/heimdal/lib/krb5/krb5-v4compat.h index 3e14c5a38f..2ea534cfe3 100644 --- a/source4/heimdal/lib/krb5/krb5-v4compat.h +++ b/source4/heimdal/lib/krb5/krb5-v4compat.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5-v4compat.h,v 1.7 2006/05/05 09:29:07 lha Exp $ */ +/* $Id: krb5-v4compat.h 17442 2006-05-05 09:31:15Z lha $ */ #ifndef __KRB5_V4COMPAT_H__ #define __KRB5_V4COMPAT_H__ diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 55a83fb533..eefda81ca9 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h,v 1.259 2007/01/03 18:51:52 lha Exp $ */ +/* $Id: krb5.h 20245 2007-02-17 00:09:57Z lha $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -222,8 +222,10 @@ typedef enum krb5_key_usage { /* Encryption key usage used in the digest encryption field */ KRB5_KU_DIGEST_OPAQUE = -19, /* Checksum key usage used in the digest opaque field */ - KRB5_KU_KRB5SIGNEDPATH = -21 + KRB5_KU_KRB5SIGNEDPATH = -21, /* Checksum key usage on KRB5SignedPath */ + KRB5_KU_CANONICALIZED_NAMES = -23 + /* Checksum key usage on PA-CANONICALIZED */ } krb5_key_usage; typedef krb5_key_usage krb5_keyusage; @@ -744,7 +746,8 @@ typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, /* flags for krb5_parse_name_flags */ enum { KRB5_PRINCIPAL_PARSE_NO_REALM = 1, - KRB5_PRINCIPAL_PARSE_MUST_REALM = 2 + KRB5_PRINCIPAL_PARSE_MUST_REALM = 2, + KRB5_PRINCIPAL_PARSE_ENTERPRISE = 4 }; /* flags for krb5_unparse_name_flags */ diff --git a/source4/heimdal/lib/krb5/krb5_ccapi.h b/source4/heimdal/lib/krb5/krb5_ccapi.h index d59b589304..b53d77ef18 100644 --- a/source4/heimdal/lib/krb5/krb5_ccapi.h +++ b/source4/heimdal/lib/krb5/krb5_ccapi.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_ccapi.h,v 1.3 2006/05/05 09:29:59 lha Exp $ */ +/* $Id: krb5_ccapi.h 17442 2006-05-05 09:31:15Z lha $ */ #ifndef KRB5_CCAPI_H #define KRB5_CCAPI_H 1 diff --git a/source4/heimdal/lib/krb5/krb5_err.et b/source4/heimdal/lib/krb5/krb5_err.et index e7bada1808..785c258ee0 100644 --- a/source4/heimdal/lib/krb5/krb5_err.et +++ b/source4/heimdal/lib/krb5/krb5_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $" +id "$Id: krb5_err.et 20760 2007-06-01 03:24:49Z lha $" error_table krb5 @@ -76,6 +76,10 @@ error_code KDC_NOT_TRUSTED, "KDC not trusted" error_code INVALID_SIG, "Invalid signature" error_code DH_KEY_PARAMETERS_NOT_ACCEPTED, "DH parameters not accepted" +index 68 +prefix KRB5_KDC_ERR +error_code WRONG_REALM, "Wrong realm" + index 69 prefix KRB5_AP_ERR error_code USER_TO_USER_REQUIRED, "User to user required" @@ -86,7 +90,8 @@ error_code CANT_VERIFY_CERTIFICATE, "Cannot verify certificate" error_code INVALID_CERTIFICATE, "Certificate invalid" error_code REVOKED_CERTIFICATE, "Certificate revoked" error_code REVOCATION_STATUS_UNKNOWN, "Revocation status unknown" -error_code CLIENT_NAME_MISMATCH, "Revocation status unknown" +error_code REVOCATION_STATUS_UNAVAILABLE, "Revocation status unavaible" +error_code CLIENT_NAME_MISMATCH, "Client name mismatch in certificate" error_code INCONSISTENT_KEY_PURPOSE, "Inconsistent key purpose" error_code DIGEST_IN_CERT_NOT_ACCEPTED, "Digest in certificate not accepted" error_code PA_CHECKSUM_MUST_BE_INCLUDED, "paChecksum must be included" @@ -103,7 +108,7 @@ error_code PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not suppo index 128 prefix -error_code KRB5_ERR_RCSID, "$Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $" +error_code KRB5_ERR_RCSID, "$Id: krb5_err.et 20760 2007-06-01 03:24:49Z lha $" error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode" error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password" diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 35d046c8d9..87169fc430 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_locl.h,v 1.97 2006/12/15 16:46:51 lha Exp $ */ +/* $Id: krb5_locl.h 20261 2007-02-18 00:32:22Z lha $ */ #ifndef __KRB5_LOCL_H__ #define __KRB5_LOCL_H__ @@ -196,9 +196,11 @@ struct _krb5_get_init_creds_opt_private { krb5_get_init_creds_tristate req_pac; /* PKINIT */ krb5_pk_init_ctx pk_init_ctx; - int canonicalize; KRB_ERROR *error; krb5_get_init_creds_tristate addressless; + int flags; +#define KRB5_INIT_CREDS_CANONICALIZE 1 +#define KRB5_INIT_CREDS_NO_C_CANON_CHECK 2 }; typedef struct krb5_context_data { @@ -244,6 +246,10 @@ typedef struct krb5_context_data { #define KRB5_DEFAULT_CCNAME_FILE "FILE:/tmp/krb5cc_%{uid}" #define KRB5_DEFAULT_CCNAME_API "API:" +#define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH 1 +#define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH 2 +#define EXTRACT_TICKET_MATCH_REALM 4 + /* * Configurable options */ diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index 3e281e5c63..51bf934bfd 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -35,7 +35,7 @@ #include <resolve.h> #include "locate_plugin.h" -RCSID("$Id: krbhst.c,v 1.61 2006/11/30 17:23:08 lha Exp $"); +RCSID("$Id: krbhst.c 19198 2006-11-30 17:23:08Z lha $"); static int string_to_proto(const char *string) diff --git a/source4/heimdal/lib/krb5/locate_plugin.h b/source4/heimdal/lib/krb5/locate_plugin.h index ec06d362cf..251712c894 100644 --- a/source4/heimdal/lib/krb5/locate_plugin.h +++ b/source4/heimdal/lib/krb5/locate_plugin.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: locate_plugin.h,v 1.1 2006/11/12 19:00:03 lha Exp $ */ +/* $Id: locate_plugin.h 18998 2006-11-12 19:00:03Z lha $ */ #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1 diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index 9523ca848c..c04f50fd9a 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: log.c,v 1.40 2006/11/21 08:08:46 lha Exp $"); +RCSID("$Id: log.c 19088 2006-11-21 08:08:46Z lha $"); struct facility { int min; diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c index 9588d936d5..ff9261a7db 100644 --- a/source4/heimdal/lib/krb5/mcache.c +++ b/source4/heimdal/lib/krb5/mcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: mcache.c,v 1.20 2005/09/30 11:16:04 lha Exp $"); +RCSID("$Id: mcache.c 19834 2007-01-11 09:26:21Z lha $"); typedef struct krb5_mcache { char *name; @@ -54,8 +54,6 @@ static struct krb5_mcache *mcc_head; #define MISDEAD(X) ((X)->dead) -#define MCC_CURSOR(C) ((struct link*)(C)) - static const char* mcc_get_name(krb5_context context, krb5_ccache id) diff --git a/source4/heimdal/lib/krb5/misc.c b/source4/heimdal/lib/krb5/misc.c index f04f8d9996..0d410b57d2 100644 --- a/source4/heimdal/lib/krb5/misc.c +++ b/source4/heimdal/lib/krb5/misc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: misc.c,v 1.6 2006/06/06 14:57:47 lha Exp $"); +RCSID("$Id: misc.c 17616 2006-06-06 14:57:47Z lha $"); krb5_error_code KRB5_LIB_FUNCTION _krb5_s4u2self_to_checksumdata(krb5_context context, diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c index c4d3ff5390..7440d54762 100755 --- a/source4/heimdal/lib/krb5/mit_glue.c +++ b/source4/heimdal/lib/krb5/mit_glue.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: mit_glue.c,v 1.12 2006/11/17 22:17:46 lha Exp $"); +RCSID("$Id: mit_glue.c 20042 2007-01-23 20:37:43Z lha $"); /* * Glue for MIT API @@ -340,3 +340,30 @@ krb5_c_keylengths(krb5_context context, *ilen = (*ilen + 7) / 8; return krb5_enctype_keysize(context, enctype, keylen); } + +krb5_error_code KRB5_LIB_FUNCTION +krb5_c_prf_length(krb5_context context, + krb5_enctype type, + size_t *length) +{ + return krb5_crypto_prf_length(context, type, length); +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_c_prf(krb5_context context, + const krb5_keyblock *key, + const krb5_data *input, + krb5_data *output) +{ + krb5_crypto crypto; + krb5_error_code ret; + + ret = krb5_crypto_init(context, key, 0, &crypto); + if (ret) + return ret; + + ret = krb5_crypto_prf(context, crypto, input, output); + krb5_crypto_destroy(context, crypto); + + return ret; +} diff --git a/source4/heimdal/lib/krb5/mk_error.c b/source4/heimdal/lib/krb5/mk_error.c index 7a8b1ba06b..7046649934 100644 --- a/source4/heimdal/lib/krb5/mk_error.c +++ b/source4/heimdal/lib/krb5/mk_error.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: mk_error.c,v 1.22 2005/06/16 21:16:40 lha Exp $"); +RCSID("$Id: mk_error.c 15457 2005-06-16 21:16:40Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_mk_error(krb5_context context, diff --git a/source4/heimdal/lib/krb5/mk_priv.c b/source4/heimdal/lib/krb5/mk_priv.c index b5a1aadfea..87e429af8c 100644 --- a/source4/heimdal/lib/krb5/mk_priv.c +++ b/source4/heimdal/lib/krb5/mk_priv.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_priv.c,v 1.35 2006/02/01 12:39:26 lha Exp $"); +RCSID("$Id: mk_priv.c 16680 2006-02-01 12:39:26Z lha $"); krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/mk_rep.c b/source4/heimdal/lib/krb5/mk_rep.c index 90823f9478..570a837201 100644 --- a/source4/heimdal/lib/krb5/mk_rep.c +++ b/source4/heimdal/lib/krb5/mk_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_rep.c,v 1.26 2004/05/25 21:33:51 lha Exp $"); +RCSID("$Id: mk_rep.c 13863 2004-05-25 21:46:46Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_mk_rep(krb5_context context, diff --git a/source4/heimdal/lib/krb5/mk_req.c b/source4/heimdal/lib/krb5/mk_req.c index adc077e13f..5f64f01e95 100644 --- a/source4/heimdal/lib/krb5/mk_req.c +++ b/source4/heimdal/lib/krb5/mk_req.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_req.c,v 1.26 2004/05/25 21:34:11 lha Exp $"); +RCSID("$Id: mk_req.c 13863 2004-05-25 21:46:46Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_mk_req_exact(krb5_context context, diff --git a/source4/heimdal/lib/krb5/mk_req_ext.c b/source4/heimdal/lib/krb5/mk_req_ext.c index 8646c4ebea..b6d55c8815 100644 --- a/source4/heimdal/lib/krb5/mk_req_ext.c +++ b/source4/heimdal/lib/krb5/mk_req_ext.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_req_ext.c,v 1.33 2006/12/27 12:07:22 lha Exp $"); +RCSID("$Id: mk_req_ext.c 19511 2006-12-27 12:07:22Z lha $"); krb5_error_code _krb5_mk_req_internal(krb5_context context, diff --git a/source4/heimdal/lib/krb5/n-fold.c b/source4/heimdal/lib/krb5/n-fold.c index 691e95eb86..1474a76b77 100644 --- a/source4/heimdal/lib/krb5/n-fold.c +++ b/source4/heimdal/lib/krb5/n-fold.c @@ -32,7 +32,7 @@ #include "krb5_locl.h" -RCSID("$Id: n-fold.c,v 1.7 2004/05/25 21:35:31 lha Exp $"); +RCSID("$Id: n-fold.c 13863 2004-05-25 21:46:46Z lha $"); static void rr13(unsigned char *buf, size_t len) diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c index 283759c98b..55d4f5ff56 100644 --- a/source4/heimdal/lib/krb5/pac.c +++ b/source4/heimdal/lib/krb5/pac.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pac.c,v 1.13 2007/01/09 11:22:56 lha Exp $"); +RCSID("$Id: pac.c 20845 2007-06-03 14:31:16Z lha $"); struct PAC_INFO_BUFFER { uint32_t type; @@ -56,14 +56,15 @@ struct krb5_pac { struct PAC_INFO_BUFFER *logon_name; }; -#define PAC_ALIGNMENT 8 +#define PAC_ALIGNMENT 8 -#define PACTYPE_SIZE 8 -#define PAC_INFO_BUFFER_SIZE 16 +#define PACTYPE_SIZE 8 +#define PAC_INFO_BUFFER_SIZE 16 -#define PAC_SERVER_CHECKSUM 6 -#define PAC_PRIVSVR_CHECKSUM 7 -#define PAC_LOGON_NAME 10 +#define PAC_SERVER_CHECKSUM 6 +#define PAC_PRIVSVR_CHECKSUM 7 +#define PAC_LOGON_NAME 10 +#define PAC_CONSTRAINED_DELEGATION 11 #define CHECK(r,f,l) \ do { \ @@ -252,12 +253,10 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p, { krb5_error_code ret; void *ptr; - size_t len, offset, header_end; + size_t len, offset, header_end, old_end; uint32_t i; - len = p->pac->numbuffers + 1; - if (len < p->pac->numbuffers) - return EINVAL; + len = p->pac->numbuffers; ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len)); @@ -272,11 +271,12 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p, offset = p->data.length + PAC_INFO_BUFFER_SIZE; - p->pac->buffers[len - 1].type = type; - p->pac->buffers[len - 1].buffersize = data->length; - p->pac->buffers[len - 1].offset_lo = offset; - p->pac->buffers[len - 1].offset_hi = 0; + p->pac->buffers[len].type = type; + p->pac->buffers[len].buffersize = data->length; + p->pac->buffers[len].offset_lo = offset; + p->pac->buffers[len].offset_hi = 0; + old_end = p->data.length; len = p->data.length + data->length + PAC_INFO_BUFFER_SIZE; if (len < p->data.length) { krb5_set_error_string(context, "integer overrun"); @@ -292,14 +292,17 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p, return ret; } - /* make place for PAC INFO BUFFER header */ + /* + * make place for new PAC INFO BUFFER header + */ header_end = PACTYPE_SIZE + (PAC_INFO_BUFFER_SIZE * p->pac->numbuffers); - memmove((unsigned char *)p->data.data + header_end, - (unsigned char *)p->data.data + header_end + PAC_INFO_BUFFER_SIZE, - PAC_INFO_BUFFER_SIZE); + memmove((unsigned char *)p->data.data + header_end + PAC_INFO_BUFFER_SIZE, + (unsigned char *)p->data.data + header_end , + old_end - header_end); + memset((unsigned char *)p->data.data + header_end, 0, PAC_INFO_BUFFER_SIZE); /* - * + * copy in new data part */ memcpy((unsigned char *)p->data.data + offset, @@ -444,12 +447,15 @@ verify_checksum(krb5_context context, ret = krb5_verify_checksum(context, crypto, KRB5_KU_OTHER_CKSUM, ptr, len, &cksum); + free(cksum.checksum.data); krb5_crypto_destroy(context, crypto); krb5_storage_free(sp); return ret; out: + if (cksum.checksum.data) + free(cksum.checksum.data); if (sp) krb5_storage_free(sp); if (crypto) @@ -890,7 +896,6 @@ _krb5_pac_sign(krb5_context context, goto out; /* Set lengths for checksum */ - ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); if (ret) goto out; diff --git a/source4/heimdal/lib/krb5/padata.c b/source4/heimdal/lib/krb5/padata.c index d5c3f422a7..b2b70f52e7 100644 --- a/source4/heimdal/lib/krb5/padata.c +++ b/source4/heimdal/lib/krb5/padata.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: padata.c,v 1.5 2005/06/17 04:28:35 lha Exp $"); +RCSID("$Id: padata.c 15469 2005-06-17 04:28:35Z lha $"); PA_DATA * krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx) diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 4f8ed8fe07..dd82842084 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c,v 1.120 2006/12/08 02:48:09 lha Exp $"); +RCSID("$Id: pkinit.c 21004 2007-06-08 01:53:10Z lha $"); struct krb5_dh_moduli { char *name; @@ -83,10 +83,11 @@ struct krb5_pk_init_ctx_data { struct krb5_dh_moduli **m; hx509_peer_info peer; int type; - int require_binding; - int require_eku; - int require_krbtgt_otherName; - int require_hostname_match; + unsigned int require_binding:1; + unsigned int require_eku:1; + unsigned int require_krbtgt_otherName:1; + unsigned int require_hostname_match:1; + unsigned int trustedCertifiers:1; }; static void @@ -170,6 +171,7 @@ _krb5_pk_create_sign(krb5_context context, } ret = hx509_cms_create_signed_1(id->hx509ctx, + 0, eContentType, eContent->data, eContent->length, @@ -438,7 +440,6 @@ build_auth_pack(krb5_context context, return ret; } - return ret; } @@ -587,18 +588,21 @@ pk_mk_padata(krb5_context context, memset(&req, 0, sizeof(req)); req.signedAuthPack = buf; - req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers)); - if (req.trustedCertifiers == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - free_PA_PK_AS_REQ(&req); - goto out; - } - ret = build_edi(context, ctx->id->hx509ctx, - ctx->id->anchors, req.trustedCertifiers); - if (ret) { - krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers"); - free_PA_PK_AS_REQ(&req); - goto out; + if (ctx->trustedCertifiers) { + + req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers)); + if (req.trustedCertifiers == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + free_PA_PK_AS_REQ(&req); + goto out; + } + ret = build_edi(context, ctx->id->hx509ctx, + ctx->id->anchors, req.trustedCertifiers); + if (ret) { + krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers"); + free_PA_PK_AS_REQ(&req); + goto out; + } } req.kdcPkId = NULL; @@ -684,6 +688,14 @@ _krb5_pk_mk_padata(krb5_context context, "pkinit_require_hostname_match", NULL); + ctx->trustedCertifiers = + krb5_config_get_bool_default(context, NULL, + TRUE, + "realms", + req_body->realm, + "pkinit_trustedCertifiers", + NULL); + return pk_mk_padata(context, ctx, req_body, nonce, md); } @@ -705,6 +717,7 @@ _krb5_pk_verify_sign(krb5_context context, id->verify_ctx, data, length, + NULL, id->certpool, contentType, content, @@ -1120,8 +1133,11 @@ pk_rd_pa_reply_dh(krb5_context context, &kdc_dh_info, &size); - if (ret) + if (ret) { + krb5_set_error_string(context, "pkinit - " + "failed to decode KDC DH Key Info"); goto out; + } if (kdc_dh_info.nonce != nonce) { krb5_set_error_string(context, "PKINIT: DH nonce is wrong"); @@ -1226,6 +1242,7 @@ pk_rd_pa_reply_dh(krb5_context context, _krb5_pk_cert_free(host); if (content.data) krb5_data_free(&content); + der_free_oid(&contentType); free_KDCDHKeyInfo(&kdc_dh_info); return ret; @@ -1262,8 +1279,10 @@ _krb5_pk_rd_pa_reply(krb5_context context, pa->padata_value.length, &rep, &size); - if (ret) + if (ret) { + krb5_set_error_string(context, "Failed to decode pkinit AS rep"); return ret; + } switch (rep.element) { case choice_PA_PK_AS_REP_dhInfo: @@ -1861,6 +1880,7 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt) free(ctx->id); ctx->id = NULL; } + free(opt->opt_private->pk_init_ctx); opt->opt_private->pk_init_ctx = NULL; #endif } diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index ce7171dbf0..f19464bf3c 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: plugin.c,v 1.4 2007/01/09 17:46:01 lha Exp $"); +RCSID("$Id: plugin.c 19789 2007-01-09 17:46:01Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 57fcf63dcf..ef3f5412db 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -41,7 +41,7 @@ #include <fnmatch.h> #include "resolve.h" -RCSID("$Id: principal.c,v 1.100 2006/12/17 22:53:39 lha Exp $"); +RCSID("$Id: principal.c 20223 2007-02-15 04:17:04Z lha $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -110,6 +110,8 @@ krb5_parse_name_flags(krb5_context context, int n; char c; int got_realm = 0; + int first_at = 1; + int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE); *principal = NULL; @@ -122,18 +124,24 @@ krb5_parse_name_flags(krb5_context context, } #undef RFLAGS - /* count number of component */ + /* count number of component, + * enterprise names only have one component + */ ncomp = 1; - for(p = name; *p; p++){ - if(*p=='\\'){ - if(!p[1]) { - krb5_set_error_string (context, - "trailing \\ in principal name"); - return KRB5_PARSE_MALFORMED; - } - p++; - } else if(*p == '/') - ncomp++; + if (!enterprise) { + for(p = name; *p; p++){ + if(*p=='\\'){ + if(!p[1]) { + krb5_set_error_string (context, + "trailing \\ in principal name"); + return KRB5_PARSE_MALFORMED; + } + p++; + } else if(*p == '/') + ncomp++; + else if(*p == '@') + break; + } } comp = calloc(ncomp, sizeof(*comp)); if (comp == NULL) { @@ -166,7 +174,10 @@ krb5_parse_name_flags(krb5_context context, ret = KRB5_PARSE_MALFORMED; goto exit; } - }else if(c == '/' || c == '@'){ + }else if(enterprise && first_at) { + if (c == '@') + first_at = 0; + }else if((c == '/' && !enterprise) || c == '@'){ if(got_realm){ krb5_set_error_string (context, "part after realm in principal name"); @@ -241,7 +252,10 @@ krb5_parse_name_flags(krb5_context context, ret = ENOMEM; goto exit; } - (*principal)->name.name_type = KRB5_NT_PRINCIPAL; + if (enterprise) + (*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL; + else + (*principal)->name.name_type = KRB5_NT_PRINCIPAL; (*principal)->name.name_string.val = comp; princ_num_comp(*principal) = n; (*principal)->realm = realm; diff --git a/source4/heimdal/lib/krb5/prompter_posix.c b/source4/heimdal/lib/krb5/prompter_posix.c index 3ea512c9a7..e0f407fb24 100644 --- a/source4/heimdal/lib/krb5/prompter_posix.c +++ b/source4/heimdal/lib/krb5/prompter_posix.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: prompter_posix.c,v 1.10 2004/05/25 21:38:14 lha Exp $"); +RCSID("$Id: prompter_posix.c 13863 2004-05-25 21:46:46Z lha $"); int KRB5_LIB_FUNCTION krb5_prompter_posix (krb5_context context, diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c index 46a36c9aac..c3f732201f 100644 --- a/source4/heimdal/lib/krb5/rd_cred.c +++ b/source4/heimdal/lib/krb5/rd_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_cred.c,v 1.29 2006/10/06 17:04:47 lha Exp $"); +RCSID("$Id: rd_cred.c 20304 2007-04-11 11:15:05Z lha $"); static krb5_error_code compare_addrs(krb5_context context, @@ -79,8 +79,10 @@ krb5_rd_cred(krb5_context context, ret = decode_KRB_CRED(in_data->data, in_data->length, &cred, &len); - if(ret) + if(ret) { + krb5_clear_error_string(context); return ret; + } if (cred.pvno != 5) { ret = KRB5KRB_AP_ERR_BADVERSION; @@ -151,6 +153,8 @@ krb5_rd_cred(krb5_context context, enc_krb_cred_part_data.length, &enc_krb_cred_part, &len); + if (enc_krb_cred_part_data.data != cred.enc_part.cipher.data) + krb5_data_free(&enc_krb_cred_part_data); if (ret) goto out; diff --git a/source4/heimdal/lib/krb5/rd_error.c b/source4/heimdal/lib/krb5/rd_error.c index 93e70c48bd..89615ee8ac 100644 --- a/source4/heimdal/lib/krb5/rd_error.c +++ b/source4/heimdal/lib/krb5/rd_error.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: rd_error.c,v 1.8 2005/05/18 04:21:57 lha Exp $"); +RCSID("$Id: rd_error.c 20304 2007-04-11 11:15:05Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_error(krb5_context context, @@ -45,8 +45,10 @@ krb5_rd_error(krb5_context context, krb5_error_code ret; ret = decode_KRB_ERROR(msg->data, msg->length, result, &len); - if(ret) + if(ret) { + krb5_clear_error_string(context); return ret; + } result->error_code += KRB5KDC_ERR_NONE; return 0; } diff --git a/source4/heimdal/lib/krb5/rd_priv.c b/source4/heimdal/lib/krb5/rd_priv.c index c52ac175fd..d3920dd941 100644 --- a/source4/heimdal/lib/krb5/rd_priv.c +++ b/source4/heimdal/lib/krb5/rd_priv.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_priv.c,v 1.33 2006/04/12 16:18:10 lha Exp $"); +RCSID("$Id: rd_priv.c 17056 2006-04-12 16:18:10Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_priv(krb5_context context, diff --git a/source4/heimdal/lib/krb5/rd_rep.c b/source4/heimdal/lib/krb5/rd_rep.c index 6b7f27c3cf..8c9b7bb441 100644 --- a/source4/heimdal/lib/krb5/rd_rep.c +++ b/source4/heimdal/lib/krb5/rd_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_rep.c,v 1.26 2006/08/21 09:19:22 lha Exp $"); +RCSID("$Id: rd_rep.c 17890 2006-08-21 09:19:22Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_rep(krb5_context context, diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index b7dea2a327..001b47f094 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001, 2003 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_req.c,v 1.70 2007/01/04 11:27:20 lha Exp $"); +RCSID("$Id: rd_req.c 21004 2007-06-08 01:53:10Z lha $"); static krb5_error_code decrypt_tkt_enc_part (krb5_context context, @@ -208,6 +208,8 @@ find_etypelist(krb5_context context, adIfRelevant.val[0].ad_data.length, etypes, NULL); + if (ret) + krb5_clear_error_string(context); free_AD_IF_RELEVANT(&adIfRelevant); diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c index b89f150159..12894d96a9 100644 --- a/source4/heimdal/lib/krb5/replay.c +++ b/source4/heimdal/lib/krb5/replay.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <vis.h> -RCSID("$Id: replay.c,v 1.12 2006/04/10 17:13:49 lha Exp $"); +RCSID("$Id: replay.c 17047 2006-04-10 17:13:49Z lha $"); struct krb5_rcache_data { char *name; diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index 11c07c9e8f..6c70244327 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: send_to_kdc.c,v 1.60 2006/10/20 18:42:01 lha Exp $"); +RCSID("$Id: send_to_kdc.c 19973 2007-01-17 17:19:52Z lha $"); struct send_to_kdc { krb5_send_to_kdc_func func; @@ -331,6 +331,8 @@ krb5_sendto (krb5_context context, int fd; int i; + krb5_data_zero(receive); + for (i = 0; i < context->max_retries; ++i) { krb5_krbhst_info *hi; diff --git a/source4/heimdal/lib/krb5/set_default_realm.c b/source4/heimdal/lib/krb5/set_default_realm.c index 965883309c..98040bc2e9 100644 --- a/source4/heimdal/lib/krb5/set_default_realm.c +++ b/source4/heimdal/lib/krb5/set_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: set_default_realm.c,v 1.14 2004/05/25 21:42:26 lha Exp $"); +RCSID("$Id: set_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); /* * Convert the simple string `s' into a NULL-terminated and freshly allocated diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c index 5422c540b9..4abcf44a43 100644 --- a/source4/heimdal/lib/krb5/store.c +++ b/source4/heimdal/lib/krb5/store.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store.c,v 1.60 2006/12/17 22:49:37 lha Exp $"); +RCSID("$Id: store.c 20529 2007-04-22 14:28:19Z lha $"); #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) @@ -891,7 +891,7 @@ krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) header |= SC_CLIENT_PRINCIPAL; if (creds->server) header |= SC_SERVER_PRINCIPAL; - if (creds->session.keyvalue.data) + if (creds->session.keytype != ETYPE_NULL) header |= SC_SESSION_KEY; if (creds->ticket.data) header |= SC_TICKET; @@ -916,7 +916,7 @@ krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) return ret; } - if (creds->session.keyvalue.data) { + if (creds->session.keytype != ETYPE_NULL) { ret = krb5_store_keyblock(sp, creds->session); if(ret) return ret; diff --git a/source4/heimdal/lib/krb5/store_emem.c b/source4/heimdal/lib/krb5/store_emem.c index b9f93728de..07acdd1a00 100644 --- a/source4/heimdal/lib/krb5/store_emem.c +++ b/source4/heimdal/lib/krb5/store_emem.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store_emem.c,v 1.14 2004/05/25 21:43:29 lha Exp $"); +RCSID("$Id: store_emem.c 13863 2004-05-25 21:46:46Z lha $"); typedef struct emem_storage{ unsigned char *base; diff --git a/source4/heimdal/lib/krb5/store_fd.c b/source4/heimdal/lib/krb5/store_fd.c index 835d3478e2..15f86fcac3 100644 --- a/source4/heimdal/lib/krb5/store_fd.c +++ b/source4/heimdal/lib/krb5/store_fd.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store_fd.c,v 1.13 2006/06/30 21:23:19 lha Exp $"); +RCSID("$Id: store_fd.c 17779 2006-06-30 21:23:19Z lha $"); typedef struct fd_storage { int fd; diff --git a/source4/heimdal/lib/krb5/store_mem.c b/source4/heimdal/lib/krb5/store_mem.c index d2b6d18252..e6e62b5a62 100644 --- a/source4/heimdal/lib/krb5/store_mem.c +++ b/source4/heimdal/lib/krb5/store_mem.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store_mem.c,v 1.13 2006/11/07 23:02:53 lha Exp $"); +RCSID("$Id: store_mem.c 20307 2007-04-11 11:16:28Z lha $"); typedef struct mem_storage{ unsigned char *base; @@ -121,7 +121,7 @@ krb5_storage_from_mem(void *buf, size_t len) krb5_storage * KRB5_LIB_FUNCTION krb5_storage_from_data(krb5_data *data) { - return krb5_storage_from_mem(data->data, data->length); + return krb5_storage_from_mem(data->data, data->length); } krb5_storage * KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 81372c158e..7eb4d32fad 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: ticket.c,v 1.18 2006/12/28 20:49:18 lha Exp $"); +RCSID("$Id: ticket.c 19544 2006-12-28 20:49:18Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_free_ticket(krb5_context context, diff --git a/source4/heimdal/lib/krb5/time.c b/source4/heimdal/lib/krb5/time.c index 4a120ab771..4cd992d48f 100644 --- a/source4/heimdal/lib/krb5/time.c +++ b/source4/heimdal/lib/krb5/time.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: time.c,v 1.13 2004/10/13 17:57:11 lha Exp $"); +RCSID("$Id: time.c 14308 2004-10-13 17:57:11Z lha $"); /* * Set the absolute time that the caller knows the kdc has so the diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c index 7f18b30c88..7f5498f592 100644 --- a/source4/heimdal/lib/krb5/transited.c +++ b/source4/heimdal/lib/krb5/transited.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: transited.c,v 1.18 2006/04/10 10:26:35 lha Exp $"); +RCSID("$Id: transited.c 17043 2006-04-10 10:26:35Z lha $"); /* this is an attempt at one of the most horrible `compression' schemes that has ever been invented; it's so amazingly brain-dead diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c index b1e12674dc..d42fbec3a5 100644 --- a/source4/heimdal/lib/krb5/v4_glue.c +++ b/source4/heimdal/lib/krb5/v4_glue.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: v4_glue.c,v 1.5 2006/05/05 09:31:00 lha Exp $"); +RCSID("$Id: v4_glue.c 17442 2006-05-05 09:31:15Z lha $"); #include "krb5-v4compat.h" diff --git a/source4/heimdal/lib/krb5/version.c b/source4/heimdal/lib/krb5/version.c index 5f0fd6680b..f7ccff5bc8 100644 --- a/source4/heimdal/lib/krb5/version.c +++ b/source4/heimdal/lib/krb5/version.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: version.c,v 1.3 1999/12/02 17:05:13 joda Exp $"); +RCSID("$Id: version.c 7464 1999-12-02 17:05:13Z joda $"); /* this is just to get a version stamp in the library file */ diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index 4252865301..85f143b8b4 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <err.h> -RCSID("$Id: warn.c,v 1.16 2006/11/21 08:06:40 lha Exp $"); +RCSID("$Id: warn.c 19086 2006-11-21 08:06:40Z lha $"); static krb5_error_code _warnerr(krb5_context context, int do_errtext, krb5_error_code code, int level, const char *fmt, va_list ap) diff --git a/source4/heimdal/lib/ntlm/heimntlm-protos.h b/source4/heimdal/lib/ntlm/heimntlm-protos.h index e9e0837003..2df32dfa50 100644 --- a/source4/heimdal/lib/ntlm/heimntlm-protos.h +++ b/source4/heimdal/lib/ntlm/heimntlm-protos.h @@ -83,7 +83,7 @@ void heim_ntlm_free_type1 (struct ntlm_type1 */*data*/); void -heim_ntlm_free_type2 (struct ntlm_type2 */*type2*/); +heim_ntlm_free_type2 (struct ntlm_type2 */*data*/); void heim_ntlm_free_type3 (struct ntlm_type3 */*data*/); diff --git a/source4/heimdal/lib/ntlm/heimntlm.h b/source4/heimdal/lib/ntlm/heimntlm.h index 1e38b2e400..1c1afe1eb1 100644 --- a/source4/heimdal/lib/ntlm/heimntlm.h +++ b/source4/heimdal/lib/ntlm/heimntlm.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: heimntlm.h,v 1.4 2006/12/20 07:28:37 lha Exp $ */ +/* $Id: heimntlm.h 19469 2006-12-20 07:28:37Z lha $ */ #ifndef HEIM_NTLM_H #define HEIM_NTLM_H diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c index 430e80505e..af950cc3b5 100644 --- a/source4/heimdal/lib/ntlm/ntlm.c +++ b/source4/heimdal/lib/ntlm/ntlm.c @@ -33,7 +33,7 @@ #include <config.h> -RCSID("$Id: ntlm.c,v 1.8 2006/12/26 00:25:17 lha Exp $"); +RCSID("$Id: ntlm.c 20816 2007-06-03 04:36:31Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -308,8 +308,10 @@ heim_ntlm_decode_targetinfo(struct ntlm_buf *data, int ucs2, void heim_ntlm_free_type1(struct ntlm_type1 *data) { - free(data->domain); - free(data->hostname); + if (data->domain) + free(data->domain); + if (data->hostname) + free(data->hostname); memset(data, 0, sizeof(*data)); } @@ -432,9 +434,12 @@ out: */ void -heim_ntlm_free_type2(struct ntlm_type2 *type2) +heim_ntlm_free_type2(struct ntlm_type2 *data) { - memset(type2, 0, sizeof(*type2)); + if (data->targetname) + free(data->targetname); + _ntlm_free_buf(&data->targetinfo); + memset(data, 0, sizeof(*data)); } int @@ -558,10 +563,18 @@ out: void heim_ntlm_free_type3(struct ntlm_type3 *data) { + _ntlm_free_buf(&data->lm); + _ntlm_free_buf(&data->ntlm); + if (data->targetname) + free(data->targetname); + if (data->username) + free(data->username); + if (data->ws) + free(data->ws); + _ntlm_free_buf(&data->sessionkey); memset(data, 0, sizeof(*data)); } - /* * */ diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c index 0d9d6119db..daf7fc5671 100644 --- a/source4/heimdal/lib/roken/base64.c +++ b/source4/heimdal/lib/roken/base64.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: base64.c,v 1.7 2005/06/23 10:47:57 lha Exp $"); +RCSID("$Id: base64.c 15506 2005-06-23 10:47:57Z lha $"); #endif #include <stdlib.h> #include <string.h> diff --git a/source4/heimdal/lib/roken/base64.h b/source4/heimdal/lib/roken/base64.h index 95992f9c21..09aadffe7c 100644 --- a/source4/heimdal/lib/roken/base64.h +++ b/source4/heimdal/lib/roken/base64.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: base64.h,v 1.4 2005/06/30 07:13:33 lha Exp $ */ +/* $Id: base64.h 15535 2005-06-30 07:13:33Z lha $ */ #ifndef _BASE64_H_ #define _BASE64_H_ diff --git a/source4/heimdal/lib/roken/bswap.c b/source4/heimdal/lib/roken/bswap.c index dd7ea832af..1e7a7abc11 100644 --- a/source4/heimdal/lib/roken/bswap.c +++ b/source4/heimdal/lib/roken/bswap.c @@ -36,7 +36,7 @@ #endif #include <roken.h> -RCSID("$Id: bswap.c,v 1.4 2005/04/12 11:28:35 lha Exp $"); +RCSID("$Id: bswap.c 14773 2005-04-12 11:29:18Z lha $"); #ifndef HAVE_BSWAP32 diff --git a/source4/heimdal/lib/roken/closefrom.c b/source4/heimdal/lib/roken/closefrom.c index 6b02f1ebca..697566561c 100644 --- a/source4/heimdal/lib/roken/closefrom.c +++ b/source4/heimdal/lib/roken/closefrom.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: closefrom.c,v 1.2 2005/04/13 08:01:38 lha Exp $"); +RCSID("$Id: closefrom.c 21005 2007-06-08 01:54:35Z lha $"); #endif #ifdef HAVE_SYS_TYPES_H diff --git a/source4/heimdal/lib/roken/copyhostent.c b/source4/heimdal/lib/roken/copyhostent.c index 7d458dc1b9..73e20ed039 100644 --- a/source4/heimdal/lib/roken/copyhostent.c +++ b/source4/heimdal/lib/roken/copyhostent.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: copyhostent.c,v 1.3 2005/04/12 11:28:36 lha Exp $"); +RCSID("$Id: copyhostent.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/dumpdata.c b/source4/heimdal/lib/roken/dumpdata.c index 402b4b1cb9..c445bfa361 100644 --- a/source4/heimdal/lib/roken/dumpdata.c +++ b/source4/heimdal/lib/roken/dumpdata.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: dumpdata.c,v 1.1 2005/09/22 23:51:35 lha Exp $"); +RCSID("$Id: dumpdata.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <unistd.h> diff --git a/source4/heimdal/lib/roken/ecalloc.c b/source4/heimdal/lib/roken/ecalloc.c index ad22a4557e..c9e6b9c6af 100644 --- a/source4/heimdal/lib/roken/ecalloc.c +++ b/source4/heimdal/lib/roken/ecalloc.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: ecalloc.c,v 1.2 2005/04/12 11:28:36 lha Exp $"); +RCSID("$Id: ecalloc.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/emalloc.c b/source4/heimdal/lib/roken/emalloc.c index 91af6b5184..0807da6105 100644 --- a/source4/heimdal/lib/roken/emalloc.c +++ b/source4/heimdal/lib/roken/emalloc.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: emalloc.c,v 1.6 2005/04/12 11:28:37 lha Exp $"); +RCSID("$Id: emalloc.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/erealloc.c b/source4/heimdal/lib/roken/erealloc.c index 497b1e7ec2..cbcfb1b469 100644 --- a/source4/heimdal/lib/roken/erealloc.c +++ b/source4/heimdal/lib/roken/erealloc.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: erealloc.c,v 1.6 2005/04/12 11:28:37 lha Exp $"); +RCSID("$Id: erealloc.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/estrdup.c b/source4/heimdal/lib/roken/estrdup.c index 1a20cdd410..a53c1f7b9d 100644 --- a/source4/heimdal/lib/roken/estrdup.c +++ b/source4/heimdal/lib/roken/estrdup.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: estrdup.c,v 1.4 2005/04/12 11:28:39 lha Exp $"); +RCSID("$Id: estrdup.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/freeaddrinfo.c b/source4/heimdal/lib/roken/freeaddrinfo.c index cd2898036b..71b5abb38f 100644 --- a/source4/heimdal/lib/roken/freeaddrinfo.c +++ b/source4/heimdal/lib/roken/freeaddrinfo.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: freeaddrinfo.c,v 1.5 2005/04/12 11:28:41 lha Exp $"); +RCSID("$Id: freeaddrinfo.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/freehostent.c b/source4/heimdal/lib/roken/freehostent.c index 1ebb01361c..e773f07a22 100644 --- a/source4/heimdal/lib/roken/freehostent.c +++ b/source4/heimdal/lib/roken/freehostent.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: freehostent.c,v 1.3 2005/04/12 11:28:41 lha Exp $"); +RCSID("$Id: freehostent.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/gai_strerror.c b/source4/heimdal/lib/roken/gai_strerror.c index 102aa75ea1..1e563ae288 100644 --- a/source4/heimdal/lib/roken/gai_strerror.c +++ b/source4/heimdal/lib/roken/gai_strerror.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: gai_strerror.c,v 1.7 2005/08/05 09:31:35 lha Exp $"); +RCSID("$Id: gai_strerror.c 15837 2005-08-05 09:31:35Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/get_window_size.c b/source4/heimdal/lib/roken/get_window_size.c index 6743e15af9..fd4e81fd74 100644 --- a/source4/heimdal/lib/roken/get_window_size.c +++ b/source4/heimdal/lib/roken/get_window_size.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: get_window_size.c,v 1.10 2005/04/12 11:28:42 lha Exp $"); +RCSID("$Id: get_window_size.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/getaddrinfo.c b/source4/heimdal/lib/roken/getaddrinfo.c index 86af8b72cc..2c232e3a59 100644 --- a/source4/heimdal/lib/roken/getaddrinfo.c +++ b/source4/heimdal/lib/roken/getaddrinfo.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getaddrinfo.c,v 1.14 2005/06/16 17:49:29 lha Exp $"); +RCSID("$Id: getaddrinfo.c 15417 2005-06-16 17:49:29Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/getarg.c b/source4/heimdal/lib/roken/getarg.c index e4e0556adf..840febbf21 100644 --- a/source4/heimdal/lib/roken/getarg.c +++ b/source4/heimdal/lib/roken/getarg.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getarg.c,v 1.48 2005/04/12 11:28:43 lha Exp $"); +RCSID("$Id: getarg.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdio.h> diff --git a/source4/heimdal/lib/roken/getarg.h b/source4/heimdal/lib/roken/getarg.h index bffa04486f..62d1b6687c 100644 --- a/source4/heimdal/lib/roken/getarg.h +++ b/source4/heimdal/lib/roken/getarg.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: getarg.h,v 1.14 2005/04/13 05:52:27 lha Exp $ */ +/* $Id: getarg.h 14776 2005-04-13 05:52:27Z lha $ */ #ifndef __GETARG_H__ #define __GETARG_H__ diff --git a/source4/heimdal/lib/roken/getipnodebyaddr.c b/source4/heimdal/lib/roken/getipnodebyaddr.c index 3f447d6d06..7e370d5f58 100644 --- a/source4/heimdal/lib/roken/getipnodebyaddr.c +++ b/source4/heimdal/lib/roken/getipnodebyaddr.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getipnodebyaddr.c,v 1.3 2005/04/12 11:28:47 lha Exp $"); +RCSID("$Id: getipnodebyaddr.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/getipnodebyname.c b/source4/heimdal/lib/roken/getipnodebyname.c index b928efcc53..04f12509ab 100644 --- a/source4/heimdal/lib/roken/getipnodebyname.c +++ b/source4/heimdal/lib/roken/getipnodebyname.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getipnodebyname.c,v 1.4 2005/04/12 11:28:47 lha Exp $"); +RCSID("$Id: getipnodebyname.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/getnameinfo.c b/source4/heimdal/lib/roken/getnameinfo.c index 2cf81897f8..04c5e1cdc9 100644 --- a/source4/heimdal/lib/roken/getnameinfo.c +++ b/source4/heimdal/lib/roken/getnameinfo.c @@ -33,10 +33,10 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getnameinfo.c,v 1.6 2005/06/16 16:53:09 lha Exp $"); +RCSID("$Id: getnameinfo.c 15412 2005-06-16 16:53:09Z lha $"); #endif -#include "roken.h" +#include <roken.h> static int doit (int af, diff --git a/source4/heimdal/lib/roken/getprogname.c b/source4/heimdal/lib/roken/getprogname.c index 7eabe40093..19f161831c 100644 --- a/source4/heimdal/lib/roken/getprogname.c +++ b/source4/heimdal/lib/roken/getprogname.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getprogname.c,v 1.3 2005/04/12 11:28:48 lha Exp $"); +RCSID("$Id: getprogname.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/h_errno.c b/source4/heimdal/lib/roken/h_errno.c index c2d4452c32..11dcb08ac2 100644 --- a/source4/heimdal/lib/roken/h_errno.c +++ b/source4/heimdal/lib/roken/h_errno.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: h_errno.c,v 1.1 2001/08/08 03:47:23 assar Exp $"); +RCSID("$Id: h_errno.c 10442 2001-08-08 03:47:23Z assar $"); #endif #ifndef HAVE_H_ERRNO diff --git a/source4/heimdal/lib/roken/hex.c b/source4/heimdal/lib/roken/hex.c index e41b508fcb..994d89484e 100644 --- a/source4/heimdal/lib/roken/hex.c +++ b/source4/heimdal/lib/roken/hex.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: hex.c,v 1.8 2006/01/09 17:09:29 lha Exp $"); +RCSID("$Id: hex.c 16504 2006-01-09 17:09:29Z lha $"); #endif #include <roken.h> #include <ctype.h> diff --git a/source4/heimdal/lib/roken/hex.h b/source4/heimdal/lib/roken/hex.h index cd47b21f9f..4c4b8508ed 100644 --- a/source4/heimdal/lib/roken/hex.h +++ b/source4/heimdal/lib/roken/hex.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hex.h,v 1.3 2005/04/12 11:28:50 lha Exp $ */ +/* $Id: hex.h 14773 2005-04-12 11:29:18Z lha $ */ #ifndef _rk_HEX_H_ #define _rk_HEX_H_ 1 diff --git a/source4/heimdal/lib/roken/hostent_find_fqdn.c b/source4/heimdal/lib/roken/hostent_find_fqdn.c index 1762b11226..4e583a1d20 100644 --- a/source4/heimdal/lib/roken/hostent_find_fqdn.c +++ b/source4/heimdal/lib/roken/hostent_find_fqdn.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: hostent_find_fqdn.c,v 1.3 2005/04/12 11:28:51 lha Exp $"); +RCSID("$Id: hostent_find_fqdn.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/inet_aton.c b/source4/heimdal/lib/roken/inet_aton.c index 0483a05256..176aed1f2b 100644 --- a/source4/heimdal/lib/roken/inet_aton.c +++ b/source4/heimdal/lib/roken/inet_aton.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: inet_aton.c,v 1.14 2005/04/12 11:28:52 lha Exp $"); +RCSID("$Id: inet_aton.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/inet_ntop.c b/source4/heimdal/lib/roken/inet_ntop.c index 35e96eb49b..430c0044c3 100644 --- a/source4/heimdal/lib/roken/inet_ntop.c +++ b/source4/heimdal/lib/roken/inet_ntop.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: inet_ntop.c,v 1.6 2005/04/12 11:28:52 lha Exp $"); +RCSID("$Id: inet_ntop.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/inet_pton.c b/source4/heimdal/lib/roken/inet_pton.c index 21606accb1..e0e5ca74b2 100644 --- a/source4/heimdal/lib/roken/inet_pton.c +++ b/source4/heimdal/lib/roken/inet_pton.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: inet_pton.c,v 1.4 2005/04/12 11:28:52 lha Exp $"); +RCSID("$Id: inet_pton.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/issuid.c b/source4/heimdal/lib/roken/issuid.c index e6b5248164..ea09d3a9ad 100644 --- a/source4/heimdal/lib/roken/issuid.c +++ b/source4/heimdal/lib/roken/issuid.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: issuid.c,v 1.6 2005/05/13 07:42:03 lha Exp $"); +RCSID("$Id: issuid.c 15131 2005-05-13 07:42:03Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/net_read.c b/source4/heimdal/lib/roken/net_read.c index f8d4dd1424..ef01f018d8 100644 --- a/source4/heimdal/lib/roken/net_read.c +++ b/source4/heimdal/lib/roken/net_read.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: net_read.c,v 1.4 2005/04/12 11:28:57 lha Exp $"); +RCSID("$Id: net_read.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <sys/types.h> diff --git a/source4/heimdal/lib/roken/net_write.c b/source4/heimdal/lib/roken/net_write.c index 83d14f4af9..e379caa750 100644 --- a/source4/heimdal/lib/roken/net_write.c +++ b/source4/heimdal/lib/roken/net_write.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: net_write.c,v 1.5 2005/04/12 11:28:58 lha Exp $"); +RCSID("$Id: net_write.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <sys/types.h> diff --git a/source4/heimdal/lib/roken/parse_bytes.h b/source4/heimdal/lib/roken/parse_bytes.h index 1537d16c33..1998f70736 100644 --- a/source4/heimdal/lib/roken/parse_bytes.h +++ b/source4/heimdal/lib/roken/parse_bytes.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: parse_bytes.h,v 1.4 2005/04/13 13:19:07 lha Exp $ */ +/* $Id: parse_bytes.h 14787 2005-04-13 13:19:07Z lha $ */ #ifndef __PARSE_BYTES_H__ #define __PARSE_BYTES_H__ diff --git a/source4/heimdal/lib/roken/parse_time.c b/source4/heimdal/lib/roken/parse_time.c index 551bee313f..1c39bde4e8 100644 --- a/source4/heimdal/lib/roken/parse_time.c +++ b/source4/heimdal/lib/roken/parse_time.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: parse_time.c,v 1.7 2005/04/12 11:28:58 lha Exp $"); +RCSID("$Id: parse_time.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <parse_units.h> diff --git a/source4/heimdal/lib/roken/parse_time.h b/source4/heimdal/lib/roken/parse_time.h index 5c9de87675..4dc2da08bc 100644 --- a/source4/heimdal/lib/roken/parse_time.h +++ b/source4/heimdal/lib/roken/parse_time.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: parse_time.h,v 1.5 2005/04/12 11:28:59 lha Exp $ */ +/* $Id: parse_time.h 14773 2005-04-12 11:29:18Z lha $ */ #ifndef __PARSE_TIME_H__ #define __PARSE_TIME_H__ diff --git a/source4/heimdal/lib/roken/parse_units.c b/source4/heimdal/lib/roken/parse_units.c index 5b01937aee..8cc6850c1f 100644 --- a/source4/heimdal/lib/roken/parse_units.c +++ b/source4/heimdal/lib/roken/parse_units.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: parse_units.c,v 1.18 2005/04/12 11:28:59 lha Exp $"); +RCSID("$Id: parse_units.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdio.h> diff --git a/source4/heimdal/lib/roken/parse_units.h b/source4/heimdal/lib/roken/parse_units.h index 9d019266ac..a42154d486 100644 --- a/source4/heimdal/lib/roken/parse_units.h +++ b/source4/heimdal/lib/roken/parse_units.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: parse_units.h,v 1.9 2005/04/12 11:28:59 lha Exp $ */ +/* $Id: parse_units.h 14773 2005-04-12 11:29:18Z lha $ */ #ifndef __PARSE_UNITS_H__ #define __PARSE_UNITS_H__ diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c index 9b54fc50f0..a8778fda57 100644 --- a/source4/heimdal/lib/roken/resolve.c +++ b/source4/heimdal/lib/roken/resolve.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -45,7 +45,7 @@ #include <assert.h> -RCSID("$Id: resolve.c,v 1.55 2006/04/14 13:56:00 lha Exp $"); +RCSID("$Id: resolve.c 19869 2007-01-12 16:03:14Z lha $"); #ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */ #undef HAVE_RES_NSEARCH @@ -492,6 +492,14 @@ parse_reply(const unsigned char *data, size_t len) return r; } +#ifdef HAVE_RES_NSEARCH +#ifdef HAVE_RES_NDESTROY +#define rk_res_free(x) res_ndestroy(x) +#else +#define rk_res_free(x) res_nclose(x) +#endif +#endif + static struct dns_reply * dns_lookup_int(const char *domain, int rr_class, int rr_type) { @@ -530,7 +538,7 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) reply = malloc(size); if (reply == NULL) { #ifdef HAVE_RES_NSEARCH - res_nclose(&state); + rk_res_free(&state); #endif return NULL; } @@ -548,18 +556,14 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) } if (len < 0) { #ifdef HAVE_RES_NSEARCH -#ifdef HAVE_RES_NDESTROY - res_ndestroy(&state); -#else - res_nclose(&state); -#endif + rk_res_free(&state); #endif free(reply); return NULL; } } while (size < len && len < rk_DNS_MAX_PACKET_SIZE); #ifdef HAVE_RES_NSEARCH - res_nclose(&state); + rk_res_free(&state); #endif len = min(len, size); diff --git a/source4/heimdal/lib/roken/resolve.h b/source4/heimdal/lib/roken/resolve.h index 2106c11ebd..fe83115b1e 100644 --- a/source4/heimdal/lib/roken/resolve.h +++ b/source4/heimdal/lib/roken/resolve.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: resolve.h,v 1.24 2005/04/12 11:29:02 lha Exp $ */ +/* $Id: resolve.h 14773 2005-04-12 11:29:18Z lha $ */ #ifndef __RESOLVE_H__ #define __RESOLVE_H__ diff --git a/source4/heimdal/lib/roken/roken-common.h b/source4/heimdal/lib/roken/roken-common.h index 8368530ff7..b835e880a2 100644 --- a/source4/heimdal/lib/roken/roken-common.h +++ b/source4/heimdal/lib/roken/roken-common.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: roken-common.h,v 1.64 2005/09/28 03:05:58 lha Exp $ */ +/* $Id: roken-common.h 20867 2007-06-03 21:00:45Z lha $ */ #ifndef __ROKEN_COMMON_H__ #define __ROKEN_COMMON_H__ @@ -376,6 +376,9 @@ int ROKEN_LIB_FUNCTION read_environment(const char *file, char ***env); void ROKEN_LIB_FUNCTION +free_environment(char **); + +void ROKEN_LIB_FUNCTION warnerr(int doerrno, const char *fmt, va_list ap) __attribute__ ((format (printf, 2, 0))); diff --git a/source4/heimdal/lib/roken/roken_gethostby.c b/source4/heimdal/lib/roken/roken_gethostby.c index 8f200dfe10..08eed5f8ed 100644 --- a/source4/heimdal/lib/roken/roken_gethostby.c +++ b/source4/heimdal/lib/roken/roken_gethostby.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: roken_gethostby.c,v 1.8 2006/04/02 00:09:28 lha Exp $"); +RCSID("$Id: roken_gethostby.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/rtbl.c b/source4/heimdal/lib/roken/rtbl.c new file mode 100644 index 0000000000..50ab50903f --- /dev/null +++ b/source4/heimdal/lib/roken/rtbl.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2000, 2002, 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID ("$Id: rtbl.c 17758 2006-06-30 13:41:40Z lha $"); +#endif +#include <roken.h> +#include "rtbl.h" + +struct column_entry { + char *data; +}; + +struct column_data { + char *header; + char *prefix; + int width; + unsigned flags; + size_t num_rows; + struct column_entry *rows; + unsigned int column_id; + char *suffix; +}; + +struct rtbl_data { + char *column_prefix; + size_t num_columns; + struct column_data **columns; + unsigned int flags; + char *column_separator; +}; + +rtbl_t ROKEN_LIB_FUNCTION +rtbl_create (void) +{ + return calloc (1, sizeof (struct rtbl_data)); +} + +void ROKEN_LIB_FUNCTION +rtbl_set_flags (rtbl_t table, unsigned int flags) +{ + table->flags = flags; +} + +unsigned int ROKEN_LIB_FUNCTION +rtbl_get_flags (rtbl_t table) +{ + return table->flags; +} + +static struct column_data * +rtbl_get_column_by_id (rtbl_t table, unsigned int id) +{ + int i; + for(i = 0; i < table->num_columns; i++) + if(table->columns[i]->column_id == id) + return table->columns[i]; + return NULL; +} + +static struct column_data * +rtbl_get_column (rtbl_t table, const char *column) +{ + int i; + for(i = 0; i < table->num_columns; i++) + if(strcmp(table->columns[i]->header, column) == 0) + return table->columns[i]; + return NULL; +} + +void ROKEN_LIB_FUNCTION +rtbl_destroy (rtbl_t table) +{ + int i, j; + + for (i = 0; i < table->num_columns; i++) { + struct column_data *c = table->columns[i]; + + for (j = 0; j < c->num_rows; j++) + free (c->rows[j].data); + free (c->rows); + free (c->header); + free (c->prefix); + free (c->suffix); + free (c); + } + free (table->column_prefix); + free (table->column_separator); + free (table->columns); + free (table); +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column_by_id (rtbl_t table, unsigned int id, + const char *header, unsigned int flags) +{ + struct column_data *col, **tmp; + + tmp = realloc (table->columns, (table->num_columns + 1) * sizeof (*tmp)); + if (tmp == NULL) + return ENOMEM; + table->columns = tmp; + col = malloc (sizeof (*col)); + if (col == NULL) + return ENOMEM; + col->header = strdup (header); + if (col->header == NULL) { + free (col); + return ENOMEM; + } + col->prefix = NULL; + col->width = 0; + col->flags = flags; + col->num_rows = 0; + col->rows = NULL; + col->column_id = id; + col->suffix = NULL; + table->columns[table->num_columns++] = col; + return 0; +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column (rtbl_t table, const char *header, unsigned int flags) +{ + return rtbl_add_column_by_id(table, 0, header, flags); +} + +int ROKEN_LIB_FUNCTION +rtbl_new_row(rtbl_t table) +{ + size_t max_rows = 0; + size_t c; + for (c = 0; c < table->num_columns; c++) + if(table->columns[c]->num_rows > max_rows) + max_rows = table->columns[c]->num_rows; + for (c = 0; c < table->num_columns; c++) { + struct column_entry *tmp; + + if(table->columns[c]->num_rows == max_rows) + continue; + tmp = realloc(table->columns[c]->rows, + max_rows * sizeof(table->columns[c]->rows)); + if(tmp == NULL) + return ENOMEM; + table->columns[c]->rows = tmp; + while(table->columns[c]->num_rows < max_rows) { + if((tmp[table->columns[c]->num_rows++].data = strdup("")) == NULL) + return ENOMEM; + } + } + return 0; +} + +static void +column_compute_width (rtbl_t table, struct column_data *column) +{ + int i; + + if(table->flags & RTBL_HEADER_STYLE_NONE) + column->width = 0; + else + column->width = strlen (column->header); + for (i = 0; i < column->num_rows; i++) + column->width = max (column->width, strlen (column->rows[i].data)); +} + +/* DEPRECATED */ +int ROKEN_LIB_FUNCTION +rtbl_set_prefix (rtbl_t table, const char *prefix) +{ + if (table->column_prefix) + free (table->column_prefix); + table->column_prefix = strdup (prefix); + if (table->column_prefix == NULL) + return ENOMEM; + return 0; +} + +int ROKEN_LIB_FUNCTION +rtbl_set_separator (rtbl_t table, const char *separator) +{ + if (table->column_separator) + free (table->column_separator); + table->column_separator = strdup (separator); + if (table->column_separator == NULL) + return ENOMEM; + return 0; +} + +int ROKEN_LIB_FUNCTION +rtbl_set_column_prefix (rtbl_t table, const char *column, + const char *prefix) +{ + struct column_data *c = rtbl_get_column (table, column); + + if (c == NULL) + return -1; + if (c->prefix) + free (c->prefix); + c->prefix = strdup (prefix); + if (c->prefix == NULL) + return ENOMEM; + return 0; +} + +int ROKEN_LIB_FUNCTION +rtbl_set_column_affix_by_id(rtbl_t table, unsigned int id, + const char *prefix, const char *suffix) +{ + struct column_data *c = rtbl_get_column_by_id (table, id); + + if (c == NULL) + return -1; + if (c->prefix) + free (c->prefix); + if(prefix == NULL) + c->prefix = NULL; + else { + c->prefix = strdup (prefix); + if (c->prefix == NULL) + return ENOMEM; + } + + if (c->suffix) + free (c->suffix); + if(suffix == NULL) + c->suffix = NULL; + else { + c->suffix = strdup (suffix); + if (c->suffix == NULL) + return ENOMEM; + } + return 0; +} + + +static const char * +get_column_prefix (rtbl_t table, struct column_data *c) +{ + if (c == NULL) + return ""; + if (c->prefix) + return c->prefix; + if (table->column_prefix) + return table->column_prefix; + return ""; +} + +static const char * +get_column_suffix (rtbl_t table, struct column_data *c) +{ + if (c && c->suffix) + return c->suffix; + return ""; +} + +static int +add_column_entry (struct column_data *c, const char *data) +{ + struct column_entry row, *tmp; + + row.data = strdup (data); + if (row.data == NULL) + return ENOMEM; + tmp = realloc (c->rows, (c->num_rows + 1) * sizeof (*tmp)); + if (tmp == NULL) { + free (row.data); + return ENOMEM; + } + c->rows = tmp; + c->rows[c->num_rows++] = row; + return 0; +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entry_by_id (rtbl_t table, unsigned int id, const char *data) +{ + struct column_data *c = rtbl_get_column_by_id (table, id); + + if (c == NULL) + return -1; + + return add_column_entry(c, data); +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id, + const char *fmt, ...) +{ + va_list ap; + char *str; + int ret; + + va_start(ap, fmt); + ret = vasprintf(&str, fmt, ap); + va_end(ap); + if (ret == -1) + return -1; + ret = rtbl_add_column_entry_by_id(table, id, str); + free(str); + return ret; +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entry (rtbl_t table, const char *column, const char *data) +{ + struct column_data *c = rtbl_get_column (table, column); + + if (c == NULL) + return -1; + + return add_column_entry(c, data); +} + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entryv (rtbl_t table, const char *column, const char *fmt, ...) +{ + va_list ap; + char *str; + int ret; + + va_start(ap, fmt); + ret = vasprintf(&str, fmt, ap); + va_end(ap); + if (ret == -1) + return -1; + ret = rtbl_add_column_entry(table, column, str); + free(str); + return ret; +} + + +int ROKEN_LIB_FUNCTION +rtbl_format (rtbl_t table, FILE * f) +{ + int i, j; + + for (i = 0; i < table->num_columns; i++) + column_compute_width (table, table->columns[i]); + if((table->flags & RTBL_HEADER_STYLE_NONE) == 0) { + for (i = 0; i < table->num_columns; i++) { + struct column_data *c = table->columns[i]; + + if(table->column_separator != NULL && i > 0) + fprintf (f, "%s", table->column_separator); + fprintf (f, "%s", get_column_prefix (table, c)); + if(i == table->num_columns - 1 && c->suffix == NULL) + /* last column, so no need to pad with spaces */ + fprintf (f, "%-*s", 0, c->header); + else + fprintf (f, "%-*s", (int)c->width, c->header); + fprintf (f, "%s", get_column_suffix (table, c)); + } + fprintf (f, "\n"); + } + + for (j = 0;; j++) { + int flag = 0; + + /* are there any more rows left? */ + for (i = 0; flag == 0 && i < table->num_columns; ++i) { + struct column_data *c = table->columns[i]; + + if (c->num_rows > j) { + ++flag; + break; + } + } + if (flag == 0) + break; + + for (i = 0; i < table->num_columns; i++) { + int w; + struct column_data *c = table->columns[i]; + + if(table->column_separator != NULL && i > 0) + fprintf (f, "%s", table->column_separator); + + w = c->width; + + if ((c->flags & RTBL_ALIGN_RIGHT) == 0) { + if(i == table->num_columns - 1 && c->suffix == NULL) + /* last column, so no need to pad with spaces */ + w = 0; + else + w = -w; + } + fprintf (f, "%s", get_column_prefix (table, c)); + if (c->num_rows <= j) + fprintf (f, "%*s", w, ""); + else + fprintf (f, "%*s", w, c->rows[j].data); + fprintf (f, "%s", get_column_suffix (table, c)); + } + fprintf (f, "\n"); + } + return 0; +} + +#ifdef TEST +int +main (int argc, char **argv) +{ + rtbl_t table; + + table = rtbl_create (); + rtbl_add_column_by_id (table, 0, "Issued", 0); + rtbl_add_column_by_id (table, 1, "Expires", 0); + rtbl_add_column_by_id (table, 2, "Foo", RTBL_ALIGN_RIGHT); + rtbl_add_column_by_id (table, 3, "Principal", 0); + + rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29"); + rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29"); + rtbl_add_column_entry_by_id (table, 2, "73"); + rtbl_add_column_entry_by_id (table, 2, "0"); + rtbl_add_column_entry_by_id (table, 2, "-2000"); + rtbl_add_column_entry_by_id (table, 3, "krbtgt/NADA.KTH.SE@NADA.KTH.SE"); + + rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29"); + rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29"); + rtbl_add_column_entry_by_id (table, 3, "afs/pdc.kth.se@NADA.KTH.SE"); + + rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29"); + rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29"); + rtbl_add_column_entry_by_id (table, 3, "afs@NADA.KTH.SE"); + + rtbl_set_separator (table, " "); + + rtbl_format (table, stdout); + + rtbl_destroy (table); + + printf("\n"); + + table = rtbl_create (); + rtbl_add_column_by_id (table, 0, "Column A", 0); + rtbl_set_column_affix_by_id (table, 0, "<", ">"); + rtbl_add_column_by_id (table, 1, "Column B", 0); + rtbl_set_column_affix_by_id (table, 1, "[", "]"); + rtbl_add_column_by_id (table, 2, "Column C", 0); + rtbl_set_column_affix_by_id (table, 2, "(", ")"); + + rtbl_add_column_entry_by_id (table, 0, "1"); + rtbl_new_row(table); + rtbl_add_column_entry_by_id (table, 1, "2"); + rtbl_new_row(table); + rtbl_add_column_entry_by_id (table, 2, "3"); + rtbl_new_row(table); + + rtbl_set_separator (table, " "); + rtbl_format (table, stdout); + + rtbl_destroy (table); + + return 0; +} + +#endif diff --git a/source4/heimdal/lib/roken/rtbl.h b/source4/heimdal/lib/roken/rtbl.h new file mode 100644 index 0000000000..9b168c7e73 --- /dev/null +++ b/source4/heimdal/lib/roken/rtbl.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2000,2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $Id: rtbl.h 17760 2006-06-30 13:42:39Z lha $ */ + +#ifndef __rtbl_h__ +#define __rtbl_h__ + +#ifndef ROKEN_LIB_FUNCTION +#ifdef _WIN32 +#define ROKEN_LIB_FUNCTION _stdcall +#else +#define ROKEN_LIB_FUNCTION +#endif +#endif + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct rtbl_data; +typedef struct rtbl_data *rtbl_t; + +#define RTBL_ALIGN_LEFT 0 +#define RTBL_ALIGN_RIGHT 1 + +/* flags */ +#define RTBL_HEADER_STYLE_NONE 1 + +int ROKEN_LIB_FUNCTION +rtbl_add_column (rtbl_t, const char*, unsigned int); + +int ROKEN_LIB_FUNCTION +rtbl_add_column_by_id (rtbl_t, unsigned int, const char*, unsigned int); + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 0))); + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entry (rtbl_t, const char*, const char*); + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entryv (rtbl_t, const char*, const char*, ...) + __attribute__ ((format (printf, 3, 0))); + +int ROKEN_LIB_FUNCTION +rtbl_add_column_entry_by_id (rtbl_t, unsigned int, const char*); + +rtbl_t ROKEN_LIB_FUNCTION +rtbl_create (void); + +void ROKEN_LIB_FUNCTION +rtbl_destroy (rtbl_t); + +int ROKEN_LIB_FUNCTION +rtbl_format (rtbl_t, FILE*); + +unsigned int ROKEN_LIB_FUNCTION +rtbl_get_flags (rtbl_t); + +int ROKEN_LIB_FUNCTION +rtbl_new_row (rtbl_t); + +int ROKEN_LIB_FUNCTION +rtbl_set_column_affix_by_id (rtbl_t, unsigned int, const char*, const char*); + +int ROKEN_LIB_FUNCTION +rtbl_set_column_prefix (rtbl_t, const char*, const char*); + +void ROKEN_LIB_FUNCTION +rtbl_set_flags (rtbl_t, unsigned int); + +int ROKEN_LIB_FUNCTION +rtbl_set_prefix (rtbl_t, const char*); + +int ROKEN_LIB_FUNCTION +rtbl_set_separator (rtbl_t, const char*); + +#ifdef __cplusplus +} +#endif + +#endif /* __rtbl_h__ */ diff --git a/source4/heimdal/lib/roken/setprogname.c b/source4/heimdal/lib/roken/setprogname.c index c13e8d4ee1..3213c1c7a5 100644 --- a/source4/heimdal/lib/roken/setprogname.c +++ b/source4/heimdal/lib/roken/setprogname.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: setprogname.c,v 1.4 2005/08/23 10:19:20 lha Exp $"); +RCSID("$Id: setprogname.c 15955 2005-08-23 10:19:20Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/signal.c b/source4/heimdal/lib/roken/signal.c index 7076847fb3..d5ea6fb86a 100644 --- a/source4/heimdal/lib/roken/signal.c +++ b/source4/heimdal/lib/roken/signal.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: signal.c,v 1.13 2005/04/12 11:29:05 lha Exp $"); +RCSID("$Id: signal.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <signal.h> diff --git a/source4/heimdal/lib/roken/simple_exec.c b/source4/heimdal/lib/roken/simple_exec.c index 048f2846dd..c4359f421e 100644 --- a/source4/heimdal/lib/roken/simple_exec.c +++ b/source4/heimdal/lib/roken/simple_exec.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: simple_exec.c,v 1.14 2005/04/13 11:39:00 lha Exp $"); +RCSID("$Id: simple_exec.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdarg.h> diff --git a/source4/heimdal/lib/roken/socket.c b/source4/heimdal/lib/roken/socket.c index 5f77aacf43..91316dfbd8 100644 --- a/source4/heimdal/lib/roken/socket.c +++ b/source4/heimdal/lib/roken/socket.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: socket.c,v 1.11 2005/09/01 18:48:17 lha Exp $"); +RCSID("$Id: socket.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <roken.h> diff --git a/source4/heimdal/lib/roken/strcollect.c b/source4/heimdal/lib/roken/strcollect.c index d6f3077348..c431e18f3d 100644 --- a/source4/heimdal/lib/roken/strcollect.c +++ b/source4/heimdal/lib/roken/strcollect.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strcollect.c,v 1.2 2005/04/12 11:29:07 lha Exp $"); +RCSID("$Id: strcollect.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdarg.h> diff --git a/source4/heimdal/lib/roken/strlwr.c b/source4/heimdal/lib/roken/strlwr.c index c0ef46dc35..356c8d2e9a 100644 --- a/source4/heimdal/lib/roken/strlwr.c +++ b/source4/heimdal/lib/roken/strlwr.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strlwr.c,v 1.6 2005/04/12 11:29:09 lha Exp $"); +RCSID("$Id: strlwr.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <string.h> #include <ctype.h> diff --git a/source4/heimdal/lib/roken/strpool.c b/source4/heimdal/lib/roken/strpool.c index cf9997af9d..d47580ff8d 100644 --- a/source4/heimdal/lib/roken/strpool.c +++ b/source4/heimdal/lib/roken/strpool.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strpool.c,v 1.2 2005/08/25 14:59:06 lha Exp $"); +RCSID("$Id: strpool.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <stdarg.h> diff --git a/source4/heimdal/lib/roken/strsep.c b/source4/heimdal/lib/roken/strsep.c index f08c33b7a5..b1ad87de27 100644 --- a/source4/heimdal/lib/roken/strsep.c +++ b/source4/heimdal/lib/roken/strsep.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strsep.c,v 1.4 2005/04/12 11:29:10 lha Exp $"); +RCSID("$Id: strsep.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <string.h> diff --git a/source4/heimdal/lib/roken/strsep_copy.c b/source4/heimdal/lib/roken/strsep_copy.c index 34759fe15c..aeade2957f 100644 --- a/source4/heimdal/lib/roken/strsep_copy.c +++ b/source4/heimdal/lib/roken/strsep_copy.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strsep_copy.c,v 1.5 2005/04/12 11:29:11 lha Exp $"); +RCSID("$Id: strsep_copy.c 14773 2005-04-12 11:29:18Z lha $"); #endif #include <string.h> diff --git a/source4/heimdal/lib/roken/strupr.c b/source4/heimdal/lib/roken/strupr.c index 4763a1a111..fadfacbb37 100644 --- a/source4/heimdal/lib/roken/strupr.c +++ b/source4/heimdal/lib/roken/strupr.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: strupr.c,v 1.6 2005/04/12 11:29:11 lha Exp $"); +RCSID("$Id: strupr.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <string.h> #include <ctype.h> diff --git a/source4/heimdal/lib/roken/vis.c b/source4/heimdal/lib/roken/vis.c index 3e54f6d58a..5dedb793cc 100644 --- a/source4/heimdal/lib/roken/vis.c +++ b/source4/heimdal/lib/roken/vis.c @@ -65,7 +65,7 @@ #if 1 #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: vis.c,v 1.13 2006/12/15 11:49:22 lha Exp $"); +RCSID("$Id: vis.c 21005 2007-06-08 01:54:35Z lha $"); #endif #include <roken.h> #ifndef _DIAGASSERT diff --git a/source4/heimdal/lib/vers/print_version.c b/source4/heimdal/lib/vers/print_version.c index 5f5a2c4a4a..4337d591c4 100644 --- a/source4/heimdal/lib/vers/print_version.c +++ b/source4/heimdal/lib/vers/print_version.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: print_version.c,v 1.10 2006/12/29 16:00:16 lha Exp $"); +RCSID("$Id: print_version.c 19566 2006-12-29 16:00:16Z lha $"); #endif #include "roken.h" |