From fcusack@ratbert.iconnet.net Mon Nov 30 21:05:47 1998 Received: from MIT.EDU (SOUTH-STATION-ANNEX.MIT.EDU [18.72.1.2]) by rt-11.MIT.EDU (8.7.5/8.7.3) with SMTP id VAA03224 for ; Mon, 30 Nov 1998 21:05:46 -0500 Received: from ratbert.iconnet.net by MIT.EDU with SMTP id AA23909; Mon, 30 Nov 98 21:05:27 EST Received: (from fcusack@localhost) by ratbert.iconnet.net (8.9.1/8.9.1) id VAA18716; Mon, 30 Nov 1998 21:06:33 -0500 (EST) Message-Id: <199812010206.VAA18716@ratbert.iconnet.net> Date: Mon, 30 Nov 1998 21:06:33 -0500 (EST) From: fcusack@iconnet.net Reply-To: fcusack@iconnet.net To: krb5-bugs@MIT.EDU Cc: fcusack@iconnet.net Subject: SAM preauth fixes X-Send-Pr-Version: 3.99 >Number: 668 >Category: krb5-kdc >Synopsis: unify sam_track_id data; securid fixes >Confidential: no >Severity: serious >Priority: medium >Responsible: krb5-unassigned >State: open >Class: sw-bug >Submitter-Id: unknown >Arrival-Date: Mon Nov 30 21:06:01 EST 1998 >Last-Modified: >Originator: Frank Cusack >Organization: Icon CMT Corp. >Release: krb5-current-19981119 >Environment: N/A System: SunOS ratbert 5.6 Generic_105181-09 sun4u sparc SUNW,Ultra-5_10 Architecture: sun4 >Description: Some fixes related to my previous pr's. This should be applied along with krb5-kdc/662-665. Fixes in this pr "unify" the predicted_sam_response so that the same data type can be used for all sam mechanisms. It adds a field `msd' which is `mechanism specific data' to the "psr". Also, prototype changes for the sam_verify_xxx functions needed for securid (for send-encrypted-sad in general). Also, a bunch of securid fixes. Securid should work now, although I am unable to test at this time. >How-To-Repeat: >Fix: Index: include/k5-int.h =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/include/k5-int.h,v retrieving revision 1.5 diff -u -r1.5 k5-int.h --- k5-int.h 1998/11/25 22:35:55 1.5 +++ k5-int.h 1998/12/01 02:00:03 @@ -344,17 +344,11 @@ #define PA_SAM_TYPE_GRAIL (PA_SAM_TYPE_EXP_BASE+0) /* testing */ #define PA_SAM_TYPE_SECURID_PREDICT (PA_SAM_TYPE_EXP_BASE+1) /* special */ -typedef struct _krb5_rb1_track_data { - krb5_magic magic; - krb5_keyblock sam_key; - krb5_data next_challenge; - krb5_int32 kdc_id; /* some magic to avoid esre replays */ -} krb5_rb1_track_data; - typedef struct _krb5_predicted_sam_response { krb5_magic magic; krb5_keyblock sam_key; krb5_int32 kdc_id; /* some magic to avoid esre replays */ + krb5_data msd; /* mechanism specific data */ } krb5_predicted_sam_response; typedef struct _krb5_sam_challenge { @@ -961,8 +955,6 @@ KRB5_PROTOTYPE((krb5_context, krb5_predicted_sam_response FAR * )); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc FAR * )); -KRB5_DLLIMP void KRB5_CALLCONV krb5_free_rb1_track_data - KRB5_PROTOTYPE((krb5_context, krb5_rb1_track_data FAR * )); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_contents KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge FAR * )); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_response_contents @@ -971,8 +963,6 @@ KRB5_PROTOTYPE((krb5_context, krb5_predicted_sam_response FAR * )); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc_contents KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc FAR * )); -KRB5_DLLIMP void KRB5_CALLCONV krb5_free_rb1_track_data_contents - KRB5_PROTOTYPE((krb5_context, krb5_rb1_track_data FAR * )); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_pa_enc_ts KRB5_PROTOTYPE((krb5_context, krb5_pa_enc_ts FAR *)); @@ -1216,9 +1206,6 @@ krb5_error_code encode_krb5_predicted_sam_response KRB5_PROTOTYPE((const krb5_predicted_sam_response * , krb5_data **)); -krb5_error_code encode_krb5_rb1_track_data - KRB5_PROTOTYPE((const krb5_rb1_track_data *, krb5_data **)); - /************************************************************************* * End of prototypes for krb5_encode.c *************************************************************************/ @@ -1237,9 +1224,6 @@ krb5_error_code decode_krb5_predicted_sam_response KRB5_PROTOTYPE((const krb5_data *, krb5_predicted_sam_response **)); - -krb5_error_code decode_krb5_rb1_track_data - KRB5_PROTOTYPE((const krb5_data *, krb5_rb1_track_data **)); /************************************************************************* Index: include/krb5/kdb.h =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/include/krb5/kdb.h,v retrieving revision 1.2 diff -u -r1.2 kdb.h --- kdb.h 1998/11/25 06:50:48 1.2 +++ kdb.h 1998/12/01 02:00:03 @@ -145,9 +145,6 @@ #define KRB5_TL_KADM_DATA 0x0003 #define KRB5_TL_KADM5_E_DATA 0x0004 #define KRB5_TL_RB1_CHALLENGE 0x0005 -#ifdef SECURID -#define KRB5_TL_SECURID_STATE 0x0006 -#endif /* SECURID */ /* * Determines the number of failed KDC requests before DISALLOW_ALL_TIX is set Index: kdc/preauth/pa_sam.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam.c,v retrieving revision 1.1 diff -u -r1.1 pa_sam.c --- pa_sam.c 1998/11/25 04:06:17 1.1 +++ pa_sam.c 1998/12/01 02:00:04 @@ -255,7 +255,7 @@ return retval; } - retval = (sam_inst_map[sam_index].generate_proc)(context, request, assoc, + retval = (sam_inst_map[sam_index].generate_proc)(context, request, &assoc, npr, sam_key, client_key, sam_inst_map[sam_index].mode, pa_data); @@ -298,7 +298,8 @@ goto cleanup; } - retval = (sam_inst_map[sam_index].verify_proc)(context, request, assoc, npr, + retval = (sam_inst_map[sam_index].verify_proc)(context, request, client, + &assoc, npr, sam_inst_map[sam_index].mode, sr, enc_tkt_reply, as_key); krb5_db_free_principal(kdc_context, &assoc, npr); Index: kdc/preauth/pa_sam.h =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam.h,v retrieving revision 1.2 diff -u -r1.2 pa_sam.h --- pa_sam.h 1998/11/25 23:34:39 1.2 +++ pa_sam.h 1998/12/01 02:00:04 @@ -31,7 +31,7 @@ typedef krb5_error_code (*sam_generate_proc) KRB5_PROTOTYPE((krb5_context context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -41,7 +41,8 @@ typedef krb5_error_code (*sam_verify_proc) KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, /* client db_entry */ + krb5_db_entry *assoc, /* sam db_entry */ int npr, int sam_mode, krb5_sam_response *sr, @@ -59,7 +60,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_grail KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -68,7 +69,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_grail KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, @@ -78,7 +80,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_enigma KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -87,7 +89,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_enigma KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, @@ -97,7 +100,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_digi_path KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -106,7 +109,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_digi_path KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, @@ -116,7 +120,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_skey KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -125,7 +129,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_skey KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, @@ -135,7 +140,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_securid KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -144,7 +149,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_securid KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, @@ -154,7 +160,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_cryptocard KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *assoc, int npr, krb5_keyblock sam_key, krb5_keyblock client_key, @@ -163,7 +169,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_verify_cryptocard KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request, - krb5_db_entry assoc, + krb5_db_entry *client, + krb5_db_entry *assoc, int npr, int mode, krb5_sam_response *sr, Index: kdc/preauth/pa_sam_cryptocard.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_cryptocard.c,v retrieving revision 1.5 diff -u -r1.5 pa_sam_cryptocard.c --- pa_sam_cryptocard.c 1998/11/25 23:34:40 1.5 +++ pa_sam_cryptocard.c 1998/12/01 02:00:05 @@ -34,7 +34,7 @@ mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; @@ -43,7 +43,7 @@ { krb5_error_code retval; krb5_sam_challenge sc; - krb5_rb1_track_data rb1_track_data; + krb5_predicted_sam_response psr; krb5_tl_data tl_data; krb5_data * scratch; @@ -55,10 +55,11 @@ char inputblock[8]; char outputblock[8]; char response[9]; + char next_challenge[8]; krb5_data predict_response; memset(&sc, 0, sizeof(sc)); - memset(&rb1_track_data, 0, sizeof(rb1_track_data)); + memset(&psr, 0, sizeof(psr)); memset(inputblock, 0, 8); session_key.contents = 0; @@ -78,7 +79,7 @@ * (Event Synchronous mode) */ tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE; - if ((retval = krb5_dbe_lookup_tl_data(kdc_context, &assoc, &tl_data)) || + if ((retval = krb5_dbe_lookup_tl_data(kdc_context, assoc, &tl_data)) || (tl_data.tl_data_length == 0)) { #endif /* KRBCONF_KDC_MODIFIES_KDB */ /* @@ -224,18 +225,13 @@ * Simply take the full encrypted response block, convert it * to ASCII numerals, and convert 0xa - 0xf to 0x0 - 0x05 */ - if ((rb1_track_data.next_challenge.data = malloc(8)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - - rb1_track_data.next_challenge.length = 8; for (i = 0; i < 8; i++) { - rb1_track_data.next_challenge.data[i] = - (outputblock[i] & 0x0f) | 0x30; - if (rb1_track_data.next_challenge.data[i] > 0x39) - rb1_track_data.next_challenge.data[i] -= 10; + next_challenge[i] = (outputblock[i] & 0x0f) | 0x30; + if (next_challenge[i] > 0x39) + next_challenge[i] -= 10; } + psr.msd.length = 8; + psr.msd.data = &next_challenge[0]; break; case RB1_MODE_H8_RC: @@ -247,11 +243,11 @@ #endif /* KRBCONF_KDC_MODIFIES_KDB */ /* Convert the SAD into a key. */ - rb1_track_data.magic = KV5M_PREDICTED_SAM_RESPONSE; - rb1_track_data.kdc_id = kdc_id; + psr.magic = KV5M_PREDICTED_SAM_RESPONSE; + psr.kdc_id = kdc_id; if (retval = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5, &predict_response, 0 /* salt */, - &rb1_track_data.sam_key)) { + &psr.sam_key)) { goto cleanup; } @@ -259,23 +255,31 @@ /* And XOR with the principal's long term key (in place). */ /* XXX There should be an abstraction for this ... */ { - krb5_octet *p = rb1_track_data.sam_key.contents; + krb5_octet *p = psr.sam_key.contents; krb5_octet *q = client_key.contents; - for (i = 0; i < rb1_track_data.sam_key.length; i++) + for (i = 0; i < psr.sam_key.length; i++) p[i] ^= q[i]; } - mit_des_fixup_key_parity(rb1_track_data.sam_key.contents); - if (mit_des_is_weak_key(rb1_track_data.sam_key.contents)) - ((krb5_octet *) rb1_track_data.sam_key.contents)[7] ^= 0xf0; + mit_des_fixup_key_parity(psr.sam_key.contents); + if (mit_des_is_weak_key(psr.sam_key.contents)) + ((krb5_octet *) psr.sam_key.contents)[7] ^= 0xf0; #endif /* !AS_REP_105_SAM_COMPAT */ /* * Now we have an encrypting key that the client will use for * the sam response, and that the KDC should use for the AP_REP. */ - if (retval = encode_krb5_rb1_track_data(&rb1_track_data, &scratch)) + if (retval = encode_krb5_predicted_sam_response(&psr, &scratch)) { + /* Don't free this, it's static (automatic). */ + psr.msd.data = NULL; + psr.msd.length = 0; goto cleanup; + } + + /* Don't free this, it's static (automatic). */ + psr.msd.data = NULL; + psr.msd.length = 0; if (retval = krb5_c_encrypt_length(context, master_keyblock.enctype, scratch->length, &enclen)) { @@ -313,8 +317,8 @@ if (retval = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5_DES, sc.sam_challenge.data, sc.sam_challenge.length, - /* key */ rb1_track_data.sam_key.contents, - /* key length */ rb1_track_data.sam_key.length, + /* key */ psr.sam_key.contents, + /* key length */ psr.sam_key.length, &sc.sam_cksum)) { goto cleanup; } @@ -337,14 +341,11 @@ krb5_free_data(context, scratch); cleanup: - if (rb1_track_data.sam_key.contents) - krb5_free_keyblock_contents(context, &rb1_track_data.sam_key); - if (rb1_track_data.next_challenge.data) - krb5_xfree(rb1_track_data.next_challenge.data); + krb5_free_predicted_sam_response_contents(context, &psr); /* Don't use the abstraction to free sc; most of it is static. */ - if (sc.sam_track_id.data); - krb5_free_data_contents(context, &sc.sam_track_id); + if (sc.sam_track_id.data) + krb5_xfree(sc.sam_track_id.data); if (sc.sam_cksum.contents) krb5_xfree(sc.sam_cksum.contents); @@ -356,25 +357,26 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_cryptocard(context, request, assoc, npr, mode, sr, enc_tkt_reply, - as_key) +sam_verify_cryptocard(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; krb5_enc_tkt_part * enc_tkt_reply; krb5_keyblock * as_key; { - krb5_error_code retval; - krb5_data scratch; - krb5_enc_data tmpdata; - krb5_tl_data tl_data; - - krb5_rb1_track_data * rb1_track_data = 0; - krb5_enc_sam_response_enc * esre = 0; - krb5_timestamp timenow; + krb5_error_code retval; + krb5_data scratch; + krb5_enc_data tmpdata; + krb5_tl_data tl_data; + + krb5_predicted_sam_response * psr = 0; + krb5_enc_sam_response_enc * esre = 0; + krb5_timestamp timenow; /* Sanity check */ if (sr->sam_type != PA_SAM_TYPE_CRYPTOCARD) { @@ -405,14 +407,14 @@ goto cleanup; } - retval = decode_krb5_rb1_track_data(&scratch, &rb1_track_data); + retval = decode_krb5_predicted_sam_response(&scratch, &psr); krb5_xfree(scratch.data); if (retval) { - com_err("krb5kdc", retval, "decode_krb5_rb1_track_data failed"); + com_err("krb5kdc", retval, "decode_krb5_predicted_sam_response failed"); goto cleanup; } - if (rb1_track_data->kdc_id != kdc_id) { + if (psr->kdc_id != kdc_id) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, "Warning - possible SAM replay attack!"); goto cleanup; @@ -429,8 +431,8 @@ goto cleanup; } - /* Now use rb1_track_data->sam_key to verify */ - if (retval = krb5_c_decrypt(context, &rb1_track_data->sam_key, + /* Now use psr->sam_key to verify */ + if (retval = krb5_c_decrypt(context, &psr->sam_key, /* XXX */ 0, 0, &sr->sam_enc_nonce_or_ts, &scratch)) { com_err("krb5kdc", retval, "decrypt nonce_or_ts failed"); @@ -459,25 +461,25 @@ } /* Success! Make sure we use the sam_key for the AS_REP. */ - krb5_copy_keyblock_contents(context, &rb1_track_data->sam_key, as_key); + krb5_copy_keyblock_contents(context, &psr->sam_key, as_key); #ifdef KRBCONF_KDC_MODIFIES_KDB /* Save the next challenge, if present. */ - if (rb1_track_data->next_challenge.length == 8) { + if (psr->msd.length == 8) { tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE; - tl_data.tl_data_length = rb1_track_data->next_challenge.length; - tl_data.tl_data_contents = rb1_track_data->next_challenge.data; + tl_data.tl_data_length = psr->msd.length; + tl_data.tl_data_contents = psr->msd.data; - if (retval = krb5_dbe_update_tl_data(kdc_context, &assoc, &tl_data)) + if (retval = krb5_dbe_update_tl_data(kdc_context, assoc, &tl_data)) com_err("krb5kdc", retval, "while updating RB-1 challenge tl_data"); - if (retval = krb5_db_put_principal(kdc_context, &assoc, &npr)) + if (retval = krb5_db_put_principal(kdc_context, assoc, &npr)) com_err("krb5kdc", retval, "while storing RB-1 challenge tl_data"); } #endif /* KRBCONF_KDC_MODIFIES_KDB */ cleanup: - if (rb1_track_data) - krb5_free_rb1_track_data(context, rb1_track_data); + if (psr) + krb5_free_predicted_sam_response(context, psr); if (esre) krb5_free_enc_sam_response_enc(context, esre); Index: kdc/preauth/pa_sam_digi_path.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_digi_path.c,v retrieving revision 1.5 diff -u -r1.5 pa_sam_digi_path.c --- pa_sam_digi_path.c 1998/11/25 23:34:40 1.5 +++ pa_sam_digi_path.c 1998/12/01 02:00:06 @@ -34,7 +34,7 @@ mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; @@ -245,7 +245,7 @@ krb5_free_predicted_sam_response_contents(context, &psr); /* Don't use the abstraction to free sc; most of it is static. */ - if (sc.sam_track_id.data); + if (sc.sam_track_id.data) krb5_xfree(sc.sam_track_id.data); if (sc.sam_cksum.contents) krb5_xfree(sc.sam_cksum.contents); @@ -258,11 +258,12 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_digi_path(context, request, assoc, npr, mode, sr, enc_tkt_reply, - as_key) +sam_verify_digi_path(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; Index: kdc/preauth/pa_sam_enigma.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_enigma.c,v retrieving revision 1.1 diff -u -r1.1 pa_sam_enigma.c --- pa_sam_enigma.c 1998/11/25 04:06:18 1.1 +++ pa_sam_enigma.c 1998/12/01 02:00:06 @@ -33,7 +33,7 @@ mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; @@ -45,10 +45,12 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_enigma(context, request, assoc, npr, mode, sr, enc_tkt_reply, as_key) +sam_verify_enigma(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; Index: kdc/preauth/pa_sam_grail.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_grail.c,v retrieving revision 1.3 diff -u -r1.3 pa_sam_grail.c --- pa_sam_grail.c 1998/11/25 23:34:40 1.3 +++ pa_sam_grail.c 1998/12/01 02:00:06 @@ -34,7 +34,7 @@ mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; @@ -144,7 +144,7 @@ krb5_free_predicted_sam_response_contents(context, &psr); /* Don't use the abstraction to free sc; most of it is static. */ - if (sc.sam_track_id.data); + if (sc.sam_track_id.data) krb5_xfree(sc.sam_track_id.data); if (sc.sam_cksum.contents) krb5_xfree(sc.sam_cksum.contents); @@ -160,10 +160,12 @@ * data is stored in the predicted_sam_response. */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_grail(context, request, assoc, npr, mode, sr, enc_tkt_reply, as_key) +sam_verify_grail(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; Index: kdc/preauth/pa_sam_securid.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_securid.c,v retrieving revision 1.4 diff -u -r1.4 pa_sam_securid.c --- pa_sam_securid.c 1998/11/25 23:34:40 1.4 +++ pa_sam_securid.c 1998/12/01 02:00:06 @@ -29,17 +29,12 @@ #include "pa_sam.h" -/* XXX This code does not work yet. */ +/* XXX This code is untested, but should work. This module depends on + the KDC being single threaded (due to global state). */ /* - * XXX This code depends on the client contacting the same KDC with - * a response containing pa_data as it initially contacted when it got - * the KRB_ERROR message. This means this specifically will not work - * with any kind of DNS load balancing/round-robin/etc. + * SecurID functionality stolen from securid.c: * - * SecurID functionality stolen from securid.c: (modified to "eliminate" - * global state problems) - * * Author: Kenneth D. Renard * Army Research Lab * Date: 9 Oct 96 @@ -47,134 +42,123 @@ */ -#if defined(SECURID) && defined(KRBCONF_KDC_MODIFIES_KDB) +#if defined(SECURID) #include #include #include #include -/* - * XXX struct SD_CLIENT must not contain any pointers. - * Also, kind of poor that we only support IP addresses. - */ -typedef struct _krb5_securid_state { +typedef struct _securid_track_data { krb5_int32 state; /* states */ - krb5_timestamp tl_time; /* to avoid stale data */ - char newpin[LENPRNST + 1]; /* for PIN verification */ + char passcode[LENPRNST + 1]; /* for PRN/PIN verification */ struct SD_CLIENT sd_info; /* SecurID state info */ - krb5_int32 kdc_id; /* Keep sd_info local */ -} krb5_securid_state; +} securid_track_data; union config_record configure; int need_to_creadcfg = 1; int need_to_sd_init = 1; + +static krb5_sam_challenge g_sc = { 0, }; +static securid_track_data g_sid_track_data = { SECURID_STATE_NONE, }; -#endif /* SECURID && KRBCONF_KDC_MODIFIES_KDB */ +#endif /* SECURID */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV sam_generate_securid(context, request, assoc, npr, sam_key, client_key, mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; int mode; krb5_pa_data * pa_data; { -#if defined(SECURID) && defined(KRBCONF_KDC_MODIFIES_KDB) +#if defined(SECURID) krb5_error_code retval; - krb5_sam_challenge sc; krb5_predicted_sam_response psr; krb5_data * scratch; krb5_enc_data tmpdata; size_t enclen; - krb5_tl_data tl_data; - krb5_securid_state securid_state; - krb5_timestamp timenow; - int update_tl_data = 0; - memset(&sc, 0, sizeof(sc)); memset(&psr, 0, sizeof(psr)); - sc.magic = KV5M_SAM_CHALLENGE; - sc.sam_type = PA_SAM_TYPE_SECURID; - sc.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; - sc.sam_type_name.data = "SecurID Authentication"; - sc.sam_type_name.length = strlen(sc.sam_type_name.data); - - /* Generate prompt based on current state. */ - tl_data.tl_data_type = KRB5_TL_SECURID_STATE; - if ((retval = krb5_dbe_lookup_tl_data(kdc_context, &assoc, &tl_data)) || - (tl_data.tl_data_length == 0)) { - if (tl_data.tl_data_length != sizeof(securid_state)) { - com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "corrupted tl_data!"); - return retval; - } - memcpy(securid_state, tl_data.tl_data_contents, sizeof(securid_state)); + /* + * g_sc and g_sid_track_data are reset when we exit this routine. + * If they have non-initial values, it is b/c it was just setup + * in the verify routine. + */ + if (g_sc.magic == 0) { + g_sc.magic = KV5M_SAM_CHALLENGE; + g_sc.sam_type = PA_SAM_TYPE_SECURID; + g_sc.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + g_sc.sam_type_name.data = "SecurID Authentication"; + g_sc.sam_type_name.length = strlen(sc.sam_type_name.data); + } + + switch (g_sid_track_data.state) { + case SECURID_STATE_NONE: + g_sid_track_data.state = SECURID_STATE_INITIAL; + g_sc.magic = KV5M_SAM_CHALLENGE; + g_sc.sam_type = PA_SAM_TYPE_SECURID; + g_sc.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + g_sc.sam_type_name.data = "SecurID Authentication"; + g_sc.sam_type_name.length = strlen(sc.sam_type_name.data); + g_sc.sam_challenge.data = NULL; + g_sc.sam_challenge.length = 0; - /* - * Verify that the tl_data is not stale (from a user abort or - * *shudder* possibly a crash). We have to use at least a one - * minute window; a next PRN could take at least that long. - */ - if (retval = krb5_timeofday(context, &timenow)) - return retval; - - if ((timenow - securid_state.tl_time) > 90) { - memset(&securid_state, 0, sizeof(securid_state)); - securid_state.state = SECURID_STATE_INITIAL; - } - - switch (securid_state.state) { - case SECURID_STATE_INITIAL: - sc.sam_reponse_prompt.data = "SecurID Passcode"; - break; + case SECURID_STATE_INITIAL: + g_sc.sam_challenge_label.data = NULL; + g_sc.sam_challenge_label.length = 0; + g_sc.sam_response_prompt.data = "SecurID Passcode"; + break; - case SECURID_STATE_NEXT_CODE: - sc.sam_response_prompt.data = "Enter next Passcode"; - break; + case SECURID_STATE_NEXT_CODE: + g_sc.sam_challenge_label.data = NULL; + g_sc.sam_challenge_label.length = 0; + g_sc.sam_response_prompt.data = "Enter next Passcode"; + break; - case SECURID_STATE_NEW_PIN: - sc.sam_challenge_label.data = "Select a new PIN"; - sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); - sc.sam_response_prompt.data = "Enter new PIN"; - break; + case SECURID_STATE_NEW_PIN: + g_sc.sam_challenge_label.data = "Select a new PIN"; + g_sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); + g_sc.sam_response_prompt.data = "Enter new PIN"; + break; - case SECURID_STATE_NEW_PIN_AGAIN: - sc.sam_response_prompt.data = "Verify the new PIN"; - break; + case SECURID_STATE_NEW_PIN_AGAIN: + g_sc.sam_challenge_label.data = "Verify the new PIN"; + g_sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); + g_sc.sam_response_prompt.data = "Enter the new PIN again"; + break; - default: - com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "bad state in securid track_data"); - return retval; - } /* switch (securid_state) */ - } else { - /* tl_data not found, this is a new user. */ - sc.sam_reponse_prompt.data = "SecurID Passcode"; - } - sc.sam_response_prompt.length = strlen(sc.sam_challenge_label.data); + default: + com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, + "bad state in g_sid_track_data"); + return retval; + } /* switch (g_sid_track_data.state) */ + g_sc.sam_response_prompt.length = strlen(g_sc.sam_response_prompt.data); - /* - * XXX Note that for states that require multiple transactions, - * the KRB_ERROR will always come from the same KDC that the - * first AS_REQ goes to; this is b/c this code runs right after - * the verify code in those states. Thus, we only have to check - * the kdc_id in the verify code. - */ psr.magic = KV5M_PREDICTED_SAM_RESPONSE; psr.kdc_id = kdc_id; - /* Encrypt with longterm key (send-encrypted-sad). */ + psr.msd.data = &g_sid_track_data; + psr.msd.length = sizeof(g_sid_track_data); + /* esre will be encrypted w/ client longterm key (send-encrypted-sad) */ krb5_copy_keyblock_contents(context, &client_key, &psr.sam_key); - if (retval = encode_krb5_predicted_sam_response(&psr, &scratch)) + if (retval = encode_krb5_predicted_sam_response(&psr, &scratch)) { + /* Don't free this, it's static. */ + psr.msd.data = NULL; + psr.msd.length = 0; goto cleanup; + } + /* Don't free this, it's static. */ + psr.msd.data = NULL; + psr.msd.length = 0; + if (retval = krb5_c_encrypt_length(context, master_keyblock.enctype, scratch->length, &enclen)) { krb5_free_data(context, scratch); @@ -187,7 +171,7 @@ goto cleanup; } tmpdata.ciphertext.length = enclen; - sc.sam_track_id = tmpdata.ciphertext; /* So we know to free it. */ + g_sc.sam_track_id = tmpdata.ciphertext; /* So we know to free it. */ retval = krb5_c_encrypt(context, &master_keyblock, /* XXX */ 0, 0, scratch, &tmpdata); @@ -195,27 +179,30 @@ if (retval) goto cleanup; - sc.sam_pk_for_sad.length = 0; - sc.sam_nonce = 0; + g_sc.sam_pk_for_sad.length = 0; + g_sc.sam_nonce = 0; #if 0 - /* We don't calculate a checksum since it could be used to crack the SAD */ - sc.sam_cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5_DES); - if ((sc.sam_cksum.contents = malloc(sc.sam_cksum.length)) == NULL) { + /* We don't calculate a checksum since it makes the password crackable */ + g_sc.sam_cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5_DES); + if ((g_sc.sam_cksum.contents = malloc(g_sc.sam_cksum.length)) == NULL) { return ENOMEM; } if (retval = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5_DES, - sc.sam_challenge.data, - sc.sam_challenge.length, + g_sc.sam_challenge.data, + g_sc.sam_challenge.length, client_key.contents, /* key */ client_key.length, /* key length */ - &sc.sam_cksum)) { + &g_sc.sam_cksum)) { goto cleanup; } +#else /* 0 */ + g_sc.sam_cksum.contents = NULL; + g_sc.sam_cksum.length = 0; #endif /* 0 */ - if (retval = encode_krb5_sam_challenge(&sc, &scratch)) + if (retval = encode_krb5_sam_challenge(&g_sc, &scratch)) goto cleanup; pa_data->magic = KV5M_PA_DATA; @@ -235,112 +222,83 @@ krb5_free_predicted_sam_response_contents(context, &psr); /* Don't use the abstraction to free sc; most of it is static. */ - if (sc.sam_track_id.data); - krb5_xfree(sc.sam_track_id.data); - if (sc.sam_cksum.contents) - krb5_xfree(sc.sam_cksum.contents); + if (g_sc.sam_track_id.data) + krb5_xfree(g_sc.sam_track_id.data); + if (g_sc.sam_cksum.contents) + krb5_xfree(g_sc.sam_cksum.contents); + + /* Reset global information for next customer. */ + g_sc.sam_magic = 0; + g_sid_track_data.state = SECURID_STATE_INITIAL; return retval; -#else /* SECURID && KRBCONF_KDC_MODIFIES_KDB */ +#else /* SECURID */ return KRB5KDC_ERR_PREAUTH_FAILED; -#endif /* SECURID && KRBCONF_KDC_MODIFIES_KDB */ +#endif /* SECURID */ } /* * The new PIN/next PRN functions force passing in the enc_tkt_reply. - * Because of this, we also have to keep per-user state somewhere, - * the obvious place is the tl_data. This generates it's own problems. */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_securid(context, request, assoc, npr, mode, sr, enc_tkt_reply, - as_key) +sam_verify_securid(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; krb5_enc_tkt_part * enc_tkt_reply; krb5_keyblock * as_key; { -#if defined(SECURID) && defined(KRBCONF_KDC_MODIFIES_KDB) - krb5_error_code retval, retval2; +#if defined(SECURID) + krb5_error_code retval; krb5_data scratch; krb5_enc_data tmpdata; - krb5_tl_data tl_data; - krb5_securid_state securid_state; - krb5_int32 old_state; + krb5_keyblock client_key; krb5_predicted_sam_response * psr = 0; krb5_enc_sam_response_enc * esre = 0; krb5_timestamp timenow; - struct SD_CLIENT sd_dat, *sd; - char passcode[LENPRNST + 1]; char * user = 0, cp; - memset(&securid_state, 0, sizeof(securid_state)); - securid_state.state = old_state = SECURID_STATE_INITIAL; + memset(&client_key, 0, sizeof(client_key)); + memset(&g_sid_track_data.sd_info, 0, sizeof(g_sid_track_data.sd_info)); /* Sanity check */ - if (sr->sam_type != PA_SAM_TYPE_SECURID) { + if (sr->sam_track_id.length && (sr->sam_type != PA_SAM_TYPE_SECURID)) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, "inconsistent sam_type (SecurID expected)"); goto cleanup; } - scratch.length = sr->sam_track_id.length; + scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length; if (!scratch.length) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "securid track_id data not found"); + "SecurID sam_enc_nonce_or_ts not found"); goto cleanup; } if ((scratch.data = malloc(scratch.length)) == NULL) { retval = ENOMEM; goto cleanup; } - - tmpdata.enctype = ENCTYPE_UNKNOWN; - tmpdata.ciphertext = sr->sam_track_id; - if (retval = krb5_c_decrypt(context, &master_keyblock, /* XXX */ 0, 0, - &tmpdata, &scratch)) { - /* Record our retval, but let the client see a generic error. */ - com_err("krb5kdc", retval, "decrypt track_id failed"); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_xfree(scratch.data); - goto cleanup; - } - retval = decode_krb5_predicted_sam_response(&scratch, &psr); - krb5_xfree(scratch.data); - if (retval) { - com_err("krb5kdc", retval, "decode_krb5_predicted_sam_response failed"); - goto cleanup; - } - - if (psr->kdc_id != kdc_id) { - com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "Warning - possible SAM replay attack!"); - /* Reset state so user can try again quickly. */ - old_state = SECURID_STATE_NONE; - goto update_tl_data; - } - - scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length; - if (!scratch.length) { - com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "SecurID sam_enc_nonce_or_ts not found"); + /* Get the client_key ourself; we may not have a psr. */ + if (retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, + client->key_data, &client_key, + NULL)) { + com_err("krb5kdc", retval, "SecurID: cannot get client key"); goto cleanup; } - if ((scratch.data = malloc(scratch.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - /* Now use psr->sam_key to verify */ - if (retval = krb5_c_decrypt(context, &psr->sam_key, /* XXX */ 0, 0, + /* Now use client_key to verify the timestamp. */ + client_key.enctype = sr->sam_enc_nonce_or_ts.enctype; + if (retval = krb5_c_decrypt(context, &client_key, /* XXX */ 0, 0, &sr->sam_enc_nonce_or_ts, &scratch)) { com_err("krb5kdc", retval, "decrypt nonce_or_ts failed"); retval = KRB5KDC_ERR_PREAUTH_FAILED; @@ -367,14 +325,17 @@ goto cleanup; } - /* Success! Unlike most SAM types, we don't set the as_key. */ - /* Now verify the Passcode. */ + if (!esre->sam_sad.length) { + com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, + "SecurID: client did not supply SAD data"); + goto cleanup; + } + if (need_to_creadcfg) { creadcfg(); need_to_creadcfg = 0; } - memset(&sd_dat, 0, sizeof(sd_dat)); if (retval = krb5_unparse_name(context, request->client->princ, &user)) { com_err("krb5kdc", retval, "Cannot unparse name for SecurID check"); @@ -383,41 +344,63 @@ if (cp = strchr(user, '@')) *cp = '\0'; - /* What did the user return to us? */ - tl_data.tl_data_type = KRB5_TL_SECURID_STATE; - if ((retval = krb5_dbe_lookup_tl_data(kdc_context, &assoc, &tl_data)) || - (tl_data.tl_data_length == 0)) { - if (tl_data.tl_data_length != sizeof(securid_state)) { + scratch.length = sr->sam_track_id.length; + if (!scratch.length) { + /* Client knew he had to use time/event-based SAM. */ + g_sid_track_data.state = SECURID_STATE_INITIAL; + } else { + if ((scratch.data = malloc(scratch.length)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + + tmpdata.enctype = ENCTYPE_UNKNOWN; + tmpdata.ciphertext = sr->sam_track_id; + if (retval = krb5_c_decrypt(context, &master_keyblock, /* XXX */ 0, 0, + &tmpdata, &scratch)) { + /* Record our retval, but let the client see a generic error. */ + com_err("krb5kdc", retval, "decrypt track_id failed"); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_xfree(scratch.data); + goto cleanup; + } + + retval = decode_krb5_predicted_sam_response(&scratch, &psr); + krb5_xfree(scratch.data); + if (retval) { + com_err("krb5kdc", retval, + "decode_krb5_predicted_sam_response failed"); + goto cleanup; + } + + if (psr->kdc_id != kdc_id) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "corrupted tl_data!"); + "Warning - possible SAM replay attack!"); goto cleanup; } - memcpy(securid_state, tl_data.tl_data_contents, sizeof(securid_state)); - old_state = securid_state.state; - /* - * Verify that the tl_data is not stale (see comment in generate). - * XXX By setting old_state we might introduce a condition where - * user cannot login (if there is a problem with updating the db). - */ - if ((timenow - securid_state.tl_time) > 90) { - memset(&securid_state, 0, sizeof(securid_state)); - securid_state.state = old_state = SECURID_STATE_INITIAL; + /* Sanity check */ + if (psr->msd.length != sizeof(g_sid_track_data)) { + com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, + "psr->msd (sid_track_data) is garbage"); + goto cleanup; } + memcpy(&g_sid_track_data, psr->msd.data, psr->msd.length); } - switch (securid_state.state) { + switch (g_sid_track_data.state) { case SECURID_STATE_INITIAL: if (esre->sam_sad.length > LENPRNST) { - /* User entered too much data, keep same state. */ + /* User entered too much data. */ retval = KRB5KDC_ERR_PREAUTH_FAILED; goto cleanup; } - memcpy(&passcode, esre->sam_sad.data, esre->sam_sad.length); - passcode[esre->sam_sad.length] = '\0'; + memcpy(&g_sid_track_data.passcode, esre->sam_sad.data, + esre->sam_sad.length); + g_sid_track_data.passcode[esre->sam_sad.length] = '\0'; if (need_to_sd_init) { - if (sd_init(&sd_dat)) { + if (sd_init(&g_sid_track_data.sd_info)) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, "Cannot initialize SecurID communications"); goto cleanup; @@ -425,7 +408,8 @@ need_to_sd_init = 0; } - retval = sd_check(passcode, user, &sd_dat); + retval = sd_check(g_sid_track_data.passcode, user, + &g_sid_track_data.sd_info); switch (retval) { case ACM_OK: setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH); @@ -447,8 +431,7 @@ * a failure. */ retval = 0; - securid_state.state = SECURID_STATE_NEXT_CODE; - securid_state.sd_info = sd_dat; + g_sid_track_data.state = SECURID_STATE_NEXT_CODE; break; case ACM_NEW_PIN_REQUIRED: @@ -461,14 +444,13 @@ * also, the prompt will be wrong.) Also, the PIN will * be visible when typed. :( */ - if (sd_dat.user_selectable == CANNOT_CHOOSE_PIN) { + if (g_sid_track_data.sd_info.user_selectable == CANNOT_CHOOSE_PIN) { com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, "SecurID new PIN needed but not user-selectable"); goto cleanup; } retval = 0; - securid_state.state = SECURID_STATE_NEW_PIN; - securid_state.sd_info = sd_dat; + g_sid_track_data.state = SECURID_STATE_NEW_PIN; break; default: @@ -483,8 +465,7 @@ break; case SECURID_STATE_NEXT_CODE: - sd = &securid_state.sd_info; - retval = sd_next(passcode, sd); + retval = sd_next(g_sid_track_data.passcode, &g_sid_track_data.sd_info); if (retval == ACM_OK) { setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH); setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH); @@ -492,26 +473,35 @@ } else { retval = KRB5KDC_ERR_PREAUTH_FAILED; } - securid_state.state = SECURID_STATE_INITIAL; break; case SECURID_STATE_NEW_PIN: - /* - * Store the user supplied PIN for verification. - * Boundary checking has already been done. - */ + /* Save the PIN and ask for it again. */ + if (esre->sam_sad.length > LENPRNST) { + /* User entered too much data. */ + retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + memcpy(&g_sid_track_data.passcode, esre->sam_sad.data, + esre->sam_sad.length); + g_sid_track_data.passcode[esre->sam_sad.length] = '\0'; + g_sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN; retval = 0; - strcpy(securid_state.newpin, passcode); - securid_state.state = SECURID_STATE_NEW_PIN_AGAIN; break; case SECURID_STATE_NEW_PIN_AGAIN: - sd = &securid_state.sd_info; /* Verify 2nd entry with the previous. */ - if (strncmp(passcode, securid_state.newpin, LENPRNST) != 0) { + if (esre->sam_sad.length > LENPRNST) { + /* User entered too much data. */ retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + if (strncmp(g_sid_track_data.passcode, esre->sam_sad.data, + LENPRNST) != 0) { + retval = KRB5KDC_ERR_PREAUTH_FAILED; } else { - retval = sd_pin(passcode, '\0', sd); + retval = sd_pin(g_sid_track_data.passcode, '\0', + &g_sid_track_data.sd_info); if (retval == ACM_NEW_PIN_ACCEPTED) { retval = 0; } else { @@ -523,52 +513,30 @@ default: com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED, - "bad state in securid tl_data"); - securid_state.state = SECURID_STATE_INITIAL; + "bad state in returned sid_track_data"); break; } /* switch (securid_state.state) */ -update_tl_data: - /* - * Update state information if it has changed. - * Unlike CRYPTOCard, we might need to fail if we can't update. - * XXX This might be bad when the databases sync properly. - */ - if (old_state != securid_state.state) { - if (retval2 = krb5_timeofday(context, &securid_state.tl_time)) { - com_err("krb5kdc", retval2, "updating tl_time"); - if (securid_state.state != SECURID_STATE_INITIAL) - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - } - tl_data.tl_data_length = sizeof(securid_state); - tl_data.tl_data_contents = &securid_state; - - if (retval2 = krb5_dbe_update_tl_data(kdc_context, &assoc, &tl_data)) { - com_err("krb5kdc", retval2, "while updating SecurID tl_data"); - if (securid_state.state != SECURID_STATE_INITIAL) - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - if (retval2 = krb5_db_put_principal(kdc_context, &assoc, &npr)) { - com_err("krb5kdc", retval2, "while storing SecurID tl_data"); - if (securid_state.state != SECURID_STATE_INITIAL) - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - } - } - cleanup: if (psr) krb5_free_predicted_sam_response(context, psr); if (esre) krb5_free_enc_sam_response_enc(context, esre); + if (client_key.contents) + krb5_free_keyblock_contents(context, &client_key); if (user) krb5_xfree(user); + if (retval || isflagset(enc_tkt_reply->flags, TKT_FLG_HW_AUTH)) { + /* Don't leave bogus state around. */ + g_sc.sam_magic = 0; + g_sid_track_data.state = SECURID_STATE_NONE; + } + return retval; -#else /* SECURID && KRBCONF_KDC_MODIFIES_KDB */ +#else /* SECURID */ return KRB5KDC_ERR_PREAUTH_FAILED; -#endif /* SECURID && KRBCONF_KDC_MODIFIES_KDB */ +#endif /* SECURID */ } Index: kdc/preauth/pa_sam_skey.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/kdc/preauth/pa_sam_skey.c,v retrieving revision 1.1 diff -u -r1.1 pa_sam_skey.c --- pa_sam_skey.c 1998/11/25 04:06:18 1.1 +++ pa_sam_skey.c 1998/12/01 02:00:06 @@ -39,7 +39,7 @@ mode, pa_data) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * assoc; int npr; krb5_keyblock sam_key; krb5_keyblock client_key; @@ -54,10 +54,12 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -sam_verify_skey(context, request, assoc, npr, mode, sr, enc_tkt_reply, as_key) +sam_verify_skey(context, request, client, assoc, npr, mode, sr, + enc_tkt_reply, as_key) krb5_context context; krb5_kdc_req * request; - krb5_db_entry assoc; + krb5_db_entry * client; + krb5_db_entry * assoc; int npr; int mode; krb5_sam_response * sr; Index: lib/krb5/asn.1/asn1_k_decode.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/asn1_k_decode.c,v retrieving revision 1.5 diff -u -r1.5 asn1_k_decode.c --- asn1_k_decode.c 1998/11/25 22:35:55 1.5 +++ asn1_k_decode.c 1998/12/01 02:00:06 @@ -814,23 +814,9 @@ { begin_structure(); get_field(val->sam_key,0,asn1_decode_encryption_key); get_field(val->kdc_id,1,asn1_decode_int32); + opt_string(val->msd,2,asn1_decode_generalstring); end_structure(); val->magic = KV5M_PREDICTED_SAM_RESPONSE; - } - cleanup(); -} - -asn1_error_code asn1_decode_rb1_track_data(buf, val) - asn1buf * buf; - krb5_rb1_track_data * val; -{ - setup(); - { begin_structure(); - opt_string(val->next_challenge, 0, asn1_decode_charstring); - get_field(val->sam_key, 1, asn1_decode_encryption_key); - get_field(val->kdc_id,2,asn1_decode_int32); - end_structure(); - val->magic = KV5M_RB1_TRACK_DATA; } cleanup(); } Index: lib/krb5/asn.1/asn1_k_decode.h =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/asn1_k_decode.h,v retrieving revision 1.2 diff -u -r1.2 asn1_k_decode.h --- asn1_k_decode.h 1998/11/25 06:50:49 1.2 +++ asn1_k_decode.h 1998/12/01 02:00:06 @@ -148,8 +148,6 @@ PROTOTYPE((asn1buf *buf, krb5_sam_response *val)); asn1_error_code asn1_decode_predicted_sam_response PROTOTYPE((asn1buf *buf, krb5_predicted_sam_response *val)); -asn1_error_code asn1_decode_rb1_track_data - PROTOTYPE((asn1buf *buf, krb5_rb1_track_data *val)); /* arrays */ asn1_error_code asn1_decode_authorization_data Index: lib/krb5/asn.1/asn1_k_encode.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/asn1_k_encode.c,v retrieving revision 1.5 diff -u -r1.5 asn1_k_encode.c --- asn1_k_encode.c 1998/11/25 22:35:56 1.5 +++ asn1_k_encode.c 1998/12/01 02:00:07 @@ -949,24 +949,12 @@ { asn1_setup(); + add_optstring(val->msd,2,asn1_encode_generalstring); asn1_addfield(val->kdc_id,1,asn1_encode_integer); asn1_addfield(&(val->sam_key),0,asn1_encode_encryption_key); asn1_makeseq(); asn1_cleanup(); -} - -asn1_error_code asn1_encode_rb1_track_data(buf, val, retlen) - asn1buf * buf; - const krb5_rb1_track_data *val; - int *retlen; -{ - asn1_setup(); - asn1_addfield(val->kdc_id,2,asn1_encode_integer); - asn1_addfield(&(val->sam_key), 1, asn1_encode_encryption_key); - add_optstring(val->next_challenge, 0, asn1_encode_charstring); - asn1_makeseq(); - asn1_cleanup(); } Index: lib/krb5/asn.1/asn1_k_encode.h =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/asn1_k_encode.h,v retrieving revision 1.2 diff -u -r1.2 asn1_k_encode.h --- asn1_k_encode.h 1998/11/25 06:50:49 1.2 +++ asn1_k_encode.h 1998/12/01 02:00:07 @@ -245,8 +245,4 @@ PROTOTYPE((asn1buf *buf, const krb5_predicted_sam_response *val, int *retlen)); -asn1_error_code asn1_encode_rb1_track_data - PROTOTYPE((asn1buf *buf, const krb5_rb1_track_data *val, - int *retlen)); - #endif Index: lib/krb5/asn.1/krb5_decode.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/krb5_decode.c,v retrieving revision 1.2 diff -u -r1.2 krb5_decode.c --- krb5_decode.c 1998/11/25 06:50:49 1.2 +++ krb5_decode.c 1998/12/01 02:00:07 @@ -836,17 +836,3 @@ cleanup(free); } - -krb5_error_code decode_krb5_rb1_track_data(code, rep) - const krb5_data * code; - krb5_rb1_track_data **rep; -{ - setup_buf_only(); /* preallocated */ - alloc_field(*rep,krb5_rb1_track_data); - - retval = asn1_decode_rb1_track_data(&buf,*rep); - if(retval) clean_return(retval); - - cleanup(free); -} - Index: lib/krb5/asn.1/krb5_encode.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/asn.1/krb5_encode.c,v retrieving revision 1.2 diff -u -r1.2 krb5_encode.c --- krb5_encode.c 1998/11/25 06:50:49 1.2 +++ krb5_encode.c 1998/12/01 02:00:07 @@ -847,14 +847,3 @@ sum += length; krb5_cleanup(); } - -krb5_error_code encode_krb5_rb1_track_data(rep, code) - const krb5_rb1_track_data * rep; - krb5_data ** code; -{ - krb5_setup(); - retval = asn1_encode_rb1_track_data(buf,rep,&length); - if(retval) return retval; - sum += length; - krb5_cleanup(); -} Index: lib/krb5/krb/kfree.c =================================================================== RCS file: /icon/d04/cvsroot/3rd-party/krb5-19981119/lib/krb5/krb/kfree.c,v retrieving revision 1.3 diff -u -r1.3 kfree.c --- kfree.c 1998/11/25 23:47:44 1.3 +++ kfree.c 1998/12/01 02:00:07 @@ -651,8 +651,10 @@ { if (!psr) return; - if (psr->sam_key.contents); + if (psr->sam_key.contents) krb5_free_keyblock_contents(ctx, &psr->sam_key); + if (psr->msd.data) + krb5_free_data_contents(ctx, &psr->msd); } KRB5_DLLIMP void KRB5_CALLCONV @@ -673,28 +675,6 @@ return; if (esre->sam_sad.data) krb5_free_data_contents(ctx, &esre->sam_sad); -} - -KRB5_DLLIMP void KRB5_CALLCONV -krb5_free_rb1_track_data(krb5_context ctx, krb5_rb1_track_data FAR *rb1td) -{ - if (!rb1td) - return - krb5_free_rb1_track_data_contents(ctx, rb1td); - krb5_xfree(rb1td); -} - - -KRB5_DLLIMP void KRB5_CALLCONV -krb5_free_rb1_track_data_contents(krb5_context ctx, - krb5_rb1_track_data FAR *rb1td) -{ - if (!rb1td) - return; - if (rb1td->sam_key.contents) - krb5_free_keyblock_contents(ctx, &rb1td->sam_key); - if (rb1td->next_challenge.data) - krb5_free_data_contents(ctx, &rb1td->next_challenge); } >Audit-Trail: >Unformatted: