summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/krb5/krb/fast.c55
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c19
-rw-r--r--src/lib/krb5/krb/init_creds_ctx.h1
-rw-r--r--src/lib/krb5/krb/preauth2.c5
4 files changed, 32 insertions, 48 deletions
diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c
index 2290d4874..226cd0665 100644
--- a/src/lib/krb5/krb/fast.c
+++ b/src/lib/krb5/krb/fast.c
@@ -346,17 +346,12 @@ decrypt_fast_reply(krb5_context context,
}
/*
- * FAST separates two concepts: the set of padata we're using to
- * decide what pre-auth mechanisms to use and the set of padata we're
- * making available to mechanisms in order for them to respond to an
- * error. The plugin interface in March 2009 does not permit
- * separating these concepts for the plugins. This function makes
- * both available for future revisions to the plugin interface. It
- * also re-encodes the padata from the current error as a encoded
- * typed-data and puts that in the e_data field. That will allow
- * existing plugins with the old interface to find the error data.
- * The output parameter out_padata contains the padata from the error
- * whenever padata is available (all the time with fast).
+ * If state contains an armor key and *err_replyptr contains a FAST error,
+ * decode it and set *err_replyptr to the inner error and *out_padata to the
+ * padata in the FAST response. Otherwise, leave *err_replyptr alone and set
+ * *out_padata to the error e_data decoded as pa-data or typed-data, or to NULL
+ * if it doesn't decode as either. In either case, set *retry to indicate
+ * whether the client should try to make a follow-up request.
*/
krb5_error_code
krb5int_fast_process_error(krb5_context context,
@@ -373,7 +368,7 @@ krb5int_fast_process_error(krb5_context context,
if (state->armor_key) {
krb5_pa_data *fx_error_pa;
krb5_pa_data **result = NULL;
- krb5_data scratch, *encoded_td = NULL;
+ krb5_data scratch;
krb5_error *fx_error = NULL;
krb5_fast_response *fast_response = NULL;
@@ -408,20 +403,7 @@ krb5int_fast_process_error(krb5_context context,
scratch.length = fx_error_pa->length;
retval = decode_krb5_error(&scratch, &fx_error);
}
- /*
- * krb5_pa_data and krb5_typed_data are safe to cast between:
- * they have the same type fields in the same order.
- * (krb5_preauthtype is a krb5_int32). If krb5_typed_data is
- * ever changed then this will need to be a copy not a cast.
- */
- if (retval == 0)
- retval = encode_krb5_typed_data((const krb5_typed_data **)
- fast_response->padata,
- &encoded_td);
if (retval == 0) {
- fx_error->e_data = *encoded_td;
- free(encoded_td); /*contents owned by fx_error*/
- encoded_td = NULL;
krb5_free_error(context, err_reply);
*err_replyptr = fx_error;
fx_error = NULL;
@@ -440,21 +422,18 @@ krb5int_fast_process_error(krb5_context context,
krb5_free_error(context, fx_error);
krb5_free_fast_response(context, fast_response);
} else { /*not FAST*/
+ /* Possibly retry if there's any e_data to process. */
*retry = (err_reply->e_data.length > 0);
- if ((err_reply->error == KDC_ERR_PREAUTH_REQUIRED ||
- err_reply->error == KDC_ERR_PREAUTH_FAILED) &&
- err_reply->e_data.length) {
- krb5_pa_data **result = NULL;
- retval = decode_krb5_padata_sequence(&err_reply->e_data, &result);
- if (retval == 0) {
- *out_padata = result;
- return 0;
- }
- krb5_free_pa_data(context, result);
- krb5_set_error_message(context, retval,
- _("Error decoding padata in error reply"));
- return retval;
+ /* Try to decode e_data as pa-data or typed-data for out_padata. */
+ retval = decode_krb5_padata_sequence(&err_reply->e_data, out_padata);
+ if (retval != 0) {
+ krb5_typed_data **tdata;
+ /* krb5_typed data and krb5_pa_data are compatible structures. */
+ if (decode_krb5_typed_data(&err_reply->e_data, &tdata) == 0)
+ *out_padata = (krb5_pa_data **)tdata;
+ retval = 0;
}
+ *out_padata = padata;
}
return retval;
}
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index f39f2184e..4237915d8 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -526,6 +526,7 @@ krb5_init_creds_free(krb5_context context,
zap(ctx->password.data, ctx->password.length);
krb5_free_data_contents(context, &ctx->password);
krb5_free_error(context, ctx->err_reply);
+ krb5_free_pa_data(context, ctx->err_padata);
krb5_free_cred_contents(context, &ctx->cred);
krb5_free_kdc_req(context, ctx->request);
krb5_free_kdc_rep(context, ctx->reply);
@@ -1130,7 +1131,7 @@ init_creds_step_request(krb5_context context,
if (ctx->preauth_to_use != NULL) {
/*
* Retry after an error other than PREAUTH_NEEDED,
- * using e-data to figure out what to change.
+ * using ctx->err_padata to figure out what to change.
*/
code = krb5_do_preauth_tryagain(context,
ctx->request,
@@ -1139,6 +1140,7 @@ init_creds_step_request(krb5_context context,
ctx->preauth_to_use,
&ctx->request->padata,
ctx->err_reply,
+ ctx->err_padata,
ctx->prompter,
ctx->prompter_data,
&ctx->preauth_rock,
@@ -1255,7 +1257,6 @@ init_creds_step_reply(krb5_context context,
krb5_data *in)
{
krb5_error_code code;
- krb5_pa_data **padata = NULL;
krb5_pa_data **kdc_padata = NULL;
krb5_boolean retry = FALSE;
int canon_flag = 0;
@@ -1277,23 +1278,26 @@ init_creds_step_reply(krb5_context context,
if (ctx->err_reply != NULL) {
code = krb5int_fast_process_error(context, ctx->fast_state,
- &ctx->err_reply, &padata, &retry);
+ &ctx->err_reply, &ctx->err_padata,
+ &retry);
if (code != 0)
goto cleanup;
- if (negotiation_requests_restart(context, ctx, padata)) {
+ if (negotiation_requests_restart(context, ctx, ctx->err_padata)) {
ctx->have_restarted = 1;
krb5_preauth_request_context_fini(context);
if ((ctx->fast_state->fast_state_flags & KRB5INT_FAST_DO_FAST) ==0)
ctx->enc_pa_rep_permitted = 0;
- code = restart_init_creds_loop(context, ctx, padata);
+ code = restart_init_creds_loop(context, ctx, ctx->err_padata);
krb5_free_error(context, ctx->err_reply);
ctx->err_reply = NULL;
+ krb5_free_pa_data(context, ctx->err_padata);
+ ctx->err_padata = NULL;
} else if (ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED &&
retry) {
/* reset the list of preauth types to try */
krb5_free_pa_data(context, ctx->preauth_to_use);
- ctx->preauth_to_use = padata;
- padata = NULL;
+ ctx->preauth_to_use = ctx->err_padata;
+ ctx->err_padata = NULL;
/* this will trigger a new call to krb5_do_preauth() */
krb5_free_error(context, ctx->err_reply);
ctx->err_reply = NULL;
@@ -1489,7 +1493,6 @@ init_creds_step_reply(krb5_context context,
ctx->complete = TRUE;
cleanup:
- krb5_free_pa_data(context, padata);
krb5_free_pa_data(context, kdc_padata);
krb5_free_keyblock(context, strengthen_key);
krb5_free_keyblock_contents(context, &encrypting_key);
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index aa3129d7a..604f3f89a 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -18,6 +18,7 @@ struct _krb5_init_creds_context {
unsigned int loopcount;
krb5_data password;
krb5_error *err_reply;
+ krb5_pa_data **err_padata;
krb5_creds cred;
krb5_kdc_req *request;
krb5_kdc_rep *reply;
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 810096a09..0c8ead5fe 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -1370,6 +1370,7 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
krb5_pa_data **padata,
krb5_pa_data ***return_padata,
krb5_error *err_reply,
+ krb5_pa_data **err_padata,
krb5_prompter_fct prompter, void *prompter_data,
krb5_clpreauth_rock preauth_rock,
krb5_gic_opt_ext *opte)
@@ -1409,8 +1410,8 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
request,
encoded_request_body,
encoded_previous_request,
- padata[i],
- err_reply,
+ padata[i]->pa_type,
+ err_reply, err_padata,
prompter, prompter_data,
&out_padata) == 0) {
if (out_padata != NULL) {