Lines Matching +full:post +full:- +full:init +full:- +full:providers

1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* kdc/kdc_preauth.c - Preauthentication routines for the KDC */
52 * Copyright (c) 2006-2008, Novell, Inc.
79 #include "k5-int.h"
98 krb5_kdcpreauth_init_fn init; member
129 /* Auto-register encrypted challenge and (if possible) pkinit. */ in get_plugin_vtables()
173 list = calloc(handle->kdc_numrealms + 1, sizeof(*list)); in get_realm_names()
176 for (i = 0; i < handle->kdc_numrealms; i++) in get_realm_names()
177 list[i] = handle->kdc_realmlist[i]->realm_name; in get_realm_names()
205 /* Add the dynamically-loaded mechanisms to the list. */ in load_preauth_plugins()
211 if (vt->init) { in load_preauth_plugins()
212 ret = vt->init(context, &moddata, realm_names); in load_preauth_plugins()
216 "initialize: %s"), vt->name, emsg); in load_preauth_plugins()
222 if (vt->loop) { in load_preauth_plugins()
223 ret = vt->loop(context, moddata, ctx); in load_preauth_plugins()
227 "loop: %s"), vt->name, emsg); in load_preauth_plugins()
229 if (vt->fini) in load_preauth_plugins()
230 vt->fini(context, moddata); in load_preauth_plugins()
236 for (j = 0; vt->pa_type_list[j] != 0; j++) { in load_preauth_plugins()
238 sys->name = vt->name; in load_preauth_plugins()
239 sys->type = vt->pa_type_list[j]; in load_preauth_plugins()
240 sys->flags = (vt->flags) ? vt->flags(context, sys->type) : 0; in load_preauth_plugins()
241 sys->moddata = moddata; in load_preauth_plugins()
242 sys->init = vt->init; in load_preauth_plugins()
244 sys->fini = (j == 0) ? vt->fini : NULL; in load_preauth_plugins()
245 sys->get_edata = vt->edata; in load_preauth_plugins()
246 sys->verify_padata = vt->verify; in load_preauth_plugins()
247 sys->return_padata = vt->return_padata; in load_preauth_plugins()
248 sys->free_modreq = vt->free_modreq; in load_preauth_plugins()
249 sys->loop = vt->loop; in load_preauth_plugins()
254 /* Add the end-of-list marker. */ in load_preauth_plugins()
256 preauth_systems[n_systems].type = -1; in load_preauth_plugins()
279 * request-specific module data which will be needed by return_padata() later.
301 ret->n_contexts = n_preauth_systems; in make_padata_context()
302 ret->contexts = malloc(sizeof(ret->contexts[0]) * ret->n_contexts); in make_padata_context()
303 if (ret->contexts == NULL) { in make_padata_context()
308 memset(ret->contexts, 0, sizeof(ret->contexts[0]) * ret->n_contexts); in make_padata_context()
310 for (i = 0; i < ret->n_contexts; i++) { in make_padata_context()
311 ret->contexts[i].pa_system = &preauth_systems[i]; in make_padata_context()
312 ret->contexts[i].modreq = NULL; in make_padata_context()
334 for (i = 0; i < context->n_contexts; i++) { in free_padata_context()
335 sys = context->contexts[i].pa_system; in free_padata_context()
336 if (!sys->free_modreq || !context->contexts[i].modreq) in free_padata_context()
338 sys->free_modreq(kcontext, sys->moddata, context->contexts[i].modreq); in free_padata_context()
339 context->contexts[i].modreq = NULL; in free_padata_context()
342 free(context->contexts); in free_padata_context()
349 return context->clockskew; in max_time_skew()
356 krb5_kdc_req *request = rock->request; in client_keys()
357 krb5_db_entry *client = rock->client; in client_keys()
362 keys = calloc(request->nktypes + 1, sizeof(krb5_keyblock)); in client_keys()
367 for (i = 0; i < request->nktypes; i++) { in client_keys()
369 if (krb5_dbe_find_enctype(context, client, request->ktype[i], in client_keys()
370 -1, 0, &entry_key) != 0) in client_keys()
392 for (k = keys; k->enctype != 0; k++) in free_keys()
400 return rock->inner_body; in request_body()
406 return rock->rstate->armor_key; in fast_armor()
413 return krb5_dbe_get_string(context, rock->client, key, value_out); in get_string()
425 return rock->client; in client_entry()
431 return rock->vctx; in event_context()
437 krb5_kdc_req *request = rock->request; in have_client_keys()
441 for (i = 0; i < request->nktypes; i++) { in have_client_keys()
442 if (krb5_dbe_find_enctype(context, rock->client, request->ktype[i], in have_client_keys()
443 -1, 0, &kd) == 0) in have_client_keys()
452 if (rock->client_keyblock->enctype == ENCTYPE_NULL) in client_keyblock()
454 return rock->client_keyblock; in client_keyblock()
461 return authind_add(context, indicator, rock->auth_indicators); in add_auth_indicator()
468 return kdc_fast_search_cookie(rock->rstate, pa_type, out); in get_cookie()
475 return kdc_fast_set_cookie(rock->rstate, pa_type, data); in set_cookie()
484 krb5_principal req_client = rock->request->client; in match_client()
485 krb5_principal client = rock->client->princ; in match_client()
488 * the post-canon client principal. */ in match_client()
496 match = krb5_principal_compare(context, ent->princ, client); in match_client()
504 return rock->client->princ; in client_name()
510 rock->send_freshness_token = TRUE; in send_freshness_token()
533 if (token->length <= 8) in check_freshness_token()
535 token_ts = load_32_be(token->data); in check_freshness_token()
536 token_kvno = load_32_be(token->data + 4); in check_freshness_token()
537 token_cksum = (uint8_t *)token->data + 8; in check_freshness_token()
538 token_cksum_len = token->length - 8; in check_freshness_token()
545 if (krb5_dbe_find_enctype(context, rock->local_tgt, -1, -1, token_kvno, in check_freshness_token()
575 krb5_free_keyblock_contents(context, rock->client_keyblock); in replace_reply_key()
576 *rock->client_keyblock = copy; in replace_reply_key()
578 rock->replaced_reply_key = TRUE; in replace_reply_key()
613 while ((ap->type != -1) && (ap->type != type)) in find_pa_system()
615 if (ap->type == -1) in find_pa_system()
621 /* Find a pointer to the request-specific module data for pa_sys. */
632 for (i = 0; i < context->n_contexts; i++) { in find_modreq()
633 if (context->contexts[i].pa_system == pa_sys) { in find_modreq()
634 *modreq_out = &context->contexts[i].modreq; in find_modreq()
650 if ((*pa_data)->pa_type == pa_type) in pa_list_includes()
668 pa_order[n_repliers] = -1; in sort_pa_order()
686 /* If we didn't find one, we have moved all of the key-replacing in sort_pa_order()
693 if (request->padata != NULL) { in sort_pa_order()
699 if (pa_list_includes(request->padata, in sort_pa_order()
703 if (pa_list_includes(request->padata, in sort_pa_order()
721 for (i = 0; pa_order[i] != -1; i++) { in sort_pa_order()
737 isflagset (client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) ? "" : "no ", in missing_required_preauth()
738 isflagset (client->attributes, KRB5_KDB_REQUIRES_HW_AUTH) ? "" : "no ", in missing_required_preauth()
739 isflagset (enc_tkt_reply->flags, TKT_FLG_PRE_AUTH) ? "" : "no ", in missing_required_preauth()
740 isflagset (enc_tkt_reply->flags, TKT_FLG_HW_AUTH) ? "" : "no "); in missing_required_preauth()
743 if (isflagset(client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) && in missing_required_preauth()
744 !isflagset(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH)) in missing_required_preauth()
747 if (isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH) && in missing_required_preauth()
748 !isflagset(enc_tkt_reply->flags, TKT_FLG_HW_AUTH)) in missing_required_preauth()
754 /* Return true if request's enctypes indicate support for etype-info2. */
760 for (i = 0; i < request->nktypes; i++) { in requires_info2()
761 if (enctype_requires_etype_info_2(request->ktype[i])) in requires_info2()
767 /* Add PA-ETYPE-INFO2 and possibly PA-ETYPE-INFO entries to pa_list as
776 if (rock->client_key == NULL) in add_etype_info()
779 if (!requires_info2(rock->request)) { in add_etype_info()
780 /* Include PA-ETYPE-INFO only for old clients. */ in add_etype_info()
781 ret = make_etype_info(context, FALSE, rock->client->princ, in add_etype_info()
782 rock->client_key, rock->client_keyblock->enctype, in add_etype_info()
792 /* Always include PA-ETYPE-INFO2. */ in add_etype_info()
793 ret = make_etype_info(context, TRUE, rock->client->princ, rock->client_key, in add_etype_info()
794 rock->client_keyblock->enctype, &der); in add_etype_info()
802 /* Add PW-SALT entries to pa_list as appropriate for the request and client
812 /* Only include this pa-data for old clients. */ in add_pw_salt()
813 if (rock->client_key == NULL || requires_info2(rock->request)) in add_pw_salt()
816 ret = krb5_dbe_compute_salt(context, rock->client_key, in add_pw_salt()
817 rock->request->client, &salttype, &salt); in add_pw_salt()
841 if (!rock->send_freshness_token) in add_freshness_token()
843 if (krb5int_find_pa_data(context, rock->request->padata, in add_freshness_token()
853 ret = krb5_c_make_checksum(context, 0, rock->local_tgt_key, in add_freshness_token()
860 store_32_be(now, pa->contents); in add_freshness_token()
861 store_32_be(current_kvno(rock->local_tgt), pa->contents + 4); in add_freshness_token()
862 memcpy(pa->contents + 8, cksum.contents, cksum.length); in add_freshness_token()
891 krb5_context context = state->context; in hint_list_finish()
892 kdc_hint_respond_fn oldrespond = state->respond; in hint_list_finish()
893 void *oldarg = state->arg; in hint_list_finish()
898 code = add_freshness_token(context, state->rock, &state->pa_data); in hint_list_finish()
901 if (state->pa_data == NULL) { in hint_list_finish()
904 state->hw_only ? "hw" : ""); in hint_list_finish()
907 *state->e_data_out = state->pa_data; in hint_list_finish()
908 state->pa_data = NULL; in hint_list_finish()
911 krb5_free_pa_data(context, state->pa_data); in hint_list_finish()
927 ret = k5_alloc_pa_data(state->pa_type, 0, &pa); in finish_get_edata()
931 ret = k5_add_pa_data_element(&state->pa_data, &pa); in finish_get_edata()
937 state->ap++; in finish_get_edata()
948 krb5_context context = state->context; in hint_list_next()
949 preauth_system *ap = state->ap; in hint_list_next()
951 if (ap->type == -1) { in hint_list_next()
956 if (state->hw_only && !(ap->flags & PA_HARDWARE)) in hint_list_next()
958 if (ap->flags & PA_PSEUDO) in hint_list_next()
961 state->pa_type = ap->type; in hint_list_next()
962 if (ap->get_edata) { in hint_list_next()
963 ap->get_edata(context, state->request, &callbacks, state->rock, in hint_list_next()
964 ap->moddata, ap->type, finish_get_edata, state); in hint_list_next()
970 state->ap++; in hint_list_next()
979 krb5_context context = rock->rstate->realm_data->realm_context; in get_preauth_hint_list()
988 state->hw_only = isflagset(rock->client->attributes, in get_preauth_hint_list()
990 state->respond = respond; in get_preauth_hint_list()
991 state->arg = arg; in get_preauth_hint_list()
992 state->request = request; in get_preauth_hint_list()
993 state->rock = rock; in get_preauth_hint_list()
994 state->context = context; in get_preauth_hint_list()
995 state->e_data_out = e_data_out; in get_preauth_hint_list()
996 state->pa_data = NULL; in get_preauth_hint_list()
997 state->ap = preauth_systems; in get_preauth_hint_list()
999 /* Add an empty PA-FX-FAST element to advertise FAST support. */ in get_preauth_hint_list()
1000 if (k5_add_empty_pa_data(&state->pa_data, KRB5_PADATA_FX_FAST) != 0) in get_preauth_hint_list()
1003 if (add_etype_info(context, rock, &state->pa_data) != 0) in get_preauth_hint_list()
1011 krb5_free_pa_data(context, state->pa_data); in get_preauth_hint_list()
1018 * It is assumed that ad is a "null-terminated" array of krb5_authdata ptrs
1034 if (enc_tkt_part->authorization_data == NULL) in add_authorization_data()
1038 enc_tkt_part->authorization_data[oldones] != NULL; oldones++); in add_authorization_data()
1046 newad[i] = enc_tkt_part->authorization_data[i]; in add_authorization_data()
1056 if (enc_tkt_part->authorization_data != NULL) in add_authorization_data()
1057 free(enc_tkt_part->authorization_data); in add_authorization_data()
1060 enc_tkt_part->authorization_data = newad; in add_authorization_data()
1126 /* pkinit alg-agility */ in filter_preauth_error()
1137 * If the client performed optimistic pre-authentication for a multi-round-trip
1139 * a PA-ETYPE-INFO2 element in addition to the pa-data from the module.
1145 krb5_context context = state->context; in maybe_add_etype_info2()
1146 krb5_kdcpreauth_rock rock = state->rock; in maybe_add_etype_info2()
1154 if (rock->client_key == NULL) in maybe_add_etype_info2()
1159 if (krb5int_find_pa_data(context, state->request->padata, in maybe_add_etype_info2()
1163 ret = make_etype_info(context, TRUE, rock->client->princ, rock->client_key, in maybe_add_etype_info2()
1164 rock->client_keyblock->enctype, &der); in maybe_add_etype_info2()
1167 ret = k5_add_pa_data_from_data(&state->pa_e_data, KRB5_PADATA_ETYPE_INFO2, in maybe_add_etype_info2()
1173 /* Release state and respond to the AS-REQ processing code with the result of
1174 * checking pre-authentication data. */
1181 if (state->pa_ok || !state->pa_found) { in finish_check_padata()
1188 /* Add key information to the saved error pa-data if required. */ in finish_check_padata()
1194 /* Return any saved error pa-data, stealing the pointer from state. */ in finish_check_padata()
1195 *state->e_data_out = state->pa_e_data; in finish_check_padata()
1196 *state->typed_e_data_out = state->typed_e_data_flag; in finish_check_padata()
1197 state->pa_e_data = NULL; in finish_check_padata()
1200 /* Discard saved error pa-data if we aren't returning it, free state, and in finish_check_padata()
1201 * respond to the AS-REQ processing code. */ in finish_check_padata()
1202 respond = state->respond; in finish_check_padata()
1203 arg = state->arg; in finish_check_padata()
1204 krb5_free_pa_data(state->context, state->pa_e_data); in finish_check_padata()
1222 *state->modreq_ptr = modreq; in finish_verify_padata()
1225 emsg = krb5_get_error_message(state->context, code); in finish_verify_padata()
1227 state->pa_sys->name, emsg); in finish_verify_padata()
1228 krb5_free_error_message(state->context, emsg); in finish_verify_padata()
1232 krb5_free_authdata(state->context, authz_data); in finish_verify_padata()
1236 typed_e_data_flag = ((state->pa_sys->flags & PA_TYPED_E_DATA) != 0); in finish_verify_padata()
1240 * that fails, or the first non-PA_REQUIRED module that fails. in finish_verify_padata()
1241 * Hang on to edata from the first non-PA_REQUIRED module. in finish_verify_padata()
1244 if (state->pa_sys->flags & PA_REQUIRED) { in finish_verify_padata()
1246 if (state->pa_e_data != NULL) in finish_verify_padata()
1247 krb5_free_pa_data(state->context, state->pa_e_data); in finish_verify_padata()
1248 state->pa_e_data = e_data; in finish_verify_padata()
1249 state->typed_e_data_flag = typed_e_data_flag; in finish_verify_padata()
1252 state->pa_ok = 0; in finish_verify_padata()
1255 } else if (state->pa_e_data == NULL) { in finish_verify_padata()
1256 /* save the first error code and e-data */ in finish_verify_padata()
1257 state->pa_e_data = e_data; in finish_verify_padata()
1258 state->typed_e_data_flag = typed_e_data_flag; in finish_verify_padata()
1259 state->saved_code = code; in finish_verify_padata()
1261 /* discard this extra e-data from non-PA_REQUIRED module */ in finish_verify_padata()
1262 krb5_free_pa_data(state->context, e_data); in finish_verify_padata()
1271 krb5_free_pa_data(state->context, e_data); in finish_verify_padata()
1275 add_authorization_data(state->enc_tkt_reply, authz_data); in finish_verify_padata()
1279 state->pa_ok = 1; in finish_verify_padata()
1280 if (state->pa_sys->flags & PA_SUFFICIENT) { in finish_verify_padata()
1281 finish_check_padata(state, state->saved_code); in finish_verify_padata()
1293 if (!state->padata) in next_padata()
1294 state->padata = state->request->padata; in next_padata()
1296 state->padata++; in next_padata()
1298 if (!*state->padata) { in next_padata()
1299 finish_check_padata(state, state->saved_code); in next_padata()
1304 krb5_klog_syslog (LOG_DEBUG, ".. pa_type 0x%x", (*state->padata)->pa_type); in next_padata()
1306 if (find_pa_system((*state->padata)->pa_type, &state->pa_sys)) in next_padata()
1308 if (find_modreq(state->pa_sys, *state->padata_context, &state->modreq_ptr)) in next_padata()
1311 krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", state->pa_sys->name); in next_padata()
1313 if (state->pa_sys->verify_padata == 0) in next_padata()
1316 state->pa_found++; in next_padata()
1317 state->pa_sys->verify_padata(state->context, state->req_pkt, in next_padata()
1318 state->request, state->enc_tkt_reply, in next_padata()
1319 *state->padata, &callbacks, state->rock, in next_padata()
1320 state->pa_sys->moddata, finish_verify_padata, in next_padata()
1332 * Returns 0 if the pre-authentication is valid, non-zero to indicate
1345 if (request->padata == 0) { in check_padata()
1360 state->respond = respond; in check_padata()
1361 state->arg = arg; in check_padata()
1362 state->context = context; in check_padata()
1363 state->rock = rock; in check_padata()
1364 state->req_pkt = req_pkt; in check_padata()
1365 state->request = request; in check_padata()
1366 state->enc_tkt_reply = enc_tkt_reply; in check_padata()
1367 state->padata_context = padata_context; in check_padata()
1368 state->e_data_out = e_data; in check_padata()
1369 state->typed_e_data_out = typed_e_data; in check_padata()
1370 state->realm = rock->rstate->realm_data; in check_padata()
1383 if (k1->enctype != k2->enctype) in keyblock_equal()
1385 if (k1->length != k2->length) in keyblock_equal()
1387 return memcmp(k1->contents, k2->contents, k1->length) == 0; in keyblock_equal()
1420 for (ap = preauth_systems; ap->type != -1; ap++) { in return_padata()
1421 if (ap->return_padata) in return_padata()
1438 for (pa_type = pa_order; *pa_type != -1; pa_type++) { in return_padata()
1440 if (key_modified && (ap->flags & PA_REPLACES_KEY)) in return_padata()
1442 if (ap->return_padata == 0) in return_padata()
1447 null_item.pa_type = ap->type; in return_padata()
1448 if (request->padata) { in return_padata()
1449 for (padata = request->padata; *padata; padata++) { in return_padata()
1450 if ((*padata)->pa_type == ap->type) { in return_padata()
1457 retval = ap->return_padata(context, pa, req_pkt, request, reply, in return_padata()
1459 ap->moddata, *modreq_ptr); in return_padata()
1475 * Add etype-info and pw-salt pa-data as needed. If we replaced the reply in return_padata()
1476 * key, we can't send consistent etype-info; the salt from the client key in return_padata()
1478 * 5.2.7.5 forbids us from sending etype-info describing the initial reply in return_padata()
1479 * key in an AS-REP if it doesn't have the same enctype as the replaced in return_padata()
1481 * the client received etype-info2 in an earlier step and already computed in return_padata()
1483 * enctype of the replaced reply key from the etype field of the enc-part in return_padata()
1484 * field of the AS-REP. in return_padata()
1496 reply->padata = send_pa_list; in return_padata()
1524 entry->magic = KV5M_ETYPE_INFO_ENTRY; in _make_etype_info_entry()
1525 entry->etype = etype; in _make_etype_info_entry()
1526 entry->length = KRB5_ETYPE_NO_SALT; in _make_etype_info_entry()
1527 entry->salt = NULL; in _make_etype_info_entry()
1528 entry->s2kparams = empty_data(); in _make_etype_info_entry()
1534 entry->length = salt->length; in _make_etype_info_entry()
1535 entry->salt = (unsigned char *)salt->data; in _make_etype_info_entry()
1536 salt->data = NULL; in _make_etype_info_entry()
1542 krb5_free_data_contents(context, &entry->s2kparams); in _make_etype_info_entry()
1548 /* Encode an etype-info or etype-info2 message for client_key with the given
1590 if (request->padata == NULL) { in include_pac_p()
1594 for (padata = request->padata; *padata != NULL; padata++) { in include_pac_p()
1595 if ((*padata)->pa_type == KRB5_PADATA_PAC_REQUEST) { in include_pac_p()
1596 data.data = (char *)(*padata)->contents; in include_pac_p()
1597 data.length = (*padata)->length; in include_pac_p()
1601 retval = req->include_pac; in include_pac_p()
1630 memcpy(pa->contents, tl_data.tl_data_contents, tl_data.tl_data_length); in return_referral_enc_padata()
1631 code = k5_add_pa_data_element(&reply->enc_padata, &pa); in return_referral_enc_padata()
1651 &reply_encpart->enc_padata); in return_enc_padata()
1656 &reply_encpart->enc_padata); in return_enc_padata()
1660 /*Add potentially other enc_padata providers*/ in return_enc_padata()