------------------------------------------------------------------------
r24465 | hartmans | 2010-10-19 15:50:37 -0400 (Tue, 19 Oct 2010) | 19 lines
ticket: 6805
subject: securID code fixes
target_version: 1.9
tags: pullup
Fixes to get securID preauth plugin working. A separate patch will
address error handling and build issues.
* Permit a preauth plugin to return KRB5KDC_ERR_PREAUTH_REQUIRED from
the verify entry point.
* If verify_securid2 fails, save the return value and return that
rather than success after dealing with encoding the out_edata
* Use the client key not the securid principal key for the sam
checksum
* indicate that securID is hardware authentication
ticket: 6805
version_fixed: 1.9
status: resolved
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-9@24492
dc483132-0cff-0310-8789-
dd5450dbe970
case 0: /* in case of PA-PAC-REQUEST with no PA-ENC-TIMESTAMP */
case KRB5KRB_AP_ERR_BAD_INTEGRITY:
case KRB5KRB_AP_ERR_SKEW:
+ case KRB5KDC_ERR_PREAUTH_REQUIRED:
case KRB5KDC_ERR_ETYPE_NOSUPP:
/* rfc 4556 */
case KRB5KDC_ERR_CLIENT_NOT_TRUSTED:
krb5_error_code get_securid_edata_2(krb5_context context,
krb5_db_entry *client,
+ krb5_keyblock *client_key,
krb5_sam_challenge_2_body *sc2b,
krb5_sam_challenge_2 *sc2);
krb5_error_code
get_securid_edata_2(krb5_context context, krb5_db_entry *client,
+ krb5_keyblock *client_key,
krb5_sam_challenge_2_body *sc2b, krb5_sam_challenge_2 *sc2)
{
krb5_error_code retval;
krb5_data scratch;
- krb5_keyblock client_key;
char *user = NULL;
char *def_user = "<unknown user>";
struct securid_track_data sid_track_data;
krb5_data tmp_data;
- client_key.contents = NULL;
scratch.data = NULL;
sc2b->sam_track_id.data = NULL;
sc2b->sam_response_prompt.data = PASSCODE_message;
sc2b->sam_response_prompt.length = strlen(sc2b->sam_response_prompt.data);
sc2b->sam_pk_for_sad.length = 0;
+ sc2b->sam_type = PA_SAM_TYPE_SECURID;
sid_track_data.state = SECURID_STATE_INITIAL;
sid_track_data.hostid = gethostid();
}
/* Get the client's key */
- if ((retval = get_securid_key(context, client, &client_key)) != 0) {
- krb5_set_error_message(context, retval,
- "while getting SecurID SAM key in "
- "get_securid_edata_2 (%s)",
- user ? user : def_user);
- goto cleanup;
- }
- sc2b->sam_etype = client_key.enctype;
+ sc2b->sam_etype = client_key->enctype;
retval = securid_make_sam_challenge_2_and_cksum(context,
- sc2, sc2b, &client_key);
+ sc2, sc2b, client_key);
if (retval) {
krb5_set_error_message(context, retval,
"while making SAM_CHALLENGE_2 checksum (%s)",
}
cleanup:
- krb5_free_keyblock_contents(context, &client_key);
free(user);
if (retval) {
krb5_free_data_contents(context, &sc2b->sam_track_id);
"verify_securid_data_2 (%s)", user);
goto cleanup;
}
- if (track_id_data.length <= sizeof (struct securid_track_data)) {
+ if (track_id_data.length < sizeof (struct securid_track_data)) {
retval = KRB5KDC_ERR_PREAUTH_FAILED;
krb5_set_error_message(context, retval,
"Length of track data incorrect");
"for user %s", securid_user);
*sc2_out = sc2p;
sc2p = NULL;
- retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
/*sc2_out is permitted as an output on error path*/
goto cleanup;
}
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 */
&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;
+ krb5_set_error_message(context, retval, "No client keys found in processing SAM2 challenge");
+ goto cleanup;
+ }
if (sam_type == 0) {
retval = KRB5_PREAUTH_BAD_TYPE;
switch (sam_type) {
#ifdef ARL_SECURID_PREAUTH
case PA_SAM_TYPE_SECURID:
- retval = get_securid_edata_2(context, client, &sc2b, &sc2);
+ retval = get_securid_edata_2(context, client, client_key, &sc2b, &sc2);
if (retval)
goto 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;
}
void *pa_module_context, void **opaque,
krb5_data **e_data, krb5_authdata ***authz_data)
{
- krb5_error_code retval;
+ krb5_error_code retval, saved_retval = 0;
krb5_sam_response_2 *sr2 = NULL;
krb5_data scratch, *scratch2;
char *client_name = NULL;
* get enough preauth data from the client. Do not set TGT flags here.
*/
cleanup:
- /*Note that e_data is an output even in error conditions.*/
+ /*Note that e_data is an output even in error conditions. If we
+ successfully encode the output e_data, we return whatever error
+ is received above. Otherwise we return the encoding error.*/
+ saved_retval = retval;
if (out_sc2) {
krb5_pa_data pa_out;
krb5_pa_data *pa_array[2];
encode_error:
krb5_free_sam_response_2(context, sr2);
free(client_name);
+ if (retval == 0)
+ retval = saved_retval;
return retval;
}
static int
kdc_preauth_flags(krb5_context context, krb5_preauthtype patype)
{
- return 0;
+ return PA_HARDWARE;
}
krb5_preauthtype supported_pa_types[] = {