Fix handling of empty passwords in get-init-creds
This commit is contained in:
parent
2fdc61e398
commit
827a48f7cc
122
krb5-1.11.2-arcfour_short.patch
Normal file
122
krb5-1.11.2-arcfour_short.patch
Normal file
@ -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;
|
492
krb5-1.11.2-empty_passwords.patch
Normal file
492
krb5-1.11.2-empty_passwords.patch
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user