static void kdc_include_padata(krb5_context context, krb5_kdc_req *request, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type, krb5_kdcpreauth_edata_respond_fn respond, void *arg) { krb5_error_code retval; krb5_keyblock *client_key = NULL; krb5_sam_challenge_2 sc2; int sam_type = 0; /* unknown */ krb5_db_entry *sam_db_entry = NULL, *client; krb5_data *encoded_challenge = NULL; krb5_pa_data *pa_data = NULL; memset(&sc2, 0, sizeof(sc2)); client = cb->client_entry(context, rock); retval = sam_get_db_entry(context, client->princ, &sam_type, &sam_db_entry); if (retval) goto cleanup; retval = cb->client_keys(context, rock, &client_key); if (retval) goto cleanup; if (client_key->enctype == 0) { retval = KRB5KDC_ERR_ETYPE_NOSUPP; com_err("krb5kdc", retval, "No client keys found in processing SAM2 challenge"); goto cleanup; } if (sam_type == 0) { retval = KRB5_PREAUTH_BAD_TYPE; goto cleanup; } /* * Defer getting the key for the SAM principal associated with the client * until the mechanism-specific code. The mechanism may want to get a * specific keytype. */ switch (sam_type) { #ifdef ARL_SECURID_PREAUTH case PA_SAM_TYPE_SECURID: retval = get_securid_edata_2(context, client, client_key, &sc2); if (retval) goto cleanup; break; #endif /* ARL_SECURID_PREAUTH */ #ifdef GRAIL_PREAUTH case PA_SAM_TYPE_GRAIL: retval = get_grail_edata(context, client, client_key, &sc2); if (retval) goto cleanup; break; #endif /* GRAIL_PREAUTH */ default: retval = KRB5_PREAUTH_BAD_TYPE; goto cleanup; } retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); if (retval) { com_err("krb5kdc", retval, "while encoding SECURID SAM_CHALLENGE_2"); goto cleanup; } pa_data = k5alloc(sizeof(*pa_data), &retval); if (pa_data == NULL) goto cleanup; pa_data->magic = KV5M_PA_DATA; pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; pa_data->contents = (krb5_octet *)encoded_challenge->data; pa_data->length = encoded_challenge->length; encoded_challenge->data = NULL; cleanup: krb5_free_data(context, encoded_challenge); if (sam_db_entry) krb5_db_free_principal(context, sam_db_entry); cb->free_keys(context, rock, client_key); (*respond)(arg, retval, pa_data); }
static krb5_error_code kdc_include_padata(krb5_context context, krb5_kdc_req *request, struct _krb5_db_entry_new *client, struct _krb5_db_entry_new *server, preauth_get_entry_data_proc get_entry_proc, void *pa_module_context, 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; int sam_type = 0; /* unknown */ krb5_db_entry *sam_db_entry = NULL; krb5_data *encoded_challenge = NULL; memset(&sc2, 0, sizeof(sc2)); memset(&sc2b, 0, sizeof(sc2b)); sc2b.magic = KV5M_SAM_CHALLENGE_2; sc2b.sam_type = sam_type; retval = sam_get_db_entry(context, client->princ, &sam_type, &sam_db_entry); if (retval) return retval; retval = get_entry_proc(context, request, client, krb5plugin_preauth_keys, &client_keys_data); 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, "No client keys found in processing SAM2 challenge"); goto cleanup; } if (sam_type == 0) { retval = KRB5_PREAUTH_BAD_TYPE; goto cleanup; } /* * Defer getting the key for the SAM principal associated with the client * until the mechanism-specific code. The mechanism may want to get a * specific keytype. */ switch (sam_type) { #ifdef ARL_SECURID_PREAUTH case PA_SAM_TYPE_SECURID: retval = get_securid_edata_2(context, client, client_key, &sc2b, &sc2); if (retval) goto cleanup; retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); if (retval) { com_err("krb5kdc", retval, "while encoding SECURID SAM_CHALLENGE_2"); goto cleanup; } pa_data->magic = KV5M_PA_DATA; pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; pa_data->contents = (krb5_octet *) encoded_challenge->data; pa_data->length = encoded_challenge->length; encoded_challenge->data = NULL; retval = 0; break; #endif /* ARL_SECURID_PREAUTH */ default: retval = KRB5_PREAUTH_BAD_TYPE; goto cleanup; } 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); } return retval; }