diff options
author | Nalin Dahyabhai <nalin@redhat.com> | 2013-05-28 17:21:45 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin@redhat.com> | 2013-05-28 17:21:45 -0400 |
commit | 827a48f7cc301b20172f12b625f9a40ff838a4a4 (patch) | |
tree | b7f8d1a68226ca7136c6b054a54d2905a6e3f67b | |
parent | 2fdc61e398ea4a9d89cbc2c5816faad6babb1925 (diff) | |
download | krb5-827a48f7cc301b20172f12b625f9a40ff838a4a4.tar.gz krb5-827a48f7cc301b20172f12b625f9a40ff838a4a4.tar.xz krb5-827a48f7cc301b20172f12b625f9a40ff838a4a4.zip |
Fix handling of empty passwords in get-init-creds
-rw-r--r-- | krb5-1.11.2-arcfour_short.patch | 122 | ||||
-rw-r--r-- | krb5-1.11.2-empty_passwords.patch | 492 | ||||
-rw-r--r-- | krb5.spec | 6 |
3 files changed, 620 insertions, 0 deletions
diff --git a/krb5-1.11.2-arcfour_short.patch b/krb5-1.11.2-arcfour_short.patch new file mode 100644 index 0000000..2f67ae3 --- /dev/null +++ b/krb5-1.11.2-arcfour_short.patch @@ -0,0 +1,122 @@ +Needed by tests for empty-password cases. + +commit 1e123231769fe640f446442cb210664d280ccbac +Author: Greg Hudson <ghudson@mit.edu> +Date: Fri May 24 13:16:52 2013 -0400 + + Fix rc4 string-to-key on unterminated inputs + + The internal UTF-8 to UCS-2 conversion functions did not properly + respect their length arguments, instead assuming that the input string + is terminated with a zero bytes. As a result, + krb5int_arcfour_string_to_key could fail on unterminated inputs. Fix + the underlying support functions to read their inputs only up to the + specified length. + + ticket: 7643 (new) + +diff --git a/src/util/support/utf8_conv.c b/src/util/support/utf8_conv.c +index d580bbc..b8bf989 100644 +--- a/src/util/support/utf8_conv.c ++++ b/src/util/support/utf8_conv.c +@@ -78,7 +78,8 @@ k5_utf8s_to_ucs2s(krb5_ucs2 *ucs2str, + + /* If input ptr is NULL or empty... */ + if (utf8str == NULL || *utf8str == '\0') { +- *ucs2str = 0; ++ if (ucs2str != NULL) ++ *ucs2str = 0; + + return 0; + } +@@ -119,9 +120,7 @@ k5_utf8s_to_ucs2s(krb5_ucs2 *ucs2str, + ucs2len++; /* Count number of wide chars stored/required */ + } + +- assert(ucs2len < count); +- +- if (ucs2str != NULL) { ++ if (ucs2str != NULL && ucs2len < count) { + /* Add null terminator if there's room in the buffer. */ + ucs2str[ucs2len] = 0; + } +@@ -172,12 +171,13 @@ krb5int_utf8cs_to_ucs2s(const char *utf8s, + return ENOMEM; + } + +- len = k5_utf8s_to_ucs2s(*ucs2s, utf8s, chars + 1, 0); ++ len = k5_utf8s_to_ucs2s(*ucs2s, utf8s, chars, 0); + if (len < 0) { + free(*ucs2s); + *ucs2s = NULL; + return EINVAL; + } ++ (*ucs2s)[chars] = 0; + + if (ucs2chars != NULL) { + *ucs2chars = chars; +@@ -223,21 +223,23 @@ krb5int_utf8cs_to_ucs2les(const char *utf8s, + { + ssize_t len; + size_t chars; ++ krb5_ucs2 *ucs2s; + +- chars = krb5int_utf8c_chars(utf8s, utf8slen); ++ *ucs2les = NULL; + +- *ucs2les = (unsigned char *)malloc((chars + 1) * sizeof(krb5_ucs2)); +- if (*ucs2les == NULL) { ++ chars = krb5int_utf8c_chars(utf8s, utf8slen); ++ ucs2s = malloc((chars + 1) * sizeof(krb5_ucs2)); ++ if (ucs2s == NULL) + return ENOMEM; +- } + +- len = k5_utf8s_to_ucs2s((krb5_ucs2 *)*ucs2les, utf8s, chars + 1, 1); ++ len = k5_utf8s_to_ucs2s(ucs2s, utf8s, chars, 1); + if (len < 0) { +- free(*ucs2les); +- *ucs2les = NULL; ++ free(ucs2s); + return EINVAL; + } ++ ucs2s[chars] = 0; + ++ *ucs2les = (unsigned char *)ucs2s; + if (ucs2leslen != NULL) { + *ucs2leslen = chars * sizeof(krb5_ucs2); + } +@@ -402,13 +404,14 @@ krb5int_ucs2cs_to_utf8s(const krb5_ucs2 *ucs2s, + return ENOMEM; + } + +- len = k5_ucs2s_to_utf8s(*utf8s, (krb5_ucs2 *)ucs2s, +- (size_t)len + 1, (ssize_t)ucs2slen, 0); ++ len = k5_ucs2s_to_utf8s(*utf8s, (krb5_ucs2 *)ucs2s, (size_t)len, ++ (ssize_t)ucs2slen, 0); + if (len < 0) { + free(*utf8s); + *utf8s = NULL; + return EINVAL; + } ++ (*utf8s)[len] = '\0'; + + if (utf8slen != NULL) { + *utf8slen = len; +@@ -438,13 +441,14 @@ krb5int_ucs2lecs_to_utf8s(const unsigned char *ucs2les, + return ENOMEM; + } + +- len = k5_ucs2s_to_utf8s(*utf8s, (krb5_ucs2 *)ucs2les, +- (size_t)len + 1, (ssize_t)ucs2leslen, 1); ++ len = k5_ucs2s_to_utf8s(*utf8s, (krb5_ucs2 *)ucs2les, (size_t)len, ++ (ssize_t)ucs2leslen, 1); + if (len < 0) { + free(*utf8s); + *utf8s = NULL; + return EINVAL; + } ++ (*utf8s)[len] = '\0'; + + if (utf8slen != NULL) { + *utf8slen = len; diff --git a/krb5-1.11.2-empty_passwords.patch b/krb5-1.11.2-empty_passwords.patch new file mode 100644 index 0000000..3941084 --- /dev/null +++ b/krb5-1.11.2-empty_passwords.patch @@ -0,0 +1,492 @@ +Should fix #960001. Adjusted to apply to 1.11.2, which didn't yet include +some other developments, renames, reformatting, and fewer tests. + +commit f3458ed803ae97b6c6c7c63baeb82b26c4943d4c +Author: Greg Hudson <ghudson@mit.edu> +Date: Thu May 23 15:33:58 2013 -0400 + + Make empty passwords work via init_creds APIs + + In the gak_data value used by krb5_get_as_key_password, separate the + already-known password from the storage we might have allocated to put + it in, so that we no longer use an empty data buffer to determine + whether we know the password. This allows empty passwords to work via + the API. + + Remove the kadm5 test which explicitly uses an empty password. + + Based on a patch from Stef Walter. + + ticket: 7642 + +diff --git a/src/lib/kadm5/unit-test/api.current/init.exp b/src/lib/kadm5/unit-test/api.current/init.exp +index b324df8..d9ae3fb 100644 +--- a/src/lib/kadm5/unit-test/api.current/init.exp ++++ b/src/lib/kadm5/unit-test/api.current/init.exp +@@ -99,33 +99,6 @@ proc test6 {} { + } + if { $RPC } { test6 } + +-test "init 7" +-proc test7 {} { +- global test +- +- send "kadm5_init admin \"\" \$KADM5_ADMIN_SERVICE null \$KADM5_STRUCT_VERSION \$KADM5_API_VERSION_3 server_handle\n" +- +- expect { +- -re "assword\[^\r\n\]*:" { } +- -re "key:$" { } +- eof { +- fail "$test: eof instead of password prompt" +- api_exit +- api_start +- return +- } +- timeout { +- fail "$test: timeout instead of password prompt" +- return +- } +- } +- one_line_succeed_test "admin" +- if {! [cmd {kadm5_destroy $server_handle}]} { +- error_and_restart "$test: couldn't close database" +- } +-} +-if { $RPC } { test7 } +- + test "init 8" + + proc test8 {} { +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 59614e7..20bc689 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -493,8 +493,7 @@ krb5_init_creds_free(krb5_context context, + } + k5_response_items_free(ctx->rctx.items); + free(ctx->in_tkt_service); +- zap(ctx->password.data, ctx->password.length); +- krb5_free_data_contents(context, &ctx->password); ++ zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length); + krb5_free_error(context, ctx->err_reply); + krb5_free_pa_data(context, ctx->err_padata); + krb5_free_cred_contents(context, &ctx->cred); +@@ -788,7 +787,7 @@ krb5_init_creds_init(krb5_context context, + ctx->prompter = prompter; + ctx->prompter_data = data; + ctx->gak_fct = krb5_get_as_key_password; +- ctx->gak_data = &ctx->password; ++ ctx->gak_data = &ctx->gakpw; + + ctx->request_time = 0; /* filled in later */ + ctx->start_time = start_time; +diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c +index 22db2b5..a97823f 100644 +--- a/src/lib/krb5/krb/gic_pwd.c ++++ b/src/lib/krb5/krb/gic_pwd.c +@@ -17,22 +17,19 @@ krb5_get_as_key_password(krb5_context context, + void *gak_data, + k5_response_items *ritems) + { +- krb5_data *password; ++ struct gak_password *gp = gak_data; + krb5_error_code ret; + krb5_data defsalt; + char *clientstr; +- char promptstr[1024]; ++ char promptstr[1024], pwbuf[1024]; ++ krb5_data pw; + krb5_prompt prompt; + krb5_prompt_type prompt_type; + const char *rpass; + +- password = (krb5_data *) gak_data; +- assert(password->length > 0); +- + /* If we need to get the AS key via the responder, ask for it. */ + if (as_key == NULL) { +- /* However, if we already have a password, don't ask. */ +- if (password->data[0] != '\0') ++ if (gp->password != NULL) + return 0; + + return k5_response_items_ask_question(ritems, +@@ -55,17 +52,20 @@ krb5_get_as_key_password(krb5_context context, + } + } + +- if (password->data[0] == '\0') { ++ if (gp->password == NULL) { + /* Check the responder for the password. */ + rpass = k5_response_items_get_answer(ritems, + KRB5_RESPONDER_QUESTION_PASSWORD); + if (rpass != NULL) { +- strlcpy(password->data, rpass, password->length); +- password->length = strlen(password->data); ++ ret = alloc_data(&gp->storage, strlen(rpass)); ++ if (ret) ++ return ret; ++ memcpy(gp->storage.data, rpass, strlen(rpass)); ++ gp->password = &gp->storage; + } + } + +- if (password->data[0] == '\0') { ++ if (gp->password == NULL) { + if (prompter == NULL) + return(EIO); + +@@ -76,9 +76,10 @@ krb5_get_as_key_password(krb5_context context, + clientstr); + free(clientstr); + ++ pw = make_data(pwbuf, sizeof(pwbuf)); + prompt.prompt = promptstr; + prompt.hidden = 1; +- prompt.reply = password; ++ prompt.reply = &pw; + prompt_type = KRB5_PROMPT_TYPE_PASSWORD; + + /* PROMPTER_INVOCATION */ +@@ -87,6 +88,12 @@ krb5_get_as_key_password(krb5_context context, + krb5int_set_prompt_types(context, 0); + if (ret) + return(ret); ++ ++ ret = krb5int_copy_data_contents(context, &pw, &gp->storage); ++ zap(pw.data, pw.length); ++ if (ret) ++ return ret; ++ gp->password = &gp->storage; + } + + if (salt == NULL) { +@@ -98,7 +105,7 @@ krb5_get_as_key_password(krb5_context context, + defsalt.length = 0; + } + +- ret = krb5_c_string_to_key_with_params(context, etype, password, salt, ++ ret = krb5_c_string_to_key_with_params(context, etype, gp->password, salt, + params->data?params:NULL, as_key); + + if (defsalt.length) +@@ -118,16 +125,11 @@ krb5_init_creds_set_password(krb5_context context, + if (s == NULL) + return ENOMEM; + +- if (ctx->password.data != NULL) { +- zap(ctx->password.data, ctx->password.length); +- krb5_free_data_contents(context, &ctx->password); +- } +- +- ctx->password.data = s; +- ctx->password.length = strlen(s); ++ zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length); ++ ctx->gakpw.storage = string2data(s); ++ ctx->gakpw.password = &ctx->gakpw.storage; + ctx->gak_fct = krb5_get_as_key_password; +- ctx->gak_data = &ctx->password; +- ++ ctx->gak_data = &ctx->gakpw; + return 0; + } + +@@ -257,6 +259,7 @@ krb5_get_init_creds_password(krb5_context context, + int tries; + krb5_creds chpw_creds; + krb5_get_init_creds_opt *chpw_opts = NULL; ++ struct gak_password gakpw; + krb5_data pw0, pw1; + char banner[1024], pw0array[1024], pw1array[1024]; + krb5_prompt prompt[2]; +@@ -267,29 +270,18 @@ krb5_get_init_creds_password(krb5_context context, + use_master = 0; + as_reply = NULL; + memset(&chpw_creds, 0, sizeof(chpw_creds)); ++ memset(&gakpw, 0, sizeof(gakpw)); + +- pw0.data = pw0array; +- +- if (password && password[0]) { +- if (strlcpy(pw0.data, password, sizeof(pw0array)) >= sizeof(pw0array)) { +- ret = EINVAL; +- goto cleanup; +- } +- pw0.length = strlen(password); +- } else { +- pw0.data[0] = '\0'; +- pw0.length = sizeof(pw0array); ++ if (password != NULL) { ++ pw0 = string2data((char *)password); ++ gakpw.password = &pw0; + } + +- pw1.data = pw1array; +- pw1.data[0] = '\0'; +- pw1.length = sizeof(pw1array); +- + /* first try: get the requested tkt from any kdc */ + + ret = krb5int_get_init_creds(context, creds, client, prompter, data, + start_time, in_tkt_service, options, +- krb5_get_as_key_password, (void *) &pw0, ++ krb5_get_as_key_password, &gakpw, + &use_master, &as_reply); + + /* check for success */ +@@ -318,7 +310,7 @@ krb5_get_init_creds_password(krb5_context context, + } + ret2 = krb5int_get_init_creds(context, creds, client, prompter, data, + start_time, in_tkt_service, options, +- krb5_get_as_key_password, (void *) &pw0, ++ krb5_get_as_key_password, &gakpw, + &use_master, &as_reply); + + if (ret2 == 0) { +@@ -365,15 +357,21 @@ krb5_get_init_creds_password(krb5_context context, + if ((ret = krb5int_get_init_creds(context, &chpw_creds, client, + prompter, data, + start_time, "kadmin/changepw", chpw_opts, +- krb5_get_as_key_password, (void *) &pw0, ++ krb5_get_as_key_password, &gakpw, + &use_master, NULL))) + goto cleanup; + ++ pw0.data = pw0array; ++ pw0.data[0] = '\0'; ++ pw0.length = sizeof(pw0array); + prompt[0].prompt = _("Enter new password"); + prompt[0].hidden = 1; + prompt[0].reply = &pw0; + prompt_types[0] = KRB5_PROMPT_TYPE_NEW_PASSWORD; + ++ pw1.data = pw1array; ++ pw1.data[0] = '\0'; ++ pw1.length = sizeof(pw1array); + prompt[1].prompt = _("Enter it again"); + prompt[1].hidden = 1; + prompt[1].reply = &pw1; +@@ -460,10 +458,11 @@ krb5_get_init_creds_password(krb5_context context, + is final. */ + + TRACE_GIC_PWD_CHANGED(context); ++ gakpw.password = &pw0; + ret = krb5int_get_init_creds(context, creds, client, prompter, data, + start_time, in_tkt_service, options, +- krb5_get_as_key_password, (void *) &pw0, ++ krb5_get_as_key_password, &gakpw, + &use_master, &as_reply); + if (ret) + goto cleanup; + +@@ -474,6 +473,7 @@ cleanup: + + if (chpw_opts) + krb5_get_init_creds_opt_free(context, chpw_opts); ++ zapfree(gakpw.storage.data, gakpw.storage.length); + memset(pw0array, 0, sizeof(pw0array)); + memset(pw1array, 0, sizeof(pw1array)); + krb5_free_cred_contents(context, &chpw_creds); +@@ -512,21 +512,17 @@ krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options, + krb5_creds *creds, krb5_kdc_rep **ret_as_reply) + { + krb5_error_code retval; +- krb5_data pw0; +- char pw0array[1024]; ++ struct gak_password gakpw; ++ krb5_data pw; + char * server; + krb5_principal server_princ, client_princ; + int use_master = 0; + krb5_get_init_creds_opt *opts = NULL; + +- pw0.data = pw0array; +- if (password && password[0]) { +- if (strlcpy(pw0.data, password, sizeof(pw0array)) >= sizeof(pw0array)) +- return EINVAL; +- pw0.length = strlen(password); +- } else { +- pw0.data[0] = '\0'; +- pw0.length = sizeof(pw0array); ++ memset(&gakpw, 0, sizeof(gakpw)); ++ if (password != NULL) { ++ pw = string2data((char *)password); ++ gakpw.password = &pw; + } + retval = krb5int_populate_gic_opt(context, &opts, + options, addrs, ktypes, +@@ -544,10 +540,11 @@ krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options, + retval = krb5int_get_init_creds(context, creds, creds->client, + krb5_prompter_posix, NULL, + 0, server, opts, +- krb5_get_as_key_password, &pw0, ++ krb5_get_as_key_password, &gakpw, + &use_master, ret_as_reply); + krb5_free_unparsed_name( context, server); + krb5_get_init_creds_opt_free(context, opts); ++ zapfree(gakpw.storage.data, gakpw.storage.length); + if (retval) { + return (retval); + } +diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h +index d886c7a..4dbb0e9 100644 +--- a/src/lib/krb5/krb/init_creds_ctx.h ++++ b/src/lib/krb5/krb/init_creds_ctx.h +@@ -10,6 +10,11 @@ struct krb5_clpreauth_rock_st { + k5_json_value *cc_config_out; + }; + ++struct gak_password { ++ krb5_data storage; ++ const krb5_data *password; ++}; ++ + struct _krb5_init_creds_context { + krb5_gic_opt_ext *opte; + char *in_tkt_service; +@@ -23,7 +28,7 @@ struct _krb5_init_creds_context { + krb5_deltat renew_life; + krb5_boolean complete; + unsigned int loopcount; +- krb5_data password; ++ struct gak_password gakpw; + krb5_error *err_reply; + krb5_pa_data **err_padata; + krb5_creds cred; +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 2358c89..91f312e 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -28,6 +28,9 @@ kdbtest: kdbtest.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) + KADMIN_OPTS= -d $(TEST_DB) -r $(TEST_REALM) -P $(TEST_MKEY) + KTEST_OPTS= $(KADMIN_OPTS) -p $(TEST_PREFIX) -n $(TEST_NUM) -D $(TEST_DEPTH) + ++t_init_creds: t_init_creds.o $(KRB5_BASE_DEPLIBS) ++ $(CC_LINK) -o $@ t_init_creds.o $(KRB5_BASE_LIBS) ++ + hist: hist.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ hist.o $(KDB5_LIBS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + +@@ -73,7 +76,7 @@ kdb_check: kdc.conf krb5.conf + $(RUN_SETUP) $(VALGRIND) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f + $(RM) $(TEST_DB)* stash_file + +-check-pytests:: hist ++check-pytests:: hist t_init_creds + $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_anonpkinit.py $(PYTESTFLAGS) +diff --git a/src/tests/t_general.py b/src/tests/t_general.py +index bb7a543..98e77a2 100755 +--- a/src/tests/t_general.py ++++ b/src/tests/t_general.py +@@ -22,6 +22,15 @@ for realm in multipass_realms(create_host=False): + # Test kinit against kdb keytab + realm.run_as_master([kinit, "-k", "-t", "KDB:", realm.user_princ]) + ++# Test that we can get initial creds with an empty password via the ++# API. We have to disable the "empty" pwqual module to create a ++# principal with an empty password. (Regression test for #7642.) ++conf={'master':{'plugins': {'pwqual': {'disable': 'empty'}}}} ++realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) ++realm.run_kadminl('addprinc -pw "" user') ++realm.run_as_client(['./t_init_creds', 'user', '']) ++realm.stop() ++ + realm = K5Realm(create_host=False) + + # Create a policy and see if it survives a dump/load. +diff --git a/src/tests/t_init_creds.c b/src/tests/t_init_creds.c +new file mode 100644 +index 0000000..6be8340 +--- /dev/null ++++ b/src/tests/t_init_creds.c +@@ -0,0 +1,88 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* tests/t_init_creds.c - test harness for getting initial creds */ ++/* ++ * Copyright (C) 2013 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * 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 COPYRIGHT HOLDERS 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 ++ * COPYRIGHT HOLDER 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. ++ */ ++ ++/* ++ * This program exercises the init_creds APIs in ways kinit doesn't. Right now ++ * it is very simplistic, but it can be extended as needed. ++ */ ++ ++#include <krb5.h> ++#include <stdio.h> ++ ++static krb5_context ctx; ++ ++static void ++check(krb5_error_code code) ++{ ++ const char *errmsg; ++ ++ if (code) { ++ errmsg = krb5_get_error_message(ctx, code); ++ fprintf(stderr, "%s\n", errmsg); ++ krb5_free_error_message(ctx, errmsg); ++ exit(1); ++ } ++} ++ ++int ++main(int argc, char **argv) ++{ ++ const char *princstr, *password; ++ krb5_principal client; ++ krb5_init_creds_context icc; ++ krb5_creds creds; ++ ++ if (argc != 3) { ++ fprintf(stderr, "Usage: t_init_creds princname password\n"); ++ exit(1); ++ } ++ princstr = argv[1]; ++ password = argv[2]; ++ ++ check(krb5_init_context(&ctx)); ++ check(krb5_parse_name(ctx, princstr, &client)); ++ ++ /* Try once with the traditional interface. */ ++ check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL, ++ NULL, 0, NULL, NULL)); ++ krb5_free_cred_contents(ctx, &creds); ++ ++ /* Try again with the step interface. */ ++ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc)); ++ check(krb5_init_creds_set_password(ctx, icc, password)); ++ check(krb5_init_creds_get(ctx, icc)); ++ krb5_init_creds_free(ctx, icc); ++ ++ krb5_free_principal(ctx, client); ++ krb5_free_context(ctx); ++ return 0; ++} @@ -80,6 +80,8 @@ Patch119: krb5-fast-msg_type.patch Patch120: krb5-1.11.2-kpasswd_pingpong.patch Patch121: krb5-cccol-primary.patch Patch122: krb5-1.11.2-gss_transited.patch +Patch123: krb5-1.11.2-empty_passwords.patch +Patch124: krb5-1.11.2-arcfour_short.patch # Patches for otp plugin backport Patch201: krb5-1.11.2-keycheck.patch @@ -302,6 +304,8 @@ ln -s NOTICE LICENSE %patch120 -p1 -b .kpasswd_pingpong %patch121 -p1 -b .cccol-primary %patch122 -p1 -b .gss_transited +%patch123 -p1 -b .empty_passwords +%patch124 -p1 -b .arcfour_short %patch201 -p1 -b .keycheck %patch202 -p1 -b .otp @@ -830,6 +834,8 @@ exit 0 * Tue May 28 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-7 - backport fix for not being able to verify the list of transited realms in GSS acceptors (RT#7639, #959685) +- backport fix for not being able to pass an empty password to the + get-init-creds APIs and have them actually use it (RT#7642, #960001) * Tue May 21 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-6 - pull in upstream fix to start treating a KRB5CCNAME value that begins |