diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/krb5/krb/fast.c | 55 | ||||
| -rw-r--r-- | src/lib/krb5/krb/get_in_tkt.c | 19 | ||||
| -rw-r--r-- | src/lib/krb5/krb/init_creds_ctx.h | 1 | ||||
| -rw-r--r-- | src/lib/krb5/krb/preauth2.c | 5 |
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) { |
