diff options
author | Andrew Bartlett <abartlet@samba.org> | 2009-09-20 23:18:34 -0700 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-11-13 23:19:05 +1100 |
commit | 5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094 (patch) | |
tree | 82c3416f2211df07d5fe1e58ee6639f09e465a60 /source4/heimdal/lib/krb5 | |
parent | 12205347163b55e79651921c6858c4d04e1faa51 (diff) | |
download | samba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.tar.gz samba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.tar.bz2 samba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.zip |
s4:heimdal: import lorikeet-heimdal-200909210500 (commit 290db8d23647a27c39b97c189a0b2ef6ec21ca69)
Diffstat (limited to 'source4/heimdal/lib/krb5')
-rw-r--r-- | source4/heimdal/lib/krb5/cache.c | 44 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/config_file.c | 357 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/context.c | 85 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/creds.c | 12 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/crypto.c | 424 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/init_creds_pw.c | 64 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/keyblock.c | 6 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/krb5_locl.h | 3 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/krbhst.c | 104 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/log.c | 16 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/pkinit.c | 29 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/principal.c | 78 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/replay.c | 19 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/send_to_kdc.c | 7 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/store.c | 265 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/store_mem.c | 6 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/ticket.c | 77 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/warn.c | 2 |
18 files changed, 1309 insertions, 289 deletions
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index 12097470d5..3617a0eefd 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -119,8 +119,8 @@ krb5_cc_register(krb5_context context, { int i; - for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { - if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) { + for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { + if(strcmp(context->cc_ops[i]->prefix, ops->prefix) == 0) { if(!override) { krb5_set_error_message(context, KRB5_CC_TYPE_EXISTS, @@ -132,20 +132,19 @@ krb5_cc_register(krb5_context context, } } if(i == context->num_cc_ops) { - krb5_cc_ops *o = realloc(context->cc_ops, - (context->num_cc_ops + 1) * - sizeof(*context->cc_ops)); + const krb5_cc_ops **o = realloc(context->cc_ops, + (context->num_cc_ops + 1) * + sizeof(context->cc_ops[0])); if(o == NULL) { krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } - context->num_cc_ops++; context->cc_ops = o; - memset(context->cc_ops + i, 0, - (context->num_cc_ops - i) * sizeof(*context->cc_ops)); + context->cc_ops[context->num_cc_ops] = NULL; + context->num_cc_ops++; } - memcpy(&context->cc_ops[i], ops, sizeof(context->cc_ops[i])); + context->cc_ops[i] = ops; return 0; } @@ -219,12 +218,12 @@ krb5_cc_resolve(krb5_context context, *id = NULL; - for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { - size_t prefix_len = strlen(context->cc_ops[i].prefix); + for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { + size_t prefix_len = strlen(context->cc_ops[i]->prefix); - if(strncmp(context->cc_ops[i].prefix, name, prefix_len) == 0 + if(strncmp(context->cc_ops[i]->prefix, name, prefix_len) == 0 && name[prefix_len] == ':') { - return allocate_ccache (context, &context->cc_ops[i], + return allocate_ccache (context, context->cc_ops[i], name + prefix_len + 1, id); } @@ -673,6 +672,13 @@ krb5_cc_store_cred(krb5_context context, * from `id' in `creds'. 'creds' must be free by the caller using * krb5_free_cred_contents. * + * @param context A Kerberos 5 context + * @param id a Kerberos 5 credential cache + * @param whichfields what fields to use for matching credentials, same + * flags as whichfields in krb5_compare_creds() + * @param mcreds template credential to use for comparing + * @param creds returned credential, free with krb5_free_cred_contents() + * * @return Return an error code or 0, see krb5_get_error_message(). * * @ingroup krb5_ccache @@ -970,10 +976,10 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) if (p1) *p1 = '\0'; - for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { - if(strcmp(context->cc_ops[i].prefix, p) == 0) { + for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { + if(strcmp(context->cc_ops[i]->prefix, p) == 0) { free(p); - return &context->cc_ops[i]; + return context->cc_ops[i]; } } free(p); @@ -1046,6 +1052,10 @@ krb5_cc_cache_get_first (krb5_context context, * Retrieve the next cache pointed to by (`cursor') in `id' * and advance `cursor'. * + * @param context A Kerberos 5 context + * @param cursor the iterator cursor, returned by krb5_cc_cache_get_first() + * @param id next ccache + * * @return Return 0 or an error code. Returns KRB5_CC_END when the end * of caches is reached, see krb5_get_error_message(). * @@ -1398,7 +1408,7 @@ krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, if (cursor->cursor == NULL) { ret = krb5_cc_cache_get_first (context, - context->cc_ops[cursor->idx].prefix, + context->cc_ops[cursor->idx]->prefix, &cursor->cursor); if (ret) { cursor->idx++; diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index ee226c78a2..03c0e335d4 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -31,6 +31,8 @@ * SUCH DAMAGE. */ +#define KRB5_DEPRECATED + #include "krb5_locl.h" /* Gaah! I want a portable funopen */ @@ -278,27 +280,6 @@ krb5_config_parse_debug (struct fileptr *f, return 0; } -krb5_error_code KRB5_LIB_FUNCTION -krb5_config_parse_string_multi(krb5_context context, - const char *string, - krb5_config_section **res) -{ - const char *str; - unsigned lineno = 0; - krb5_error_code ret; - struct fileptr f; - f.f = NULL; - f.s = string; - - ret = krb5_config_parse_debug (&f, res, &lineno, &str); - if (ret) { - krb5_set_error_message (context, ret, "%s:%u: %s", - "<constant>", lineno, str); - return ret; - } - return 0; -} - /** * Parse a configuration file and add the result into res. This * interface can be used to parse several configuration files into one @@ -403,6 +384,19 @@ free_binding (krb5_context context, krb5_config_binding *b) } } +/** + * Free configuration file section, the result of + * krb5_config_parse_file() and krb5_config_parse_file_multi(). + * + * @param context A Kerberos 5 context + * @param s the configuration section to free + * + * @return returns 0 on successes, otherwise an error code, see + * krb5_get_error_message() + * + * @ingroup krb5_support + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_config_file_free (krb5_context context, krb5_config_section *s) { @@ -410,6 +404,8 @@ krb5_config_file_free (krb5_context context, krb5_config_section *s) return 0; } +#ifndef HEIMDAL_SMALLER + krb5_error_code _krb5_config_copy(krb5_context context, krb5_config_section *c, @@ -444,20 +440,20 @@ _krb5_config_copy(krb5_context context, return 0; } - +#endif /* HEIMDAL_SMALLER */ const void * -krb5_config_get_next (krb5_context context, - const krb5_config_section *c, - const krb5_config_binding **pointer, - int type, - ...) +_krb5_config_get_next (krb5_context context, + const krb5_config_section *c, + const krb5_config_binding **pointer, + int type, + ...) { const char *ret; va_list args; va_start(args, type); - ret = krb5_config_vget_next (context, c, pointer, type, args); + ret = _krb5_config_vget_next (context, c, pointer, type, args); va_end(args); return ret; } @@ -486,11 +482,11 @@ vget_next(krb5_context context, } const void * -krb5_config_vget_next (krb5_context context, - const krb5_config_section *c, - const krb5_config_binding **pointer, - int type, - va_list args) +_krb5_config_vget_next (krb5_context context, + const krb5_config_section *c, + const krb5_config_binding **pointer, + int type, + va_list args) { const krb5_config_binding *b; const char *p; @@ -522,31 +518,43 @@ krb5_config_vget_next (krb5_context context, } const void * -krb5_config_get (krb5_context context, - const krb5_config_section *c, - int type, - ...) +_krb5_config_get (krb5_context context, + const krb5_config_section *c, + int type, + ...) { const void *ret; va_list args; va_start(args, type); - ret = krb5_config_vget (context, c, type, args); + ret = _krb5_config_vget (context, c, type, args); va_end(args); return ret; } const void * -krb5_config_vget (krb5_context context, - const krb5_config_section *c, - int type, - va_list args) +_krb5_config_vget (krb5_context context, + const krb5_config_section *c, + int type, + va_list args) { const krb5_config_binding *foo = NULL; - return krb5_config_vget_next (context, c, &foo, type, args); + return _krb5_config_vget_next (context, c, &foo, type, args); } +/** + * Get a list of configuration binding list for more processing + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return NULL if configuration list is not found, a list otherwise + * + * @ingroup krb5_support + */ + const krb5_config_binding * krb5_config_get_list (krb5_context context, const krb5_config_section *c, @@ -561,14 +569,41 @@ krb5_config_get_list (krb5_context context, return ret; } +/** + * Get a list of configuration binding list for more processing + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return NULL if configuration list is not found, a list otherwise + * + * @ingroup krb5_support + */ + const krb5_config_binding * krb5_config_vget_list (krb5_context context, const krb5_config_section *c, va_list args) { - return krb5_config_vget (context, c, krb5_config_list, args); + return _krb5_config_vget (context, c, krb5_config_list, args); } +/** + * Returns a "const char *" to a string in the configuration database. + * The string may not be valid after a reload of the configuration + * database so a caller should make a local copy if it needs to keep + * the string. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return NULL if configuration string not found, a string otherwise + * + * @ingroup krb5_support + */ + const char* KRB5_LIB_FUNCTION krb5_config_get_string (krb5_context context, const krb5_config_section *c, @@ -583,14 +618,41 @@ krb5_config_get_string (krb5_context context, return ret; } +/** + * Like krb5_config_get_string(), but uses a va_list instead of ... + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return NULL if configuration string not found, a string otherwise + * + * @ingroup krb5_support + */ + const char* KRB5_LIB_FUNCTION krb5_config_vget_string (krb5_context context, const krb5_config_section *c, va_list args) { - return krb5_config_vget (context, c, krb5_config_string, args); + return _krb5_config_vget (context, c, krb5_config_string, args); } +/** + * Like krb5_config_vget_string(), but instead of returning NULL, + * instead return a default value. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return a configuration string + * + * @ingroup krb5_support + */ + const char* KRB5_LIB_FUNCTION krb5_config_vget_string_default (krb5_context context, const krb5_config_section *c, @@ -605,6 +667,21 @@ krb5_config_vget_string_default (krb5_context context, return ret; } +/** + * Like krb5_config_get_string(), but instead of returning NULL, + * instead return a default value. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return a configuration string + * + * @ingroup krb5_support + */ + const char* KRB5_LIB_FUNCTION krb5_config_get_string_default (krb5_context context, const krb5_config_section *c, @@ -620,6 +697,19 @@ krb5_config_get_string_default (krb5_context context, return ret; } +/** + * Get a list of configuration strings, free the result with + * krb5_config_free_strings(). + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + char ** KRB5_LIB_FUNCTION krb5_config_vget_strings(krb5_context context, const krb5_config_section *c, @@ -630,8 +720,8 @@ krb5_config_vget_strings(krb5_context context, const krb5_config_binding *b = NULL; const char *p; - while((p = krb5_config_vget_next(context, c, &b, - krb5_config_string, args))) { + while((p = _krb5_config_vget_next(context, c, &b, + krb5_config_string, args))) { char *tmp = strdup(p); char *pos = NULL; char *s; @@ -667,6 +757,19 @@ cleanup: } +/** + * Get a list of configuration strings, free the result with + * krb5_config_free_strings(). + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + char** krb5_config_get_strings(krb5_context context, const krb5_config_section *c, @@ -680,6 +783,15 @@ krb5_config_get_strings(krb5_context context, return ret; } +/** + * Free the resulting strings from krb5_config-get_strings() and + * krb5_config_vget_strings(). + * + * @param strings strings to free + * + * @ingroup krb5_support + */ + void KRB5_LIB_FUNCTION krb5_config_free_strings(char **strings) { @@ -691,6 +803,24 @@ krb5_config_free_strings(char **strings) free(strings); } +/** + * Like krb5_config_get_bool_default() but with a va_list list of + * configuration selection. + * + * Configuration value to a boolean value, where yes/true and any + * non-zero number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_config_vget_bool_default (krb5_context context, const krb5_config_section *c, @@ -707,6 +837,20 @@ krb5_config_vget_bool_default (krb5_context context, return FALSE; } +/** + * krb5_config_get_bool() will convert the configuration + * option value to a boolean value, where yes/true and any non-zero + * number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_config_vget_bool (krb5_context context, const krb5_config_section *c, @@ -715,6 +859,22 @@ krb5_config_vget_bool (krb5_context context, return krb5_config_vget_bool_default (context, c, FALSE, args); } +/** + * krb5_config_get_bool_default() will convert the configuration + * option value to a boolean value, where yes/true and any non-zero + * number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_config_get_bool_default (krb5_context context, const krb5_config_section *c, @@ -729,6 +889,22 @@ krb5_config_get_bool_default (krb5_context context, return ret; } +/** + * Like krb5_config_get_bool() but with a va_list list of + * configuration selection. + * + * Configuration value to a boolean value, where yes/true and any + * non-zero number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_config_get_bool (krb5_context context, const krb5_config_section *c, @@ -742,6 +918,23 @@ krb5_config_get_bool (krb5_context context, return ret; } +/** + * Get the time from the configuration file using a relative time. + * + * Like krb5_config_get_time_default() but with a va_list list of + * configuration selection. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return parsed the time (or def_value on parse error) + * + * @ingroup krb5_support + */ + int KRB5_LIB_FUNCTION krb5_config_vget_time_default (krb5_context context, const krb5_config_section *c, @@ -759,14 +952,40 @@ krb5_config_vget_time_default (krb5_context context, return t; } +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return parsed the time or -1 on error + * + * @ingroup krb5_support + */ + int KRB5_LIB_FUNCTION -krb5_config_vget_time (krb5_context context, - const krb5_config_section *c, - va_list args) +krb5_config_vget_time(krb5_context context, + const krb5_config_section *c, + va_list args) { return krb5_config_vget_time_default (context, c, -1, args); } +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return parsed the time (or def_value on parse error) + * + * @ingroup krb5_support + */ + int KRB5_LIB_FUNCTION krb5_config_get_time_default (krb5_context context, const krb5_config_section *c, @@ -781,6 +1000,18 @@ krb5_config_get_time_default (krb5_context context, return ret; } +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return parsed the time or -1 on error + * + * @ingroup krb5_support + */ + int KRB5_LIB_FUNCTION krb5_config_get_time (krb5_context context, const krb5_config_section *c, @@ -850,3 +1081,29 @@ krb5_config_get_int (krb5_context context, va_end(ap); return ret; } + + +#ifndef HEIMDAL_SMALLER + +krb5_error_code KRB5_LIB_FUNCTION +krb5_config_parse_string_multi(krb5_context context, + const char *string, + krb5_config_section **res) KRB5_DEPRECATED +{ + const char *str; + unsigned lineno = 0; + krb5_error_code ret; + struct fileptr f; + f.f = NULL; + f.s = string; + + ret = krb5_config_parse_debug (&f, res, &lineno, &str); + if (ret) { + krb5_set_error_message (context, ret, "%s:%u: %s", + "<constant>", lineno, str); + return ret; + } + return 0; +} + +#endif diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 9ece38e145..8bf8b79022 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -85,32 +85,6 @@ set_etypes (krb5_context context, } /* - * - */ - -static krb5_error_code -copy_etypes (krb5_context context, - krb5_enctype *enctypes, - krb5_enctype **ret_enctypes) -{ - unsigned int i; - - for (i = 0; enctypes[i]; i++) - ; - i++; - - *ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i); - if (*ret_enctypes == NULL) { - krb5_set_error_message(context, ENOMEM, - N_("malloc: out of memory", "")); - return ENOMEM; - } - memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i); - return 0; -} - - -/* * read variables from the configuration file and set in `context' */ @@ -119,6 +93,7 @@ init_context_from_config_file(krb5_context context) { krb5_error_code ret; const char * tmp; + char **s; krb5_enctype *tmptypes; INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew"); @@ -229,6 +204,16 @@ init_context_from_config_file(krb5_context context) krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE); } + s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL); + if(s) { + char **p; + krb5_initlog(context, "libkrb5", &context->debug_dest); + for(p = s; *p; p++) + krb5_addlog_dest(context, context->debug_dest, *p); + krb5_config_free_strings(s); + } + + return 0; } @@ -328,8 +313,35 @@ out: return ret; } +#ifndef HEIMDAL_SMALLER + +/* + * + */ + +static krb5_error_code +copy_etypes (krb5_context context, + krb5_enctype *enctypes, + krb5_enctype **ret_enctypes) +{ + unsigned int i; + + for (i = 0; enctypes[i]; i++) + ; + i++; + + *ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i); + if (*ret_enctypes == NULL) { + krb5_set_error_message(context, ENOMEM, + N_("malloc: out of memory", "")); + return ENOMEM; + } + memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i); + return 0; +} + /** - * Make a copy for the Kerberos 5 context, allocated krb5_contex shoud + * Make a copy for the Kerberos 5 context, the new krb5_context shoud * be freed with krb5_free_context(). * * @param context the Kerberos context to copy @@ -399,6 +411,8 @@ krb5_copy_context(krb5_context context, krb5_context *out) #if 0 /* XXX */ if(context->warn_dest != NULL) ; + if(context->debug_dest != NULL) + ; #endif ret = krb5_set_extra_addresses(p, context->extra_addresses); @@ -421,6 +435,8 @@ krb5_copy_context(krb5_context context, krb5_context *out) return ret; } +#endif + /** * Frees the krb5_context allocated by krb5_init_context(). * @@ -446,6 +462,8 @@ krb5_free_context(krb5_context context) krb5_clear_error_message(context); if(context->warn_dest != NULL) krb5_closelog(context, context->warn_dest); + if(context->debug_dest != NULL) + krb5_closelog(context, context->debug_dest); krb5_set_extra_addresses(context, NULL); krb5_set_ignore_addresses(context, NULL); krb5_set_send_to_kdc_func(context, NULL, NULL); @@ -835,21 +853,24 @@ krb5_init_ets(krb5_context context) { if(context->et_list == NULL){ krb5_add_et_list(context, initialize_krb5_error_table_r); - bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); - krb5_add_et_list(context, initialize_asn1_error_table_r); - bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); - krb5_add_et_list(context, initialize_heim_error_table_r); - bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); krb5_add_et_list(context, initialize_k524_error_table_r); + +#ifdef COM_ERR_BINDDOMAIN_krb5 + bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); +#endif #ifdef PKINIT krb5_add_et_list(context, initialize_hx_error_table_r); +#ifdef COM_ERR_BINDDOMAIN_hx bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); #endif +#endif } } diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index 26c0dfbecb..6cc2714172 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -183,6 +183,18 @@ krb5_times_equal(const krb5_times *a, const krb5_times *b) * Return TRUE if `mcreds' and `creds' are equal (`whichfields' * determines what equal means). * + * + * The following flags, set in whichfields affects the comparison: + * - KRB5_TC_MATCH_SRV_NAMEONLY Consider all realms equal when comparing the service principal. + * - KRB5_TC_MATCH_KEYTYPE Compare enctypes. + * - KRB5_TC_MATCH_FLAGS_EXACT Make sure that the ticket flags are identical. + * - KRB5_TC_MATCH_FLAGS Make sure that all ticket flags set in mcreds are also present in creds . + * - KRB5_TC_MATCH_TIMES_EXACT Compares the ticket times exactly. + * - KRB5_TC_MATCH_TIMES Compares only the expiration times of the creds. + * - KRB5_TC_MATCH_AUTHDATA Compares the authdata fields. + * - KRB5_TC_MATCH_2ND_TKT Compares the second tickets (used by user-to-user authentication). + * - KRB5_TC_MATCH_IS_SKEY Compares the existance of the second ticket. + * * @param context Kerberos 5 context. * @param whichfields which fields to compare. * @param mcreds cred to compare with. diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 42e2fdf359..bdcdb2ea0a 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -36,20 +36,10 @@ #include "krb5_locl.h" #include <pkinit_asn1.h> -#define WEAK_ENCTYPES 1 - #ifndef HEIMDAL_SMALLER #define DES3_OLD_ENCTYPE 1 #endif - -#ifdef HAVE_OPENSSL /* XXX forward decl for hcrypto glue */ -const EVP_CIPHER * _krb5_EVP_hcrypto_aes_128_cts(void); -const EVP_CIPHER * _krb5_EVP_hcrypto_aes_256_cts(void); -#define EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts -#define EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts -#endif - struct key_data { krb5_keyblock *key; krb5_data *schedule; @@ -180,7 +170,7 @@ struct evp_schedule { static HEIMDAL_MUTEX crypto_mutex = HEIMDAL_MUTEX_INITIALIZER; -#ifdef WEAK_ENCTYPES +#ifdef HEIM_WEAK_CRYPTO static void krb5_DES_random_key(krb5_context context, krb5_keyblock *key) @@ -555,15 +545,6 @@ DES3_random_to_key(krb5_context context, * ARCFOUR */ -static void -ARCFOUR_schedule(krb5_context context, - struct key_type *kt, - struct key_data *kd) -{ - RC4_set_key (kd->schedule->data, - kd->key->keyvalue.length, kd->key->keyvalue.data); -} - static krb5_error_code ARCFOUR_string_to_key(krb5_context context, krb5_enctype enctype, @@ -722,7 +703,7 @@ evp_cleanup(krb5_context context, struct key_data *kd) * */ -#ifdef WEAK_ENCTYPES +#ifdef HEIM_WEAK_CRYPTO static struct salt_type des_salt[] = { { KRB5_PW_SALT, @@ -793,7 +774,7 @@ static struct key_type keytype_null = { NULL }; -#ifdef WEAK_ENCTYPES +#ifdef HEIM_WEAK_CRYPTO static struct key_type keytype_des_old = { KEYTYPE_DES, "des-old", @@ -819,7 +800,7 @@ static struct key_type keytype_des = { evp_cleanup, EVP_des_cbc }; -#endif /* WEAK_ENCTYPES */ +#endif /* HEIM_WEAK_CRYPTO */ #ifdef DES3_OLD_ENCTYPE static struct key_type keytype_des3 = { @@ -862,7 +843,7 @@ static struct key_type keytype_aes128 = { AES_salt, NULL, evp_cleanup, - EVP_hcrypto_aes_128_cts + EVP_aes_128_cbc }; static struct key_type keytype_aes256 = { @@ -876,7 +857,7 @@ static struct key_type keytype_aes256 = { AES_salt, NULL, evp_cleanup, - EVP_hcrypto_aes_256_cts + EVP_aes_256_cbc }; static struct key_type keytype_arcfour = { @@ -884,10 +865,13 @@ static struct key_type keytype_arcfour = { "arcfour", 128, 16, - sizeof(RC4_KEY), + sizeof(struct evp_schedule), + NULL, + evp_schedule, + arcfour_salt, NULL, - ARCFOUR_schedule, - arcfour_salt + evp_cleanup, + EVP_rc4 }; krb5_error_code KRB5_LIB_FUNCTION @@ -1204,37 +1188,7 @@ NONE_checksum(krb5_context context, return 0; } -static krb5_error_code -CRC32_checksum(krb5_context context, - struct key_data *key, - const void *data, - size_t len, - unsigned usage, - Checksum *C) -{ - uint32_t crc; - unsigned char *r = C->checksum.data; - _krb5_crc_init_table (); - crc = _krb5_crc_update (data, len, 0); - r[0] = crc & 0xff; - r[1] = (crc >> 8) & 0xff; - r[2] = (crc >> 16) & 0xff; - r[3] = (crc >> 24) & 0xff; - return 0; -} - -static krb5_error_code -RSA_MD4_checksum(krb5_context context, - struct key_data *key, - const void *data, - size_t len, - unsigned usage, - Checksum *C) -{ - if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1) - krb5_abortx(context, "md4 checksum failed"); - return 0; -} +#if defined(DES3_OLD_ENCTYPE) || defined(HEIM_WEAK_CRYPTO) static krb5_error_code des_checksum(krb5_context context, @@ -1299,7 +1253,7 @@ des_verify(krb5_context context, EVP_DigestUpdate(m, data, len); EVP_DigestFinal_ex (m, res, NULL); EVP_MD_CTX_destroy(m); - if(memcmp(res, tmp + 8, sizeof(res)) != 0) { + if(ct_memcmp(res, tmp + 8, sizeof(res)) != 0) { krb5_clear_error_message (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } @@ -1308,6 +1262,42 @@ des_verify(krb5_context context, return ret; } +#endif + +#ifdef HEIM_WEAK_CRYPTO + +static krb5_error_code +CRC32_checksum(krb5_context context, + struct key_data *key, + const void *data, + size_t len, + unsigned usage, + Checksum *C) +{ + uint32_t crc; + unsigned char *r = C->checksum.data; + _krb5_crc_init_table (); + crc = _krb5_crc_update (data, len, 0); + r[0] = crc & 0xff; + r[1] = (crc >> 8) & 0xff; + r[2] = (crc >> 16) & 0xff; + r[3] = (crc >> 24) & 0xff; + return 0; +} + +static krb5_error_code +RSA_MD4_checksum(krb5_context context, + struct key_data *key, + const void *data, + size_t len, + unsigned usage, + Checksum *C) +{ + if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1) + krb5_abortx(context, "md4 checksum failed"); + return 0; +} + static krb5_error_code RSA_MD4_DES_checksum(krb5_context context, struct key_data *key, @@ -1331,19 +1321,6 @@ RSA_MD4_DES_verify(krb5_context context, } static krb5_error_code -RSA_MD5_checksum(krb5_context context, - struct key_data *key, - const void *data, - size_t len, - unsigned usage, - Checksum *C) -{ - if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md5(), NULL) != 1) - krb5_abortx(context, "md5 checksum failed"); - return 0; -} - -static krb5_error_code RSA_MD5_DES_checksum(krb5_context context, struct key_data *key, const void *data, @@ -1365,6 +1342,8 @@ RSA_MD5_DES_verify(krb5_context context, return des_verify(context, EVP_md5(), key, data, len, C); } +#endif /* HEIM_WEAK_CRYPTO */ + #ifdef DES3_OLD_ENCTYPE static krb5_error_code RSA_MD5_DES3_checksum(krb5_context context, @@ -1576,6 +1555,7 @@ static struct checksum_type checksum_none = { NONE_checksum, NULL }; +#ifdef HEIM_WEAK_CRYPTO static struct checksum_type checksum_crc32 = { CKSUMTYPE_CRC32, "crc32", @@ -1603,15 +1583,6 @@ static struct checksum_type checksum_rsa_md4_des = { RSA_MD4_DES_checksum, RSA_MD4_DES_verify }; -static struct checksum_type checksum_rsa_md5 = { - CKSUMTYPE_RSA_MD5, - "rsa-md5", - 64, - 16, - F_CPROOF, - RSA_MD5_checksum, - NULL -}; static struct checksum_type checksum_rsa_md5_des = { CKSUMTYPE_RSA_MD5_DES, "rsa-md5-des", @@ -1621,6 +1592,31 @@ static struct checksum_type checksum_rsa_md5_des = { RSA_MD5_DES_checksum, RSA_MD5_DES_verify }; +#endif /* HEIM_WEAK_CRYPTO */ + +static krb5_error_code +RSA_MD5_checksum(krb5_context context, + struct key_data *key, + const void *data, + size_t len, + unsigned usage, + Checksum *C) +{ + if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md5(), NULL) != 1) + krb5_abortx(context, "md5 checksum failed"); + return 0; +} + +static struct checksum_type checksum_rsa_md5 = { + CKSUMTYPE_RSA_MD5, + "rsa-md5", + 64, + 16, + F_CPROOF, + RSA_MD5_checksum, + NULL +}; + #ifdef DES3_OLD_ENCTYPE static struct checksum_type checksum_rsa_md5_des3 = { CKSUMTYPE_RSA_MD5_DES3, @@ -1683,14 +1679,16 @@ static struct checksum_type checksum_hmac_md5 = { static struct checksum_type *checksum_types[] = { &checksum_none, +#ifdef HEIM_WEAK_CRYPTO &checksum_crc32, &checksum_rsa_md4, &checksum_rsa_md4_des, - &checksum_rsa_md5, &checksum_rsa_md5_des, +#endif #ifdef DES3_OLD_ENCTYPE &checksum_rsa_md5_des3, #endif + &checksum_rsa_md5, &checksum_sha1, &checksum_hmac_sha1_des3, &checksum_hmac_sha1_aes128, @@ -1889,7 +1887,7 @@ verify_checksum(krb5_context context, } if(c.checksum.length != cksum->checksum.length || - memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) { + ct_memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) { krb5_clear_error_message (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { @@ -2060,7 +2058,103 @@ evp_encrypt(krb5_context context, return 0; } -#ifdef WEAK_ENCTYPES +static const char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 }; + +static krb5_error_code +evp_encrypt_cts(krb5_context context, + struct key_data *key, + void *data, + size_t len, + krb5_boolean encryptp, + int usage, + void *ivec) +{ + size_t i, blocksize; + struct evp_schedule *ctx = key->schedule->data; + char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH]; + EVP_CIPHER_CTX *c; + unsigned char *p; + + c = encryptp ? &ctx->ectx : &ctx->dctx; + + blocksize = EVP_CIPHER_CTX_block_size(c); + + if (len < blocksize) { + krb5_set_error_message(context, EINVAL, + "message block too short"); + return EINVAL; + } else if (len == blocksize) { + EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); + EVP_Cipher(c, data, data, len); + return 0; + } + + if (ivec) + EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1); + else + EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); + + if (encryptp) { + + p = data; + i = ((len - 1) / blocksize) * blocksize; + EVP_Cipher(c, p, p, i); + p += i - blocksize; + len -= i; + memcpy(ivec2, p, blocksize); + + for (i = 0; i < len; i++) + tmp[i] = p[i + blocksize] ^ ivec2[i]; + for (; i < blocksize; i++) + tmp[i] = 0 ^ ivec2[i]; + + EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); + EVP_Cipher(c, p, tmp, blocksize); + + memcpy(p + blocksize, ivec2, len); + if (ivec) + memcpy(ivec, p, blocksize); + } else { + char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH]; + + p = data; + if (len > blocksize * 2) { + /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */ + i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize); + memcpy(ivec2, p + i - blocksize, blocksize); + EVP_Cipher(c, p, p, i); + p += i; + len -= i + blocksize; + } else { + if (ivec) + memcpy(ivec2, ivec, blocksize); + else + memcpy(ivec2, zero_ivec, blocksize); + len -= blocksize; + } + + memcpy(tmp, p, blocksize); + EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); + EVP_Cipher(c, tmp2, p, blocksize); + + memcpy(tmp3, p + blocksize, len); + memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */ + + for (i = 0; i < len; i++) + p[i + blocksize] = tmp2[i] ^ tmp3[i]; + + EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); + EVP_Cipher(c, p, tmp3, blocksize); + + for (i = 0; i < blocksize; i++) + p[i] ^= ivec2[i]; + if (ivec) + memcpy(ivec, tmp, blocksize); + } + return 0; +} + +#ifdef HEIM_WEAK_CRYPTO static krb5_error_code evp_des_encrypt_null_ivec(krb5_context context, struct key_data *key, @@ -2149,12 +2243,12 @@ ARCFOUR_subencrypt(krb5_context context, unsigned usage, void *ivec) { + EVP_CIPHER_CTX ctx; struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); Checksum k1_c, k2_c, k3_c, cksum; struct key_data ke; krb5_keyblock kb; unsigned char t[4]; - RC4_KEY rc4_key; unsigned char *cdata = data; unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; krb5_error_code ret; @@ -2196,8 +2290,12 @@ ARCFOUR_subencrypt(krb5_context context, if (ret) krb5_abortx(context, "hmac failed"); - RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); - RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); + EVP_CIPHER_CTX_init(&ctx); + + EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 1); + EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16); + EVP_CIPHER_CTX_cleanup(&ctx); + memset (k1_c_data, 0, sizeof(k1_c_data)); memset (k2_c_data, 0, sizeof(k2_c_data)); memset (k3_c_data, 0, sizeof(k3_c_data)); @@ -2212,12 +2310,12 @@ ARCFOUR_subdecrypt(krb5_context context, unsigned usage, void *ivec) { + EVP_CIPHER_CTX ctx; struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); Checksum k1_c, k2_c, k3_c, cksum; struct key_data ke; krb5_keyblock kb; unsigned char t[4]; - RC4_KEY rc4_key; unsigned char *cdata = data; unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; unsigned char cksum_data[16]; @@ -2250,8 +2348,10 @@ ARCFOUR_subdecrypt(krb5_context context, if (ret) krb5_abortx(context, "hmac failed"); - RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); - RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); + EVP_CIPHER_CTX_init(&ctx); + EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 0); + EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16); + EVP_CIPHER_CTX_cleanup(&ctx); ke.key = &kb; kb.keyvalue = k2_c.checksum; @@ -2267,7 +2367,7 @@ ARCFOUR_subdecrypt(krb5_context context, memset (k2_c_data, 0, sizeof(k2_c_data)); memset (k3_c_data, 0, sizeof(k3_c_data)); - if (memcmp (cksum.checksum.data, data, 16) != 0) { + if (ct_memcmp (cksum.checksum.data, data, 16) != 0) { krb5_clear_error_message (context); return KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { @@ -2471,7 +2571,7 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = { &checksum_sha1, &checksum_hmac_sha1_aes128, F_DERIVED, - evp_encrypt, + evp_encrypt_cts, 16, AES_PRF }; @@ -2485,7 +2585,7 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = { &checksum_sha1, &checksum_hmac_sha1_aes256, F_DERIVED, - evp_encrypt, + evp_encrypt_cts, 16, AES_PRF }; @@ -2503,7 +2603,7 @@ static struct encryption_type enctype_des3_cbc_none = { 0, NULL }; -#ifdef WEAK_ENCTYPES +#ifdef HEIM_WEAK_CRYPTO static struct encryption_type enctype_des_cbc_crc = { ETYPE_DES_CBC_CRC, "des-cbc-crc", @@ -2588,7 +2688,7 @@ static struct encryption_type enctype_des_pcbc_none = { 0, NULL }; -#endif /* WEAK_ENCTYPES */ +#endif /* HEIM_WEAK_CRYPTO */ static struct encryption_type *etypes[] = { &enctype_aes256_cts_hmac_sha1, @@ -2600,7 +2700,7 @@ static struct encryption_type *etypes[] = { &enctype_des3_cbc_md5, &enctype_old_des3_cbc_sha1, #endif -#ifdef WEAK_ENCTYPES +#ifdef HEIM_WEAK_CRYPTO &enctype_des_cbc_crc, &enctype_des_cbc_md4, &enctype_des_cbc_md5, @@ -3584,6 +3684,7 @@ krb5_create_checksum_iov(krb5_context context, * @param usage Key usage for this buffer * @param data array of buffers to process * @param num_data length of array + * @param type return checksum type if not NULL * * @return Return an error code or 0. * @ingroup krb5_crypto @@ -4044,6 +4145,23 @@ _get_derived_key(krb5_context context, return 0; } +/** + * Create a crypto context used for all encryption and signature + * operation. The encryption type to use is taken from the key, but + * can be overridden with the enctype parameter. This can be useful + * for encryptions types which is compatiable (DES for example). + * + * To free the crypto context, use krb5_crypto_destroy(). + * + * @param context Kerberos context + * @param key the key block information with all key data + * @param etype the encryption type + * @param crypto the resulting crypto context + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_init(krb5_context context, @@ -4116,6 +4234,17 @@ free_key_usage(krb5_context context, struct key_usage *ku, free_key_data(context, &ku->key, et); } +/** + * Free a crypto context created by krb5_crypto_init(). + * + * @param context Kerberos context + * @param crypto crypto context to free + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_destroy(krb5_context context, krb5_crypto crypto) @@ -4130,6 +4259,18 @@ krb5_crypto_destroy(krb5_context context, return 0; } +/** + * Return the blocksize used algorithm referenced by the crypto context + * + * @param context Kerberos context + * @param crypto crypto context to query + * @param blocksize the resulting blocksize + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getblocksize(krb5_context context, krb5_crypto crypto, @@ -4139,6 +4280,18 @@ krb5_crypto_getblocksize(krb5_context context, return 0; } +/** + * Return the encryption type used by the crypto context + * + * @param context Kerberos context + * @param crypto crypto context to query + * @param enctype the resulting encryption type + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getenctype(krb5_context context, krb5_crypto crypto, @@ -4148,6 +4301,18 @@ krb5_crypto_getenctype(krb5_context context, return 0; } +/** + * Return the padding size used by the crypto context + * + * @param context Kerberos context + * @param crypto crypto context to query + * @param padsize the return padding size + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getpadsize(krb5_context context, krb5_crypto crypto, @@ -4157,6 +4322,18 @@ krb5_crypto_getpadsize(krb5_context context, return 0; } +/** + * Return the confounder size used by the crypto context + * + * @param context Kerberos context + * @param crypto crypto context to query + * @param confoundersize the returned confounder size + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getconfoundersize(krb5_context context, krb5_crypto crypto, @@ -4386,8 +4563,8 @@ krb5_crypto_overhead (krb5_context context, krb5_crypto crypto) * @param context Kerberos 5 context * @param type the enctype resulting key will be of * @param data input random data to convert to a key - * @param data size of input random data, at least krb5_enctype_keysize() long - * @param data key, output key, free with krb5_free_keyblock_contents() + * @param size size of input random data, at least krb5_enctype_keysize() long + * @param key key, output key, free with krb5_free_keyblock_contents() * * @return Return an error code or 0. * @@ -4444,6 +4621,7 @@ _krb5_pk_octetstring2key(krb5_context context, void *keydata; unsigned char counter; unsigned char shaoutput[SHA_DIGEST_LENGTH]; + EVP_MD_CTX *m; if(et == NULL) { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, @@ -4459,19 +4637,27 @@ _krb5_pk_octetstring2key(krb5_context context, return ENOMEM; } + m = EVP_MD_CTX_create(); + if (m == NULL) { + free(keydata); + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + return ENOMEM; + } + counter = 0; offset = 0; do { - SHA_CTX m; - SHA1_Init(&m); - SHA1_Update(&m, &counter, 1); - SHA1_Update(&m, dhdata, dhsize); + EVP_DigestInit_ex(m, EVP_sha1(), NULL); + EVP_DigestUpdate(m, &counter, 1); + EVP_DigestUpdate(m, dhdata, dhsize); + if (c_n) - SHA1_Update(&m, c_n->data, c_n->length); + EVP_DigestUpdate(m, c_n->data, c_n->length); if (k_n) - SHA1_Update(&m, k_n->data, k_n->length); - SHA1_Final(shaoutput, &m); + EVP_DigestUpdate(m, k_n->data, k_n->length); + + EVP_DigestFinal_ex(m, shaoutput, NULL); memcpy((unsigned char *)keydata + offset, shaoutput, @@ -4482,6 +4668,8 @@ _krb5_pk_octetstring2key(krb5_context context, } while(offset < keylen); memset(shaoutput, 0, sizeof(shaoutput)); + EVP_MD_CTX_destroy(m); + ret = krb5_random_to_key(context, type, keydata, keylen, key); memset(keydata, 0, sizeof(keylen)); free(keydata); @@ -4595,6 +4783,7 @@ _krb5_pk_kdf(krb5_context context, uint32_t counter; unsigned char *keydata; unsigned char shaoutput[SHA_DIGEST_LENGTH]; + EVP_MD_CTX *m; if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) != 0) { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, @@ -4633,18 +4822,26 @@ _krb5_pk_kdf(krb5_context context, return ret; } + m = EVP_MD_CTX_create(); + if (m == NULL) { + free(keydata); + free(other.data); + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + return ENOMEM; + } + offset = 0; counter = 1; do { unsigned char cdata[4]; - SHA_CTX m; - SHA1_Init(&m); + EVP_DigestInit_ex(m, EVP_sha1(), NULL); _krb5_put_int(cdata, counter, 4); - SHA1_Update(&m, cdata, 4); - SHA1_Update(&m, dhdata, dhsize); - SHA1_Update(&m, other.data, other.length); - SHA1_Final(shaoutput, &m); + EVP_DigestUpdate(m, cdata, 4); + EVP_DigestUpdate(m, dhdata, dhsize); + EVP_DigestUpdate(m, other.data, other.length); + + EVP_DigestFinal_ex(m, shaoutput, NULL); memcpy((unsigned char *)keydata + offset, shaoutput, @@ -4655,6 +4852,7 @@ _krb5_pk_kdf(krb5_context context, } while(offset < keylen); memset(shaoutput, 0, sizeof(shaoutput)); + EVP_MD_CTX_destroy(m); free(other.data); ret = krb5_random_to_key(context, enctype, keydata, keylen, key); @@ -4765,7 +4963,7 @@ krb5_crypto_prfplus(krb5_context context, * @param crypto1 first key to combine * @param crypto2 second key to combine * @param pepper1 factor to combine with first key to garante uniqueness - * @param pepper1 factor to combine with second key to garante uniqueness + * @param pepper2 factor to combine with second key to garante uniqueness * @param enctype the encryption type of the resulting key * @param res allocated key, free with krb5_free_keyblock_contents() * diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index ff89a90d55..5363d533e7 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -398,6 +398,9 @@ get_init_creds_common(krb5_context context, } } if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { + if (ctx->etypes) + free(ctx->etypes); + etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); if (etypes == NULL) { @@ -1417,10 +1420,17 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_keytab keytab) { krb5_keytab_key_proc_args *a; + krb5_keytab_entry entry; + krb5_kt_cursor cursor; + krb5_enctype *etypes = NULL; + krb5_error_code ret; + size_t netypes = 0; + int kvno = 0; a = malloc(sizeof(*a)); if (a == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + krb5_set_error_message(context, ENOMEM, + N_("malloc: out of memory", "")); return ENOMEM; } @@ -1431,6 +1441,58 @@ krb5_init_creds_set_keytab(krb5_context context, ctx->keyseed = (void *)a; ctx->keyproc = keytab_key_proc; + /* + * We need to the KDC what enctypes we support for this keytab, + * esp if the keytab is really a password based entry, then the + * KDC might have more enctypes in the database then what we have + * in the keytab. + */ + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if(ret) + goto out; + + while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0){ + void *ptr; + + if (!krb5_principal_compare(context, entry.principal, ctx->cred.client)) + goto next; + + /* check if we ahve this kvno already */ + if (entry.vno > kvno) { + /* remove old list of etype */ + if (etypes) + free(etypes); + netypes = 0; + kvno = entry.vno; + } else if (entry.vno != kvno) + goto next; + + /* check if enctype is supported */ + if (krb5_enctype_valid(context, entry.keyblock.keytype) != 0) + goto next; + + /* add enctype to supported list */ + ptr = realloc(etypes, sizeof(etypes[0]) * (netypes + 2)); + if (ptr == NULL) + goto next; + + etypes = ptr; + etypes[netypes] = entry.keyblock.keytype; + etypes[netypes + 1] = ETYPE_NULL; + netypes++; + next: + krb5_kt_free_entry(context, &entry); + } + krb5_kt_end_seq_get(context, keytab, &cursor); + + if (etypes) { + if (ctx->etypes) + free(ctx->etypes); + ctx->etypes = etypes; + } + + out: return 0; } diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index 57ed7875fc..046caee6d6 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -97,7 +97,7 @@ krb5_free_keyblock(krb5_context context, * @param inblock the key to copy * @param to the output key. * - * @param 0 on success or a Kerberos 5 error code + * @return 0 on success or a Kerberos 5 error code * * @ingroup krb5_crypto */ @@ -118,7 +118,7 @@ krb5_copy_keyblock_contents (krb5_context context, * @param inblock the key to copy * @param to the output key. * - * @param 0 on success or a Kerberos 5 error code + * @return 0 on success or a Kerberos 5 error code * * @ingroup krb5_crypto */ @@ -165,6 +165,8 @@ krb5_keyblock_get_enctype(const krb5_keyblock *block) * Fill in `key' with key data of type `enctype' from `data' of length * `size'. Key should be freed using krb5_free_keyblock_contents(). * + * @return 0 on success or a Kerberos 5 error code + * * @ingroup krb5_crypto */ diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index b56219cced..71dc1327c6 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -234,7 +234,8 @@ typedef struct krb5_context_data { krb5_config_section *cf; struct et_list *et_list; struct krb5_log_facility *warn_dest; - krb5_cc_ops *cc_ops; + struct krb5_log_facility *debug_dest; + const krb5_cc_ops **cc_ops; int num_cc_ops; const char *http_proxy; const char *time_fmt; diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index e9111abec9..4e4b4562e5 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -86,8 +86,11 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm); r = rk_dns_lookup(domain, dns_type); - if(r == NULL) + if(r == NULL) { + _krb5_debug(context, 0, + "DNS lookup failed domain: %s", domain); return KRB5_KDC_UNREACH; + } for(num_srv = 0, rr = r->head; rr; rr = rr->next) if(rr->type == rk_ns_t_srv) @@ -176,6 +179,15 @@ krbhst_get_default_proto(struct krb5_krbhst_data *kd) return KRB5_KRBHST_UDP; } +/* + * + */ + +const char * +_krb5_krbhst_get_realm(krb5_krbhst_handle handle) +{ + return handle->realm; +} /* * parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port' @@ -186,7 +198,7 @@ static struct krb5_krbhst_info* parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd, const char *spec, int def_port, int port) { - const char *p = spec; + const char *p = spec, *q; struct krb5_krbhst_info *hi; hi = calloc(1, sizeof(*hi) + strlen(spec)); @@ -209,7 +221,17 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd, p += 4; } - if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) { + if (p[0] == '[' && (q = strchr(p, ']')) != NULL) { + /* if address looks like [foo:bar] or [foo:bar]: its a ipv6 + adress, strip of [] */ + memcpy(hi->hostname, &p[1], q - p - 1); + hi->hostname[q - p - 1] = '\0'; + p = q + 1; + /* get trailing : */ + if (p[0] == ':') + p++; + } else if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) { + /* copy everything before : */ free(hi); return NULL; } @@ -218,7 +240,7 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd, strlwr(hi->hostname); hi->port = hi->def_port = def_port; - if(p != NULL) { + if(p != NULL && p[0]) { char *end; hi->port = strtol(p, &end, 0); if(end == p) { @@ -374,11 +396,15 @@ static void srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, const char *proto, const char *service) { + krb5_error_code ret; krb5_krbhst_info **res; int count, i; - if (srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service, - kd->port)) + ret = srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service, + kd->port); + _krb5_debug(context, 2, "searching DNS for realm %s %s.%s -> %d", + kd->realm, proto, service, ret); + if (ret) return; for(i = 0; i < count; i++) append_host_hostinfo(kd, res[i]); @@ -395,11 +421,13 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, const char *conf_string) { int i; - char **hostlist; hostlist = krb5_config_get_strings(context, NULL, "realms", kd->realm, conf_string, NULL); + _krb5_debug(context, 2, "configuration file for realm %s%s found", + kd->realm, hostlist ? "" : " not"); + if(hostlist == NULL) return; kd->flags |= KD_CONFIG_EXISTS; @@ -426,6 +454,9 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, struct addrinfo hints; char portstr[NI_MAXSERV]; + _krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)", + kd->fallback_count, kd->realm, serv_string); + /* * Don't try forever in case the DNS server keep returning us * entries (like wildcard entries or the .nu TLD) @@ -545,8 +576,10 @@ plugin_get_hosts(krb5_context context, N_("Locate plugin failed to lookup realm %s: %d", ""), kd->realm, ret); break; - } else if (ret == 0) + } else if (ret == 0) { + _krb5_debug(context, 2, "plugin found result for realm %s", kd->realm); kd->flags |= KD_CONFIG_EXISTS; + } } _krb5_plugin_free(list); @@ -577,8 +610,12 @@ kdc_get_next(krb5_context context, return 0; } - if (kd->flags & KD_CONFIG_EXISTS) - return KRB5_KDC_UNREACH; /* XXX */ + if (kd->flags & KD_CONFIG_EXISTS) { + _krb5_debug(context, 1, + "Configuration exists for realm %s, wont go to DNS", + kd->realm); + return KRB5_KDC_UNREACH; + } if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) { @@ -612,6 +649,8 @@ kdc_get_next(krb5_context context, return 0; } + _krb5_debug(context, 0, "No KDC entries found for %s", kd->realm); + return KRB5_KDC_UNREACH; /* XXX */ } @@ -636,8 +675,12 @@ admin_get_next(krb5_context context, return 0; } - if (kd->flags & KD_CONFIG_EXISTS) - return KRB5_KDC_UNREACH; /* XXX */ + if (kd->flags & KD_CONFIG_EXISTS) { + _krb5_debug(context, 1, + "Configuration exists for realm %s, wont go to DNS", + kd->realm); + return KRB5_KDC_UNREACH; + } if(context->srv_lookup) { if((kd->flags & KD_SRV_TCP) == 0) { @@ -660,6 +703,8 @@ admin_get_next(krb5_context context, return 0; } + _krb5_debug(context, 0, "No admin entries found for realm %s", kd->realm); + return KRB5_KDC_UNREACH; /* XXX */ } @@ -684,8 +729,12 @@ kpasswd_get_next(krb5_context context, return 0; } - if (kd->flags & KD_CONFIG_EXISTS) - return KRB5_KDC_UNREACH; /* XXX */ + if (kd->flags & KD_CONFIG_EXISTS) { + _krb5_debug(context, 1, + "Configuration exists for realm %s, wont go to DNS", + kd->realm); + return KRB5_KDC_UNREACH; + } if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0) { @@ -714,7 +763,9 @@ kpasswd_get_next(krb5_context context, return ret; } - return KRB5_KDC_UNREACH; /* XXX */ + _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm); + + return KRB5_KDC_UNREACH; } static krb5_error_code @@ -736,8 +787,12 @@ krb524_get_next(krb5_context context, kd->flags |= KD_CONFIG; } - if (kd->flags & KD_CONFIG_EXISTS) - return KRB5_KDC_UNREACH; /* XXX */ + if (kd->flags & KD_CONFIG_EXISTS) { + _krb5_debug(context, 1, + "Configuration exists for realm %s, wont go to DNS", + kd->realm); + return KRB5_KDC_UNREACH; + } if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0) { @@ -764,11 +819,14 @@ krb524_get_next(krb5_context context, return (*kd->get_next)(context, kd, host); } - return KRB5_KDC_UNREACH; /* XXX */ + _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm); + + return KRB5_KDC_UNREACH; } static struct krb5_krbhst_data* common_init(krb5_context context, + const char *service, const char *realm, int flags) { @@ -782,6 +840,9 @@ common_init(krb5_context context, return NULL; } + _krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x", + service, realm, flags); + /* For 'realms' without a . do not even think of going to DNS */ if (!strchr(realm, '.')) kd->flags |= KD_CONFIG_EXISTS; @@ -816,32 +877,37 @@ krb5_krbhst_init_flags(krb5_context context, krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *, krb5_krbhst_info **); int def_port; + const char *service; switch(type) { case KRB5_KRBHST_KDC: next = kdc_get_next; def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88)); + service = "kdc"; break; case KRB5_KRBHST_ADMIN: next = admin_get_next; def_port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749)); + service = "admin"; break; case KRB5_KRBHST_CHANGEPW: next = kpasswd_get_next; def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp", KPASSWD_PORT)); + service = "change_password"; break; case KRB5_KRBHST_KRB524: next = krb524_get_next; def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444)); + service = "524"; break; default: krb5_set_error_message(context, ENOTTY, N_("unknown krbhst type (%u)", ""), type); return ENOTTY; } - if((kd = common_init(context, realm, flags)) == NULL) + if((kd = common_init(context, service, realm, flags)) == NULL) return ENOMEM; kd->get_next = next; kd->def_port = def_port; diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index 5b84bc2f4c..9f81460973 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -488,3 +488,19 @@ krb5_log(krb5_context context, return ret; } +void KRB5_LIB_FUNCTION +_krb5_debug(krb5_context context, + int level, + const char *fmt, + ...) + __attribute__((format (printf, 3, 4))) +{ + va_list ap; + + if (context == NULL || context->debug_dest == NULL) + return; + + va_start(ap, fmt); + krb5_vlog(context, context->debug_dest, level, fmt, ap); + va_end(ap); +} diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index af5568f44b..2f6d7854a5 100644 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -1161,24 +1161,6 @@ pk_rd_pa_reply_enckey(krb5_context context, } der_free_oid(&contentType); -#if 0 /* windows LH with interesting CMS packets, leaks memory */ - { - size_t ph = 1 + der_length_len (length); - unsigned char *ptr = malloc(length + ph); - size_t l; - - memcpy(ptr + ph, p, length); - - ret = der_put_length_and_tag (ptr + ph - 1, ph, length, - ASN1_C_UNIV, CONS, UT_Sequence, &l); - if (ret) - return ret; - ptr += ph - l; - length += l; - p = ptr; - } -#endif - /* win2k uses ContentInfo */ if (type == PKINIT_WIN2K) { heim_oid type; @@ -1882,11 +1864,12 @@ pk_copy_error(krb5_context context, { va_list va; char *s, *f; + int ret; va_start(va, fmt); - vasprintf(&f, fmt, va); + ret = vasprintf(&f, fmt, va); va_end(va); - if (f == NULL) { + if (ret == -1 || f == NULL) { krb5_clear_error_message(context); return; } @@ -2203,13 +2186,15 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt) ctx = opt->opt_private->pk_init_ctx; switch (ctx->keyex) { case USE_DH: - DH_free(ctx->u.dh); + if (ctx->u.dh) + DH_free(ctx->u.dh); break; case USE_RSA: break; case USE_ECDH: #ifdef HAVE_OPENSSL - EC_KEY_free(ctx->u.eckey); + if (ctx->u.eckey) + EC_KEY_free(ctx->u.eckey); #endif break; } diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 9899f5661f..1483d59f9d 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -425,6 +425,19 @@ unparse_name_fixed(krb5_context context, return 0; } +/** + * Unparse the principal name to a fixed buffer + * + * @param context A Kerberos context. + * @param principal principal to unparse + * @param name buffer to write name to + * @param len length of buffer + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_fixed(krb5_context context, krb5_const_principal principal, @@ -434,6 +447,20 @@ krb5_unparse_name_fixed(krb5_context context, return unparse_name_fixed(context, principal, name, len, 0); } +/** + * Unparse the principal name to a fixed buffer. The realm is skipped + * if its a default realm. + * + * @param context A Kerberos context. + * @param principal principal to unparse + * @param name buffer to write name to + * @param len length of buffer + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_fixed_short(krb5_context context, krb5_const_principal principal, @@ -444,6 +471,20 @@ krb5_unparse_name_fixed_short(krb5_context context, KRB5_PRINCIPAL_UNPARSE_SHORT); } +/** + * Unparse the principal name with unparse flags to a fixed buffer. + * + * @param context A Kerberos context. + * @param principal principal to unparse + * @param flags unparse flags + * @param name buffer to write name to + * @param len length of buffer + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_fixed_flags(krb5_context context, krb5_const_principal principal, @@ -538,6 +579,19 @@ krb5_unparse_name_flags(krb5_context context, return unparse_name(context, principal, name, flags); } +/** + * Unparse the principal name to a allocated buffer. The realm is + * skipped if its a default realm. + * + * @param context A Kerberos context. + * @param principal principal to unparse + * @param name returned buffer, free with krb5_xfree() + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_short(krb5_context context, krb5_const_principal principal, @@ -546,18 +600,18 @@ krb5_unparse_name_short(krb5_context context, return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT); } -#if 0 /* not implemented */ - -krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_ext(krb5_context context, - krb5_const_principal principal, - char **name, - size_t *size) -{ - krb5_abortx(context, "unimplemented krb5_unparse_name_ext called"); -} - -#endif +/** + * Set a new realm for a principal, and as a side-effect free the + * previous realm. + * + * @param context A Kerberos context. + * @param principal principal set the realm for + * @param realm the new realm to set + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ krb5_error_code KRB5_LIB_FUNCTION krb5_principal_set_realm(krb5_context context, diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c index 37556cfbc5..be484c29dc 100644 --- a/source4/heimdal/lib/krb5/replay.c +++ b/source4/heimdal/lib/krb5/replay.c @@ -178,17 +178,20 @@ krb5_rc_close(krb5_context context, static void checksum_authenticator(Authenticator *auth, void *data) { - MD5_CTX md5; - int i; + EVP_MD_CTX *m = EVP_MD_CTX_create(); + unsigned i; - MD5_Init (&md5); - MD5_Update (&md5, auth->crealm, strlen(auth->crealm)); + EVP_DigestInit_ex(m, EVP_md5(), NULL); + + EVP_DigestUpdate(m, auth->crealm, strlen(auth->crealm)); for(i = 0; i < auth->cname.name_string.len; i++) - MD5_Update(&md5, auth->cname.name_string.val[i], + EVP_DigestUpdate(m, auth->cname.name_string.val[i], strlen(auth->cname.name_string.val[i])); - MD5_Update (&md5, &auth->ctime, sizeof(auth->ctime)); - MD5_Update (&md5, &auth->cusec, sizeof(auth->cusec)); - MD5_Final (data, &md5); + EVP_DigestUpdate(m, &auth->ctime, sizeof(auth->ctime)); + EVP_DigestUpdate(m, &auth->cusec, sizeof(auth->cusec)); + + EVP_DigestFinal_ex(m, data, NULL); + EVP_MD_CTX_destroy(m); } krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index 50b42f2f10..0efe14eb4f 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -379,6 +379,10 @@ krb5_sendto (krb5_context context, while (krb5_krbhst_next(context, handle, &hi) == 0) { struct addrinfo *ai, *a; + _krb5_debug(context, 2, + "trying to communicate with host %s in realm %s", + hi->hostname, _krb5_krbhst_get_realm(handle)); + if (context->send_to_kdc) { struct send_to_kdc *s = context->send_to_kdc; @@ -441,6 +445,9 @@ krb5_sendto (krb5_context context, krb5_clear_error_message (context); ret = KRB5_KDC_UNREACH; out: + _krb5_debug(context, 2, + "result of trying to talk to realm %s = %d", + _krb5_krbhst_get_realm(handle), ret); return ret; } diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c index 2ba83ef0d5..6e1374adf9 100644 --- a/source4/heimdal/lib/krb5/store.c +++ b/source4/heimdal/lib/krb5/store.c @@ -40,12 +40,30 @@ #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \ krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER)) +/** + * Add the flags on a storage buffer by or-ing in the flags to the buffer. + * + * @param sp the storage buffer to set the flags on + * @param flags the flags to set + * + * @ingroup krb5_storage + */ + void KRB5_LIB_FUNCTION krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags) { sp->flags |= flags; } +/** + * Clear the flags on a storage buffer + * + * @param sp the storage buffer to clear the flags on + * @param flags the flags to clear + * + * @ingroup krb5_storage + */ + void KRB5_LIB_FUNCTION krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags) { @@ -359,6 +377,18 @@ krb5_ret_int(krb5_storage *sp, return 0; } +/** + * Read a int32 from storage, byte order is controlled by the settings + * on the storage, see krb5_storage_set_byteorder(). + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int32(krb5_storage *sp, int32_t *value) @@ -373,6 +403,18 @@ krb5_ret_int32(krb5_storage *sp, return 0; } +/** + * Read a uint32 from storage, byte order is controlled by the settings + * on the storage, see krb5_storage_set_byteorder(). + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_uint32(krb5_storage *sp, uint32_t *value) @@ -429,6 +471,17 @@ krb5_store_uint16(krb5_storage *sp, return krb5_store_int16(sp, (int16_t)value); } +/** + * Read a int16 from storage, byte order is controlled by the settings + * on the storage, see krb5_storage_set_byteorder(). + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int16(krb5_storage *sp, int16_t *value) @@ -446,6 +499,18 @@ krb5_ret_int16(krb5_storage *sp, return 0; } +/** + * Read a int16 from storage, byte order is controlled by the settings + * on the storage, see krb5_storage_set_byteorder(). + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_uint16(krb5_storage *sp, uint16_t *value) @@ -501,6 +566,17 @@ krb5_store_uint8(krb5_storage *sp, return krb5_store_int8(sp, (int8_t)value); } +/** + * Read a int8 from storage + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int8(krb5_storage *sp, int8_t *value) @@ -513,6 +589,17 @@ krb5_ret_int8(krb5_storage *sp, return 0; } +/** + * Read a uint8 from storage + * + * @param sp the storage to write too + * @param value the value read from the buffer + * + * @return 0 for success, or a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_uint8(krb5_storage *sp, uint8_t *value) @@ -528,7 +615,8 @@ krb5_ret_uint8(krb5_storage *sp, } /** - * Store a data to the storage. + * Store a data to the storage. The data is stored with an int32 as + * lenght plus the data (not padded). * * @param sp the storage buffer to write to * @param data the buffer to store. @@ -587,6 +675,18 @@ krb5_ret_data(krb5_storage *sp, return 0; } +/** + * Store a string to the buffer. The data is formated as an len:uint32 + * plus the string itself (not padded). + * + * @param sp the storage buffer to write to + * @param s the string to store. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_store_string(krb5_storage *sp, const char *s) { @@ -596,6 +696,18 @@ krb5_store_string(krb5_storage *sp, const char *s) return krb5_store_data(sp, data); } +/** + * Parse a string from the storage. + * + * @param sp the storage buffer to read from + * @param string the parsed string + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_string(krb5_storage *sp, char **string) @@ -614,6 +726,18 @@ krb5_ret_string(krb5_storage *sp, return 0; } +/** + * Store a zero terminated string to the buffer. The data is stored + * one character at a time until a NUL is stored. + * + * @param sp the storage buffer to write to + * @param s the string to store. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_store_stringz(krb5_storage *sp, const char *s) { @@ -630,6 +754,17 @@ krb5_store_stringz(krb5_storage *sp, const char *s) return 0; } +/** + * Parse zero terminated string from the storage. + * + * @param sp the storage buffer to read from + * @param string the parsed string + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_stringz(krb5_storage *sp, char **string) @@ -733,6 +868,16 @@ krb5_ret_stringnl(krb5_storage *sp, return 0; } +/** + * Write a principal block to storage. + * + * @param sp the storage buffer to write to + * @param p the principal block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ krb5_error_code KRB5_LIB_FUNCTION krb5_store_principal(krb5_storage *sp, @@ -760,6 +905,17 @@ krb5_store_principal(krb5_storage *sp, return 0; } +/** + * Parse principal from the storage. + * + * @param sp the storage buffer to read from + * @param princ the parsed principal + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_principal(krb5_storage *sp, krb5_principal *princ) @@ -931,6 +1087,17 @@ krb5_ret_times(krb5_storage *sp, krb5_times *times) return ret; } +/** + * Write a address block to storage. + * + * @param sp the storage buffer to write to + * @param p the address block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_store_address(krb5_storage *sp, krb5_address p) { @@ -941,6 +1108,17 @@ krb5_store_address(krb5_storage *sp, krb5_address p) return ret; } +/** + * Read a address block from the storage. + * + * @param sp the storage buffer to write to + * @param adr the address block read from storage + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_address(krb5_storage *sp, krb5_address *adr) { @@ -953,6 +1131,17 @@ krb5_ret_address(krb5_storage *sp, krb5_address *adr) return ret; } +/** + * Write a addresses block to storage. + * + * @param sp the storage buffer to write to + * @param p the addresses block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_store_addrs(krb5_storage *sp, krb5_addresses p) { @@ -967,6 +1156,17 @@ krb5_store_addrs(krb5_storage *sp, krb5_addresses p) return ret; } +/** + * Read a addresses block from the storage. + * + * @param sp the storage buffer to write to + * @param adr the addresses block read from storage + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) { @@ -987,6 +1187,17 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) return ret; } +/** + * Write a auth data block to storage. + * + * @param sp the storage buffer to write to + * @param auth the auth data block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) { @@ -1003,6 +1214,17 @@ krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) return 0; } +/** + * Read a auth data from the storage. + * + * @param sp the storage buffer to write to + * @param auth the auth data block read from storage + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) { @@ -1037,9 +1259,15 @@ bitswap32(int32_t b) return r; } - -/* +/** + * Write a credentials block to storage. + * + * @param sp the storage buffer to write to + * @param creds the creds block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. * + * @ingroup krb5_storage */ krb5_error_code KRB5_LIB_FUNCTION @@ -1083,6 +1311,17 @@ krb5_store_creds(krb5_storage *sp, krb5_creds *creds) return ret; } +/** + * Read a credentials block from the storage. + * + * @param sp the storage buffer to write to + * @param creds the credentials block read from storage + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) { @@ -1144,8 +1383,15 @@ cleanup: #define SC_AUTHDATA 0x0020 #define SC_ADDRESSES 0x0040 -/* +/** + * Write a tagged credentials block to storage. + * + * @param sp the storage buffer to write to + * @param creds the creds block to write. + * + * @return 0 on success, a Kerberos 5 error code on failure. * + * @ingroup krb5_storage */ krb5_error_code KRB5_LIB_FUNCTION @@ -1229,6 +1475,17 @@ krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) return ret; } +/** + * Read a tagged credentials block from the storage. + * + * @param sp the storage buffer to write to + * @param creds the credentials block read from storage + * + * @return 0 on success, a Kerberos 5 error code on failure. + * + * @ingroup krb5_storage + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ret_creds_tag(krb5_storage *sp, krb5_creds *creds) diff --git a/source4/heimdal/lib/krb5/store_mem.c b/source4/heimdal/lib/krb5/store_mem.c index a7b0c2d2dc..a913e182d5 100644 --- a/source4/heimdal/lib/krb5/store_mem.c +++ b/source4/heimdal/lib/krb5/store_mem.c @@ -110,7 +110,7 @@ mem_no_trunc(krb5_storage *sp, off_t offset) } /** - * + * Create a fixed size memory storage block * * @return A krb5_storage on success, or NULL on out of memory error. * @@ -149,7 +149,7 @@ krb5_storage_from_mem(void *buf, size_t len) } /** - * + * Create a fixed size memory storage block * * @return A krb5_storage on success, or NULL on out of memory error. * @@ -168,7 +168,7 @@ krb5_storage_from_data(krb5_data *data) } /** - * + * Create a fixed size memory storage block that is read only * * @return A krb5_storage on success, or NULL on out of memory error. * diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 86c4924506..3bd9387906 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -33,6 +33,18 @@ #include "krb5_locl.h" +/** + * Free ticket and content + * + * @param context a Kerberos 5 context + * @param ticket ticket to free + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_free_ticket(krb5_context context, krb5_ticket *ticket) @@ -44,6 +56,19 @@ krb5_free_ticket(krb5_context context, return 0; } +/** + * Copy ticket and content + * + * @param context a Kerberos 5 context + * @param from ticket to copy + * @param to new copy of ticket, free with krb5_free_ticket() + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_ticket(krb5_context context, const krb5_ticket *from, @@ -80,6 +105,19 @@ krb5_copy_ticket(krb5_context context, return 0; } +/** + * Return client principal in ticket + * + * @param context a Kerberos 5 context + * @param ticket ticket to copy + * @param client client principal, free with krb5_free_principal() + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ticket_get_client(krb5_context context, const krb5_ticket *ticket, @@ -88,6 +126,19 @@ krb5_ticket_get_client(krb5_context context, return krb5_copy_principal(context, ticket->client, client); } +/** + * Return server principal in ticket + * + * @param context a Kerberos 5 context + * @param ticket ticket to copy + * @param server server principal, free with krb5_free_principal() + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_ticket_get_server(krb5_context context, const krb5_ticket *ticket, @@ -96,6 +147,17 @@ krb5_ticket_get_server(krb5_context context, return krb5_copy_principal(context, ticket->server, server); } +/** + * Return end time of ticket + * + * @param context a Kerberos 5 context + * @param ticket ticket to copy + * + * @return end time of ticket + * + * @ingroup krb5 + */ + time_t KRB5_LIB_FUNCTION krb5_ticket_get_endtime(krb5_context context, const krb5_ticket *ticket) @@ -261,10 +323,17 @@ out: return ret; } -/* - * Extract the authorization data type of `type' from the - * 'ticket'. Store the field in `data'. This function is to use for - * kerberos applications. +/** + * Extract the authorization data type of type from the ticket. Store + * the field in data. This function is to use for kerberos + * applications. + * + * @param context a Kerberos 5 context + * @param ticket Kerberos ticket + * @param type type to fetch + * @param data returned data, free with krb5_data_free() + * + * @ingroup krb5 */ krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index b88b2004fb..05239186ec 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -269,7 +269,7 @@ krb5_vabort(krb5_context context, krb5_error_code code, } /** - * Log a warning to the log, default stderr, include bthe error from + * Log a warning to the log, default stderr, include the error from * the last failure and then abort. * * @param context A Kerberos 5 context |