allow server preauth plugin verify_padata function to return e-data
authorKevin Coffman <kwc@citi.umich.edu>
Mon, 13 Nov 2006 22:59:55 +0000 (22:59 +0000)
committerKevin Coffman <kwc@citi.umich.edu>
Mon, 13 Nov 2006 22:59:55 +0000 (22:59 +0000)
Change server-side preauth plugin interface to allow the plugin's
verify_padata function to return e-data to be returned to the client.
(Patch from Nalin Dahyabhai <nalin@redhat.com>)

Update sample plugins to return e-data to exercise the code.

Fix memory leak in the wpse plugin.

ticket: new
Component: krb5-kdc
Target_Version: 1.6
Tags: pullup

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

src/include/krb5/preauth_plugin.h
src/kdc/do_as_req.c
src/kdc/kdc_preauth.c
src/kdc/kdc_util.h
src/plugins/preauth/cksum_body/cksum_body_main.c
src/plugins/preauth/wpse/wpse_main.c

index f1b7dd334509022f49831bc93b493c373f19c969..f7ecd3be0040246fc97d38cbcedfb769706e1bd4 100644 (file)
@@ -298,7 +298,8 @@ typedef struct krb5plugin_preauth_server_ftable_v0 {
                                   krb5_pa_data *data,
                                   preauth_get_entry_data_proc,
                                   void *pa_module_context,
-                                  void **pa_request_context);
+                                  void **pa_request_context,
+                                  krb5_data **e_data);
     /* Generate preauthentication response data to send to the client as part
      * of the AS-REP.  If it needs to override the key which is used to encrypt
      * the response, it can do so.  The module is expected (but not required,
index 38118d4cbb51c82afc225d4d3ce032b9b925f51a..37bd9e319cc1dcb6bec1016d35812f72c3ee12ec 100644 (file)
@@ -262,7 +262,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
      */
     if (request->padata) {
        errcode = check_padata(kdc_context, &client, req_pkt, request,
-                              &enc_tkt_reply, &pa_context);
+                              &enc_tkt_reply, &pa_context, &e_data);
        if (errcode) {
 #ifdef KRBCONF_KDC_MODIFIES_KDB
            /*
index dfbb5fcc90a9cb6a98ed51ebfa9720632f2f9ee9..9994ae3ea8aac25706ab5347e17d76bdcd2c24b9 100644 (file)
@@ -84,7 +84,8 @@ typedef krb5_error_code (*verify_proc)
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
                    preauth_get_entry_data_proc get_entry_data,
                    void *pa_module_context,
-                   void **pa_request_context);
+                   void **pa_request_context,
+                   krb5_data **e_data);
 
 typedef krb5_error_code (*edata_proc)
     (krb5_context, krb5_kdc_req *request,
@@ -133,7 +134,8 @@ static krb5_error_code verify_enc_timestamp
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
                    preauth_get_entry_data_proc get_entry_data,
                    void *pa_system_context,
-                   void **pa_request_context);
+                   void **pa_request_context,
+                   krb5_data **e_data);
 
 static krb5_error_code get_etype_info
     (krb5_context, krb5_kdc_req *request,
@@ -200,7 +202,8 @@ static krb5_error_code verify_sam_response
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
                    preauth_get_entry_data_proc get_entry_data,
                    void *pa_module_context,
-                   void **pa_request_context);
+                   void **pa_request_context,
+                   krb5_data **e_data);
 
 static krb5_error_code get_sam_edata
     (krb5_context, krb5_kdc_req *request,
@@ -873,12 +876,13 @@ errout:
 krb5_error_code
 check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
              krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
-             void **padata_context)
+             void **padata_context, krb5_data *e_data)
 {
     krb5_error_code retval = 0;
     krb5_pa_data **padata;
     krb5_preauth_systems *pa_sys;
     void **pa_context;
+    krb5_data *pa_e_data = NULL;
     int        pa_ok = 0, pa_found = 0;
 
     if (request->padata == 0)
@@ -908,7 +912,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
        retval = pa_sys->verify_padata(context, client, req_pkt, request,
                                       enc_tkt_reply, *padata,
                                       get_entry_data, pa_sys->plugin_context,
-                                      pa_context);
+                                      pa_context, &pa_e_data);
        if (retval) {
            const char * emsg = krb5_get_error_message (context, retval);
            krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
@@ -926,7 +930,29 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
            if (pa_sys->flags & PA_SUFFICIENT) 
                break;
        }
+       /*
+        * If we're looping and e_data was returned, free it here
+        * since we won't be returning it anyway
+        */
+       if (pa_e_data != NULL) {
+           krb5_free_data(context, pa_e_data);
+           pa_e_data = NULL;
+       }
     }
+
+    /* Return any e_data from the preauth that caused us to exit the loop */
+    if (pa_e_data != NULL) {
+       e_data->data = malloc(pa_e_data->length);
+       if (e_data->data == NULL) {
+           krb5_free_data(context, pa_e_data);
+           return KRB5KRB_ERR_GENERIC;
+       }
+       memcpy(e_data->data, pa_e_data->data, pa_e_data->length);
+       e_data->length = pa_e_data->length;
+       krb5_free_data(context, pa_e_data);
+       pa_e_data = NULL;
+    }
+
     if (pa_ok)
        return 0;
 
@@ -941,9 +967,9 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
        krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", emsg);
        krb5_free_error_message(context, emsg);
     }
-/* The following switch statement allows us
- * to return some preauth system errors back to the client.
- */
+    /* The following switch statement allows us
    * to return some preauth system errors back to the client.
    */
     switch(retval) {
     case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     case KRB5KRB_AP_ERR_SKEW:
@@ -1117,7 +1143,8 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
                     krb5_pa_data *pa,
                     preauth_get_entry_data_proc ets_get_entry_data,
                     void *pa_system_context,
-                    void **pa_request_context)
+                    void **pa_request_context,
+                    krb5_data **e_data)
 {
     krb5_pa_enc_ts *           pa_enc = 0;
     krb5_error_code            retval;
@@ -2104,7 +2131,8 @@ verify_sam_response(krb5_context context, krb5_db_entry *client,
                    krb5_pa_data *pa,
                    preauth_get_entry_data_proc sam_get_entry_data,
                    void *pa_system_context,
-                   void **pa_request_context)
+                   void **pa_request_context,
+                   krb5_data **e_data)
 {
     krb5_error_code            retval;
     krb5_data                  scratch;
index 21f7e88f3324fa6e57eefe4d8a4adfca80c58ec8..7fefb964e9e7229247630d4747f66aacd7aeefda 100644 (file)
@@ -152,7 +152,7 @@ krb5_error_code unload_preauth_plugins(krb5_context context);
 krb5_error_code check_padata
     (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
               krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
-              void **padata_context);
+              void **padata_context, krb5_data *e_data);
     
 krb5_error_code return_padata
     (krb5_context context, krb5_db_entry *client,
index 8d7aa00af16282b0f9464913fbf94cf32bbf66a6..6b46b00a33ff5d82afc0f1aa98016e53993cfe35 100644 (file)
@@ -289,7 +289,8 @@ server_verify(krb5_context kcontext,
              krb5_pa_data *data,
              preauth_get_entry_data_proc server_get_entry_data,
              void *pa_module_context,
-             void **pa_request_context)
+             void **pa_request_context,
+             krb5_data **e_data)
 {
     krb5_int32 cksumtype;
     krb5_checksum checksum;
@@ -302,6 +303,7 @@ server_verify(krb5_context kcontext,
     krb5_cksumtype *cksumtypes;
     krb5_error_code status;
     struct server_stats *stats;
+    krb5_data *test_edata;
 
     stats = pa_module_context;
 
@@ -425,10 +427,35 @@ server_verify(krb5_context kcontext,
            fprintf(stderr, "Checksum mismatch.\n");
        }
 #endif
+       /* Return edata to exercise code that handles edata... */
+       test_edata = malloc(sizeof(*test_edata));
+       if (test_edata != NULL) {
+           test_edata->data = malloc(20);
+           if (test_edata->data == NULL) {
+               free(test_edata);
+           } else {
+               test_edata->length = 20;
+               memset(test_edata->data, 'F', 20); /* fill it with junk */
+               *e_data = test_edata;
+           }
+       }
        stats->failures++;
        return KRB5KDC_ERR_PREAUTH_FAILED;
     }
 
+    /* Return edata to exercise code that handles edata... */
+    test_edata = malloc(sizeof(*test_edata));
+    if (test_edata != NULL) {
+       test_edata->data = malloc(20);
+       if (test_edata->data == NULL) {
+           free(test_edata);
+       } else {
+           test_edata->length = 20;
+           memset(test_edata->data, 'S', 20); /* fill it with junk */
+           *e_data = test_edata;
+       }
+    }
+
     /* Note that preauthentication succeeded. */
     enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
     stats->successes++;
index 8ccd7cd129be6b9f3da560b240c53779051ea9a3..46ea66230786e0c282e16ddee28421095641ce46 100644 (file)
@@ -247,9 +247,12 @@ server_verify(krb5_context kcontext,
              krb5_pa_data *data,
              preauth_get_entry_data_proc server_get_entry_data,
              void *pa_module_context,
-             void **pa_request_context)
+             void **pa_request_context,
+             krb5_data **e_data)
 {
     krb5_int32 nnonce;
+    krb5_data *test_edata;
+
     /* Verify the preauth data. */
     if (data->length != 4)
        return KRB5KDC_ERR_PREAUTH_FAILED;
@@ -264,6 +267,19 @@ server_verify(krb5_context kcontext,
      * per-request cleanup. */
     if (*pa_request_context == NULL)
        *pa_request_context = malloc(4);
+
+    /* Return edata to exercise code that handles edata... */
+    test_edata = malloc(sizeof(*test_edata));
+    if (test_edata != NULL) {
+       test_edata->data = malloc(20);
+       if (test_edata->data == NULL) {
+           free(test_edata);
+       } else {
+           test_edata->length = 20;
+           memset(test_edata->data, '#', 20); /* fill it with junk */
+           *e_data = test_edata;
+       }
+    }
     return 0;
 }
 
@@ -333,6 +349,7 @@ server_return(krb5_context kcontext,
     enctype = htonl(kb->enctype);
     memcpy((*send_pa)->contents, &enctype, 4);
     memcpy((*send_pa)->contents + 4, kb->contents, kb->length);
+    krb5_free_keyblock_contents(kcontext, encrypting_key);
     krb5_copy_keyblock_contents(kcontext, kb, encrypting_key);
 
     /* Clean up. */