Copyright statements, whitespace, and other code formatting
authorGreg Hudson <ghudson@mit.edu>
Sat, 2 Oct 2010 17:17:35 +0000 (17:17 +0000)
committerGreg Hudson <ghudson@mit.edu>
Sat, 2 Oct 2010 17:17:35 +0000 (17:17 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24415 dc483132-0cff-0310-8789-dd5450dbe970

src/plugins/preauth/securid_sam2/extern.h
src/plugins/preauth/securid_sam2/securid2.c
src/plugins/preauth/securid_sam2/securid_sam2_main.c

index 8bea143bb103e1f6e26d83b2d24d9e0a53c7862c..100c132302757a4247853613e7c375ee9ea6e312 100644 (file)
@@ -1,18 +1,50 @@
- krb5_error_code sam_get_db_entry(krb5_context , krb5_principal,
-                        int *, krb5_db_entry **);
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * plugins/preauth/securid_sam2/extern.h
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Declarations for SecurID SAM2 plugin.
+ */
+
+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);
+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 get_securid_edata_2(krb5_context context,
-                               krb5_db_entry *client,
-                               krb5_sam_challenge_2_body *sc2b,
-                                   krb5_sam_challenge_2 *sc2);
+                                    krb5_db_entry *client,
+                                    krb5_sam_challenge_2_body *sc2b,
+                                    krb5_sam_challenge_2 *sc2);
 
 krb5_error_code verify_securid_data_2(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_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);
index b7d744e6099463d51531116044a2fe4f6bef6003..b0012a15aea4b47167eba55539f55b7a9085c523 100644 (file)
@@ -1,22 +1,46 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * plugins/preauth/securid_sam2/securid2.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 
 #include "k5-int.h"
 #include <kdb.h>
 #include <stdio.h>
 #include <adm_proto.h>
-
-
 #include <syslog.h>
 #include <acexport.h>
 #include <sdi_defs.h>
 #include <sdi_athd.h>
 #include "extern.h"
 
-#define KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC          0x5ec1d000
+#define KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC 0x5ec1d000
 struct securid_track_data {
-       SDI_HANDLE handle;
-       char state;
-       char passcode[LENPRNST+1];
-        long hostid;
+    SDI_HANDLE handle;
+    char state;
+    char passcode[LENPRNST+1];
+    long hostid;
 };
 
 #define SECURID_STATE_NEW_PIN           1       /* Ask for a new pin */
@@ -24,283 +48,293 @@ struct securid_track_data {
 #define SECURID_STATE_NEXT_CODE         3       /* Ask for the next pin code */
 #define SECURID_STATE_INITIAL           4
 
-
-static char *PASSCODE_message =        "SecurID Passcode";
-static char *NEXT_PASSCODE_message =   "Next Passcode";
-static char *NEW_PIN_AGAIN_message =   "New PIN Again";
-static char PIN_message[64];           /* Max length should be 50 chars */
-
-/*     krb5_error_code get_securid_key():
- *             inputs:  context:  from KDC process
- *                      client:   database entry of client executing
- *                                SecurID SAM preauthentication
- *             outputs: client_securid_key: pointer to krb5_keyblock
- *                                which is key for the client's SecurID
- *                                database entry.
- *             returns: 0 on success
- *                      KRB5 error codes otherwise
+static char *PASSCODE_message =         "SecurID Passcode";
+static char *NEXT_PASSCODE_message =    "Next Passcode";
+static char *NEW_PIN_AGAIN_message =    "New PIN Again";
+static char PIN_message[64];            /* Max length should be 50 chars */
+
+/*
+ * krb5_error_code get_securid_key():
+ *   inputs:  context:  from KDC process
+ *            client:   database entry of client executing
+ *                      SecurID SAM preauthentication
+ *   outputs: client_securid_key: pointer to krb5_keyblock
+ *                      which is key for the client's SecurID
+ *                      database entry.
+ *   returns: 0 on success
+ *            KRB5 error codes otherwise
  *
- *             builds pricipal name with final instance of "SECURID" and
- *             finds the database entry, decrypts the key out of the database
- *             and passes the key back to the calling process
+ *   builds pricipal name with final instance of "SECURID" and
+ *   finds the database entry, decrypts the key out of the database
+ *   and passes the key back to the calling process
  */
 
-static krb5_error_code get_securid_key(krb5_context context,
-                                      krb5_db_entry *client,
-                                      krb5_keyblock *client_securid_key)
+static krb5_error_code
+get_securid_key(krb5_context context, krb5_db_entry *client,
+                krb5_keyblock *client_securid_key)
 {
-  krb5_db_entry *sam_securid_entry = NULL;
+    krb5_db_entry *sam_securid_entry = NULL;
     krb5_key_data *client_securid_key_data = NULL;
     int sam_type = PA_SAM_TYPE_SECURID;
     krb5_error_code retval = 0;
 
-    if (!client_securid_key) return(KRB5_PREAUTH_NO_KEY);
+    if (!client_securid_key)
+        return KRB5_PREAUTH_NO_KEY;
 
     retval = sam_get_db_entry(context, client->princ,
-                             &sam_type, &sam_securid_entry);
-
+                              &sam_type, &sam_securid_entry);
     if (retval)
-      return(KRB5_PREAUTH_NO_KEY);
-
+        return KRB5_PREAUTH_NO_KEY;
 
-    /* Find key with key_type = salt_type = kvno = -1.  This finds the */
-    /* latest kvno in the list.                                        */
+    /* Find key with key_type = salt_type = kvno = -1.  This finds the  */
+    /* latest kvno in the list.                                         */
 
     retval = krb5_dbe_find_enctype(context, sam_securid_entry,
-               -1, -1, -1, &client_securid_key_data);
+                                   -1, -1, -1, &client_securid_key_data);
     if (retval) {
-       krb5_set_error_message(context, retval,
-               "while getting key from client's SAM SecurID entry");
-       goto cleanup;
+        krb5_set_error_message(context, retval,
+                               "while getting key from client's SAM SecurID "
+                               "entry");
+        goto cleanup;
     }
-    retval = krb5_dbe_decrypt_key_data(context, NULL,
-               client_securid_key_data, client_securid_key, NULL);
+    retval = krb5_dbe_decrypt_key_data(context, NULL, client_securid_key_data,
+                                       client_securid_key, NULL);
     if (retval) {
-       krb5_set_error_message(context, retval,
-               "while decrypting key from client's SAM SecurID entry ");
-       goto cleanup;
+        krb5_set_error_message(context, retval,
+                               "while decrypting key from client's SAM "
+                               "SecurID entry ");
+        goto cleanup;
     }
- cleanup:
+cleanup:
     if (sam_securid_entry)
-      krb5_db_free_principal(context, sam_securid_entry);
+        krb5_db_free_principal(context, sam_securid_entry);
     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)
+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);
+    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:
-  if (encoded_challenge_body) krb5_free_data(context, encoded_challenge_body);
-  if (cksum_array) krb5_xfree(cksum_array);
-  if (cksum) krb5_xfree(cksum);
-  return (retval);
+    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) {
+                             krb5_data *enc_track_data, krb5_data *output)
+{
     krb5_error_code retval;
     krb5_keyblock sam_key;
     krb5_enc_data tmp_enc_data;
     sam_key.contents = NULL;
 
-    if ((retval = get_securid_key(context, client,
-                                 &sam_key) ) != 0)
-       return(retval);
+    retval = get_securid_key(context, client, &sam_key);
+    if (retval != 0)
+        return retval;
 
     tmp_enc_data.ciphertext = *enc_track_data;
     tmp_enc_data.enctype = ENCTYPE_UNKNOWN;
     tmp_enc_data.kvno = 0;
 
     output->length = tmp_enc_data.ciphertext.length;
-    if (output->data)
-       free(output->data);
+    free(output->data);
     output->data = k5alloc(output->length, &retval);
-    if (retval) goto cleanup;
+    if (output->data == NULL)
+        goto cleanup;
     retval = krb5_c_decrypt(context, &sam_key,
-       KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, &tmp_enc_data, output);
- cleanup:
+                            KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0,
+                            &tmp_enc_data, output);
+cleanup:
     krb5_free_keyblock_contents(context, &sam_key);
 
     if (retval) {
-       output->length = 0;
-       if (output->data)
-         free(output->data);
-       output->data = NULL;
-       return(retval);
+        output->length = 0;
+        free(output->data);
+        output->data = NULL;
+        return retval;
     }
 
-    return(0);
+    return 0;
 }
 
 static krb5_error_code
 securid_encrypt_track_data_2(krb5_context context, krb5_db_entry *client,
-                        krb5_data *track_data, krb5_data *output) {
+                             krb5_data *track_data, krb5_data *output)
+{
     krb5_error_code retval;
     size_t olen;
     krb5_keyblock sam_key;
     krb5_enc_data tmp_enc_data;
+
     output->data = NULL;
 
-    if ((retval = get_securid_key(context,client,
-                                 &sam_key)) != 0)
-       return(retval);
+    retval = get_securid_key(context,client, &sam_key);
+    if (retval != 0)
+        return retval;
 
-    if ((retval = krb5_c_encrypt_length(context, sam_key.enctype,
-                                       track_data->length, &olen)) != 0)
-      goto cleanup;
-    assert (olen <= 65536);
+    retval = krb5_c_encrypt_length(context, sam_key.enctype,
+                                   track_data->length, &olen);
+    if (retval  != 0)
+        goto cleanup;
+    assert(olen <= 65536);
     output->length = olen;
     output->data = k5alloc(output->length, &retval);
     if (retval)
-      goto cleanup;
+        goto cleanup;
     tmp_enc_data.ciphertext = *output;
     tmp_enc_data.enctype = sam_key.enctype;
     tmp_enc_data.kvno = 0;
 
     retval = krb5_c_encrypt(context, &sam_key,
-       KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, track_data, &tmp_enc_data);
- cleanup:
+                            KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0,
+                            track_data, &tmp_enc_data);
+cleanup:
     krb5_free_keyblock_contents(context, &sam_key);
 
     if (retval) {
-       output->length = 0;
-       if (output->data)
-         krb5_xfree(output->data);
-       output->data = NULL;
-       return(retval);
+        output->length = 0;
+        free(output->data);
+        output->data = NULL;
+        return retval;
     }
-    return(0);
+    return 0;
 }
 
 
-krb5_error_code get_securid_edata_2(krb5_context context,
-                               krb5_db_entry *client,
-                               krb5_sam_challenge_2_body *sc2b,
-                               krb5_sam_challenge_2 *sc2)
+krb5_error_code
+get_securid_edata_2(krb5_context context, krb5_db_entry *client,
+                    krb5_sam_challenge_2_body *sc2b, krb5_sam_challenge_2 *sc2)
 {
-       krb5_error_code retval;
-       krb5_data scratch;
-       krb5_keyblock client_key;
-       char *user = NULL;
-       char *def_user = "<unknown user>";
-       struct securid_track_data sid_track_data;
-       krb5_data tmp_data;
-       client_key.contents = NULL;
-       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;
-
-          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);
-          if((retval = securid_encrypt_track_data_2(context, client,
-                                                   &tmp_data,
-                                                    &sc2b->sam_track_id)) != 0) {
-            krb5_set_error_message(context, retval, "While encrypting nonce track data");
-            goto cleanup;
-          }
-
-
-          scratch.data = (char *)&sc2b->sam_nonce;
-          scratch.length = sizeof(sc2b->sam_nonce);
-          retval = krb5_c_random_make_octets(context, &scratch);
-          if (retval) {
-            krb5_set_error_message(context, retval,
-               "while generating nonce data in get_securid_edata_2 (%s)",
-               user ? user : def_user);
-            goto cleanup;
-          }
-
-          /* Get the client's key */
-          if ((retval = get_securid_key(context, client, &client_key)) != 0) {
-            krb5_set_error_message(context, retval,
-               "while getting SecurID SAM key in get_securid_edata_2 (%s)",
-               user ? user : def_user);
-            goto cleanup;
-          }
-          sc2b->sam_etype = client_key.enctype;
-
-          retval = securid_make_sam_challenge_2_and_cksum(context,
-                       sc2, sc2b, &client_key);
-          if (retval) {
-             krb5_set_error_message(context, retval,
-               "while making SAM_CHALLENGE_2 checksum (%s)",
-               user ? user : def_user);
-          }
-
- cleanup:
-          krb5_free_keyblock_contents(context, &client_key);
-       if (user) krb5_xfree(user);
-       if (retval) {
-         krb5_free_data_contents(context, &sc2b->sam_track_id);
-         sc2b->sam_track_id.data = NULL;
-       }
-       return(retval);
+    krb5_error_code retval;
+    krb5_data scratch;
+    krb5_keyblock client_key;
+    char *user = NULL;
+    char *def_user = "<unknown user>";
+    struct securid_track_data sid_track_data;
+    krb5_data tmp_data;
+
+    client_key.contents = NULL;
+    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;
+
+    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);
+    if (retval != 0) {
+        krb5_set_error_message(context, retval,
+                               "While encrypting nonce track data");
+        goto cleanup;
+    }
+
+    scratch.data = (char *)&sc2b->sam_nonce;
+    scratch.length = sizeof(sc2b->sam_nonce);
+    retval = krb5_c_random_make_octets(context, &scratch);
+    if (retval) {
+        krb5_set_error_message(context, retval,
+                               "while generating nonce data in "
+                               "get_securid_edata_2 (%s)",
+                               user ? user : def_user);
+        goto cleanup;
+    }
+
+    /* Get the client's key */
+    if ((retval = get_securid_key(context, client, &client_key)) != 0) {
+        krb5_set_error_message(context, retval,
+                               "while getting SecurID SAM key in "
+                               "get_securid_edata_2 (%s)",
+                               user ? user : def_user);
+        goto cleanup;
+    }
+    sc2b->sam_etype = client_key.enctype;
+
+    retval = securid_make_sam_challenge_2_and_cksum(context,
+                                                    sc2, sc2b, &client_key);
+    if (retval) {
+        krb5_set_error_message(context, retval,
+                               "while making SAM_CHALLENGE_2 checksum (%s)",
+                               user ? user : def_user);
+    }
+
+cleanup:
+    krb5_free_keyblock_contents(context, &client_key);
+    free(user);
+    if (retval) {
+        krb5_free_data_contents(context, &sc2b->sam_track_id);
+        sc2b->sam_track_id.data = NULL;
+    }
+    return retval;
 }
 
-krb5_error_code verify_securid_data_2(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
+verify_securid_data_2(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 retval;
     int new_pin = 0;
@@ -321,354 +355,386 @@ krb5_error_code verify_securid_data_2(krb5_context context,
     memset(&scratch, 0, sizeof(scratch));
     *sc2_out = NULL;
 
-    if ((retval = krb5_unparse_name(context, client->princ, &user)) !=0 ) {
-       krb5_set_error_message(context, retval,
-               "while unparsing client name in verify_securid_data_2");
-       return(retval);
+    retval = krb5_unparse_name(context, client->princ, &user);
+    if (retval != 0) {
+        krb5_set_error_message(context, retval,
+                               "while unparsing client name in "
+                               "verify_securid_data_2");
+        return retval;
     }
 
     if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) ||
-       (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) {
-         retval = KRB5KDC_ERR_PREAUTH_FAILED;
-         krb5_set_error_message(context, retval,
-               "No preauth data supplied in verify_securid_data_2 (%s)", user);
-         goto cleanup;
+        (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) {
+          retval = KRB5KDC_ERR_PREAUTH_FAILED;
+          krb5_set_error_message(context, retval,
+                                 "No preauth data supplied in "
+                                 "verify_securid_data_2 (%s)", user);
+          goto cleanup;
     }
 
     retval = 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);
+                                   sr2->sam_enc_nonce_or_sad.enctype,
+                                   KRB5_KDB_SALTTYPE_NORMAL,
+                                   sr2->sam_enc_nonce_or_sad.kvno,
+                                   &client_key_data);
     if (retval) {
-       krb5_set_error_message(context, retval,
-               "while getting client key in verify_securid_data_2 (%s)", user);
-       goto cleanup;
+        krb5_set_error_message(context, retval,
+                               "while getting client key in "
+                               "verify_securid_data_2 (%s)", user);
+        goto cleanup;
     }
 
-    if ((retval = krb5_dbe_decrypt_key_data(context, NULL,
-                                             client_key_data, &client_key, NULL)) != 0) {
-       krb5_set_error_message(context, retval,
-               "while decrypting client key in verify_securid_data_2 (%s)",
-               user);
-       goto cleanup;
+    retval = krb5_dbe_decrypt_key_data(context, NULL, client_key_data,
+                                       &client_key, NULL);
+    if (retval != 0) {
+        krb5_set_error_message(context, retval,
+                               "while decrypting client key in "
+                               "verify_securid_data_2 (%s)",
+                               user);
+        goto cleanup;
     }
 
     scratch.length = sr2->sam_enc_nonce_or_sad.ciphertext.length;
     scratch.data = k5alloc(scratch.length, &retval);
     if (retval)
-      goto cleanup;
+        goto cleanup;
     retval = krb5_c_decrypt(context, &client_key,
-               KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0,
-               &sr2->sam_enc_nonce_or_sad, &scratch);
+                            KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0,
+                            &sr2->sam_enc_nonce_or_sad, &scratch);
     if (retval) {
-       krb5_set_error_message(context, retval,
-               "while decrypting SAD in verify_securid_data_2 (%s)", user);
-       goto cleanup;
+        krb5_set_error_message(context, retval,
+                               "while decrypting SAD in "
+                               "verify_securid_data_2 (%s)", user);
+        goto cleanup;
     }
 
     retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2);
     if (retval) {
-       krb5_set_error_message(context, retval,
-               "while decoding SAD in verify_securid_data_2 (%s)", user);
-       esre2 = NULL;
-       goto cleanup;
+        krb5_set_error_message(context, retval,
+                               "while decoding SAD in "
+                               "verify_securid_data_2 (%s)", user);
+        esre2 = NULL;
+        goto cleanup;
     }
 
     if (sr2->sam_nonce != esre2->sam_nonce) {
-       krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
-               "while checking nonce in verify_securid_data_2 (%s)", user);
-       retval = KRB5KDC_ERR_PREAUTH_FAILED;
-       goto cleanup;
+        krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                               "while checking nonce in "
+                               "verify_securid_data_2 (%s)", user);
+        retval = KRB5KDC_ERR_PREAUTH_FAILED;
+        goto cleanup;
     }
 
-    if ((esre2->sam_sad.length == 0) || (esre2->sam_sad.data == NULL)) {
-       krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
-               "No SecurID passcode in verify_securid_data_2 (%s)", user);
-       retval = KRB5KDC_ERR_PREAUTH_FAILED;
-       goto cleanup;
+    if (esre2->sam_sad.length == 0 || esre2->sam_sad.data == NULL) {
+        krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                               "No SecurID passcode in "
+                               "verify_securid_data_2 (%s)", user);
+        retval = KRB5KDC_ERR_PREAUTH_FAILED;
+        goto cleanup;
     }
 
     /* Copy out SAD to null-terminated buffer */
     memset(passcode, 0, sizeof(passcode));
     if (esre2->sam_sad.length > (sizeof(passcode) - 1)) {
-       retval = KRB5KDC_ERR_PREAUTH_FAILED;
-       krb5_set_error_message(context, retval,
-               "SecurID passcode/PIN too long (%d bytes) in verify_securid_data_2 (%s)",
-               esre2->sam_sad.length, user);
-       goto cleanup;
+        retval = KRB5KDC_ERR_PREAUTH_FAILED;
+        krb5_set_error_message(context, retval,
+                               "SecurID passcode/PIN too long (%d bytes) in "
+                               "verify_securid_data_2 (%s)",
+                               esre2->sam_sad.length, user);
+        goto cleanup;
     }
     memcpy(passcode, esre2->sam_sad.data, esre2->sam_sad.length);
 
     securid_user = strdup(user);
     if (!securid_user) {
-      retval = ENOMEM;
-       krb5_set_error_message(context, ENOMEM,
-               "while copying user name in verify_securid_data_2 (%s)", user);
-       goto cleanup;
+        retval = ENOMEM;
+        krb5_set_error_message(context, ENOMEM,
+                               "while copying user name in "
+                               "verify_securid_data_2 (%s)", user);
+        goto cleanup;
     }
-    if ((cp = strchr(securid_user, '@')))
-       *cp = (char)0;
+    cp = strchr(securid_user, '@');
+    if (cp != NULL)
+        *cp = '\0';
 
-    /* Check for any track_id data that may have state from a previous */
-    /* attempt at SecurID authentication                               */
+    /* Check for any track_id data that may have state from a previous attempt
+     * at SecurID authentication. */
 
     if (sr2->sam_track_id.data && (sr2->sam_track_id.length > 0)) {
-       krb5_data track_id_data;
-       memset(&track_id_data, 0, sizeof(track_id_data));
-       retval = securid_decrypt_track_data_2(context, client,
-                       &sr2->sam_track_id, &track_id_data);
-       if (retval) {
-          krb5_set_error_message(context, retval,
-             "while decrypting SecurID trackID in verify_securid_data_2 (%s)",
-                       user);
-          goto cleanup;
-       }
-       if (track_id_data.length <= sizeof (struct securid_track_data)) {
-         retval = KRB5KDC_ERR_PREAUTH_FAILED;
-         krb5_set_error_message(context, retval, "Length of track data incorrect");
-         goto cleanup;
-       }
-       trackp = (struct securid_track_data *)track_id_data.data;
-
-       if(trackp->hostid != gethostid()) {
-         krb5_klog_syslog(LOG_INFO, "Unexpected challenge response");
-         retval = KRB5KDC_ERR_DISCARD;
-         goto cleanup;
-       }
-
-       switch(trackp->state) {
-         case SECURID_STATE_INITIAL:
-           goto initial;
-           break;
-         case SECURID_STATE_NEW_PIN_AGAIN:
-               {
-                 int pin1_len, pin2_len;
-
-                 trackp->handle = ntohl(trackp->handle);
-                 pin2_len = strlen(passcode);
-                 pin1_len = strlen(trackp->passcode);
-
-                 if ((pin1_len != pin2_len) ||
-                       (memcmp(passcode, trackp->passcode, pin1_len) != 0)) {
-                    retval = KRB5KDC_ERR_PREAUTH_FAILED;
-                    krb5_klog_syslog(LOG_INFO,
-                       "New SecurID PIN Failed for user %s: PIN mis-match",
-                       user);
-                    break;
-                 }
-                 retval = SD_Pin(trackp->handle, passcode);
-                 SD_Close(trackp->handle);
-                 if (retval == ACM_NEW_PIN_ACCEPTED) {
-                   enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
-                   enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
-                    krb5_klog_syslog(LOG_INFO,
-                       "SecurID PIN Accepted for %s in verify_securid_data_2",
-                       securid_user);
-                    retval = 0;
-                 } else {
-                    retval = KRB5KDC_ERR_PREAUTH_FAILED;
-                    krb5_klog_syslog(LOG_INFO,
-                       "SecurID PIN Failed for user %s (AceServer returns %d) in verify_securid_data_2",
-                        user, retval);
-                 }
-                 break;
-               }
-         case SECURID_STATE_NEW_PIN: {
-           krb5_sam_challenge_2_body sc2b;
-           sc2p = k5alloc(sizeof *sc2p, &retval);
-           if (retval)
-             goto cleanup;
-           memset(sc2p, 0, sizeof(*sc2p));
-               memset(&sc2b, 0, sizeof(sc2b));
-               sc2b.sam_type = PA_SAM_TYPE_SECURID;
-               sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message;
-               sc2b.sam_response_prompt.length =
-                               strlen(sc2b.sam_response_prompt.data);
-               sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
-               sc2b.sam_etype = client_key.enctype;
-
-               tmp_data.data = (char *)&sc2b.sam_nonce;
-               tmp_data.length = sizeof(sc2b.sam_nonce);
-               if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
-                 krb5_set_error_message(context, retval,
-                       "while making nonce for SecurID new PIN2 SAM_CHALLENGE_2 (%s)", user);
-                 goto cleanup;
-               }
-               sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN;
-               sid_track_data.handle = trackp->handle;
-               sid_track_data.hostid = gethostid();
-               /* Should we complain if sizes don't work ??  */
-               memcpy(sid_track_data.passcode, passcode,
-                       sizeof(sid_track_data.passcode));
-               tmp_data.data = (char *)&sid_track_data;
-               tmp_data.length = sizeof(sid_track_data);
-               if ((retval = securid_encrypt_track_data_2(context, client,
-                                                          &tmp_data, &sc2b.sam_track_id))) {
-                  krb5_set_error_message(context, retval,
-                       "while encrypting NEW PIN2 SecurID track data for SAM_CHALLENGE_2 (%s)",
-                       securid_user);
-                  goto cleanup;
-               }
-               retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
-                       &sc2b, &client_key);
-               if (retval) {
-                  krb5_set_error_message(context, retval,
-                     "while making cksum for SAM_CHALLENGE_2 (new PIN2) (%s)",
-                     securid_user);
-                  goto cleanup;
-               }
-               krb5_klog_syslog(LOG_INFO,
-                  "Requesting verification of new PIN for user %s",
-                  securid_user);
-               *sc2_out = sc2p;
-               sc2p = NULL;
-               /*sc2_out may be set even on error path*/
-               retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
-               goto cleanup;
-         }
-         case SECURID_STATE_NEXT_CODE:
-               trackp->handle = ntohl(trackp->handle);
-               retval = SD_Next(trackp->handle, passcode);
-               SD_Close(trackp->handle);
-               if (retval == ACM_OK) {
-                 enc_tkt_reply->flags |=  TKT_FLG_HW_AUTH
-                   | TKT_FLG_PRE_AUTH;
-
-                  krb5_klog_syslog(LOG_INFO,
-                       "Next SecurID Code Accepted for user %s", securid_user);
-                  retval = 0;
-               } else {
-                  krb5_klog_syslog(LOG_INFO,
-                       "Next SecurID Code Failed for user %s (AceServer returns %d) in verify_securid_data_2",
-                       user, retval);
-                  retval = KRB5KDC_ERR_PREAUTH_FAILED;
-               }
-               break;
-       }
-    } else {           /* No track data, this is first of N attempts */
-initial:
-      if ((retval = SD_Init(&sd_handle))) {
-          krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
-               "SD_Init() returns error %d in verify_securid_data_2 (%s)",
-                       retval, securid_user);
-          retval = KRB5KDC_ERR_PREAUTH_FAILED;
-          goto cleanup;
-       }
-
-       if((retval = SD_Lock(sd_handle, securid_user)) != ACM_OK) {
-         SD_Close(sd_handle);
-         retval = KRB5KDC_ERR_PREAUTH_FAILED;
-         krb5_klog_syslog(LOG_INFO,
-               "SD_Lock() failed (AceServer returns %d) for %s",
-               retval, securid_user);
-         goto cleanup;
-       }
-
-       retval = SD_Check(sd_handle, passcode, securid_user);
-       switch (retval) {
-          case ACM_OK:
-               SD_Close(sd_handle);
-                   enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
-                   enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
-                   krb5_klog_syslog(LOG_INFO,
-                  "SecurID passcode accepted for user %s", user);
-               retval = 0;
-               break;
-          case ACM_ACCESS_DENIED:
-               SD_Close(sd_handle);
-               retval = KRB5KDC_ERR_PREAUTH_FAILED;
-               krb5_klog_syslog(LOG_INFO,
-                  "AceServer returns Access Denied for user %s (SAM2)",user);
-               goto cleanup;
-          case ACM_NEW_PIN_REQUIRED:
-            new_pin = 1;
-            /*fall through*/
-          case ACM_NEXT_CODE_REQUIRED: {
-               krb5_sam_challenge_2_body sc2b;
-               sc2p = k5alloc(sizeof *sc2p, &retval);
-               if (retval)
-                 goto cleanup;
-
-               memset(sc2p, 0, sizeof(*sc2p));
-               memset(&sc2b, 0, sizeof(sc2b));
-
-               sc2b.sam_type = PA_SAM_TYPE_SECURID;
-               sc2b.sam_response_prompt.data = NEXT_PASSCODE_message;
-               sc2b.sam_response_prompt.length =
-                               strlen(sc2b.sam_response_prompt.data);
-               sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
-               sc2b.sam_etype = client_key.enctype;
-               if (new_pin) {
-                 if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS)
-                     && (AceGetMinPinLen(sd_handle, &min_pin_len) == ACE_SUCCESS)
-                     && (AceGetAlphanumeric(sd_handle, &alpha_pin) == ACE_SUCCESS))
-                   {
-                     sprintf(PIN_message,
-                             "New PIN must contain %d to %d %sdigits",
-                             min_pin_len, max_pin_len,
-                             (alpha_pin == 0) ? "" : "alphanumeric ");
-                     sc2b.sam_challenge_label.data = PIN_message;
-                     sc2b.sam_challenge_label.length =
-                       strlen(sc2b.sam_challenge_label.data);
-                   } else {
-                   sc2b.sam_challenge_label.length = 0;
-                 }
-               }
-
-               tmp_data.data = (char *)&sc2b.sam_nonce;
-               tmp_data.length = sizeof(sc2b.sam_nonce);
-               if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
-                  krb5_set_error_message(context, retval,
-                       "while making nonce for SecurID  SAM_CHALLENGE_2 (%s)", user);
-                  goto cleanup;
-               }
-               if (new_pin)
-                               sid_track_data.state = SECURID_STATE_NEW_PIN;
-               else            sid_track_data.state = SECURID_STATE_NEXT_CODE;
-               sid_track_data.handle = htonl(sd_handle);
-               sid_track_data.hostid = gethostid();
-               tmp_data.data = (char *)&sid_track_data;
-               tmp_data.length = sizeof(sid_track_data);
-               if ((retval = securid_encrypt_track_data_2(context, client,
-                                                          &tmp_data, &sc2b.sam_track_id))) {
-                  krb5_set_error_message(context, retval,
-                       "while encrypting SecurID track data for SAM_CHALLENGE_2 (%s)",
-                       securid_user);
-                  goto cleanup;
-               }
-               retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
-                       &sc2b, &client_key);
-               if (retval) {
-                  krb5_set_error_message(context, retval,
-                     "while making cksum for SAM_CHALLENGE_2 (%s)",
-                     securid_user);
-               }
-               if (new_pin)
-                               krb5_klog_syslog(LOG_INFO,
-                  "New SecurID PIN required for user %s", securid_user);
-               else            krb5_klog_syslog(LOG_INFO,
-                  "Next SecurID passcode required for user %s", securid_user);
-               *sc2_out = sc2p;
-               sc2p = NULL;
-               retval = KRB5KDC_ERR_PREAUTH_FAILED;
-               /*sc2_out is permitted as an output on error path*/
-               goto cleanup;
-          }
-          default:
-               krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
-                       "AceServer returns unknown error code %d in verify_securid_data_2\n", retval);
-               retval = KRB5KDC_ERR_PREAUTH_FAILED;
-               goto cleanup;
-       }
-    }  /* no track_id data */
+        krb5_data track_id_data;
+
+        memset(&track_id_data, 0, sizeof(track_id_data));
+        retval = securid_decrypt_track_data_2(context, client,
+                                              &sr2->sam_track_id,
+                                              &track_id_data);
+        if (retval) {
+            krb5_set_error_message(context, retval,
+                                   "while decrypting SecurID trackID in "
+                                   "verify_securid_data_2 (%s)", user);
+           goto cleanup;
+        }
+        if (track_id_data.length <= sizeof (struct securid_track_data)) {
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_set_error_message(context, retval,
+                                   "Length of track data incorrect");
+            goto cleanup;
+        }
+        trackp = (struct securid_track_data *)track_id_data.data;
+
+        if(trackp->hostid != gethostid()) {
+            krb5_klog_syslog(LOG_INFO, "Unexpected challenge response");
+            retval = KRB5KDC_ERR_DISCARD;
+            goto cleanup;
+        }
+
+        switch(trackp->state) {
+        case SECURID_STATE_INITIAL:
+            goto initial;
+            break;
+        case SECURID_STATE_NEW_PIN_AGAIN:
+        {
+            int pin1_len, pin2_len;
+
+            trackp->handle = ntohl(trackp->handle);
+            pin2_len = strlen(passcode);
+            pin1_len = strlen(trackp->passcode);
+
+            if ((pin1_len != pin2_len) ||
+                (memcmp(passcode, trackp->passcode, pin1_len) != 0)) {
+                retval = KRB5KDC_ERR_PREAUTH_FAILED;
+                krb5_klog_syslog(LOG_INFO, "New SecurID PIN Failed for user "
+                                 "%s: PIN mis-match", user);
+                break;
+            }
+            retval = SD_Pin(trackp->handle, passcode);
+            SD_Close(trackp->handle);
+            if (retval == ACM_NEW_PIN_ACCEPTED) {
+                enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
+                enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
+                krb5_klog_syslog(LOG_INFO, "SecurID PIN Accepted for %s in "
+                                 "verify_securid_data_2",
+                                 securid_user);
+                retval = 0;
+            } else {
+                retval = KRB5KDC_ERR_PREAUTH_FAILED;
+                krb5_klog_syslog(LOG_INFO,
+                                 "SecurID PIN Failed for user %s (AceServer "
+                                 "returns %d) in verify_securid_data_2",
+                                 user, retval);
+            }
+            break;
+        }
+        case SECURID_STATE_NEW_PIN: {
+            krb5_sam_challenge_2_body sc2b;
+            sc2p = k5alloc(sizeof *sc2p, &retval);
+            if (retval)
+                goto cleanup;
+            memset(sc2p, 0, sizeof(*sc2p));
+            memset(&sc2b, 0, sizeof(sc2b));
+            sc2b.sam_type = PA_SAM_TYPE_SECURID;
+            sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message;
+            sc2b.sam_response_prompt.length =
+                strlen(sc2b.sam_response_prompt.data);
+            sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+            sc2b.sam_etype = client_key.enctype;
+
+            tmp_data.data = (char *)&sc2b.sam_nonce;
+            tmp_data.length = sizeof(sc2b.sam_nonce);
+            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
+                krb5_set_error_message(context, retval,
+                                       "while making nonce for SecurID new "
+                                       "PIN2 SAM_CHALLENGE_2 (%s)", user);
+                goto cleanup;
+            }
+            sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN;
+            sid_track_data.handle = trackp->handle;
+            sid_track_data.hostid = gethostid();
+            /* Should we complain if sizes don't work ??  */
+            memcpy(sid_track_data.passcode, passcode,
+                   sizeof(sid_track_data.passcode));
+            tmp_data.data = (char *)&sid_track_data;
+            tmp_data.length = sizeof(sid_track_data);
+            if ((retval = securid_encrypt_track_data_2(context, client,
+                                                       &tmp_data,
+                                                       &sc2b.sam_track_id))) {
+                krb5_set_error_message(context, retval,
+                                       "while encrypting NEW PIN2 SecurID "
+                                       "track data for SAM_CHALLENGE_2 (%s)",
+                                       securid_user);
+                goto cleanup;
+            }
+            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
+                                                            &sc2b,
+                                                            &client_key);
+            if (retval) {
+                krb5_set_error_message(context, retval,
+                                       "while making cksum for "
+                                       "SAM_CHALLENGE_2 (new PIN2) (%s)",
+                                       securid_user);
+                goto cleanup;
+            }
+            krb5_klog_syslog(LOG_INFO,
+                             "Requesting verification of new PIN for user %s",
+                             securid_user);
+            *sc2_out = sc2p;
+            sc2p = NULL;
+            /*sc2_out may be set even on error path*/
+            retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
+            goto cleanup;
+        }
+        case SECURID_STATE_NEXT_CODE:
+            trackp->handle = ntohl(trackp->handle);
+            retval = SD_Next(trackp->handle, passcode);
+            SD_Close(trackp->handle);
+            if (retval == ACM_OK) {
+                enc_tkt_reply->flags |=  TKT_FLG_HW_AUTH | TKT_FLG_PRE_AUTH;
+
+                krb5_klog_syslog(LOG_INFO, "Next SecurID Code Accepted for "
+                                 "user %s", securid_user);
+                retval = 0;
+            } else {
+                krb5_klog_syslog(LOG_INFO, "Next SecurID Code Failed for user "
+                                 "%s (AceServer returns %d) in "
+                                 "verify_securid_data_2", user, retval);
+                retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            }
+            break;
+        }
+    } else {            /* No track data, this is first of N attempts */
+    initial:
+        retval = SD_Init(&sd_handle);
+        if (retval) {
+            krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                                   "SD_Init() returns error %d in "
+                                   "verify_securid_data_2 (%s)",
+                                   retval, securid_user);
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            goto cleanup;
+        }
+
+        retval = SD_Lock(sd_handle, securid_user);
+        if (retval != ACM_OK) {
+            SD_Close(sd_handle);
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_klog_syslog(LOG_INFO,
+                             "SD_Lock() failed (AceServer returns %d) for %s",
+                             retval, securid_user);
+            goto cleanup;
+        }
+
+        retval = SD_Check(sd_handle, passcode, securid_user);
+        switch (retval) {
+        case ACM_OK:
+            SD_Close(sd_handle);
+            enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
+            enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
+            krb5_klog_syslog(LOG_INFO, "SecurID passcode accepted for user %s",
+                             user);
+            retval = 0;
+            break;
+        case ACM_ACCESS_DENIED:
+            SD_Close(sd_handle);
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_klog_syslog(LOG_INFO, "AceServer returns Access Denied for "
+                             "user %s (SAM2)", user);
+            goto cleanup;
+        case ACM_NEW_PIN_REQUIRED:
+            new_pin = 1;
+            /*fall through*/
+        case ACM_NEXT_CODE_REQUIRED: {
+            krb5_sam_challenge_2_body sc2b;
+            sc2p = k5alloc(sizeof *sc2p, &retval);
+            if (retval)
+                goto cleanup;
+
+            memset(sc2p, 0, sizeof(*sc2p));
+            memset(&sc2b, 0, sizeof(sc2b));
+
+            sc2b.sam_type = PA_SAM_TYPE_SECURID;
+            sc2b.sam_response_prompt.data = NEXT_PASSCODE_message;
+            sc2b.sam_response_prompt.length =
+                strlen(sc2b.sam_response_prompt.data);
+            sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+            sc2b.sam_etype = client_key.enctype;
+            if (new_pin) {
+                if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS)
+                    && (AceGetMinPinLen(sd_handle,
+                                        &min_pin_len) == ACE_SUCCESS)
+                    && (AceGetAlphanumeric(sd_handle,
+                                           &alpha_pin) == ACE_SUCCESS)) {
+                    sprintf(PIN_message,
+                            "New PIN must contain %d to %d %sdigits",
+                            min_pin_len, max_pin_len,
+                            (alpha_pin == 0) ? "" : "alphanumeric ");
+                    sc2b.sam_challenge_label.data = PIN_message;
+                    sc2b.sam_challenge_label.length =
+                        strlen(sc2b.sam_challenge_label.data);
+                } else {
+                    sc2b.sam_challenge_label.length = 0;
+                }
+            }
+
+            tmp_data.data = (char *)&sc2b.sam_nonce;
+            tmp_data.length = sizeof(sc2b.sam_nonce);
+            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
+                krb5_set_error_message(context, retval, "while making nonce "
+                                       "for SecurID SAM_CHALLENGE_2 (%s)",
+                                       user);
+                goto cleanup;
+            }
+            if (new_pin)
+                sid_track_data.state = SECURID_STATE_NEW_PIN;
+            else
+                sid_track_data.state = SECURID_STATE_NEXT_CODE;
+            sid_track_data.handle = htonl(sd_handle);
+            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);
+            if (retval) {
+                   krb5_set_error_message(context, retval,
+                                          "while encrypting SecurID track "
+                                          "data for SAM_CHALLENGE_2 (%s)",
+                                          securid_user);
+                   goto cleanup;
+            }
+            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
+                                                            &sc2b,
+                                                            &client_key);
+            if (retval) {
+                krb5_set_error_message(context, retval, "while making cksum "
+                                       "for SAM_CHALLENGE_2 (%s)",
+                                       securid_user);
+            }
+            if (new_pin)
+                krb5_klog_syslog(LOG_INFO, "New SecurID PIN required for "
+                                 "user %s", securid_user);
+            else
+                krb5_klog_syslog(LOG_INFO, "Next SecurID passcode required "
+                                 "for user %s", securid_user);
+            *sc2_out = sc2p;
+            sc2p = NULL;
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            /*sc2_out is permitted as an output on error path*/
+            goto cleanup;
+        }
+        default:
+            krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                                   "AceServer returns unknown error code %d "
+                                   "in verify_securid_data_2\n", retval);
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            goto cleanup;
+        }
+    }   /* no track_id data */
 
 cleanup:
-    if (client_key.contents) krb5_free_keyblock_contents(context, &client_key);
-    if (scratch.data) krb5_xfree(scratch.data);
-    if (esre2) krb5_free_enc_sam_response_enc_2(context, esre2);
-    if (user) krb5_xfree(user);
-    if (securid_user) krb5_xfree(securid_user);
-    if (trackp) krb5_xfree(trackp);
-    if (sc2p)
-      krb5_free_sam_challenge_2(context, sc2p);
-    return(retval);
+    krb5_free_keyblock_contents(context, &client_key);
+    free(scratch.data);
+    krb5_free_enc_sam_response_enc_2(context, esre2);
+    free(user);
+    free(securid_user);
+    free(trackp);
+    krb5_free_sam_challenge_2(context, sc2p);
+    return retval;
 }
index f61414d5467aa3a47b9d6bac9a82d425c983aa11..695934cc47638f6e5cda013925e6c94b2c62221c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 /*
- * plugins/preauth/encrypted_challenge/encrypted_challenge.c
+ * plugins/preauth/securid_sam2/securid_sam2_main.c
  *
  * Copyright (C) 2009, 2010 by the Massachusetts Institute of Technology.
  * All rights reserved.
 #include <kdb.h>
 #include "extern.h"
 
-
 static struct {
-  char* name;
-  int   sam_type;
+    char* name;
+    int   sam_type;
 } *sam_ptr, sam_inst_map[] = {
-  { "SECURID", PA_SAM_TYPE_SECURID, },
-  { "GRAIL", PA_SAM_TYPE_GRAIL, },
-  { 0, 0 },
+    { "SECURID", PA_SAM_TYPE_SECURID, },
+    { "GRAIL", PA_SAM_TYPE_GRAIL, },
+    { 0, 0 },
 };
 
- krb5_error_code sam_get_db_entry(
-    krb5_context context,
-                       krb5_principal client,
-                       int *sam_type,
-                       struct _krb5_db_entry_new **db_entry)
+krb5_error_code
+sam_get_db_entry(krb5_context context, krb5_principal client,
+                 int *sam_type, struct _krb5_db_entry_new **db_entry)
 {
     struct _krb5_db_entry_new *assoc = NULL;
-   krb5_principal newp = NULL;
-   int probeslot;
-   void *ptr = NULL;
-   krb5_error_code retval;
-   if (db_entry)
+    krb5_principal newp = NULL;
+    int probeslot;
+    void *ptr = NULL;
+    krb5_error_code retval;
+
+    if (db_entry)
        *db_entry = NULL;
-   retval = krb5_copy_principal(context, client, &newp);
-   if (retval) {
-       krb5_set_error_message(context, retval, "copying client name for preauth probe");
-       return retval;
-   }
+    retval = krb5_copy_principal(context, client, &newp);
+    if (retval) {
+        krb5_set_error_message(context, retval,
+                               "copying client name for preauth probe");
+        return retval;
+    }
 
-   probeslot = krb5_princ_size(context, newp)++;
-   ptr =
-       realloc(krb5_princ_name(context, newp),
-               krb5_princ_size(context, newp) * sizeof(krb5_data));
+    probeslot = krb5_princ_size(context, newp)++;
+    ptr = realloc(krb5_princ_name(context, newp),
+                  krb5_princ_size(context, newp) * sizeof(krb5_data));
    if (ptr == NULL) {
        retval = ENOMEM;
        goto cleanup;
-   } else krb5_princ_name(context, newp) = ptr;
+   }
+   krb5_princ_name(context, newp) = ptr;
 
    for(sam_ptr = sam_inst_map; sam_ptr->name; sam_ptr++) {
-       if (*sam_type && (*sam_type != sam_ptr->sam_type)) continue;
+       if (*sam_type && *sam_type != sam_ptr->sam_type)
+           continue;
 
-       krb5_princ_component(context,newp,probeslot)->data = sam_ptr->name;
-       krb5_princ_component(context,newp,probeslot)->length =
-       strlen(sam_ptr->name);
-       retval = krb5_db_get_principal(context, newp, 0, &assoc);
-       if(!retval )
-          break;
-       }
+       krb5_princ_component(context,newp,probeslot)->data = sam_ptr->name;
+       krb5_princ_component(context,newp,probeslot)->length =
+           strlen(sam_ptr->name);
+       retval = krb5_db_get_principal(context, newp, 0, &assoc);
+       if (!retval)
+           break;
+   }
 cleanup:
    if (ptr) {
        krb5_princ_component(context,newp,probeslot)->data = 0;
@@ -101,13 +101,16 @@ cleanup:
    if (retval)
        return retval;
    if (sam_ptr->sam_type)  {
-       /* Found entry of type sam_ptr->sam_type */
-       if (sam_type) *sam_type = sam_ptr->sam_type;
-       if (db_entry) *db_entry = assoc;
-        else krb5_db_free_principal( context, assoc);
-       return(0);
+       /* Found entry of type sam_ptr->sam_type */
+       if (sam_type)
+           *sam_type = sam_ptr->sam_type;
+       if (db_entry)
+           *db_entry = assoc;
+       else
+           krb5_db_free_principal(context, assoc);
+       return 0;
    } else {
-       return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+       return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
    }
 }
 
@@ -118,62 +121,67 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request,
                    preauth_get_entry_data_proc get_entry_proc,
                    void *pa_module_context, krb5_pa_data *pa_data)
 {
-  krb5_error_code retval;
-  krb5_sam_challenge_2 sc2;
-  krb5_sam_challenge_2_body sc2b;
-  int sam_type = 0;            /* unknown */
-  krb5_db_entry *sam_db_entry = NULL;
-  krb5_data *encoded_challenge = NULL;
-  memset(&sc2, 0, sizeof(sc2));
-  memset(&sc2b, 0, sizeof(sc2b));
-  sc2b.magic = KV5M_SAM_CHALLENGE_2;
-  sc2b.sam_type = sam_type;
+    krb5_error_code retval;
+    krb5_sam_challenge_2 sc2;
+    krb5_sam_challenge_2_body sc2b;
+    int sam_type = 0;             /* unknown */
+    krb5_db_entry *sam_db_entry = NULL;
+    krb5_data *encoded_challenge = NULL;
 
-  retval = sam_get_db_entry(context, client->princ, &sam_type,
-                       &sam_db_entry);
-  if (retval) return (retval);
+    memset(&sc2, 0, sizeof(sc2));
+    memset(&sc2b, 0, sizeof(sc2b));
+    sc2b.magic = KV5M_SAM_CHALLENGE_2;
+    sc2b.sam_type = sam_type;
 
-  if (sam_type == 0) {
-     retval = KRB5_PREAUTH_BAD_TYPE;
-     goto cleanup;
-  }
+    retval = sam_get_db_entry(context, client->princ, &sam_type,
+                              &sam_db_entry);
+    if (retval)
+        return retval;
 
-  /* Defer getting the key for the SAM principal associated with the   */
-  /* client until the mechanism-specific code.  The mechanism may want */
-  /* to get a specific keytype                                         */
+    if (sam_type == 0) {
+        retval = KRB5_PREAUTH_BAD_TYPE;
+        goto cleanup;
+    }
 
+    /*
+     * Defer getting the key for the SAM principal associated with the client
+     * until the mechanism-specific code.  The mechanism may want to get a
+     * specific keytype.
+     */
 
-  switch (sam_type) {
+    switch (sam_type) {
 #ifdef ARL_SECURID_PREAUTH
-     case PA_SAM_TYPE_SECURID:
-         if ((retval = get_securid_edata_2(context, client, &sc2b, &sc2)))
-          goto cleanup;
+    case PA_SAM_TYPE_SECURID:
+        retval = get_securid_edata_2(context, client, &sc2b, &sc2);
+        if (retval)
+            goto cleanup;
 
-       retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge);
-       if (retval) {
-          krb5_set_error_message(context, retval,"while encoding SECURID SAM_CHALLENGE_2");
-           goto cleanup;
-       }
+        retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge);
+        if (retval) {
+            krb5_set_error_message(context, retval,
+                                   "while encoding SECURID SAM_CHALLENGE_2");
+            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;
+        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;
+        retval = 0;
+        break;
 #endif  /* ARL_SECURID_PREAUTH */
-     default:
-       retval = KRB5_PREAUTH_BAD_TYPE;
-       goto cleanup;
-  }
+    default:
+        retval = KRB5_PREAUTH_BAD_TYPE;
+        goto cleanup;
+    }
 
 cleanup:
-      krb5_free_data( context, encoded_challenge);
-  if (sam_db_entry)
-       krb5_db_free_principal(context, sam_db_entry);
-  return (retval);
+    krb5_free_data(context, encoded_challenge);
+    if (sam_db_entry)
+        krb5_db_free_principal(context, sam_db_entry);
+    return retval;
 }
 
 static krb5_error_code
@@ -185,70 +193,70 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
                    krb5_data **e_data, krb5_authdata ***authz_data)
 {
     krb5_error_code retval;
-  krb5_sam_response_2 *sr2 = NULL;
-  krb5_data scratch, *scratch2;
+    krb5_sam_response_2 *sr2 = NULL;
+    krb5_data scratch, *scratch2;
     char *client_name = NULL;
     krb5_sam_challenge_2 *out_sc2 = NULL;
 
-  scratch.data = (char *) pa_data->contents;
-  scratch.length = pa_data->length;
+    scratch.data = (char *) pa_data->contents;
+    scratch.length = pa_data->length;
 
-  retval = krb5_unparse_name(context, client->princ, &client_name);
-  if (retval)
-     goto cleanup;
+    retval = krb5_unparse_name(context, client->princ, &client_name);
+    if (retval)
+        goto cleanup;
 
-  retval = decode_krb5_sam_response_2(&scratch, &sr2);
-  if (retval) {
-      krb5_set_error_message(context,  retval,
-               "while decoding SAM_RESPONSE_2 in verify_sam_response_2");
-     sr2 = NULL;
-     goto cleanup;
-  }
+    retval = decode_krb5_sam_response_2(&scratch, &sr2);
+    if (retval) {
+        krb5_set_error_message(context,  retval, "while decoding "
+                               "SAM_RESPONSE_2 in verify_sam_response_2");
+        sr2 = NULL;
+        goto cleanup;
+    }
 
-  switch (sr2->sam_type) {
+    switch (sr2->sam_type) {
 #ifdef ARL_SECURID_PREAUTH
-       case PA_SAM_TYPE_SECURID:
-         retval = verify_securid_data_2(context, client, sr2,
-                                         enc_tkt_reply, pa_data, &out_sc2);
-         if (retval) goto cleanup;
-         break;
+    case PA_SAM_TYPE_SECURID:
+        retval = verify_securid_data_2(context, client, sr2, enc_tkt_reply,
+                                       pa_data, &out_sc2);
+        if (retval)
+            goto cleanup;
+        break;
 #endif  /* ARL_SECURID_PREAUTH */
-       default:
-         retval = KRB5_PREAUTH_BAD_TYPE;
-         krb5_set_error_message(context , retval, "while verifying SAM 2 data");
-         break;
-  }
+    default:
+        retval = KRB5_PREAUTH_BAD_TYPE;
+        krb5_set_error_message(context, retval, "while verifying SAM 2 data");
+        break;
+    }
 
-  /* It is up to the method-specific verify routine to set the ticket flags */
-  /* to indicate TKT_FLG_HW_AUTH and/or TKT_FLG_PRE_AUTH.  Some methods     */
-  /* may require more than one round of dialog with the client and must     */
-  /* return successfully from their verify routine.  If does not set the    */
-  /* TGT flags, the required_preauth conditions will not be met and it will */
-  /* try again to get enough preauth data from the client.  Do not set TGT  */
-  /* flags here.                                                            */
+  /*
+   * It is up to the method-specific verify routine to set the ticket flags to
+   * indicate TKT_FLG_HW_AUTH and/or TKT_FLG_PRE_AUTH.  Some methods may
+   * require more than one round of dialog with the client and must return
+   * successfully from their verify routine.  If does not set the TGT flags,
+   * the required_preauth conditions will not be met and it will try again to
+   * get enough preauth data from the client.  Do not set TGT flags here.
+   */
 cleanup:
-  /*Note that e_data is an output even in error conditions.*/
-  if (out_sc2) {
-      krb5_pa_data pa_out;
-      krb5_pa_data *pa_array[2];
-      pa_array[0] = &pa_out;
-      pa_array[1] = NULL;
-      pa_out.pa_type = KRB5_PADATA_SAM_CHALLENGE_2;
-      retval = encode_krb5_sam_challenge_2(out_sc2, &scratch2);
-      krb5_free_sam_challenge_2(context, out_sc2);
-      if (retval)
-          goto encode_error;
-      pa_out.contents = (krb5_octet *) scratch2->data;
-      pa_out.length = scratch2->length;
-      retval = encode_krb5_padata_sequence(pa_array, e_data);
-      krb5_free_data(context, scratch2);
-        }
-encode_error: if (sr2)
-     krb5_free_sam_response_2(context, sr2);
-  if (client_name)
-free(client_name);
-
-  return(retval);
+    /*Note that e_data is an output even in error conditions.*/
+    if (out_sc2) {
+        krb5_pa_data pa_out;
+        krb5_pa_data *pa_array[2];
+        pa_array[0] = &pa_out;
+        pa_array[1] = NULL;
+        pa_out.pa_type = KRB5_PADATA_SAM_CHALLENGE_2;
+        retval = encode_krb5_sam_challenge_2(out_sc2, &scratch2);
+        krb5_free_sam_challenge_2(context, out_sc2);
+        if (retval)
+            goto encode_error;
+        pa_out.contents = (krb5_octet *) scratch2->data;
+        pa_out.length = scratch2->length;
+        retval = encode_krb5_padata_sequence(pa_array, e_data);
+        krb5_free_data(context, scratch2);
+    }
+encode_error:
+    krb5_free_sam_response_2(context, sr2);
+    free(client_name);
+    return retval;
 }