svn rev #25832: trunk/src/plugins/preauth/securid_sam2/
ghudson@MIT.EDU
ghudson at MIT.EDU
Thu Apr 26 17:47:05 EDT 2012
http://src.mit.edu/fisheye/changelog/krb5/?cs=25832
Commit By: ghudson
Log Message:
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.
Changed Files:
U trunk/src/plugins/preauth/securid_sam2/Makefile.in
U trunk/src/plugins/preauth/securid_sam2/extern.h
A trunk/src/plugins/preauth/securid_sam2/grail.c
U trunk/src/plugins/preauth/securid_sam2/securid2.c
U trunk/src/plugins/preauth/securid_sam2/securid_sam2.exports
U trunk/src/plugins/preauth/securid_sam2/securid_sam2_main.c
Modified: trunk/src/plugins/preauth/securid_sam2/Makefile.in
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/Makefile.in 2012-04-26 21:47:02 UTC (rev 25831)
+++ trunk/src/plugins/preauth/securid_sam2/Makefile.in 2012-04-26 21:47:05 UTC (rev 25832)
@@ -5,7 +5,8 @@
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 @@
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
Modified: trunk/src/plugins/preauth/securid_sam2/extern.h
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/extern.h 2012-04-26 21:47:02 UTC (rev 25831)
+++ trunk/src/plugins/preauth/securid_sam2/extern.h 2012-04-26 21:47:05 UTC (rev 25832)
@@ -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_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);
Added: trunk/src/plugins/preauth/securid_sam2/grail.c
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/grail.c (rev 0)
+++ trunk/src/plugins/preauth/securid_sam2/grail.c 2012-04-26 21:47:05 UTC (rev 25832)
@@ -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 <kdb.h>
+#include <adm_proto.h>
+#include <ctype.h>
+#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 */
Modified: trunk/src/plugins/preauth/securid_sam2/securid2.c
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/securid2.c 2012-04-26 21:47:02 UTC (rev 25831)
+++ trunk/src/plugins/preauth/securid_sam2/securid2.c 2012-04-26 21:47:05 UTC (rev 25832)
@@ -36,6 +36,8 @@
* RESULTING FROM THE USE OF THIS SOFTWARE.
*/
+#ifdef ARL_SECURID_PREAUTH
+
#include "k5-int.h"
#include <kdb.h>
#include <stdio.h>
@@ -120,64 +122,6 @@
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 @@
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 = "<unknown 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 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 @@
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 @@
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 @@
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 @@
krb5_free_sam_challenge_2(context, sc2p);
return retval;
}
+
+#endif /* ARL_SECURID_PREAUTH */
Modified: trunk/src/plugins/preauth/securid_sam2/securid_sam2.exports
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/securid_sam2.exports 2012-04-26 21:47:02 UTC (rev 25831)
+++ trunk/src/plugins/preauth/securid_sam2/securid_sam2.exports 2012-04-26 21:47:05 UTC (rev 25832)
@@ -1 +1 @@
-preauthentication_server_1
+kdcpreauth_securid_sam2_initvt
Modified: trunk/src/plugins/preauth/securid_sam2/securid_sam2_main.c
===================================================================
--- trunk/src/plugins/preauth/securid_sam2/securid_sam2_main.c 2012-04-26 21:47:02 UTC (rev 25831)
+++ trunk/src/plugins/preauth/securid_sam2/securid_sam2_main.c 2012-04-26 21:47:05 UTC (rev 25832)
@@ -112,6 +112,61 @@
}
}
+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 @@
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 @@
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");
+ 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;
- }
-
- 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 */
+#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 @@
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");
More information about the cvs-krb5
mailing list