[3010] in Kerberos-V5-bugs
krb5-kdc/668: SAM preauth fixes
daemon@ATHENA.MIT.EDU (fcusack@iconnet.net)
Mon Nov 30 21:06:15 1998
Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: krb5-unassigned@RT-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, fcusack@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
>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 <sdi_athd.h>
#include <sdi_defs.h>
#include <sdconf.h>
#include <sdacmvls.h>
-/*
- * 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: