From: Greg Hudson Date: Thu, 6 Oct 2011 16:18:56 +0000 (+0000) Subject: Use type-safe callbacks in preauth interface X-Git-Tag: krb5-1.10-alpha1~60 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=7003d3dbdfd0a7f4f6843068affb290c844ccb65;p=krb5.git Use type-safe callbacks in preauth interface Replace the generic get_data functions in clpreauth and kdcpreauth with structures containing callback functions. Each structure has a minor version number to allow adding new callbacks. For simplicity, the new fast armor key callbacks return aliases, which is how we would supply the armor key as a function parameter. The new client keys callback is paired with a free_keys callback to reduce the amount of cleanup code needed in modules. ticket: 6971 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25315 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/fast_factor.h b/src/include/fast_factor.h index 734d37779..32581bd44 100644 --- a/src/include/fast_factor.h +++ b/src/include/fast_factor.h @@ -26,47 +26,9 @@ #ifndef FAST_FACTOR_H -/* - * Returns success with a null armor_key if FAST is available but not in use. - * Returns failure if the client library does not support FAST. - */ -static inline krb5_error_code -fast_get_armor_key(krb5_context context, krb5_clpreauth_get_data_fn get_data, - krb5_clpreauth_rock rock, krb5_keyblock **armor_key) -{ - krb5_error_code retval = 0; - krb5_data *data; - retval = get_data(context, rock, krb5_clpreauth_fast_armor, &data); - if (retval == 0) { - *armor_key = (krb5_keyblock *) data->data; - data->data = NULL; - get_data(context, rock, krb5_clpreauth_free_fast_armor, &data); - } - return retval; -} - -static inline krb5_error_code -fast_kdc_get_armor_key(krb5_context context, - krb5_kdcpreauth_get_data_fn get_data, - krb5_kdcpreauth_rock rock, - krb5_keyblock **armor_key) -{ - krb5_error_code retval; - krb5_data *data; - retval = (*get_data)(context, rock, krb5_kdcpreauth_fast_armor, &data); - if (retval == 0) { - *armor_key = (krb5_keyblock *) data->data; - data->data = NULL; - (*get_data)(context, rock, krb5_kdcpreauth_free_fast_armor, &data); - } - return retval; -} - - - static inline krb5_error_code fast_kdc_replace_reply_key(krb5_context context, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock) { return 0; @@ -74,7 +36,7 @@ fast_kdc_replace_reply_key(krb5_context context, static inline krb5_error_code fast_set_kdc_verified(krb5_context context, - krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock) { return 0; diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index c64cc3699..1646263d9 100644 --- a/src/include/krb5/preauth_plugin.h +++ b/src/include/krb5/preauth_plugin.h @@ -161,40 +161,26 @@ typedef krb5_error_code krb5_keyblock *as_key, void *gak_data); -/* - * Provided by krb5: a client module's callback functions are allowed to - * request various information to enable it to process a request. - */ -enum krb5_clpreauth_request_type { - /* - * The returned krb5_data item holds the enctype expected to be used to - * encrypt the encrypted portion of the AS_REP packet. When handling a - * PREAUTH_REQUIRED error, this typically comes from etype-info2. When - * handling an AS reply, it is initialized from the AS reply itself. - */ - krb5_clpreauth_get_etype = 1, - - /* Free the data returned from krb5plugin_clpreauth_req_get_etype */ - krb5_clpreauth_free_etype = 2, +/* Before using a callback after version 1, modules must check the vers + * field of the callback structure. */ +typedef struct krb5_clpreauth_callbacks_st { + int vers; /* - * The returned krb5_data contains the FAST armor key in a krb5_keyblock. - * Returns success with a NULL data item in the krb5_data if the client - * library supports FAST but is not using it. + * Get the enctype expected to be used to encrypt the encrypted portion of + * the AS_REP packet. When handling a PREAUTH_REQUIRED error, this + * typically comes from etype-info2. When handling an AS reply, it is + * initialized from the AS reply itself. */ - krb5_clpreauth_fast_armor = 3, + krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock); - /* - * Frees return from KRB5PLUGIN_CLPREAUTH_FAST_ARMOR. It is - * acceptable to set data->data to NULL and free the keyblock using - * krb5_free_keyblock; in that case, this frees the krb5_data only. - */ - krb5_clpreauth_free_fast_armor = 4 -}; -typedef krb5_error_code -(*krb5_clpreauth_get_data_fn)(krb5_context context, - krb5_clpreauth_rock rock, - krb5_int32 request_type, krb5_data **data); + /* Get a pointer to the FAST armor key, or NULL if the client is not using + * FAST. The returned pointer is an alias and should not be freed. */ + krb5_keyblock *(*fast_armor)(krb5_context context, + krb5_clpreauth_rock rock); + + /* End of version 1 clpreauth callbacks. */ +} *krb5_clpreauth_callbacks; /* * Optional: per-plugin initialization/cleanup. The init function is called by @@ -247,7 +233,7 @@ typedef krb5_error_code krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, @@ -271,7 +257,7 @@ typedef krb5_error_code krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, @@ -331,52 +317,50 @@ typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock; typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata; typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq; -/* - * Provided by krb5: a kdcpreauth module's callback functions are allowed to - * request specific types of information about the given client or server - * record or request, even though the database records themselves are opaque to - * the module. - */ -enum krb5_kdcpreauth_request_type { - /* The returned krb5_data item holds a DER-encoded X.509 certificate. */ - krb5_kdcpreauth_request_certificate = 1, - /* The returned krb5_data_item holds a krb5_deltat. */ - krb5_kdcpreauth_max_time_skew = 2, - /* - * The returned krb5_data_item holds an array of krb5_keyblock structures, - * containing the client keys, terminated by an entry with key type = 0. - * Each keyblock should have its contents freed in turn, and then the data - * item itself should be freed. - */ - krb5_kdcpreauth_keys = 3, - /* - * The returned krb5_data_item holds the request structure, re-encoded - * using DER. Unless the client implementation is the same as the server - * implementation, there's a good chance that the result will not match - * what the client sent, so don't create any fatal errors if it doesn't - * match up. - */ - krb5_kdcpreauth_request_body = 4, - /* - * The returned krb5_data contains a krb5_keyblock with the FAST armor key. - * The data member is NULL if this method is not part of a FAST tunnel. - */ - krb5_kdcpreauth_fast_armor = 5, +/* Before using a callback after version 1, modules must check the vers + * field of the callback structure. */ +typedef struct krb5_kdcpreauth_callbacks_st { + int vers; + + krb5_deltat (*max_time_skew)(krb5_context context, + krb5_kdcpreauth_rock rock); + /* - * Frees a fast armor key. It is acceptable to set data to NULL and free - * the keyblock using krb5_free_keyblock; in that case, this function - * simply frees the data. + * Get an array of krb5_keyblock structures containing the client keys + * matching the request enctypes, terminated by an entry with key type = 0. + * Returns ENOENT if no keys are available for the request enctypes. Free + * the resulting object with the free_keys callback. */ - krb5_kdcpreauth_free_fast_armor = 6, + krb5_error_code (*client_keys)(krb5_context context, + krb5_kdcpreauth_rock rock, + krb5_keyblock **keys_out); + + /* Free the result of client_keys. */ + void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock, + krb5_keyblock *keys); + /* - * The returned krb5_data contains a pointer to the client DB entry. The - * pointer is an alias and should not be freed. + * Get the request structure, re-encoded using DER. Unless the client + * implementation is the same as the server implementation, there's a good + * chance that the result will not match what the client sent, so don't + * create any fatal errors if it doesn't match up. Free the resulting data + * object with krb5_free_data. */ - krb5_kdcpreauth_get_client = 7 -}; -typedef krb5_error_code -(*krb5_kdcpreauth_get_data_fn)(krb5_context context, krb5_kdcpreauth_rock rock, - krb5_int32 request_type, krb5_data **); + krb5_error_code (*request_body)(krb5_context context, + krb5_kdcpreauth_rock rock, + krb5_data **body_out); + + /* Get a pointer to the FAST armor key, or NULL if the request did not use + * FAST. The returned pointer is an alias and should not be freed. */ + krb5_keyblock *(*fast_armor)(krb5_context context, + krb5_kdcpreauth_rock rock); + + /* Get a pointer to the client DB entry (returned as a void pointer to + * avoid a dependency on a libkdb5 type). */ + void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock); + + /* End of version 1 kdcpreauth callbacks. */ +} *krb5_kdcpreauth_callbacks; /* Optional: preauth plugin initialization function. */ typedef krb5_error_code @@ -413,7 +397,7 @@ typedef int */ typedef krb5_error_code (*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get_data, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_out); @@ -445,7 +429,7 @@ typedef void krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data, - krb5_kdcpreauth_get_data_fn get_data, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, @@ -464,7 +448,7 @@ typedef krb5_error_code krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa_out, - krb5_kdcpreauth_get_data_fn get_data, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 87586d700..7e9cde1f9 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -107,24 +107,23 @@ typedef struct preauth_system_st { static void verify_enc_timestamp(krb5_context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data, - krb5_kdcpreauth_get_data_fn get, - krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, void *arg); static krb5_error_code get_enc_ts(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata modata, krb5_pa_data *data); static krb5_error_code get_etype_info(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data); static krb5_error_code get_etype_info2(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data); static krb5_error_code @@ -140,7 +139,7 @@ static krb5_error_code return_etype_info(krb5_context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); @@ -148,7 +147,7 @@ static krb5_error_code return_etype_info2(krb5_context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); @@ -156,7 +155,7 @@ static krb5_error_code return_pw_salt(krb5_context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); @@ -510,158 +509,87 @@ free_padata_context(krb5_context kcontext, void *padata_context) free(context); } -/* Retrieve a specified tl_data item from the given entry, and return its - * contents in a new krb5_data, which must be freed by the caller. - */ -static krb5_error_code -get_entry_tl_data(krb5_context context, krb5_db_entry *entry, - krb5_int16 tl_data_type, krb5_data **result) +static krb5_deltat +max_time_skew(krb5_context context, krb5_kdcpreauth_rock rock) { - krb5_tl_data *tl; - for (tl = entry->tl_data; tl != NULL; tl = tl->tl_data_next) { - if (tl->tl_data_type == tl_data_type) { - *result = malloc(sizeof(krb5_data)); - if (*result == NULL) { - return ENOMEM; - } - (*result)->magic = KV5M_DATA; - (*result)->data = malloc(tl->tl_data_length); - if ((*result)->data == NULL) { - free(*result); - *result = NULL; - return ENOMEM; - } - memcpy((*result)->data, tl->tl_data_contents, tl->tl_data_length); - return 0; - } - } - return ENOENT; + return context->clockskew; } -/* - * Retrieve a specific piece of information pertaining to the client entry or - * request and return it in a new krb5_data item which the caller must free. - * - * This may require massaging data into a contrived format, but it will - * hopefully keep us from having to reveal library-internal functions to - * modules. - */ static krb5_error_code -get_data(krb5_context context, krb5_kdcpreauth_rock rock, krb5_int32 type, - krb5_data **result) +client_keys(krb5_context context, krb5_kdcpreauth_rock rock, + krb5_keyblock **keys_out) { - int i, k; - krb5_data *ret; - krb5_deltat *delta; - krb5_keyblock *keys; - krb5_key_data *entry_key; - krb5_error_code error; krb5_kdc_req *request = rock->request; - struct kdc_request_state *state = rock->rstate; krb5_db_entry *client = rock->client; + krb5_keyblock *keys, key; + krb5_key_data *entry_key; + int i, k; - switch (type) { - case krb5_kdcpreauth_request_certificate: - return get_entry_tl_data(context, client, KRB5_TL_USER_CERTIFICATE, - result); - break; - case krb5_kdcpreauth_max_time_skew: - ret = malloc(sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - delta = malloc(sizeof(krb5_deltat)); - if (delta == NULL) { - free(ret); - return ENOMEM; - } - *delta = context->clockskew; - ret->data = (char *) delta; - ret->length = sizeof(*delta); - *result = ret; - return 0; - break; - case krb5_kdcpreauth_keys: - ret = malloc(sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - keys = malloc(sizeof(krb5_keyblock) * (request->nktypes + 1)); - if (keys == NULL) { - free(ret); - return ENOMEM; - } - ret->data = (char *) keys; - ret->length = sizeof(krb5_keyblock) * (request->nktypes + 1); - memset(ret->data, 0, ret->length); - k = 0; - for (i = 0; i < request->nktypes; i++) { - entry_key = NULL; - if (krb5_dbe_find_enctype(context, client, request->ktype[i], - -1, 0, &entry_key) != 0) - continue; - if (krb5_dbe_decrypt_key_data(context, NULL, entry_key, - &keys[k], NULL) != 0) { - if (keys[k].contents != NULL) - krb5_free_keyblock_contents(context, &keys[k]); - memset(&keys[k], 0, sizeof(keys[k])); - continue; - } - k++; - } - if (k > 0) { - *result = ret; - return 0; - } else { - free(keys); - free(ret); - } - break; - case krb5_kdcpreauth_request_body: - ret = NULL; - encode_krb5_kdc_req_body(request, &ret); - if (ret != NULL) { - *result = ret; - return 0; - } - return ASN1_PARSE_ERROR; - break; - case krb5_kdcpreauth_fast_armor: - ret = calloc(1, sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - if (state->armor_key == NULL) { - *result = ret; - return 0; - } - error = krb5_copy_keyblock(context, state->armor_key, &keys); - if (error == 0) { - ret->data = (char *) keys; - ret->length = sizeof(krb5_keyblock); - *result = ret; - return 0; - } - free(ret); - return error; - case krb5_kdcpreauth_free_fast_armor: - if ((*result)->data) { - keys = (krb5_keyblock *) (*result)->data; - krb5_free_keyblock(context, keys); - } - free(*result); - return 0; - case krb5_kdcpreauth_get_client: - ret = malloc(sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - ret->data = (char *)&rock->client; - ret->length = sizeof(rock->client); - *result = ret; - return 0; - default: - break; + keys = malloc(sizeof(krb5_keyblock) * (request->nktypes + 1)); + if (keys == NULL) + return ENOMEM; + + memset(keys, 0, sizeof(krb5_keyblock) * (request->nktypes + 1)); + k = 0; + for (i = 0; i < request->nktypes; i++) { + entry_key = NULL; + if (krb5_dbe_find_enctype(context, client, request->ktype[i], + -1, 0, &entry_key) != 0) + continue; + if (krb5_dbe_decrypt_key_data(context, NULL, entry_key, + &key, NULL) != 0) + continue; + keys[k++] = key; } - return ENOENT; + if (k == 0) { + free(keys); + return ENOENT; + } + *keys_out = keys; + return 0; } +static void free_keys(krb5_context context, krb5_kdcpreauth_rock rock, + krb5_keyblock *keys) +{ + krb5_keyblock *k; + + if (keys == NULL) + return; + for (k = keys; k->enctype != 0; k++) + krb5_free_keyblock_contents(context, k); + free(keys); +} + +static krb5_error_code +request_body(krb5_context context, krb5_kdcpreauth_rock rock, + krb5_data **body_out) +{ + return encode_krb5_kdc_req_body(rock->request, body_out); +} + +static krb5_keyblock * +fast_armor(krb5_context context, krb5_kdcpreauth_rock rock) +{ + return rock->rstate->armor_key; +} + +static void * +client_entry(krb5_context context, krb5_kdcpreauth_rock rock) +{ + return rock->client; +} + +static struct krb5_kdcpreauth_callbacks_st callbacks = { + 1, + max_time_skew, + client_keys, + free_keys, + request_body, + fast_armor, + client_entry +}; + static krb5_error_code find_pa_system(int type, preauth_system **preauth) { @@ -851,7 +779,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock, (*pa)->magic = KV5M_PA_DATA; (*pa)->pa_type = ap->type; if (ap->get_edata) { - retval = ap->get_edata(kdc_context, request, get_data, rock, + retval = ap->get_edata(kdc_context, request, &callbacks, rock, ap->moddata, *pa); if (retval) { /* just failed on this type, continue */ @@ -1139,7 +1067,7 @@ next_padata(struct padata_state *state) state->pa_found++; state->pa_sys->verify_padata(state->context, state->req_pkt, state->request, state->enc_tkt_reply, - *state->padata, get_data, state->rock, + *state->padata, &callbacks, state->rock, state->pa_sys->moddata, finish_verify_padata, state); return; @@ -1282,7 +1210,7 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock, } } retval = ap->return_padata(context, pa, req_pkt, request, reply, - encrypting_key, send_pa, get_data, rock, + encrypting_key, send_pa, &callbacks, rock, ap->moddata, *modreq_ptr); if (retval) goto cleanup; @@ -1321,7 +1249,7 @@ request_contains_enctype(krb5_context context, const krb5_kdc_req *request, static krb5_error_code get_enc_ts(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { if (rock->rstate->armor_key != NULL) @@ -1333,7 +1261,7 @@ get_enc_ts(krb5_context context, krb5_kdc_req *request, static void verify_enc_timestamp(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data *pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, @@ -1576,7 +1504,7 @@ cleanup: static krb5_error_code get_etype_info(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { int i; @@ -1591,7 +1519,7 @@ get_etype_info(krb5_context context, krb5_kdc_req *request, static krb5_error_code get_etype_info2(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { return etype_info_helper(context, request, rock->client, pa_data, 1); @@ -1678,7 +1606,7 @@ static krb5_error_code return_etype_info2(krb5_context context, krb5_pa_data * padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) { @@ -1692,7 +1620,7 @@ static krb5_error_code return_etype_info(krb5_context context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) { @@ -1705,7 +1633,7 @@ static krb5_error_code return_pw_salt(krb5_context context, krb5_pa_data *in_padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) { krb5_error_code retval; diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c index 62fa615e0..b52d03620 100644 --- a/src/kdc/kdc_preauth_ec.c +++ b/src/kdc/kdc_preauth_ec.c @@ -36,24 +36,18 @@ static krb5_error_code kdc_include_padata(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { - krb5_error_code retval = 0; - krb5_keyblock *armor_key = NULL; - retval = fast_kdc_get_armor_key(context, get, rock, &armor_key); - if (retval) - return retval; - if (armor_key == 0) - return ENOENT; - krb5_free_keyblock(context, armor_key); - return 0; + krb5_keyblock *armor_key = cb->fast_armor(context, rock); + + return (armor_key == NULL) ? ENOENT : 0; } static void kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *data, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data *data, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, void *arg) @@ -62,10 +56,9 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, krb5_timestamp now; krb5_enc_data *enc = NULL; krb5_data scratch, plain; - krb5_keyblock *armor_key = NULL; + krb5_keyblock *armor_key = cb->fast_armor(context, rock); krb5_pa_enc_ts *ts = NULL; krb5_keyblock *client_keys = NULL; - krb5_data *client_data = NULL; krb5_keyblock *challenge_key = NULL; krb5_keyblock *kdc_challenge_key; krb5_kdcpreauth_modreq modreq = NULL; @@ -73,8 +66,7 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, plain.data = NULL; - retval = fast_kdc_get_armor_key(context, get, rock, &armor_key); - if (retval == 0 &&armor_key == NULL) { + if (armor_key == NULL) { retval = ENOENT; krb5_set_error_message(context, ENOENT, "Encrypted Challenge used outside of FAST tunnel"); } @@ -89,9 +81,8 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, retval = ENOMEM; } if (retval == 0) - retval = (*get)(context, rock, krb5_kdcpreauth_keys, &client_data); + retval = cb->client_keys(context, rock, &client_keys); if (retval == 0) { - client_keys = (krb5_keyblock *) client_data->data; for (i = 0; client_keys[i].enctype&& (retval == 0); i++ ) { retval = krb5_c_fx_cf2_simple(context, armor_key, "clientchallengearmor", @@ -108,18 +99,11 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, break; /*We failed to decrypt. Try next key*/ retval = 0; - krb5_free_keyblock_contents(context, &client_keys[i]); } if (client_keys[i].enctype == 0) { retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_error_message(context, retval, "Incorrect password in encrypted challenge"); - } else { /*not run out of keys*/ - int j; - assert (retval == 0); - for (j = i+1; client_keys[j].enctype; j++) - krb5_free_keyblock_contents(context, &client_keys[j]); } - } if (retval == 0) retval = decode_krb5_pa_enc_ts(&plain, &ts); @@ -133,7 +117,7 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, * may cause the client to fail, but at this point the KDC has * considered this a success, so the return value is ignored. */ - fast_kdc_replace_reply_key(context, get, rock); + fast_kdc_replace_reply_key(context, cb, rock); if (krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor", &client_keys[i], "challengelongterm", &kdc_challenge_key) == 0) @@ -142,13 +126,7 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, retval = KRB5KRB_AP_ERR_SKEW; } } - if (client_keys) { - if (client_keys[i].enctype) - krb5_free_keyblock_contents(context, &client_keys[i]); - krb5_free_data(context, client_data); - } - if (armor_key) - krb5_free_keyblock(context, armor_key); + cb->free_keys(context, rock, client_keys); if (plain.data) free(plain.data); if (enc) @@ -163,7 +141,7 @@ static krb5_error_code kdc_return_preauth(krb5_context context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) { diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index 9807eeafd..8c43938ef 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -372,94 +372,24 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size, return 0; } -/* - * Retrieve a specific piece of information required by the plugin and - * return it in a new krb5_data item. There are separate request_types - * to obtain the data and free it. - * - * This may require massaging data into a contrived format, but it will - * hopefully keep us from having to reveal library-internal functions - * or data to the plugin modules. - */ - -static krb5_error_code -client_data_proc(krb5_context kcontext, krb5_clpreauth_rock rock, - krb5_int32 request_type, krb5_data **retdata) +static krb5_enctype +get_etype(krb5_context context, krb5_clpreauth_rock rock) { - krb5_data *ret; - krb5_error_code retval; - char *data; - - if (rock->magic != CLIENT_ROCK_MAGIC) - return EINVAL; - if (retdata == NULL) - return EINVAL; + return *rock->etype; +} - switch (request_type) { - case krb5_clpreauth_get_etype: - { - krb5_enctype *eptr; - ret = malloc(sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - data = malloc(sizeof(krb5_enctype)); - if (data == NULL) { - free(ret); - return ENOMEM; - } - ret->data = data; - ret->length = sizeof(krb5_enctype); - eptr = (krb5_enctype *)data; - *eptr = *rock->etype; - *retdata = ret; - return 0; - } - break; - case krb5_clpreauth_free_etype: - ret = *retdata; - if (ret == NULL) - return 0; - if (ret->data) - free(ret->data); - free(ret); - return 0; - break; - case krb5_clpreauth_fast_armor: { - krb5_keyblock *key = NULL; - ret = calloc(1, sizeof(krb5_data)); - if (ret == NULL) - return ENOMEM; - retval = 0; - if (rock->fast_state->armor_key) - retval = krb5_copy_keyblock(kcontext, rock->fast_state->armor_key, - &key); - if (retval == 0) { - ret->data = (char *) key; - ret->length = key?sizeof(krb5_keyblock):0; - key = NULL; - } - if (retval == 0) { - *retdata = ret; - ret = NULL; - } - if (ret) - free(ret); - return retval; - } - case krb5_clpreauth_free_fast_armor: - ret = *retdata; - if (ret) { - if (ret->data) - krb5_free_keyblock(kcontext, (krb5_keyblock *) ret->data); - free(ret); - *retdata = NULL; - } - return 0; - default: - return EINVAL; - } +static krb5_keyblock * +fast_armor(krb5_context context, krb5_clpreauth_rock rock) +{ + return rock->fast_state->armor_key; } +static struct krb5_clpreauth_callbacks_st callbacks = { + 1, + get_etype, + fast_armor +}; + /* Tweak the request body, for now adding any enctypes which the module claims * to add support for to the list, but in the future perhaps doing more * involved things. */ @@ -545,7 +475,7 @@ run_preauth_plugins(krb5_context kcontext, ret = module->client_process(kcontext, module->moddata, *module->modreq_p, (krb5_get_init_creds_opt *)opte, - client_data_proc, preauth_rock, + &callbacks, preauth_rock, request, encoded_request_body, encoded_previous_request, in_padata, prompter, prompter_data, gak_fct, @@ -1535,8 +1465,7 @@ krb5_do_preauth_tryagain(krb5_context kcontext, if ((*module->client_tryagain)(kcontext, module->moddata, *module->modreq_p, (krb5_get_init_creds_opt *)opte, - client_data_proc, - preauth_rock, + &callbacks, preauth_rock, request, encoded_request_body, encoded_previous_request, diff --git a/src/lib/krb5/krb/preauth_ec.c b/src/lib/krb5/krb/preauth_ec.c index 94c928461..6ef397568 100644 --- a/src/lib/krb5/krb/preauth_ec.c +++ b/src/lib/krb5/krb/preauth_ec.c @@ -43,7 +43,7 @@ preauth_flags(krb5_context context, krb5_preauthtype pa_type) static krb5_error_code process_preauth(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - krb5_clpreauth_get_data_fn get_data_proc, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *padata, @@ -53,22 +53,16 @@ process_preauth(krb5_context context, krb5_clpreauth_moddata moddata, krb5_pa_data ***out_padata) { krb5_error_code retval = 0; - krb5_enctype enctype = 0; - krb5_keyblock *challenge_key = NULL, *armor_key = NULL; - krb5_data *etype_data = NULL; + krb5_enctype enctype; + krb5_keyblock *challenge_key = NULL, *armor_key; - retval = fast_get_armor_key(context, get_data_proc, rock, &armor_key); - if (retval || armor_key == NULL) - return 0; - retval = get_data_proc(context, rock, krb5_clpreauth_get_etype, - &etype_data); - if (retval == 0) { - enctype = *((krb5_enctype *)etype_data->data); - if (as_key->length == 0 ||as_key->enctype != enctype) - retval = gak_fct(context, request->client, - enctype, prompter, prompter_data, - salt, s2kparams, - as_key, gak_data); + armor_key = cb->fast_armor(context, rock); + enctype = cb->get_etype(context, rock); + if (as_key->length == 0 ||as_key->enctype != enctype) { + retval = gak_fct(context, request->client, + enctype, prompter, prompter_data, + salt, s2kparams, + as_key, gak_data); } if (retval == 0 && padata->length) { krb5_enc_data *enc = NULL; @@ -99,7 +93,7 @@ process_preauth(krb5_context context, krb5_clpreauth_moddata moddata, if (scratch.data) krb5_free_data_contents(context, &scratch); if (retval == 0) - fast_set_kdc_verified(context, get_data_proc, rock); + fast_set_kdc_verified(context, cb, rock); if (enc) krb5_free_enc_data(context, enc); } else if (retval == 0) { /*No padata; we send*/ @@ -158,10 +152,6 @@ process_preauth(krb5_context context, krb5_clpreauth_moddata moddata, } if (challenge_key) krb5_free_keyblock(context, challenge_key); - if (armor_key) - krb5_free_keyblock(context, armor_key); - if (etype_data != NULL) - get_data_proc(context, rock, krb5_clpreauth_free_etype, &etype_data); return retval; } diff --git a/src/plugins/preauth/cksum_body/cksum_body_main.c b/src/plugins/preauth/cksum_body/cksum_body_main.c index 794cd2ffb..da2643fc1 100644 --- a/src/plugins/preauth/cksum_body/cksum_body_main.c +++ b/src/plugins/preauth/cksum_body/cksum_body_main.c @@ -83,7 +83,7 @@ client_process(krb5_context kcontext, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - krb5_clpreauth_get_data_fn client_get_data_proc, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, @@ -273,34 +273,28 @@ server_fini(krb5_context kcontext, krb5_kdcpreauth_moddata moddata) * client) which matches type data->pa_type. */ static krb5_error_code server_get_edata(krb5_context kcontext, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { - krb5_data *key_data; - krb5_keyblock *keys, *key; + krb5_keyblock *keys; krb5_int32 *enctypes, enctype; int i; /* Retrieve the client's keys. */ - key_data = NULL; - if ((*get)(kcontext, rock, krb5_kdcpreauth_keys, &key_data) != 0) { + if (cb->client_keys(kcontext, rock, &keys) != 0) { #ifdef DEBUG fprintf(stderr, "Error retrieving client keys.\n"); #endif return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; } - /* Count which types of keys we've got, freeing the contents, which we - * don't need at this point. */ - keys = (krb5_keyblock *) key_data->data; - key = NULL; - for (i = 0; keys[i].enctype != 0; i++) - krb5_free_keyblock_contents(kcontext, &keys[i]); + /* Count which types of keys we've got. */ + for (i = 0; keys[i].enctype != 0; i++); /* Return the list of encryption types. */ enctypes = malloc((unsigned)i * 4); if (enctypes == NULL) { - krb5_free_data(kcontext, key_data); + cb->free_keys(kcontext, rock, keys); return ENOMEM; } #ifdef DEBUG @@ -319,7 +313,7 @@ server_get_edata(krb5_context kcontext, krb5_kdc_req *request, data->pa_type = KRB5_PADATA_CKSUM_BODY_REQ; data->length = (i * 4); data->contents = (unsigned char *) enctypes; - krb5_free_data(kcontext, key_data); + cb->free_keys(kcontext, rock, keys); return 0; } @@ -330,7 +324,7 @@ server_verify(krb5_context kcontext, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, @@ -339,11 +333,10 @@ server_verify(krb5_context kcontext, krb5_int32 cksumtype; krb5_checksum checksum; krb5_boolean valid; - krb5_data *key_data, *req_body; + krb5_data *req_body; krb5_keyblock *keys, *key; size_t length; - int i; - unsigned int j, cksumtypes_count; + unsigned int i, cksumtypes_count; krb5_cksumtype *cksumtypes; krb5_error_code status; struct server_stats *stats; @@ -387,8 +380,7 @@ server_verify(krb5_context kcontext, checksum.length = length; /* Pull up the client's keys. */ - key_data = NULL; - if ((*get)(kcontext, rock, krb5_kdcpreauth_keys, &key_data) != 0) { + if (cb->client_keys(kcontext, rock, &keys) != 0) { #ifdef DEBUG fprintf(stderr, "Error retrieving client keys.\n"); #endif @@ -398,56 +390,47 @@ server_verify(krb5_context kcontext, } /* Find the key which would have been used to generate the checksum. */ - keys = (krb5_keyblock *) key_data->data; - key = NULL; - for (i = 0; keys[i].enctype != 0; i++) { - key = &keys[i]; + for (key = keys; key->enctype != 0; key++) { cksumtypes_count = 0; cksumtypes = NULL; if (krb5_c_keyed_checksum_types(kcontext, key->enctype, &cksumtypes_count, &cksumtypes) != 0) continue; - for (j = 0; j < cksumtypes_count; j++) { - if (cksumtypes[j] == checksum.checksum_type) + for (i = 0; i < cksumtypes_count; i++) { + if (cksumtypes[i] == checksum.checksum_type) break; } if (cksumtypes != NULL) krb5_free_cksumtypes(kcontext, cksumtypes); - if (j < cksumtypes_count) { + if (i < cksumtypes_count) { #ifdef DEBUG fprintf(stderr, "Found checksum key.\n"); #endif break; } } - if ((key == NULL) || (key->enctype == 0)) { - for (i = 0; keys[i].enctype != 0; i++) - krb5_free_keyblock_contents(kcontext, &keys[i]); - krb5_free_data(kcontext, key_data); + if (key->enctype == 0) { + cb->free_keys(kcontext, rock, keys); stats->failures++; (*respond)(arg, KRB5KDC_ERR_SUMTYPE_NOSUPP, NULL, NULL, NULL); return; } /* Save a copy of the key. */ - if (krb5_copy_keyblock(kcontext, &keys[i], &key) != 0) { - for (i = 0; keys[i].enctype != 0; i++) - krb5_free_keyblock_contents(kcontext, &keys[i]); - krb5_free_data(kcontext, key_data); + if (krb5_copy_keyblock(kcontext, keys, &key) != 0) { + cb->free_keys(kcontext, rock, keys); stats->failures++; (*respond)(arg, KRB5KDC_ERR_SUMTYPE_NOSUPP, NULL, NULL, NULL); return; } - for (i = 0; keys[i].enctype != 0; i++) - krb5_free_keyblock_contents(kcontext, &keys[i]); - krb5_free_data(kcontext, key_data); + cb->free_keys(kcontext, rock, keys); /* Rebuild a copy of the client's request-body. If we were serious * about doing this with any chance of working interoperability, we'd * extract the structure directly from the req_pkt structure. This * will probably work if it's us on both ends, though. */ req_body = NULL; - if ((*get)(kcontext, rock, krb5_kdcpreauth_request_body, &req_body) != 0) { + if (cb->request_body(kcontext, rock, &req_body) != 0) { krb5_free_keyblock(kcontext, key); stats->failures++; (*respond)(arg, KRB5KDC_ERR_PREAUTH_FAILED, NULL, NULL, NULL); @@ -563,7 +546,7 @@ server_return(krb5_context kcontext, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c index a6232e997..85a1e427d 100644 --- a/src/plugins/preauth/pkinit/pkinit_clnt.c +++ b/src/plugins/preauth/pkinit/pkinit_clnt.c @@ -1020,9 +1020,8 @@ static krb5_error_code pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *gic_opt, - krb5_clpreauth_get_data_fn get_data_proc, - krb5_clpreauth_rock rock, krb5_kdc_req *request, - krb5_data *encoded_request_body, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, + krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *in_padata, krb5_prompter_fct prompter, void *prompter_data, @@ -1032,22 +1031,18 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata, { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_enctype enctype = -1; - krb5_data *cdata = NULL; int processing_request = 0; pkinit_context plgctx = (pkinit_context)moddata; pkinit_req_context reqctx = (pkinit_req_context)modreq; - krb5_keyblock *armor_key = NULL; + krb5_keyblock *armor_key = cb->fast_armor(context, rock); pkiDebug("pkinit_client_process %p %p %p %p\n", context, plgctx, reqctx, request); /* Remove (along with armor_key) when FAST PKINIT is settled. */ - retval = fast_get_armor_key(context, get_data_proc, rock, &armor_key); - if (retval == 0 && armor_key != NULL) { - /* Don't use PKINIT if also using FAST. */ - krb5_free_keyblock(context, armor_key); + /* Don't use PKINIT if also using FAST. */ + if (armor_key != NULL) return EINVAL; - } if (plgctx == NULL || reqctx == NULL) return EINVAL; @@ -1100,15 +1095,7 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata, /* * Get the enctype of the reply. */ - retval = (*get_data_proc)(context, rock, krb5_clpreauth_get_etype, - &cdata); - if (retval) { - pkiDebug("get_data_proc returned %d (%s)\n", - retval, error_message(retval)); - return retval; - } - enctype = *((krb5_enctype *)cdata->data); - (*get_data_proc)(context, rock, krb5_clpreauth_free_etype, &cdata); + enctype = cb->get_etype(context, rock); retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request, in_padata, enctype, as_key, encoded_previous_request); @@ -1123,9 +1110,8 @@ static krb5_error_code pkinit_client_tryagain(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *gic_opt, - krb5_clpreauth_get_data_fn get_data_proc, - krb5_clpreauth_rock rock, krb5_kdc_req *request, - krb5_data *encoded_request_body, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, + krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *in_padata, krb5_error *err_reply, krb5_prompter_fct prompter, void *prompter_data, diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c index b7aea625a..4a477afec 100644 --- a/src/plugins/preauth/pkinit/pkinit_srv.c +++ b/src/plugins/preauth/pkinit/pkinit_srv.c @@ -101,24 +101,21 @@ cleanup: static krb5_error_code pkinit_server_get_edata(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { krb5_error_code retval = 0; pkinit_kdc_context plgctx = NULL; - krb5_keyblock *armor_key = NULL; + krb5_keyblock *armor_key = cb->fast_armor(context, rock); pkiDebug("pkinit_server_get_edata: entered!\n"); /* Remove (along with armor_key) when FAST PKINIT is settled. */ - retval = fast_kdc_get_armor_key(context, get, rock, &armor_key); - if (retval == 0 && armor_key != NULL) { - /* Don't advertise PKINIT if the client used FAST. */ - krb5_free_keyblock(context, armor_key); + /* Don't advertise PKINIT if the client used FAST. */ + if (armor_key != NULL) return EINVAL; - } /* * If we don't have a realm context for the given realm, @@ -291,7 +288,7 @@ pkinit_server_verify_padata(krb5_context context, krb5_kdc_req * request, krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data * data, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, @@ -311,7 +308,7 @@ pkinit_server_verify_padata(krb5_context context, krb5_kdc_req *tmp_as_req = NULL; krb5_data k5data; int is_signed = 1; - krb5_keyblock *armor_key; + krb5_keyblock *armor_key = cb->fast_armor(context, rock); krb5_pa_data **e_data = NULL; krb5_kdcpreauth_modreq modreq = NULL; @@ -322,10 +319,8 @@ pkinit_server_verify_padata(krb5_context context, } /* Remove (along with armor_key) when FAST PKINIT is settled. */ - retval = fast_kdc_get_armor_key(context, get, rock, &armor_key); - if (retval == 0 && armor_key != NULL) { - /* Don't allow PKINIT if the client used FAST. */ - krb5_free_keyblock(context, armor_key); + /* Don't allow PKINIT if the client used FAST. */ + if (armor_key != NULL) { (*respond)(arg, EINVAL, NULL, NULL, NULL); return; } @@ -700,7 +695,7 @@ pkinit_server_return_padata(krb5_context context, krb5_kdc_rep * reply, krb5_keyblock * encrypting_key, krb5_pa_data ** send_pa, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) diff --git a/src/plugins/preauth/securid_sam2/securid_sam2_main.c b/src/plugins/preauth/securid_sam2/securid_sam2_main.c index 5ed59c811..80335ff82 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2_main.c +++ b/src/plugins/preauth/securid_sam2/securid_sam2_main.c @@ -50,19 +50,6 @@ static struct { { 0, 0 }, }; -static krb5_db_entry * -get_client_entry(krb5_context context, krb5_kdcpreauth_get_data_fn get, - krb5_kdcpreauth_rock rock) -{ - krb5_data *data; - krb5_db_entry *client; - - (*get)(context, rock, krb5_kdcpreauth_get_client, &data); - client = *(krb5_db_entry **)data->data; - free(data); - return client; -} - krb5_error_code sam_get_db_entry(krb5_context context, krb5_principal client, int *sam_type, struct _krb5_db_entry_new **db_entry) @@ -127,11 +114,10 @@ cleanup: static krb5_error_code kdc_include_padata(krb5_context context, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, krb5_kdcpreauth_rock rock, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { krb5_error_code retval; - krb5_data *client_keys_data = NULL; krb5_keyblock *client_key = NULL; krb5_sam_challenge_2 sc2; krb5_sam_challenge_2_body sc2b; @@ -144,15 +130,14 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, sc2b.magic = KV5M_SAM_CHALLENGE_2; sc2b.sam_type = sam_type; - client = get_client_entry(context, get, rock); + client = cb->client_entry(context, rock); retval = sam_get_db_entry(context, client->princ, &sam_type, &sam_db_entry); if (retval) return retval; - retval = (*get)(context, rock, krb5_kdcpreauth_keys, &client_keys_data); + retval = cb->client_keys(context, rock, &client_key); if (retval) goto cleanup; - client_key = (krb5_keyblock *) client_keys_data->data; if (client_key->enctype == 0) { retval = KRB5KDC_ERR_ETYPE_NOSUPP; com_err("krb5kdc", retval, @@ -203,20 +188,14 @@ cleanup: krb5_free_data(context, encoded_challenge); if (sam_db_entry) krb5_db_free_principal(context, sam_db_entry); - if (client_keys_data) { - while (client_key->enctype) { - krb5_free_keyblock_contents(context, client_key); - client_key++; - } - krb5_free_data(context, client_keys_data); - } + cb->free_keys(context, rock, client_key); return retval; } static void kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa_data, krb5_kdcpreauth_get_data_fn get, + krb5_pa_data *pa_data, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, void *arg) { @@ -225,7 +204,7 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, krb5_data scratch, *scratch2, *e_data = NULL; char *client_name = NULL; krb5_sam_challenge_2 *out_sc2 = NULL; - krb5_db_entry *client = get_client_entry(context, get, rock); + krb5_db_entry *client = cb->client_entry(context, rock); scratch.data = (char *) pa_data->contents; scratch.length = pa_data->length; diff --git a/src/plugins/preauth/wpse/wpse_main.c b/src/plugins/preauth/wpse/wpse_main.c index e437d6b03..4da2c2f48 100644 --- a/src/plugins/preauth/wpse/wpse_main.c +++ b/src/plugins/preauth/wpse/wpse_main.c @@ -90,7 +90,7 @@ client_process(krb5_context kcontext, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - krb5_clpreauth_get_data_fn client_get_data_proc, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, @@ -246,7 +246,7 @@ server_free_modreq(krb5_context kcontext, static krb5_error_code server_get_edata(krb5_context kcontext, krb5_kdc_req *request, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) @@ -264,7 +264,7 @@ server_verify(krb5_context kcontext, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, @@ -360,7 +360,7 @@ server_return(krb5_context kcontext, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - krb5_kdcpreauth_get_data_fn get, + krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) {