From c45c43a82491f5c4487087cb424381e884559433 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Fri, 5 Aug 2016 12:28:03 -0400 Subject: [PATCH] Use responder for non-preauth AS requests If no AS reply key is computed during pre-authentication (typically because no pre-authentication was required by the KDC), ask for the password using the responder before calling gak_fct for the key, and supply any resulting responder items to gak_fct. ticket: 8454 target_version: 1.14-next target_version: 1.13-next tags: pullup --- src/lib/krb5/krb/get_in_tkt.c | 24 +++++++++++++++++++++++- src/tests/t_general.py | 5 +++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index 24cd970..4290d0c 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -1391,6 +1391,8 @@ init_creds_step_reply(krb5_context context, krb5_keyblock encrypting_key; krb5_boolean fast_avail; krb5_ccache out_ccache = k5_gic_opt_get_out_ccache(ctx->opt); + krb5_responder_fn responder; + void *responder_data; encrypting_key.length = 0; encrypting_key.contents = NULL; @@ -1549,13 +1551,33 @@ init_creds_step_reply(krb5_context context, code = -1; if (code != 0) { + /* If a responder was provided and we are using a password, ask for the + * password using the responder before falling back to the prompter. */ + k5_gic_opt_get_responder(ctx->opt, &responder, &responder_data); + if (responder != NULL && !ctx->as_key.length) { + /* Indicate a need for the AS key by calling the gak_fct with a + * NULL as_key. */ + code = ctx->gak_fct(context, ctx->request->client, ctx->etype, + NULL, NULL, NULL, NULL, NULL, ctx->gak_data, + ctx->rctx.items); + if (code != 0) + goto cleanup; + + /* If that produced a responder question, invoke the responder. */ + if (!k5_response_items_empty(ctx->rctx.items)) { + code = (*responder)(context, responder_data, &ctx->rctx); + if (code != 0) + goto cleanup; + } + } + /* if we haven't get gotten a key, get it now */ TRACE_INIT_CREDS_GAK(context, &ctx->salt, &ctx->s2kparams); code = (*ctx->gak_fct)(context, ctx->request->client, ctx->reply->enc_part.enctype, ctx->prompter, ctx->prompter_data, &ctx->salt, &ctx->s2kparams, - &ctx->as_key, ctx->gak_data, NULL); + &ctx->as_key, ctx->gak_data, ctx->rctx.items); if (code != 0) goto cleanup; TRACE_INIT_CREDS_AS_KEY_GAK(context, &ctx->as_key); diff --git a/src/tests/t_general.py b/src/tests/t_general.py index fbdeddf..6d523fe 100755 --- a/src/tests/t_general.py +++ b/src/tests/t_general.py @@ -34,6 +34,11 @@ realm.stop() realm = K5Realm(create_host=False) +# Regression test for #8454 (responder callback isn't used when +# preauth is not required). +realm.run(['./responder', '-r', 'password=%s' % password('user'), + realm.user_princ]) + # Test that WRONG_REALM responses aren't treated as referrals unless # they contain a crealm field pointing to a different realm. # (Regression test for #8060.) -- 2.8.1