From b066ddfa869b362f7055b2532977a0f2d3860b35 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Tue, 19 Oct 2010 19:50:37 +0000 Subject: [PATCH] securID code fixes 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 target_version: 1.9 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24465 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/kdc_preauth.c | 1 + src/plugins/preauth/securid_sam2/extern.h | 1 + src/plugins/preauth/securid_sam2/securid2.c | 20 ++++-------- .../preauth/securid_sam2/securid_sam2_main.c | 32 ++++++++++++++++--- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 957ac23031c..52fb51a0c95 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -1181,6 +1181,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, 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: diff --git a/src/plugins/preauth/securid_sam2/extern.h b/src/plugins/preauth/securid_sam2/extern.h index 100c1323027..791eddf2446 100644 --- a/src/plugins/preauth/securid_sam2/extern.h +++ b/src/plugins/preauth/securid_sam2/extern.h @@ -39,6 +39,7 @@ securid_make_sam_challenge_2_and_cksum(krb5_context context, 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); diff --git a/src/plugins/preauth/securid_sam2/securid2.c b/src/plugins/preauth/securid_sam2/securid2.c index f5e07154949..0a481c7c31d 100644 --- a/src/plugins/preauth/securid_sam2/securid2.c +++ b/src/plugins/preauth/securid_sam2/securid2.c @@ -266,17 +266,16 @@ securid_encrypt_track_data_2(krb5_context context, krb5_db_entry *client, 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 = ""; struct securid_track_data sid_track_data; krb5_data tmp_data; - client_key.contents = NULL; scratch.data = NULL; sc2b->sam_track_id.data = NULL; @@ -291,6 +290,7 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client, 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(); @@ -316,17 +316,10 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client, } /* 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)", @@ -334,7 +327,6 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client, } cleanup: - krb5_free_keyblock_contents(context, &client_key); free(user); if (retval) { krb5_free_data_contents(context, &sc2b->sam_track_id); @@ -486,7 +478,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client, "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"); @@ -728,7 +720,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client, "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; } diff --git a/src/plugins/preauth/securid_sam2/securid_sam2_main.c b/src/plugins/preauth/securid_sam2/securid_sam2_main.c index 695934cc476..3e1ada28e20 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2_main.c +++ b/src/plugins/preauth/securid_sam2/securid_sam2_main.c @@ -122,6 +122,8 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, 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 */ @@ -137,6 +139,16 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, &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; @@ -152,7 +164,7 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, 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; @@ -181,6 +193,13 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, 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; } @@ -192,7 +211,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, 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; @@ -237,7 +256,10 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, * 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]; @@ -256,6 +278,8 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, encode_error: krb5_free_sam_response_2(context, sr2); free(client_name); + if (retval == 0) + retval = saved_retval; return retval; } @@ -263,7 +287,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, static int kdc_preauth_flags(krb5_context context, krb5_preauthtype patype) { - return 0; + return PA_HARDWARE; } krb5_preauthtype supported_pa_types[] = {