summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2011-10-06 16:18:56 +0000
committerGreg Hudson <ghudson@mit.edu>2011-10-06 16:18:56 +0000
commit7003d3dbdfd0a7f4f6843068affb290c844ccb65 (patch)
tree2b31a19ce468926f02f471597b68cb60d3bffe82 /src/plugins
parent72dc9d3ca51e6b54f088f7dc6a68c38504cde1d9 (diff)
downloadkrb5-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.c63
-rw-r--r--src/plugins/preauth/pkinit/pkinit_clnt.c30
-rw-r--r--src/plugins/preauth/pkinit/pkinit_srv.c23
-rw-r--r--src/plugins/preauth/securid_sam2/securid_sam2_main.c33
-rw-r--r--src/plugins/preauth/wpse/wpse_main.c8
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)
{