securID code fixes
authorSam Hartman <hartmans@mit.edu>
Tue, 19 Oct 2010 19:50:37 +0000 (19:50 +0000)
committerSam Hartman <hartmans@mit.edu>
Tue, 19 Oct 2010 19:50:37 +0000 (19:50 +0000)
Fixes to get securID preauth plugin working. A separate patch will
address error handling and build issues.

* Permit a preauth plugin to return KRB5KDC_ERR_PREAUTH_REQUIRED from
  the verify entry point.

* If verify_securid2 fails, save the return value and return that
  rather than success after dealing with encoding the out_edata

* Use the client key not the securid principal key for the sam
  checksum

* indicate that securID is hardware authentication

ticket: 6805
target_version: 1.9
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24465 dc483132-0cff-0310-8789-dd5450dbe970

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

index 957ac23031ce51dcb1d97f007a5a9c1fd52164a5..52fb51a0c951f444c4f724b816d24303034b902f 100644 (file)
@@ -1181,6 +1181,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
     case 0: /* in case of PA-PAC-REQUEST with no PA-ENC-TIMESTAMP */
     case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     case KRB5KRB_AP_ERR_SKEW:
+    case KRB5KDC_ERR_PREAUTH_REQUIRED:
     case KRB5KDC_ERR_ETYPE_NOSUPP:
         /* rfc 4556 */
     case KRB5KDC_ERR_CLIENT_NOT_TRUSTED:
index 100c132302757a4247853613e7c375ee9ea6e312..791eddf244693accdb2326f341c4cdd7b035ffea 100644 (file)
@@ -39,6 +39,7 @@ securid_make_sam_challenge_2_and_cksum(krb5_context context,
 
 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);
 
index f5e07154949716b20a3c0ca5ff19a32541591ede..0a481c7c31dbababb1fd1b1503af973ed2c0c1df 100644 (file)
@@ -266,17 +266,16 @@ 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_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;
 
@@ -291,6 +290,7 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client,
     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();
@@ -316,17 +316,10 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client,
     }
 
     /* 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;
+    sc2b->sam_etype = client_key->enctype;
 
     retval = securid_make_sam_challenge_2_and_cksum(context,
-                                                    sc2, sc2b, &client_key);
+                                                    sc2, sc2b, client_key);
     if (retval) {
         krb5_set_error_message(context, retval,
                                "while making SAM_CHALLENGE_2 checksum (%s)",
@@ -334,7 +327,6 @@ get_securid_edata_2(krb5_context context, krb5_db_entry *client,
     }
 
 cleanup:
-    krb5_free_keyblock_contents(context, &client_key);
     free(user);
     if (retval) {
         krb5_free_data_contents(context, &sc2b->sam_track_id);
@@ -486,7 +478,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client,
                                    "verify_securid_data_2 (%s)", user);
            goto cleanup;
         }
-        if (track_id_data.length <= sizeof (struct securid_track_data)) {
+        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");
@@ -728,7 +720,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client,
                                  "for user %s", securid_user);
             *sc2_out = sc2p;
             sc2p = NULL;
-            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
             /*sc2_out is permitted as an output on error path*/
             goto cleanup;
         }
index 695934cc47638f6e5cda013925e6c94b2c62221c..3e1ada28e2032bdb2aff406d821692e7ce51ba1c 100644 (file)
@@ -122,6 +122,8 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request,
                    void *pa_module_context, krb5_pa_data *pa_data)
 {
     krb5_error_code retval;
+    krb5_data *client_keys_data = NULL;
+    krb5_keyblock *client_key = NULL;
     krb5_sam_challenge_2 sc2;
     krb5_sam_challenge_2_body sc2b;
     int sam_type = 0;             /* unknown */
@@ -137,6 +139,16 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request,
                               &sam_db_entry);
     if (retval)
         return retval;
+    retval = get_entry_proc(context, request, client,
+                            krb5plugin_preauth_keys, &client_keys_data);
+    if (retval)
+        goto cleanup;
+    client_key = (krb5_keyblock *) client_keys_data->data;
+    if (client_key->enctype == 0) {
+        retval = KRB5KDC_ERR_ETYPE_NOSUPP;
+        krb5_set_error_message(context, retval, "No client keys found in processing SAM2 challenge");
+        goto cleanup;
+    }
 
     if (sam_type == 0) {
         retval = KRB5_PREAUTH_BAD_TYPE;
@@ -152,7 +164,7 @@ 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, &sc2b, &sc2);
+        retval = get_securid_edata_2(context, client, client_key, &sc2b, &sc2);
         if (retval)
             goto cleanup;
 
@@ -181,6 +193,13 @@ cleanup:
     krb5_free_data(context, encoded_challenge);
     if (sam_db_entry)
         krb5_db_free_principal(context, sam_db_entry);
+    if (client_keys_data) {
+        while (client_key->enctype) {
+            krb5_free_keyblock_contents(context, client_key);
+            client_key++;
+        }
+        krb5_free_data(context, client_keys_data);
+    }
     return retval;
 }
 
@@ -192,7 +211,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
                    void *pa_module_context, void **opaque,
                    krb5_data **e_data, krb5_authdata ***authz_data)
 {
-    krb5_error_code retval;
+    krb5_error_code retval, saved_retval = 0;
     krb5_sam_response_2 *sr2 = NULL;
     krb5_data scratch, *scratch2;
     char *client_name = NULL;
@@ -237,7 +256,10 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
    * 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.*/
+    /*Note that e_data is an output even in error conditions. If we
+      successfully encode the output e_data, we return whatever error
+      is received above. Otherwise we return the encoding error.*/
+    saved_retval = retval;
     if (out_sc2) {
         krb5_pa_data pa_out;
         krb5_pa_data *pa_array[2];
@@ -256,6 +278,8 @@ cleanup:
 encode_error:
     krb5_free_sam_response_2(context, sr2);
     free(client_name);
+    if (retval == 0)
+        retval = saved_retval;
     return retval;
 }
 
@@ -263,7 +287,7 @@ encode_error:
 static int
 kdc_preauth_flags(krb5_context context, krb5_preauthtype patype)
 {
-    return 0;
+    return PA_HARDWARE;
 }
 
 krb5_preauthtype supported_pa_types[] = {