krb5 commit: Get rid of static KDC authdata systems

Greg Hudson ghudson at mit.edu
Mon Jun 15 12:56:00 EDT 2015


https://github.com/krb5/krb5/commit/c96fe6c87a69122e6b699385f52a959d375ca4bb
commit c96fe6c87a69122e6b699385f52a959d375ca4bb
Author: Greg Hudson <ghudson at mit.edu>
Date:   Tue Sep 23 12:36:20 2014 -0400

    Get rid of static KDC authdata systems
    
    Remove the static_authdata_systems table from kdc_authdata.c and
    instead call the relevant functions explicitly in handle_authdata.
    Eliminate the flags field from krb5_authdata_systems as it is no
    longer used.  Rename the functions to be more descriptive.  Move
    simple conditionals on authdata processing to handle_authdata for
    clarity.  Move handle_authdata to the end of the file to avoid the
    need for static function declarations.

 src/kdc/kdc_authdata.c |  383 ++++++++++++++++--------------------------------
 1 files changed, 123 insertions(+), 260 deletions(-)

diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index e70a27b..410a57a 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -66,67 +66,12 @@ typedef krb5_error_code (*authdata_proc_2)(
 typedef krb5_error_code (*init_proc)(krb5_context, void **);
 typedef void (*fini_proc)(krb5_context, void *);
 
-static krb5_error_code handle_request_authdata(
-    krb5_context context,
-    unsigned int flags,
-    krb5_db_entry *client,
-    krb5_db_entry *server,
-    krb5_db_entry *krbtgt,
-    krb5_keyblock *client_key,
-    krb5_keyblock *server_key,
-    krb5_keyblock *krbtgt_key,
-    krb5_data *req_pkt,
-    krb5_kdc_req *request,
-    krb5_const_principal for_user_princ,
-    krb5_enc_tkt_part *enc_tkt_request,
-    krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code handle_tgt_authdata(
-    krb5_context context,
-    unsigned int flags,
-    krb5_db_entry *client,
-    krb5_db_entry *server,
-    krb5_db_entry *krbtgt,
-    krb5_keyblock *client_key,
-    krb5_keyblock *server_key,
-    krb5_keyblock *krbtgt_key,
-    krb5_data *req_pkt,
-    krb5_kdc_req *request,
-    krb5_const_principal for_user_princ,
-    krb5_enc_tkt_part *enc_tkt_request,
-    krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code
-handle_kdb_authdata(krb5_context context, unsigned int flags,
-                    krb5_db_entry *client, krb5_db_entry *server,
-                    krb5_db_entry *krbtgt, krb5_keyblock *client_key,
-                    krb5_keyblock *server_key, krb5_keyblock *krbtgt_key,
-                    krb5_data *req_pkt, krb5_kdc_req *request,
-                    krb5_const_principal for_user_princ,
-                    krb5_enc_tkt_part *enc_tkt_request,
-                    krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code
-handle_signedpath_authdata(krb5_context context, unsigned int flags,
-                           krb5_db_entry *client, krb5_db_entry *server,
-                           krb5_db_entry *krbtgt, krb5_keyblock *client_key,
-                           krb5_keyblock *server_key,
-                           krb5_keyblock *krbtgt_key,
-                           krb5_data *req_pkt, krb5_kdc_req *request,
-                           krb5_const_principal for_user_princ,
-                           krb5_enc_tkt_part *enc_tkt_request,
-                           krb5_enc_tkt_part *enc_tkt_reply);
-
 typedef struct _krb5_authdata_systems {
     const char *name;
 #define AUTHDATA_SYSTEM_UNKNOWN -1
 #define AUTHDATA_SYSTEM_V0      0
 #define AUTHDATA_SYSTEM_V2      2
     int         type;
-#define AUTHDATA_FLAG_CRITICAL  0x1
-#define AUTHDATA_FLAG_PRE_PLUGIN 0x2
-#define AUTHDATA_FLAG_ANONYMOUS 0x4 /* Use plugin even for anonymous tickets */
-    int         flags;
     void       *plugin_context;
     init_proc   init;
     fini_proc   fini;
@@ -136,50 +81,6 @@ typedef struct _krb5_authdata_systems {
     } handle_authdata;
 } krb5_authdata_systems;
 
-static krb5_authdata_systems static_authdata_systems[] = {
-    {
-        /* Propagate client-submitted authdata */
-        "tgs_req",
-        AUTHDATA_SYSTEM_V2,
-        AUTHDATA_FLAG_CRITICAL | AUTHDATA_FLAG_PRE_PLUGIN |
-        AUTHDATA_FLAG_ANONYMOUS,
-        NULL,
-        NULL,
-        NULL,
-        { handle_request_authdata }
-    },
-    {
-        /* Propagate TGT authdata */
-        "tgt",
-        AUTHDATA_SYSTEM_V2,
-        AUTHDATA_FLAG_CRITICAL | AUTHDATA_FLAG_ANONYMOUS,
-        NULL,
-        NULL,
-        NULL,
-        { handle_tgt_authdata }
-    },
-    {
-        /* Verify and issue KDB issued authdata */
-        "kdb",
-        AUTHDATA_SYSTEM_V2,
-        AUTHDATA_FLAG_CRITICAL,
-        NULL,
-        NULL,
-        NULL,
-        { handle_kdb_authdata }
-    },
-    {
-        /* Verify and issue signed delegation path */
-        "signedpath",
-        AUTHDATA_SYSTEM_V2,
-        AUTHDATA_FLAG_CRITICAL,
-        NULL,
-        NULL,
-        NULL,
-        { handle_signedpath_authdata }
-    }
-};
-
 static krb5_authdata_systems *authdata_systems;
 static int n_authdata_systems;
 static struct plugin_dir_handle authdata_plugins;
@@ -244,9 +145,6 @@ load_authdata_plugins(krb5_context context)
         }
     }
 
-    module_count += sizeof(static_authdata_systems)
-        / sizeof(static_authdata_systems[0]);
-
     /* Build the complete list of supported authdata options, and
      * leave room for a terminator entry.
      */
@@ -258,19 +156,6 @@ load_authdata_plugins(krb5_context context)
 
     k = 0;
 
-    /*
-     * Special case to ensure that handle_request_authdata is
-     * first in the list, to make unenc_authdata available to
-     * plugins.
-     */
-    for (i = 0; i < (sizeof(static_authdata_systems) /
-                     sizeof(static_authdata_systems[0])); i++) {
-        if ((static_authdata_systems[i].flags & AUTHDATA_FLAG_PRE_PLUGIN) == 0)
-            continue;
-        assert(static_authdata_systems[i].init == NULL);
-        authdata_systems[k++] = static_authdata_systems[i];
-    }
-
     /* Add dynamically loaded V2 plugins */
     if (authdata_plugins_ftables_v2 != NULL) {
         struct krb5plugin_authdata_server_ftable_v2 *ftable;
@@ -343,15 +228,6 @@ load_authdata_plugins(krb5_context context)
         }
     }
 
-    for (i = 0;
-         i < sizeof(static_authdata_systems) / sizeof(static_authdata_systems[0]);
-         i++) {
-        if (static_authdata_systems[i].flags & AUTHDATA_FLAG_PRE_PLUGIN)
-            continue;
-        assert(static_authdata_systems[i].init == NULL);
-        authdata_systems[k++] = static_authdata_systems[i];
-    }
-
     n_authdata_systems = k;
     /* Add the end-of-list marker. */
     authdata_systems[k].name = "[end]";
@@ -539,29 +415,16 @@ merge_authdata (krb5_context context,
     return 0;
 }
 
-/* Handle copying TGS-REQ authorization data into reply */
+/* Copy TGS-REQ authorization data into the ticket authdata. */
 static krb5_error_code
-handle_request_authdata (krb5_context context,
-                         unsigned int flags,
-                         krb5_db_entry *client,
-                         krb5_db_entry *server,
-                         krb5_db_entry *krbtgt,
-                         krb5_keyblock *client_key,
-                         krb5_keyblock *server_key,
-                         krb5_keyblock *krbtgt_key,
-                         krb5_data *req_pkt,
-                         krb5_kdc_req *request,
-                         krb5_const_principal for_user_princ,
-                         krb5_enc_tkt_part *enc_tkt_request,
-                         krb5_enc_tkt_part *enc_tkt_reply)
+copy_request_authdata(krb5_context context, krb5_keyblock *client_key,
+                      krb5_kdc_req *request,
+                      krb5_enc_tkt_part *enc_tkt_request,
+                      krb5_authdata ***tkt_authdata)
 {
     krb5_error_code code;
     krb5_data scratch;
 
-    if (request->msg_type != KRB5_TGS_REQ ||
-        request->authorization_data.ciphertext.data == NULL)
-        return 0;
-
     assert(enc_tkt_request != NULL);
 
     scratch.length = request->authorization_data.ciphertext.length;
@@ -613,58 +476,37 @@ handle_request_authdata (krb5_context context,
 
     code = merge_authdata(context,
                           request->unenc_authdata,
-                          &enc_tkt_reply->authorization_data,
+                          tkt_authdata,
                           TRUE,            /* copy */
                           TRUE);    /* ignore_kdc_issued */
 
     return code;
 }
 
-/* Handle copying TGT authorization data into reply */
+/* Copy TGT authorization data into the ticket authdata. */
 static krb5_error_code
-handle_tgt_authdata (krb5_context context,
-                     unsigned int flags,
-                     krb5_db_entry *client,
-                     krb5_db_entry *server,
-                     krb5_db_entry *krbtgt,
-                     krb5_keyblock *client_key,
-                     krb5_keyblock *server_key,
-                     krb5_keyblock *krbtgt_key,
-                     krb5_data *req_pkt,
-                     krb5_kdc_req *request,
-                     krb5_const_principal for_user_princ,
-                     krb5_enc_tkt_part *enc_tkt_request,
-                     krb5_enc_tkt_part *enc_tkt_reply)
+copy_tgt_authdata(krb5_context context, krb5_kdc_req *request,
+                  krb5_authdata **tgt_authdata, krb5_authdata ***tkt_authdata)
 {
-    if (request->msg_type != KRB5_TGS_REQ)
-        return 0;
-
-    if (has_mandatory_for_kdc_authdata(context,
-                                       enc_tkt_request->authorization_data))
+    if (has_mandatory_for_kdc_authdata(context, tgt_authdata))
         return KRB5KDC_ERR_POLICY;
 
     return merge_authdata(context,
-                          enc_tkt_request->authorization_data,
-                          &enc_tkt_reply->authorization_data,
+                          tgt_authdata,
+                          tkt_authdata,
                           TRUE,            /* copy */
                           TRUE);    /* ignore_kdc_issued */
 }
 
-/* Handle backend-managed authorization data */
+/* Fetch authorization data from KDB module. */
 static krb5_error_code
-handle_kdb_authdata (krb5_context context,
-                     unsigned int flags,
-                     krb5_db_entry *client,
-                     krb5_db_entry *server,
-                     krb5_db_entry *krbtgt,
-                     krb5_keyblock *client_key,
-                     krb5_keyblock *server_key,
-                     krb5_keyblock *krbtgt_key,
-                     krb5_data *req_pkt,
-                     krb5_kdc_req *request,
-                     krb5_const_principal for_user_princ,
-                     krb5_enc_tkt_part *enc_tkt_request,
-                     krb5_enc_tkt_part *enc_tkt_reply)
+fetch_kdb_authdata(krb5_context context, unsigned int flags,
+                   krb5_db_entry *client, krb5_db_entry *server,
+                   krb5_db_entry *krbtgt, krb5_keyblock *client_key,
+                   krb5_keyblock *server_key, krb5_keyblock *krbtgt_key,
+                   krb5_kdc_req *request, krb5_const_principal for_user_princ,
+                   krb5_enc_tkt_part *enc_tkt_request,
+                   krb5_enc_tkt_part *enc_tkt_reply)
 {
     krb5_error_code code;
     krb5_authdata **tgt_authdata, **db_authdata = NULL;
@@ -727,67 +569,6 @@ handle_kdb_authdata (krb5_context context,
     return code;
 }
 
-krb5_error_code
-handle_authdata (krb5_context context,
-                 unsigned int flags,
-                 krb5_db_entry *client,
-                 krb5_db_entry *server,
-                 krb5_db_entry *krbtgt,
-                 krb5_keyblock *client_key,
-                 krb5_keyblock *server_key,
-                 krb5_keyblock *krbtgt_key,
-                 krb5_data *req_pkt,
-                 krb5_kdc_req *request,
-                 krb5_const_principal for_user_princ,
-                 krb5_enc_tkt_part *enc_tkt_request,
-                 krb5_enc_tkt_part *enc_tkt_reply)
-{
-    krb5_error_code code = 0;
-    int i;
-
-    for (i = 0; i < n_authdata_systems; i++) {
-        const krb5_authdata_systems *asys = &authdata_systems[i];
-        if (isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS) &&
-            !isflagset(asys->flags, AUTHDATA_FLAG_ANONYMOUS))
-            continue;
-
-        switch (asys->type) {
-        case AUTHDATA_SYSTEM_V0:
-            /* V0 was only in AS-REQ code path */
-            if (request->msg_type != KRB5_AS_REQ)
-                continue;
-
-            code = (*asys->handle_authdata.v0)(context, client, req_pkt,
-                                               request, enc_tkt_reply);
-            break;
-        case AUTHDATA_SYSTEM_V2:
-            code = (*asys->handle_authdata.v2)(context, flags,
-                                               client, server, krbtgt,
-                                               client_key, server_key, krbtgt_key,
-                                               req_pkt, request, for_user_princ,
-                                               enc_tkt_request,
-                                               enc_tkt_reply);
-            break;
-        default:
-            code = 0;
-            break;
-        }
-        if (code != 0) {
-            const char *emsg;
-
-            emsg = krb5_get_error_message (context, code);
-            krb5_klog_syslog(LOG_INFO, _("authdata (%s) handling failure: %s"),
-                             asys->name, emsg);
-            krb5_free_error_message (context, emsg);
-
-            if (asys->flags & AUTHDATA_FLAG_CRITICAL)
-                break;
-        }
-    }
-
-    return code;
-}
-
 static krb5_error_code
 make_ad_signedpath_data(krb5_context context,
                         krb5_const_principal client,
@@ -842,7 +623,6 @@ make_ad_signedpath_data(krb5_context context,
 
 static krb5_error_code
 verify_ad_signedpath_checksum(krb5_context context,
-                              const krb5_db_entry *krbtgt,
                               krb5_keyblock *krbtgt_key,
                               krb5_enc_tkt_part *enc_tkt_part,
                               krb5_principal *deleg_path,
@@ -882,7 +662,6 @@ verify_ad_signedpath_checksum(krb5_context context,
 
 static krb5_error_code
 verify_ad_signedpath(krb5_context context,
-                     krb5_db_entry *krbtgt,
                      krb5_keyblock *krbtgt_key,
                      krb5_enc_tkt_part *enc_tkt_part,
                      krb5_principal **pdelegated,
@@ -918,7 +697,6 @@ verify_ad_signedpath(krb5_context context,
     }
 
     code = verify_ad_signedpath_checksum(context,
-                                         krbtgt,
                                          krbtgt_key,
                                          enc_tkt_part,
                                          sp->delegated,
@@ -943,7 +721,6 @@ cleanup:
 static krb5_error_code
 make_ad_signedpath_checksum(krb5_context context,
                             krb5_const_principal for_user_princ,
-                            const krb5_db_entry *krbtgt,
                             krb5_keyblock *krbtgt_key,
                             krb5_enc_tkt_part *enc_tkt_part,
                             krb5_principal *deleg_path,
@@ -996,7 +773,6 @@ static krb5_error_code
 make_ad_signedpath(krb5_context context,
                    krb5_const_principal for_user_princ,
                    krb5_principal server,
-                   const krb5_db_entry *krbtgt,
                    krb5_keyblock *krbtgt_key,
                    krb5_principal *deleg_path,
                    krb5_enc_tkt_part *enc_tkt_reply)
@@ -1033,7 +809,6 @@ make_ad_signedpath(krb5_context context,
 
     code = make_ad_signedpath_checksum(context,
                                        for_user_princ,
-                                       krbtgt,
                                        krbtgt_key,
                                        enc_tkt_reply,
                                        sp.delegated,
@@ -1114,20 +889,15 @@ only_pac_p(krb5_context context, krb5_authdata **authdata)
         (authdata[1] == NULL);
 }
 
+/* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH
+ * element if we should. */
 static krb5_error_code
-handle_signedpath_authdata (krb5_context context,
-                            unsigned int flags,
-                            krb5_db_entry *client,
-                            krb5_db_entry *server,
-                            krb5_db_entry *krbtgt,
-                            krb5_keyblock *client_key,
-                            krb5_keyblock *server_key,
-                            krb5_keyblock *krbtgt_key,
-                            krb5_data *req_pkt,
-                            krb5_kdc_req *request,
-                            krb5_const_principal for_user_princ,
-                            krb5_enc_tkt_part *enc_tkt_request,
-                            krb5_enc_tkt_part *enc_tkt_reply)
+handle_signticket(krb5_context context, unsigned int flags,
+                  krb5_db_entry *client, krb5_db_entry *server,
+                  krb5_keyblock *krbtgt_key, krb5_kdc_req *request,
+                  krb5_const_principal for_user_princ,
+                  krb5_enc_tkt_part *enc_tkt_request,
+                  krb5_enc_tkt_part *enc_tkt_reply)
 {
     krb5_error_code code = 0;
     krb5_principal *deleg_path = NULL;
@@ -1143,7 +913,6 @@ handle_signedpath_authdata (krb5_context context,
     if (request->msg_type == KRB5_TGS_REQ &&
         !only_pac_p(context, enc_tkt_request->authorization_data)) {
         code = verify_ad_signedpath(context,
-                                    krbtgt,
                                     krbtgt_key,
                                     enc_tkt_request,
                                     &deleg_path,
@@ -1165,7 +934,6 @@ handle_signedpath_authdata (krb5_context context,
         code = make_ad_signedpath(context,
                                   for_user_princ,
                                   s4u2proxy ? client->princ : NULL,
-                                  krbtgt,
                                   krbtgt_key,
                                   deleg_path,
                                   enc_tkt_reply);
@@ -1178,3 +946,98 @@ cleanup:
 
     return code;
 }
+
+krb5_error_code
+handle_authdata (krb5_context context,
+                 unsigned int flags,
+                 krb5_db_entry *client,
+                 krb5_db_entry *server,
+                 krb5_db_entry *krbtgt,
+                 krb5_keyblock *client_key,
+                 krb5_keyblock *server_key,
+                 krb5_keyblock *krbtgt_key,
+                 krb5_data *req_pkt,
+                 krb5_kdc_req *request,
+                 krb5_const_principal for_user_princ,
+                 krb5_enc_tkt_part *enc_tkt_request,
+                 krb5_enc_tkt_part *enc_tkt_reply)
+{
+    krb5_error_code code = 0;
+    int i;
+
+    if (request->msg_type == KRB5_TGS_REQ &&
+        request->authorization_data.ciphertext.data != NULL) {
+        /* Copy TGS request authdata.  This must be done first so that modules
+         * have access to the unencrypted request authdata. */
+        code = copy_request_authdata(context, client_key, request,
+                                     enc_tkt_request,
+                                     &enc_tkt_reply->authorization_data);
+        if (code)
+            return code;
+    }
+
+    for (i = 0; i < n_authdata_systems; i++) {
+        const krb5_authdata_systems *asys = &authdata_systems[i];
+        if (isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS))
+            continue;
+
+        switch (asys->type) {
+        case AUTHDATA_SYSTEM_V0:
+            /* V0 was only in AS-REQ code path */
+            if (request->msg_type != KRB5_AS_REQ)
+                continue;
+
+            code = (*asys->handle_authdata.v0)(context, client, req_pkt,
+                                               request, enc_tkt_reply);
+            break;
+        case AUTHDATA_SYSTEM_V2:
+            code = (*asys->handle_authdata.v2)(context, flags,
+                                               client, server, krbtgt,
+                                               client_key, server_key, krbtgt_key,
+                                               req_pkt, request, for_user_princ,
+                                               enc_tkt_request,
+                                               enc_tkt_reply);
+            break;
+        default:
+            code = 0;
+            break;
+        }
+        if (code != 0) {
+            const char *emsg;
+
+            emsg = krb5_get_error_message (context, code);
+            krb5_klog_syslog(LOG_INFO, _("authdata (%s) handling failure: %s"),
+                             asys->name, emsg);
+            krb5_free_error_message (context, emsg);
+        }
+    }
+
+    if (request->msg_type == KRB5_TGS_REQ) {
+        /* Copy authdata from the TGT to the issued ticket. */
+        code = copy_tgt_authdata(context, request,
+                                 enc_tkt_request->authorization_data,
+                                 &enc_tkt_reply->authorization_data);
+        if (code)
+            return code;
+    }
+
+    if (!isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS)) {
+        /* Fetch authdata from the KDB if appropriate. */
+        code = fetch_kdb_authdata(context, flags, client, server, krbtgt,
+                                  client_key, server_key, krbtgt_key, request,
+                                  for_user_princ, enc_tkt_request,
+                                  enc_tkt_reply);
+        if (code)
+            return code;
+
+        /* Validate and insert AD-SIGNTICKET authdata.  This must happen last
+         * since it contains a signature over the other authdata. */
+        code = handle_signticket(context, flags, client, server, krbtgt_key,
+                                 request, for_user_princ, enc_tkt_request,
+                                 enc_tkt_reply);
+        if (code)
+            return code;
+    }
+
+    return 0;
+}


More information about the cvs-krb5 mailing list