From 97023f5f10fb091225ad131a0b35f1d91cd12b1e Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Fri, 1 Oct 2010 17:12:26 +0000 Subject: Remove support for the old pa-sam-challenge and pa-sam-response preauth type per discussion on krbdev. The pa-sam-challenge-2 code remains in the client. preauth: remove pa-sam-challenge git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24403 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/kdc_preauth.c | 725 -------------------------------------------------- 1 file changed, 725 deletions(-) (limited to 'src/kdc/kdc_preauth.c') diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 503c2313b8..0c477266b3 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -202,35 +202,6 @@ return_pw_salt(krb5_context, krb5_pa_data * padata, void *pa_system_context, void **pa_request_context); -/* SAM preauth support */ -static krb5_error_code -verify_sam_response(krb5_context, krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, - krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data, - preauth_get_entry_data_proc get_entry_data, - void *pa_module_context, - void **pa_request_context, - krb5_data **e_data, - krb5_authdata ***authz_data); - -static krb5_error_code -get_sam_edata(krb5_context, krb5_kdc_req *request, - krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc get_entry_data, - void *pa_module_context, - krb5_pa_data *data); -static krb5_error_code -return_sam_data(krb5_context, krb5_pa_data * padata, - krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_kdc_rep *reply, - krb5_key_data *client_key, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc get_entry_data, - void *pa_module_context, - void **pa_request_context); #if APPLE_PKINIT /* PKINIT preauth support */ @@ -339,28 +310,6 @@ static krb5_preauth_systems static_preauth_systems[] = { 0, return_pw_salt }, - { - "sam-response", - KRB5_PADATA_SAM_RESPONSE, - 0, - NULL, - NULL, - NULL, - 0, - verify_sam_response, - return_sam_data - }, - { - "sam-challenge", - KRB5_PADATA_SAM_CHALLENGE, - PA_HARDWARE, /* causes get_preauth_hint_list to use this */ - NULL, - NULL, - NULL, - get_sam_edata, - 0, - 0 - }, { "pac-request", KRB5_PADATA_PAC_REQUEST, @@ -1868,681 +1817,7 @@ cleanup: return retval; } -static krb5_error_code -return_sam_data(krb5_context context, krb5_pa_data *in_padata, - krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request, - krb5_kdc_rep *reply, krb5_key_data *client_key, - krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc sam_get_entry_data, - void *pa_system_context, - void **pa_request_context) -{ - krb5_error_code retval; - krb5_data scratch; - int i; - - krb5_sam_response *sr = 0; - krb5_predicted_sam_response *psr = 0; - - if (in_padata->contents == 0) - return 0; - - /* - * We start by doing the same thing verify_sam_response() does: - * extract the psr from the padata (which is an sr). Nothing - * here should generate errors! We've already successfully done - * all this once. - */ - - scratch.data = (char *)in_padata->contents; - scratch.length = in_padata->length; - - if ((retval = decode_krb5_sam_response(&scratch, &sr))) { - kdc_err(context, retval, - "return_sam_data(): decode_krb5_sam_response failed"); - goto cleanup; - } - - { - krb5_enc_data tmpdata; - - tmpdata.enctype = ENCTYPE_UNKNOWN; - tmpdata.ciphertext = sr->sam_track_id; - - scratch.length = tmpdata.ciphertext.length; - if ((scratch.data = (char *) malloc(scratch.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - - if ((retval = krb5_c_decrypt(context, &psr_key, /* XXX */ 0, 0, - &tmpdata, &scratch))) { - kdc_err(context, retval, - "return_sam_data(): decrypt track_id failed"); - free(scratch.data); - goto cleanup; - } - } - - if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) { - kdc_err(context, retval, - "return_sam_data(): decode_krb5_predicted_sam_response failed"); - free(scratch.data); - goto cleanup; - } - - /* We could use sr->sam_flags, but it may be absent or altered. */ - if (psr->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) { - kdc_err(context, retval = KRB5KDC_ERR_PREAUTH_FAILED, - "Unsupported SAM flag must-pk-encrypt-sad"); - goto cleanup; - } - if (psr->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) { - /* No key munging */ - goto cleanup; - } - if (psr->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) { - /* Use sam_key instead of client key */ - krb5_free_keyblock_contents(context, encrypting_key); - krb5_copy_keyblock_contents(context, &psr->sam_key, encrypting_key); - /* XXX Attach a useful pa_data */ - goto cleanup; - } - - /* Otherwise (no flags set), we XOR the keys */ - /* XXX The passwords-04 draft is underspecified here wrt different - key types. We will do what I hope to get into the -05 draft. */ - { - krb5_octet *p = encrypting_key->contents; - krb5_octet *q = psr->sam_key.contents; - int length = ((encrypting_key->length < psr->sam_key.length) - ? encrypting_key->length - : psr->sam_key.length); - - for (i = 0; i < length; i++) - p[i] ^= q[i]; - } - - /* Post-mixing key correction */ - switch (encrypting_key->enctype) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - mit_des_fixup_key_parity(encrypting_key->contents); - if (mit_des_is_weak_key(encrypting_key->contents)) - ((krb5_octet *) encrypting_key->contents)[7] ^= 0xf0; - break; - - /* XXX case ENCTYPE_DES3_CBC_MD5: listed in 1510bis-04 draft */ - case ENCTYPE_DES3_CBC_SHA: /* XXX deprecated? */ - case ENCTYPE_DES3_CBC_RAW: - case ENCTYPE_DES3_CBC_SHA1: - for (i = 0; i < 3; i++) { - mit_des_fixup_key_parity(encrypting_key->contents + i * 8); - if (mit_des_is_weak_key(encrypting_key->contents + i * 8)) - ((krb5_octet *) encrypting_key->contents)[7 + i * 8] ^= 0xf0; - } - break; - - default: - kdc_err(context, retval = KRB5KDC_ERR_PREAUTH_FAILED, - "Unimplemented keytype for SAM key mixing"); - goto cleanup; - } - - /* XXX Attach a useful pa_data */ -cleanup: - if (sr) - krb5_free_sam_response(context, sr); - if (psr) - krb5_free_predicted_sam_response(context, psr); - - return retval; -} - -static struct { - char* name; - int sam_type; -} *sam_ptr, sam_inst_map[] = { - { "SNK4", PA_SAM_TYPE_DIGI_PATH, }, - { "SECURID", PA_SAM_TYPE_SECURID, }, - { "GRAIL", PA_SAM_TYPE_GRAIL, }, - { 0, 0 }, -}; - -static krb5_error_code -get_sam_edata(krb5_context context, krb5_kdc_req *request, - krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc sam_get_entry_data, - void *pa_system_context, krb5_pa_data *pa_data) -{ - krb5_error_code retval; - krb5_sam_challenge sc; - krb5_predicted_sam_response psr; - krb5_data * scratch; - krb5_keyblock encrypting_key, *mkey_ptr; - char response[9]; - char inputblock[8]; - krb5_data predict_response; - - memset(&sc, 0, sizeof(sc)); - memset(&psr, 0, sizeof(psr)); - - /* - * Given the client name we can figure out what type of preauth - * they need. The spec is currently for querying the database for - * names that match the types of preauth used. Later we should - * make this mapping show up in kdc.conf. In the meantime, we - * hardcode the following: - * /SNK4 -- Digital Pathways SNK/4 preauth. - * /GRAIL -- experimental preauth - * The first one found is used. See sam_inst_map above. - * - * For SNK4 in particular, the key in the database is the key for - * the device; kadmin needs a special interface for it. - */ - - { - krb5_db_entry *assoc; - krb5_key_data *assoc_key; - krb5_principal newp; - int probeslot; - - sc.sam_type = 0; - - retval = krb5_copy_principal(kdc_context, request->client, &newp); - if (retval) { - kdc_err(kdc_context, retval, "copying client name for preauth probe"); - return retval; - } - - probeslot = krb5_princ_size(context, newp)++; - krb5_princ_name(kdc_context, newp) = - realloc(krb5_princ_name(kdc_context, newp), - krb5_princ_size(context, newp) * sizeof(krb5_data)); - - for(sam_ptr = sam_inst_map; sam_ptr->name; sam_ptr++) { - krb5_princ_component(kdc_context,newp,probeslot)->data = sam_ptr->name; - krb5_princ_component(kdc_context,newp,probeslot)->length = - strlen(sam_ptr->name); - retval = krb5_db_get_principal(kdc_context, newp, 0, &assoc); - if(retval == 0) { - sc.sam_type = sam_ptr->sam_type; - break; - } - } - - krb5_princ_component(kdc_context,newp,probeslot)->data = 0; - krb5_princ_component(kdc_context,newp,probeslot)->length = 0; - krb5_princ_size(context, newp)--; - - krb5_free_principal(kdc_context, newp); - - /* if sc.sam_type is set, it worked */ - if (sc.sam_type) { - /* so use assoc to get the key out! */ - { - if ((retval = krb5_dbe_find_mkey(context, master_keylist, - assoc, &mkey_ptr))) { - krb5_keylist_node *tmp_mkey_list; - /* try refreshing the mkey list in case it's been updated */ - if (krb5_db_fetch_mkey_list(context, master_princ, - &master_keyblock, 0, - &tmp_mkey_list) == 0) { - krb5_dbe_free_key_list(context, master_keylist); - master_keylist = tmp_mkey_list; - if ((retval = krb5_dbe_find_mkey(context, master_keylist, - assoc, &mkey_ptr))) { - return (retval); - } - } else { - return (retval); - } - } - - /* here's what do_tgs_req does */ - retval = krb5_dbe_find_enctype(kdc_context, assoc, - ENCTYPE_DES_CBC_RAW, - KRB5_KDB_SALTTYPE_NORMAL, - 0, /* Get highest kvno */ - &assoc_key); - if (retval) { - char *sname; - krb5_unparse_name(kdc_context, request->client, &sname); - kdc_err(kdc_context, retval, - "snk4 finding the enctype and key <%s>", sname); - free(sname); - return retval; - } - /* convert server.key into a real key */ - retval = krb5_dbe_decrypt_key_data(kdc_context, mkey_ptr, - assoc_key, &encrypting_key, - NULL); - if (retval) { - kdc_err(kdc_context, retval, - "snk4 pulling out key entry"); - return retval; - } - /* now we can use encrypting_key... */ - } - } else { - /* SAM is not an option - so don't return as hint */ - return KRB5_PREAUTH_BAD_TYPE; - } - } - sc.magic = KV5M_SAM_CHALLENGE; - psr.sam_flags = sc.sam_flags = KRB5_SAM_USE_SAD_AS_KEY; - - /* Replay prevention */ - if ((retval = krb5_copy_principal(context, request->client, &psr.client))) - return retval; -#ifdef USE_RCACHE - if ((retval = krb5_us_timeofday(context, &psr.stime, &psr.susec))) - return retval; -#endif /* USE_RCACHE */ - - switch (sc.sam_type) { - case PA_SAM_TYPE_GRAIL: - sc.sam_type_name.data = "Experimental System"; - sc.sam_type_name.length = strlen(sc.sam_type_name.data); - sc.sam_challenge_label.data = "experimental challenge label"; - sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); - sc.sam_challenge.data = "12345"; - sc.sam_challenge.length = strlen(sc.sam_challenge.data); - -#if 0 /* Enable this to test "normal" (no flags set) mode. */ - psr.sam_flags = sc.sam_flags = 0; -#endif - - psr.magic = KV5M_PREDICTED_SAM_RESPONSE; - /* string2key on sc.sam_challenge goes in here */ - /* eblock is just to set the enctype */ - { - const krb5_enctype type = ENCTYPE_DES_CBC_MD5; - - if ((retval = krb5_c_string_to_key(context, type, &sc.sam_challenge, - 0 /* salt */, &psr.sam_key))) - goto cleanup; - - if ((retval = encode_krb5_predicted_sam_response(&psr, &scratch))) - goto cleanup; - - { - size_t enclen; - krb5_enc_data tmpdata; - - if ((retval = krb5_c_encrypt_length(context, - psr_key.enctype, - scratch->length, &enclen))) - goto cleanup; - - if ((tmpdata.ciphertext.data = (char *) malloc(enclen)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - tmpdata.ciphertext.length = enclen; - - if ((retval = krb5_c_encrypt(context, &psr_key, - /* XXX */ 0, 0, scratch, &tmpdata))) - goto cleanup; - - sc.sam_track_id = tmpdata.ciphertext; - } - } - - sc.sam_response_prompt.data = "response prompt"; - sc.sam_response_prompt.length = strlen(sc.sam_response_prompt.data); - sc.sam_pk_for_sad.length = 0; - sc.sam_nonce = 0; - /* Generate checksum */ - /*krb5_checksum_size(context, ctype)*/ - /*krb5_calculate_checksum(context,ctype,in,in_length,seed, - seed_length,outcksum) */ - /*krb5_verify_checksum(context,ctype,cksum,in,in_length,seed, - seed_length) */ -#if 0 /* XXX a) glue appears broken; b) this gives up the SAD */ - sc.sam_cksum.contents = (krb5_octet *) - malloc(krb5_checksum_size(context, CKSUMTYPE_RSA_MD5_DES)); - if (sc.sam_cksum.contents == NULL) return(ENOMEM); - - retval = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5_DES, - sc.sam_challenge.data, - sc.sam_challenge.length, - psr.sam_key.contents, /* key */ - psr.sam_key.length, /* key length */ - &sc.sam_cksum); - if (retval) { free(sc.sam_cksum.contents); return(retval); } -#endif /* 0 */ - - retval = encode_krb5_sam_challenge(&sc, &scratch); - if (retval) goto cleanup; - pa_data->magic = KV5M_PA_DATA; - pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE; - pa_data->contents = (krb5_octet *)scratch->data; - pa_data->length = scratch->length; - - retval = 0; - break; - case PA_SAM_TYPE_DIGI_PATH: - sc.sam_type_name.data = "Digital Pathways"; - sc.sam_type_name.length = strlen(sc.sam_type_name.data); -#if 1 - sc.sam_challenge_label.data = "Enter the following on your keypad"; - sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); -#endif - /* generate digit string, take it mod 1000000 (six digits.) */ - { - int j; - krb5_keyblock session_key; - char outputblock[8]; - int i; - - session_key.contents = 0; - - memset(inputblock, 0, 8); - - retval = krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_CRC, - &session_key); - - if (retval) { - /* random key failed */ - kdc_err(kdc_context, retval, - "generating random challenge for preauth"); - return retval; - } - /* now session_key has a key which we can pick bits out of */ - /* we need six decimal digits. Grab 6 bytes, div 2, mod 10 each. */ - if (session_key.length != 8) { - kdc_err(kdc_context, retval = KRB5KDC_ERR_ETYPE_NOSUPP, - "keytype didn't match code expectations"); - return retval; - } - for(i = 0; i<6; i++) { - inputblock[i] = '0' + ((session_key.contents[i]/2) % 10); - } - if (session_key.contents) - krb5_free_keyblock_contents(kdc_context, &session_key); - - /* retval = krb5_finish_key(kdc_context, &eblock); */ - /* now we have inputblock containing the 8 byte input to DES... */ - sc.sam_challenge.data = inputblock; - sc.sam_challenge.length = 6; - - encrypting_key.enctype = ENCTYPE_DES_CBC_RAW; - - if (retval) - kdc_err(kdc_context, retval, "snk4 processing key"); - - { - krb5_data plain; - krb5_enc_data cipher; - - plain.length = 8; - plain.data = inputblock; - - /* XXX I know this is enough because of the fixed raw enctype. - if it's not, the underlying code will return a reasonable - error, which should never happen */ - cipher.ciphertext.length = 8; - cipher.ciphertext.data = outputblock; - - if ((retval = krb5_c_encrypt(kdc_context, &encrypting_key, - /* XXX */ 0, 0, &plain, &cipher))) { - kdc_err(kdc_context, retval, - "snk4 response generation failed"); - return retval; - } - } - - /* now output block is the raw bits of the response; convert it - to display form */ - for (j=0; j<4; j++) { - char n[2]; - int k; - n[0] = outputblock[j] & 0xf; - n[1] = (outputblock[j]>>4) & 0xf; - for (k=0; k<2; k++) { - if(n[k] > 9) n[k] = ((n[k]-1)>>2); - /* This is equivalent to: - if(n[k]>=0xa && n[k]<=0xc) n[k] = 2; - if(n[k]>=0xd && n[k]<=0xf) n[k] = 3; - */ - } - /* for v4, we keygen: *(j+(char*)&key1) = (n[1]<<4) | n[0]; */ - /* for v5, we just generate a string */ - response[2*j+0] = '0' + n[1]; - response[2*j+1] = '0' + n[0]; - /* and now, response has what we work with. */ - } - response[8] = 0; - predict_response.data = response; - predict_response.length = 8; -#if 0 /* for debugging, hack the output too! */ - sc.sam_challenge_label.data = response; - sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); -#endif - } - - psr.magic = KV5M_PREDICTED_SAM_RESPONSE; - /* string2key on sc.sam_challenge goes in here */ - /* eblock is just to set the enctype */ - { - retval = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5, - &predict_response, 0 /* salt */, - &psr.sam_key); - if (retval) goto cleanup; - - retval = encode_krb5_predicted_sam_response(&psr, &scratch); - if (retval) goto cleanup; - - { - size_t enclen; - krb5_enc_data tmpdata; - - if ((retval = krb5_c_encrypt_length(context, - psr_key.enctype, - scratch->length, &enclen))) - goto cleanup; - - if ((tmpdata.ciphertext.data = (char *) malloc(enclen)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - tmpdata.ciphertext.length = enclen; - - if ((retval = krb5_c_encrypt(context, &psr_key, - /* XXX */ 0, 0, scratch, &tmpdata))) - goto cleanup; - - sc.sam_track_id = tmpdata.ciphertext; - } - if (retval) goto cleanup; - } - - sc.sam_response_prompt.data = "Enter the displayed response"; - sc.sam_response_prompt.length = strlen(sc.sam_response_prompt.data); - sc.sam_pk_for_sad.length = 0; - sc.sam_nonce = 0; - /* Generate checksum */ - /*krb5_checksum_size(context, ctype)*/ - /*krb5_calculate_checksum(context,ctype,in,in_length,seed, - seed_length,outcksum) */ - /*krb5_verify_checksum(context,ctype,cksum,in,in_length,seed, - seed_length) */ -#if 0 /* XXX a) glue appears broken; b) this gives up the SAD */ - sc.sam_cksum.contents = (krb5_octet *) - malloc(krb5_checksum_size(context, CKSUMTYPE_RSA_MD5_DES)); - if (sc.sam_cksum.contents == NULL) return(ENOMEM); - - retval = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5_DES, - sc.sam_challenge.data, - sc.sam_challenge.length, - psr.sam_key.contents, /* key */ - psr.sam_key.length, /* key length */ - &sc.sam_cksum); - if (retval) { free(sc.sam_cksum.contents); return(retval); } -#endif /* 0 */ - - retval = encode_krb5_sam_challenge(&sc, &scratch); - if (retval) goto cleanup; - pa_data->magic = KV5M_PA_DATA; - pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE; - pa_data->contents = (krb5_octet *)scratch->data; - pa_data->length = scratch->length; - - retval = 0; - break; - } - -cleanup: - krb5_free_keyblock_contents(context, &encrypting_key); - return retval; -} - -static krb5_error_code -verify_sam_response(krb5_context context, krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa, - preauth_get_entry_data_proc sam_get_entry_data, - void *pa_system_context, - void **pa_request_context, - krb5_data **e_data, - krb5_authdata ***authz_data) -{ - krb5_error_code retval; - krb5_data scratch; - krb5_sam_response *sr = 0; - krb5_predicted_sam_response *psr = 0; - krb5_enc_sam_response_enc *esre = 0; - krb5_timestamp timenow; - char *princ_req = 0, *princ_psr = 0; - - scratch.data = (char *)pa->contents; - scratch.length = pa->length; - - if ((retval = decode_krb5_sam_response(&scratch, &sr))) { - scratch.data = 0; - kdc_err(context, retval, "decode_krb5_sam_response failed"); - goto cleanup; - } - /* XXX We can only handle the challenge/response model of SAM. - See passwords-04, par 4.1, 4.2 */ - { - krb5_enc_data tmpdata; - - tmpdata.enctype = ENCTYPE_UNKNOWN; - tmpdata.ciphertext = sr->sam_track_id; - - scratch.length = tmpdata.ciphertext.length; - if ((scratch.data = (char *) malloc(scratch.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - - if ((retval = krb5_c_decrypt(context, &psr_key, /* XXX */ 0, 0, - &tmpdata, &scratch))) { - kdc_err(context, retval, "decrypt track_id failed"); - goto cleanup; - } - } - - if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) { - kdc_err(context, retval, - "decode_krb5_predicted_sam_response failed -- replay attack?"); - goto cleanup; - } - - /* Replay detection */ - if ((retval = krb5_unparse_name(context, request->client, &princ_req))) - goto cleanup; - if ((retval = krb5_unparse_name(context, psr->client, &princ_psr))) - goto cleanup; - if (strcmp(princ_req, princ_psr) != 0) { - kdc_err(context, retval = KRB5KDC_ERR_PREAUTH_FAILED, - "Principal mismatch in SAM psr! -- replay attack?"); - goto cleanup; - } - - if ((retval = krb5_timeofday(context, &timenow))) - goto cleanup; - -#ifdef USE_RCACHE - { - krb5_donot_replay rep; - extern krb5_deltat rc_lifetime; - /* - * Verify this response came back in a timely manner. - * We do this b/c otherwise very old (expunged from the rcache) - * psr's would be able to be replayed. - */ - if (timenow - psr->stime > rc_lifetime) { - kdc_err(context, retval = KRB5KDC_ERR_PREAUTH_FAILED, - "SAM psr came back too late! -- replay attack?"); - goto cleanup; - } - - /* Now check the replay cache. */ - rep.client = princ_psr; - rep.server = "SAM/rc"; /* Should not match any principal name. */ - rep.msghash = NULL; - rep.ctime = psr->stime; - rep.cusec = psr->susec; - retval = krb5_rc_store(kdc_context, kdc_rcache, &rep); - if (retval) { - kdc_err(kdc_context, retval, "SAM psr replay attack!"); - goto cleanup; - } - } -#endif /* USE_RCACHE */ - - - { - free(scratch.data); - scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length; - if ((scratch.data = (char *) malloc(scratch.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - - if ((retval = krb5_c_decrypt(context, &psr->sam_key, /* XXX */ 0, - 0, &sr->sam_enc_nonce_or_ts, &scratch))) { - kdc_err(context, retval, "decrypt nonce_or_ts failed"); - goto cleanup; - } - } - - if ((retval = decode_krb5_enc_sam_response_enc(&scratch, &esre))) { - kdc_err(context, retval, "decode_krb5_enc_sam_response_enc failed"); - goto cleanup; - } - - if (esre->sam_timestamp != sr->sam_patimestamp) { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - } - - if (labs(timenow - sr->sam_patimestamp) > context->clockskew) { - retval = KRB5KRB_AP_ERR_SKEW; - goto cleanup; - } - - setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH); - -cleanup: - if (retval) - kdc_err(context, retval, "sam verify failure"); - if (scratch.data) free(scratch.data); - if (sr) free(sr); - if (psr) free(psr); - if (esre) free(esre); - if (princ_psr) free(princ_psr); - if (princ_req) free(princ_req); - - return retval; -} #if APPLE_PKINIT /* PKINIT preauth support */ -- cgit