From: Greg Hudson Date: Mon, 17 Aug 2015 21:41:22 +0000 (-0400) Subject: Refactor finish_check_padata() in KDC X-Git-Tag: krb5-1.14-alpha1~24 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=426d0bae0ebc8a4d4c6e44dd8953cde2196b5d82;p=thirdparty%2Fkrb5.git Refactor finish_check_padata() in KDC Use a helper function to filter the error codes from preauth modules. Use a cleanup handler so that we aren't separately considering the disposition of state and state->pa_e_data along different exit paths. --- diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index bbb4ed2eed..2509c38d50 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -939,43 +939,16 @@ struct padata_state { krb5_boolean *typed_e_data_out; }; -static void -finish_check_padata(struct padata_state *state, krb5_error_code code) +/* Return code if it is 0 or one of the codes we pass through to the client. + * Otherwise return KRB5KDC_ERR_PREAUTH_FAILED. */ +static krb5_error_code +filter_preauth_error(krb5_error_code code) { - kdc_preauth_respond_fn oldrespond; - void *oldarg; - - assert(state); - oldrespond = state->respond; - oldarg = state->arg; - - if (!state->pa_ok) { - /* Return any saved preauth e-data. */ - *state->e_data_out = state->pa_e_data; - *state->typed_e_data_out = state->typed_e_data_flag; - } else - krb5_free_pa_data(state->context, state->pa_e_data); - - if (state->pa_ok) { - free(state); - (*oldrespond)(oldarg, 0); - return; - } - - /* pa system was not found; we may return PREAUTH_REQUIRED later, - but we did not actually fail to verify the pre-auth. */ - if (!state->pa_found) { - free(state); - (*oldrespond)(oldarg, 0); - return; - } - free(state); - /* The following switch statement allows us * to return some preauth system errors back to the client. */ switch(code) { - case 0: /* in case of PA-PAC-REQUEST with no PA-ENC-TIMESTAMP */ + case 0: case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_SKEW: case KRB5KDC_ERR_PREAUTH_REQUIRED: @@ -1006,14 +979,42 @@ finish_check_padata(struct padata_state *state, krb5_error_code code) case KRB5KDC_ERR_NO_ACCEPTABLE_KDF: /* rfc 6113 */ case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED: - (*oldrespond)(oldarg, code); - return; + return code; default: - (*oldrespond)(oldarg, KRB5KDC_ERR_PREAUTH_FAILED); - return; + return KRB5KDC_ERR_PREAUTH_FAILED; } } +/* Release state and respond to the AS-REQ processing code with the result of + * checking pre-authentication data. */ +static void +finish_check_padata(struct padata_state *state, krb5_error_code code) +{ + kdc_preauth_respond_fn respond; + void *arg; + + if (state->pa_ok || !state->pa_found) { + /* Return successfully. If we didn't match a preauth system, we may + * return PREAUTH_REQUIRED later, but we didn't fail to verify. */ + code = 0; + goto cleanup; + } + + /* Return any saved error pa-data, stealing the pointer from state. */ + *state->e_data_out = state->pa_e_data; + *state->typed_e_data_out = state->typed_e_data_flag; + state->pa_e_data = NULL; + +cleanup: + /* Discard saved error pa-data if we aren't returning it, free state, and + * respond to the AS-REQ processing code. */ + respond = state->respond; + arg = state->arg; + krb5_free_pa_data(state->context, state->pa_e_data); + free(state); + (*respond)(arg, filter_preauth_error(code)); +} + static void next_padata(struct padata_state *state);