summaryrefslogtreecommitdiffstats
path: root/src/kdc/kdc_preauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kdc/kdc_preauth.c')
-rw-r--r--src/kdc/kdc_preauth.c246
1 files changed, 87 insertions, 159 deletions
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;