diff options
| author | Greg Hudson <ghudson@mit.edu> | 2011-10-06 16:18:56 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2011-10-06 16:18:56 +0000 |
| commit | 7003d3dbdfd0a7f4f6843068affb290c844ccb65 (patch) | |
| tree | 2b31a19ce468926f02f471597b68cb60d3bffe82 /src/plugins | |
| parent | 72dc9d3ca51e6b54f088f7dc6a68c38504cde1d9 (diff) | |
| download | krb5-7003d3dbdfd0a7f4f6843068affb290c844ccb65.tar.gz krb5-7003d3dbdfd0a7f4f6843068affb290c844ccb65.tar.xz krb5-7003d3dbdfd0a7f4f6843068affb290c844ccb65.zip | |
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
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/preauth/cksum_body/cksum_body_main.c | 63 | ||||
| -rw-r--r-- | src/plugins/preauth/pkinit/pkinit_clnt.c | 30 | ||||
| -rw-r--r-- | src/plugins/preauth/pkinit/pkinit_srv.c | 23 | ||||
| -rw-r--r-- | src/plugins/preauth/securid_sam2/securid_sam2_main.c | 33 | ||||
| -rw-r--r-- | src/plugins/preauth/wpse/wpse_main.c | 8 |
5 files changed, 50 insertions, 107 deletions
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) { |
