summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2011-11-11 17:01:12 +0000
committerGreg Hudson <ghudson@mit.edu>2011-11-11 17:01:12 +0000
commitda7e5ac4cfb7fba11c849197a5bf1fa6e0cda37d (patch)
tree965469afc561830fccfef7bad98e7255ede7e904 /src
parent6aff398f9eead4c619d20a55e0c72459b7e1ef51 (diff)
downloadkrb5-da7e5ac4cfb7fba11c849197a5bf1fa6e0cda37d.tar.gz
krb5-da7e5ac4cfb7fba11c849197a5bf1fa6e0cda37d.tar.xz
krb5-da7e5ac4cfb7fba11c849197a5bf1fa6e0cda37d.zip
Avoid looping when preauth can't be generated
If we receive a PREAUTH_REQUIRED error and fail to generate any real preauthentication, error out immediately instead of continuing to generate non-preauthenticated requests until we hit the loop count. There is a lot of room to generate a more meaningful error about why we failed to generate preauth (although in many cases the answer may be too complicated to explain in an error message), but that requires more radical restructuring of the preauth framework. ticket: 6430 target_version: 1.10 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25469 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/include/k5-int.h2
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c12
-rw-r--r--src/lib/krb5/krb/init_creds_ctx.h1
-rw-r--r--src/lib/krb5/krb/preauth2.c6
4 files changed, 16 insertions, 5 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index fec4a7f80..b82fe5b6f 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -1098,7 +1098,7 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request,
krb5_data *encoded_previous_request, krb5_pa_data **in_padata,
krb5_pa_data ***out_padata, krb5_prompter_fct prompter,
void *prompter_data, krb5_clpreauth_rock preauth_rock,
- krb5_gic_opt_ext *opte);
+ krb5_gic_opt_ext *opte, krb5_boolean *got_real_out);
krb5_error_code KRB5_CALLCONV
krb5_do_preauth_tryagain(krb5_context context, krb5_kdc_req *request,
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 6794986d4..f39f2184e 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1102,6 +1102,7 @@ init_creds_step_request(krb5_context context,
krb5_data *out)
{
krb5_error_code code;
+ krb5_boolean got_real;
if (ctx->loopcount >= MAX_IN_TKT_LOOPS) {
code = KRB5_GET_IN_TKT_LOOP;
@@ -1119,7 +1120,10 @@ init_creds_step_request(krb5_context context,
ctx->prompter,
ctx->prompter_data,
&ctx->preauth_rock,
- ctx->opte);
+ ctx->opte,
+ &got_real);
+ if (code == 0 && !got_real && ctx->preauth_required)
+ code = KRB5_PREAUTH_FAILED;
if (code != 0)
goto cleanup;
} else {
@@ -1257,7 +1261,7 @@ init_creds_step_reply(krb5_context context,
int canon_flag = 0;
krb5_keyblock *strengthen_key = NULL;
krb5_keyblock encrypting_key;
- krb5_boolean fast_avail;
+ krb5_boolean fast_avail, got_real;
encrypting_key.length = 0;
encrypting_key.contents = NULL;
@@ -1296,6 +1300,7 @@ init_creds_step_reply(krb5_context context,
code = sort_krb5_padata_sequence(context,
&ctx->request->client->realm,
ctx->preauth_to_use);
+ ctx->preauth_required = TRUE;
} else if (canon_flag && ctx->err_reply->error == KDC_ERR_WRONG_REALM) {
if (ctx->err_reply->client == NULL ||
@@ -1364,7 +1369,8 @@ init_creds_step_reply(krb5_context context,
ctx->prompter,
ctx->prompter_data,
&ctx->preauth_rock,
- ctx->opte);
+ ctx->opte,
+ &got_real);
if (code != 0)
goto cleanup;
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index de43163d8..aa3129d7a 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -33,6 +33,7 @@ struct _krb5_init_creds_context {
krb5_boolean enc_pa_rep_permitted;
krb5_boolean have_restarted;
krb5_boolean sent_nontrivial_preauth;
+ krb5_boolean preauth_required;
};
krb5_error_code
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index fd5c63536..810096a09 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -1434,7 +1434,8 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request,
krb5_data *encoded_previous_request,
krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
krb5_prompter_fct prompter, void *prompter_data,
- krb5_clpreauth_rock rock, krb5_gic_opt_ext *opte)
+ krb5_clpreauth_rock rock, krb5_gic_opt_ext *opte,
+ krb5_boolean *got_real_out)
{
unsigned int h;
int i, j, out_pa_list_size;
@@ -1446,6 +1447,8 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request,
static const int paorder[] = { PA_INFO, PA_REAL };
int realdone;
+ *got_real_out = FALSE;
+
if (in_padata == NULL) {
*out_padata = NULL;
return(0);
@@ -1640,6 +1643,7 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request,
if (etype_info)
krb5_free_etype_info(context, etype_info);
+ *got_real_out = realdone;
return(0);
cleanup:
if (out_pa_list) {