From ce3ba8ba7670b57ffb2b1e2707f0cb443e900b0f Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Thu, 26 Apr 2012 21:47:05 +0000 Subject: [PATCH] Make it easier to test SAM-2 client code Add a method to the securid_sam2 plugin, built with alternate compile-time flags, which supplies a plain-text challenge to the client to be used as the OTP value. This lets us manually exercise the SAM-2 client code and a little bit of the KDC code. securid_make_sam_challenge_2_and_cksum is moved into the method- independent code and renamed. get_securid_edata_2 has its sc2b parameter removed as it was not used by the caller. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25832 dc483132-0cff-0310-8789-dd5450dbe970 --- src/plugins/preauth/securid_sam2/Makefile.in | 10 +- src/plugins/preauth/securid_sam2/extern.h | 20 +- src/plugins/preauth/securid_sam2/grail.c | 273 ++++++++++++++++++ src/plugins/preauth/securid_sam2/securid2.c | 112 ++----- .../preauth/securid_sam2/securid_sam2.exports | 2 +- .../preauth/securid_sam2/securid_sam2_main.c | 110 +++++-- 6 files changed, 407 insertions(+), 120 deletions(-) create mode 100644 src/plugins/preauth/securid_sam2/grail.c diff --git a/src/plugins/preauth/securid_sam2/Makefile.in b/src/plugins/preauth/securid_sam2/Makefile.in index 860b473eb..fff52c729 100644 --- a/src/plugins/preauth/securid_sam2/Makefile.in +++ b/src/plugins/preauth/securid_sam2/Makefile.in @@ -5,7 +5,8 @@ KRB5_CONFIG_SETUP = KRB5_CONFIG=$(top_srcdir)/config-files/krb5.conf ; export KR PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR) -DEFS=@DEFS@ -DARL_SECURID_PREAUTH +DEFS=@DEFS@ +DEFINES=-DARL_SECURID_PREAUTH LOCALINCLUDES = -I../../../include/krb5 -I. @@ -18,15 +19,16 @@ RELDIR=../plugins/preauth/securid_sam2 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(TOPLIBD)/libkrb5$(SHLIBEXT) $(KADMSRV_DEPLIBS) +ACELIB= -laceclnt SHLIB_EXPLIBS= -lkrb5 -lcom_err -lk5crypto $(SUPPORT_LIB) $(KADMSRV_LIBS) \ - $(LIBS) -laceclnt + $(LIBS) $(ACELIB) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) STOBJLISTS=OBJS.ST -STLIBOBJS=securid_sam2_main.o securid2.o +STLIBOBJS=securid_sam2_main.o securid2.o grail.o -SRCS= $(srcdir)/securid_sam2_main.c $(srcdir)/securid2.c 2 +SRCS= $(srcdir)/securid_sam2_main.c $(srcdir)/securid2.c $(srcdir)/grail.c all-unix:: all-libs install-unix:: install-libs diff --git a/src/plugins/preauth/securid_sam2/extern.h b/src/plugins/preauth/securid_sam2/extern.h index 5a76b7eb6..c8c76dd07 100644 --- a/src/plugins/preauth/securid_sam2/extern.h +++ b/src/plugins/preauth/securid_sam2/extern.h @@ -32,16 +32,14 @@ krb5_error_code sam_get_db_entry(krb5_context , krb5_principal, int *, krb5_db_entry **); -krb5_error_code -securid_make_sam_challenge_2_and_cksum(krb5_context context, - krb5_sam_challenge_2 *sc2, - krb5_sam_challenge_2_body *sc2b, - krb5_keyblock *cksum_key); +krb5_error_code sam_make_challenge(krb5_context context, + krb5_sam_challenge_2_body *sc2b, + krb5_keyblock *cksum_key, + krb5_sam_challenge_2 *sc2_out); krb5_error_code get_securid_edata_2(krb5_context context, krb5_db_entry *client, krb5_keyblock *client_key, - krb5_sam_challenge_2_body *sc2b, krb5_sam_challenge_2 *sc2); krb5_error_code verify_securid_data_2(krb5_context context, @@ -50,3 +48,13 @@ krb5_error_code verify_securid_data_2(krb5_context context, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa, krb5_sam_challenge_2 **sc2_out); + +krb5_error_code get_grail_edata(krb5_context context, krb5_db_entry *client, + krb5_keyblock *client_key, + krb5_sam_challenge_2 *sc2_out); + +krb5_error_code verify_grail_data(krb5_context context, krb5_db_entry *client, + krb5_sam_response_2 *sr2, + krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *pa, + krb5_sam_challenge_2 **sc2_out); diff --git a/src/plugins/preauth/securid_sam2/grail.c b/src/plugins/preauth/securid_sam2/grail.c new file mode 100644 index 000000000..18d48f924 --- /dev/null +++ b/src/plugins/preauth/securid_sam2/grail.c @@ -0,0 +1,273 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* plugins/preauth/securid_sam2/grail.c - Test method for SAM-2 preauth */ +/* + * Copyright (C) 2012 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This test method exists to exercise the client SAM-2 code and some of the + * KDC SAM-2 code. We make up a weakly random number and presents it to the + * client in the prompt (in plain text), as well as encrypted in the track ID. + * To verify, we compare the decrypted track ID to the entered value. + * + * Do not use this method in production; it is not secure. + */ + +#ifdef GRAIL_PREAUTH + +#include "k5-int.h" +#include +#include +#include +#include "extern.h" + +static krb5_error_code +get_grail_key(krb5_context context, krb5_db_entry *client, + krb5_keyblock *key_out) +{ + krb5_db_entry *grail_entry = NULL; + krb5_key_data *kd; + int sam_type = PA_SAM_TYPE_GRAIL; + krb5_error_code ret = 0; + + ret = sam_get_db_entry(context, client->princ, &sam_type, &grail_entry); + if (ret) + return KRB5_PREAUTH_NO_KEY; + ret = krb5_dbe_find_enctype(context, grail_entry, -1, -1, -1, &kd); + if (ret) + goto cleanup; + ret = krb5_dbe_decrypt_key_data(context, NULL, kd, key_out, NULL); + if (ret) + goto cleanup; + +cleanup: + if (grail_entry) + krb5_db_free_principal(context, grail_entry); + return ret; +} + +static krb5_error_code +decrypt_track_data(krb5_context context, krb5_db_entry *client, + krb5_data *enc_track_data, krb5_data *output) +{ + krb5_error_code ret; + krb5_keyblock sam_key; + krb5_enc_data enc; + krb5_data result = empty_data(); + + sam_key.contents = NULL; + *output = empty_data(); + + ret = get_grail_key(context, client, &sam_key); + if (ret != 0) + return ret; + enc.ciphertext = *enc_track_data; + enc.enctype = ENCTYPE_UNKNOWN; + enc.kvno = 0; + ret = alloc_data(&result, enc_track_data->length); + if (ret) + goto cleanup; + ret = krb5_c_decrypt(context, &sam_key, + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, &enc, + &result); + if (ret) + goto cleanup; + + *output = result; + result = empty_data(); + +cleanup: + krb5_free_keyblock_contents(context, &sam_key); + krb5_free_data_contents(context, &result); + return ret; +} + +static krb5_error_code +encrypt_track_data(krb5_context context, krb5_db_entry *client, + krb5_data *track_data, krb5_data *output) +{ + krb5_error_code ret; + size_t olen; + krb5_keyblock sam_key; + krb5_enc_data enc; + + *output = empty_data(); + enc.ciphertext = empty_data(); + sam_key.contents = NULL; + + ret = get_grail_key(context, client, &sam_key); + if (ret != 0) + return ret; + + ret = krb5_c_encrypt_length(context, sam_key.enctype, + track_data->length, &olen); + if (ret != 0) + goto cleanup; + assert(olen <= 65536); + ret = alloc_data(&enc.ciphertext, olen); + if (ret) + goto cleanup; + enc.enctype = sam_key.enctype; + enc.kvno = 0; + + ret = krb5_c_encrypt(context, &sam_key, + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, + track_data, &enc); + if (ret) + goto cleanup; + + *output = enc.ciphertext; + enc.ciphertext = empty_data(); + +cleanup: + krb5_free_keyblock_contents(context, &sam_key); + krb5_free_data_contents(context, &enc.ciphertext); + return ret; +} + +krb5_error_code +get_grail_edata(krb5_context context, krb5_db_entry *client, + krb5_keyblock *client_key, krb5_sam_challenge_2 *sc2_out) +{ + krb5_error_code ret; + krb5_data tmp_data, track_id = empty_data(); + int tval = time(NULL) % 77777; + krb5_sam_challenge_2_body sc2b; + char tval_string[256], prompt[256]; + + snprintf(tval_string, sizeof(tval_string), "%d", tval); + snprintf(prompt, sizeof(prompt), "Enter %d", tval); + + memset(&sc2b, 0, sizeof(sc2b)); + sc2b.magic = KV5M_SAM_CHALLENGE_2; + sc2b.sam_track_id = empty_data(); + sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + sc2b.sam_type_name = empty_data(); + sc2b.sam_challenge_label = empty_data(); + sc2b.sam_challenge = empty_data(); + sc2b.sam_response_prompt = string2data(prompt); + sc2b.sam_pk_for_sad = empty_data(); + sc2b.sam_type = PA_SAM_TYPE_GRAIL; + sc2b.sam_etype = client_key->enctype; + + tmp_data = string2data(tval_string); + ret = encrypt_track_data(context, client, &tmp_data, &track_id); + if (ret) + goto cleanup; + sc2b.sam_track_id = track_id; + + tmp_data = make_data(&sc2b.sam_nonce, sizeof(sc2b.sam_nonce)); + ret = krb5_c_random_make_octets(context, &tmp_data); + if (ret) + goto cleanup; + + ret = sam_make_challenge(context, &sc2b, client_key, sc2_out); + +cleanup: + krb5_free_data_contents(context, &track_id); + return ret; +} + +krb5_error_code +verify_grail_data(krb5_context context, krb5_db_entry *client, + krb5_sam_response_2 *sr2, krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *pa, krb5_sam_challenge_2 **sc2_out) +{ + krb5_error_code ret; + krb5_key_data *client_key_data = NULL; + krb5_keyblock client_key; + krb5_data scratch = empty_data(), track_id_data = empty_data(); + krb5_enc_sam_response_enc_2 *esre2 = NULL; + + *sc2_out = NULL; + memset(&client_key, 0, sizeof(client_key)); + + if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) || + (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) + return KRB5KDC_ERR_PREAUTH_FAILED; + + ret = krb5_dbe_find_enctype(context, client, + sr2->sam_enc_nonce_or_sad.enctype, + KRB5_KDB_SALTTYPE_NORMAL, + sr2->sam_enc_nonce_or_sad.kvno, + &client_key_data); + if (ret) + goto cleanup; + + ret = krb5_dbe_decrypt_key_data(context, NULL, client_key_data, + &client_key, NULL); + if (ret) + goto cleanup; + ret = alloc_data(&scratch, sr2->sam_enc_nonce_or_sad.ciphertext.length); + if (ret) + goto cleanup; + ret = krb5_c_decrypt(context, &client_key, KRB5_KEYUSAGE_PA_SAM_RESPONSE, + NULL, &sr2->sam_enc_nonce_or_sad, &scratch); + if (ret) + goto cleanup; + + ret = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2); + if (ret) + goto cleanup; + + if (sr2->sam_nonce != esre2->sam_nonce) { + ret = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + + if (esre2->sam_sad.length == 0 || esre2->sam_sad.data == NULL) { + ret = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + + ret = decrypt_track_data(context, client, &sr2->sam_track_id, + &track_id_data); + if (ret) + goto cleanup; + + /* Some enctypes aren't length-preserving; try to work anyway. */ + while (track_id_data.length > 0 && + !isdigit(track_id_data.data[track_id_data.length - 1])) + track_id_data.length--; + + if (!data_eq(track_id_data, esre2->sam_sad)) { + ret = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + + enc_tkt_reply->flags |= (TKT_FLG_HW_AUTH | TKT_FLG_PRE_AUTH); + +cleanup: + krb5_free_keyblock_contents(context, &client_key); + krb5_free_data_contents(context, &scratch); + krb5_free_enc_sam_response_enc_2(context, esre2); + return ret; +} + +#endif /* GRAIL_PREAUTH */ diff --git a/src/plugins/preauth/securid_sam2/securid2.c b/src/plugins/preauth/securid_sam2/securid2.c index 816946eeb..57d4e37d2 100644 --- a/src/plugins/preauth/securid_sam2/securid2.c +++ b/src/plugins/preauth/securid_sam2/securid2.c @@ -36,6 +36,8 @@ * RESULTING FROM THE USE OF THIS SOFTWARE. */ +#ifdef ARL_SECURID_PREAUTH + #include "k5-int.h" #include #include @@ -120,64 +122,6 @@ cleanup: return retval; } -krb5_error_code -securid_make_sam_challenge_2_and_cksum(krb5_context context, - krb5_sam_challenge_2 *sc2, - krb5_sam_challenge_2_body *sc2b, - krb5_keyblock *cksum_key) -{ - krb5_error_code retval; - krb5_checksum **cksum_array = NULL; - krb5_checksum *cksum = NULL; - krb5_cksumtype cksumtype; - krb5_data *encoded_challenge_body = NULL; - - if (!cksum_key) - return KRB5_PREAUTH_NO_KEY; - if (!sc2 || !sc2b) - return KRB5KDC_ERR_PREAUTH_FAILED; - - retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body); - if (retval || !encoded_challenge_body) { - encoded_challenge_body = NULL; - goto cksum_cleanup; - } - - cksum_array = calloc(2, sizeof(krb5_checksum *)); - if (!cksum_array) { - retval = ENOMEM; - goto cksum_cleanup; - } - - cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval); - if (retval) - goto cksum_cleanup; - cksum_array[0] = cksum; - cksum_array[1] = NULL; - - retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype, - &cksumtype); - if (retval) - goto cksum_cleanup; - - retval = krb5_c_make_checksum(context, cksumtype, cksum_key, - KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM, - encoded_challenge_body, cksum); - if (retval) - goto cksum_cleanup; - - sc2->sam_cksum = cksum_array; - sc2->sam_challenge_2_body = *encoded_challenge_body; - return 0; - -cksum_cleanup: - krb5_free_data(context, encoded_challenge_body); - free(cksum_array); - free(cksum); - return retval; -} - - static krb5_error_code securid_decrypt_track_data_2(krb5_context context, krb5_db_entry *client, krb5_data *enc_track_data, krb5_data *output) @@ -262,45 +206,47 @@ cleanup: krb5_error_code get_securid_edata_2(krb5_context context, krb5_db_entry *client, - krb5_keyblock *client_key, - krb5_sam_challenge_2_body *sc2b, krb5_sam_challenge_2 *sc2) + krb5_keyblock *client_key, krb5_sam_challenge_2 *sc2) { krb5_error_code retval; - krb5_data scratch; + krb5_data scratch, track_id = empty_data(); char *user = NULL; char *def_user = ""; struct securid_track_data sid_track_data; krb5_data tmp_data; + krb5_sam_challenge_2_body sc2b; scratch.data = NULL; - sc2b->sam_track_id.data = NULL; retval = krb5_unparse_name(context, client->princ, &user); if (retval) goto cleanup; - sc2b->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; - sc2b->sam_type_name.length = 0; - sc2b->sam_challenge_label.length = 0; - sc2b->sam_challenge.length = 0; - sc2b->sam_response_prompt.data = PASSCODE_message; - sc2b->sam_response_prompt.length = strlen(sc2b->sam_response_prompt.data); - sc2b->sam_pk_for_sad.length = 0; - sc2b->sam_type = PA_SAM_TYPE_SECURID; + memset(&sc2b, 0, sizeof(sc2b)); + sc2b.magic = KV5M_SAM_CHALLENGE_2; + sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + sc2b.sam_type_name.length = 0; + sc2b.sam_challenge_label.length = 0; + sc2b.sam_challenge.length = 0; + sc2b.sam_response_prompt.data = PASSCODE_message; + sc2b.sam_response_prompt.length = strlen(sc2b.sam_response_prompt.data); + sc2b.sam_pk_for_sad.length = 0; + sc2b.sam_type = PA_SAM_TYPE_SECURID; sid_track_data.state = SECURID_STATE_INITIAL; sid_track_data.hostid = gethostid(); tmp_data.data = (char *)&sid_track_data; tmp_data.length = sizeof(sid_track_data); retval = securid_encrypt_track_data_2(context, client, &tmp_data, - &sc2b->sam_track_id); + &track_id); if (retval != 0) { com_err("krb5kdc", retval, "while encrypting nonce track data"); goto cleanup; } + sc2b.sam_track_id = track_id; - scratch.data = (char *)&sc2b->sam_nonce; - scratch.length = sizeof(sc2b->sam_nonce); + scratch.data = (char *)&sc2b.sam_nonce; + scratch.length = sizeof(sc2b.sam_nonce); retval = krb5_c_random_make_octets(context, &scratch); if (retval) { com_err("krb5kdc", retval, @@ -310,10 +256,9 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client, } /* Get the client's key */ - sc2b->sam_etype = client_key->enctype; + sc2b.sam_etype = client_key->enctype; - retval = securid_make_sam_challenge_2_and_cksum(context, - sc2, sc2b, client_key); + retval = sam_make_challenge(context, &sc2b, client_key, sc2); if (retval) { com_err("krb5kdc", retval, "while making SAM_CHALLENGE_2 checksum (%s)", @@ -322,10 +267,7 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client, cleanup: free(user); - if (retval) { - krb5_free_data_contents(context, &sc2b->sam_track_id); - sc2b->sam_track_id.data = NULL; - } + krb5_free_data_contents(context, &track_id); return retval; } @@ -554,9 +496,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client, securid_user); goto cleanup; } - retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, - &sc2b, - &client_key); + retval = sam_make_challenge(context, &sc2b, &client_key, sc2p); if (retval) { com_err("krb5kdc", retval, "while making cksum for " @@ -688,9 +628,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client, securid_user); goto cleanup; } - retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, - &sc2b, - &client_key); + retval = sam_make_challenge(context, &sc2b, &client_key, sc2p); if (retval) { com_err("krb5kdc", retval, "while making cksum for SAM_CHALLENGE_2 (%s)", @@ -727,3 +665,5 @@ cleanup: krb5_free_sam_challenge_2(context, sc2p); return retval; } + +#endif /* ARL_SECURID_PREAUTH */ diff --git a/src/plugins/preauth/securid_sam2/securid_sam2.exports b/src/plugins/preauth/securid_sam2/securid_sam2.exports index cb26d4722..9abae9196 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2.exports +++ b/src/plugins/preauth/securid_sam2/securid_sam2.exports @@ -1 +1 @@ -preauthentication_server_1 +kdcpreauth_securid_sam2_initvt diff --git a/src/plugins/preauth/securid_sam2/securid_sam2_main.c b/src/plugins/preauth/securid_sam2/securid_sam2_main.c index b20a87d8b..5dcd2ebf3 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2_main.c +++ b/src/plugins/preauth/securid_sam2/securid_sam2_main.c @@ -112,6 +112,61 @@ cleanup: } } +krb5_error_code +sam_make_challenge(krb5_context context, krb5_sam_challenge_2_body *sc2b, + krb5_keyblock *cksum_key, krb5_sam_challenge_2 *sc2_out) +{ + krb5_error_code retval; + krb5_checksum **cksum_array = NULL; + krb5_checksum *cksum = NULL; + krb5_cksumtype cksumtype; + krb5_data *encoded_challenge_body = NULL; + + if (!cksum_key) + return KRB5_PREAUTH_NO_KEY; + if (!sc2_out || !sc2b) + return KRB5KDC_ERR_PREAUTH_FAILED; + + retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body); + if (retval || !encoded_challenge_body) { + encoded_challenge_body = NULL; + goto cksum_cleanup; + } + + cksum_array = calloc(2, sizeof(krb5_checksum *)); + if (!cksum_array) { + retval = ENOMEM; + goto cksum_cleanup; + } + + cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval); + if (retval) + goto cksum_cleanup; + cksum_array[0] = cksum; + cksum_array[1] = NULL; + + retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype, + &cksumtype); + if (retval) + goto cksum_cleanup; + + retval = krb5_c_make_checksum(context, cksumtype, cksum_key, + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM, + encoded_challenge_body, cksum); + if (retval) + goto cksum_cleanup; + + sc2_out->sam_cksum = cksum_array; + sc2_out->sam_challenge_2_body = *encoded_challenge_body; + return 0; + +cksum_cleanup: + krb5_free_data(context, encoded_challenge_body); + free(cksum_array); + free(cksum); + return retval; +} + static void kdc_include_padata(krb5_context context, krb5_kdc_req *request, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, @@ -121,16 +176,12 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, krb5_error_code retval; krb5_keyblock *client_key = NULL; krb5_sam_challenge_2 sc2; - krb5_sam_challenge_2_body sc2b; int sam_type = 0; /* unknown */ krb5_db_entry *sam_db_entry = NULL, *client; krb5_data *encoded_challenge = NULL; krb5_pa_data *pa_data = NULL; memset(&sc2, 0, sizeof(sc2)); - memset(&sc2b, 0, sizeof(sc2b)); - sc2b.magic = KV5M_SAM_CHALLENGE_2; - sc2b.sam_type = sam_type; client = cb->client_entry(context, rock); retval = sam_get_db_entry(context, client->princ, &sam_type, @@ -161,34 +212,39 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, switch (sam_type) { #ifdef ARL_SECURID_PREAUTH case PA_SAM_TYPE_SECURID: - retval = get_securid_edata_2(context, client, client_key, &sc2b, &sc2); + retval = get_securid_edata_2(context, client, client_key, &sc2); if (retval) goto cleanup; - - retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); - if (retval) { - com_err("krb5kdc", retval, - "while encoding SECURID SAM_CHALLENGE_2"); - goto cleanup; - } - - pa_data = k5alloc(sizeof(*pa_data), &retval); - if (pa_data == NULL) - goto cleanup; - pa_data->magic = KV5M_PA_DATA; - pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; - pa_data->contents = (krb5_octet *) encoded_challenge->data; - pa_data->length = encoded_challenge->length; - encoded_challenge->data = NULL; - - retval = 0; break; #endif /* ARL_SECURID_PREAUTH */ +#ifdef GRAIL_PREAUTH + case PA_SAM_TYPE_GRAIL: + retval = get_grail_edata(context, client, client_key, &sc2); + if (retval) + goto cleanup; + break; +#endif /* GRAIL_PREAUTH */ default: retval = KRB5_PREAUTH_BAD_TYPE; goto cleanup; } + retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); + if (retval) { + com_err("krb5kdc", retval, + "while encoding SECURID SAM_CHALLENGE_2"); + goto cleanup; + } + + pa_data = k5alloc(sizeof(*pa_data), &retval); + if (pa_data == NULL) + goto cleanup; + pa_data->magic = KV5M_PA_DATA; + pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; + pa_data->contents = (krb5_octet *)encoded_challenge->data; + pa_data->length = encoded_challenge->length; + encoded_challenge->data = NULL; + cleanup: krb5_free_data(context, encoded_challenge); if (sam_db_entry) @@ -235,6 +291,14 @@ kdc_verify_preauth(krb5_context context, krb5_data *req_pkt, goto cleanup; break; #endif /* ARL_SECURID_PREAUTH */ +#ifdef GRAIL_PREAUTH + case PA_SAM_TYPE_GRAIL: + retval = verify_grail_data(context, client, sr2, enc_tkt_reply, + pa_data, &out_sc2); + if (retval) + goto cleanup; + break; +#endif /* GRAIL_PREAUTH */ default: retval = KRB5_PREAUTH_BAD_TYPE; com_err("krb5kdc", retval, "while verifying SAM 2 data"); -- 2.26.2