krb5 commit: Allow the KDB to see and modify auth indicators

Greg Hudson ghudson at mit.edu
Tue Aug 27 01:24:41 EDT 2019


https://github.com/krb5/krb5/commit/7196c03f18f14695abeb5ae4923004469b172f0f
commit 7196c03f18f14695abeb5ae4923004469b172f0f
Author: Greg Hudson <ghudson at mit.edu>
Date:   Wed Aug 7 17:51:17 2019 -0400

    Allow the KDB to see and modify auth indicators
    
    Amend the sign_authdata method signature to include a modifiable
    auth_indicators array.  Bump the DAL major version and the libkdb5
    soname.  Add a test case using the test KDB module.
    
    ticket: 8823 (new)

 src/include/kdb.h               |   16 +++++++++++-----
 src/kdc/do_as_req.c             |    2 +-
 src/kdc/do_tgs_req.c            |    9 ++-------
 src/kdc/kdc_authdata.c          |   26 +++++++++++++++-----------
 src/kdc/kdc_util.h              |    2 +-
 src/lib/kdb/Makefile.in         |    2 +-
 src/lib/kdb/kdb5.c              |   10 +++-------
 src/plugins/kdb/test/kdb_test.c |   23 ++++++++++++++++++++++-
 src/tests/t_authdata.py         |    5 +++++
 9 files changed, 61 insertions(+), 34 deletions(-)

diff --git a/src/include/kdb.h b/src/include/kdb.h
index 86d4a64..38419f6 100644
--- a/src/include/kdb.h
+++ b/src/include/kdb.h
@@ -69,7 +69,7 @@
 
 /* This version will be incremented when incompatible changes are made to the
  * KDB API, and will be kept in sync with the libkdb major version. */
-#define KRB5_KDB_API_VERSION 9
+#define KRB5_KDB_API_VERSION 10
 
 /* Salt types */
 #define KRB5_KDB_SALTTYPE_NORMAL        0
@@ -670,6 +670,7 @@ krb5_error_code krb5_db_sign_authdata(krb5_context kcontext,
                                       krb5_keyblock *session_key,
                                       krb5_timestamp authtime,
                                       krb5_authdata **tgt_auth_data,
+                                      krb5_data ***auth_indicators,
                                       krb5_authdata ***signed_auth_data);
 
 krb5_error_code krb5_db_check_transited_realms(krb5_context kcontext,
@@ -871,7 +872,7 @@ krb5_error_code krb5_db_register_keytab(krb5_context context);
  * This number indicates the date of the last incompatible change to the DAL.
  * The maj_ver field of the module's vtable structure must match this version.
  */
-#define KRB5_KDB_DAL_MAJOR_VERSION 7
+#define KRB5_KDB_DAL_MAJOR_VERSION 8
 
 /*
  * A krb5_context can hold one database object.  Modules should use
@@ -1304,6 +1305,12 @@ typedef struct _kdb_vftabl {
      *
      *   tgt_auth_data: For TGS requests, the authorization data present in the
      *     subject ticket.  For AS requests, NULL.
+     *
+     *   auth_indicators: Points to NULL or a null-terminated list of krb5_data
+     *     pointers, each containing an authentication indicator (RFC 8129).
+     *     The method may modify this list, or free it and replace
+     *     *auth_indicators with NULL, to change which auth indicators will be
+     *     included in the ticket.
      */
     krb5_error_code (*sign_authdata)(krb5_context kcontext,
                                      unsigned int flags,
@@ -1317,6 +1324,7 @@ typedef struct _kdb_vftabl {
                                      krb5_keyblock *session_key,
                                      krb5_timestamp authtime,
                                      krb5_authdata **tgt_auth_data,
+                                     krb5_data ***auth_indicators,
                                      krb5_authdata ***signed_auth_data);
 
     /*
@@ -1405,8 +1413,6 @@ typedef struct _kdb_vftabl {
      */
     void (*free_principal_e_data)(krb5_context kcontext, krb5_octet *e_data);
 
-    /* End of minor version 0. */
-
     /*
      * Optional: get a principal entry for S4U2Self based on X509 certificate.
      *
@@ -1426,7 +1432,7 @@ typedef struct _kdb_vftabl {
                                               unsigned int flags,
                                               krb5_db_entry **entry_out);
 
-    /* End of minor version 1 for major version 7. */
+    /* End of minor version 0 for major version 8. */
 } kdb_vftabl;
 
 #endif /* !defined(_WIN32) */
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index a14e64f..894a9d4 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -300,7 +300,7 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
                               &state->local_tgt_key, &state->client_keyblock,
                               &state->server_keyblock, NULL, state->req_pkt,
                               state->request, NULL, NULL,
-                              state->auth_indicators, &state->enc_tkt_reply);
+                              &state->auth_indicators, &state->enc_tkt_reply);
     if (errcode) {
         krb5_klog_syslog(LOG_INFO, _("AS_REQ : handle_authdata (%d)"),
                          errcode);
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 98f4cc6..bed5630 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -610,15 +610,10 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
                               header_server, local_tgt, &local_tgt_key,
                               subkey != NULL ? subkey :
                               header_ticket->enc_part2->session,
-                              encrypting_key, /* U2U or server key */
-                              header_key,
-                              pkt,
-                              request,
+                              encrypting_key, header_key, pkt, request,
                               s4u_x509_user ?
                               s4u_x509_user->user_id.user : NULL,
-                              subject_tkt,
-                              auth_indicators,
-                              &enc_tkt_reply);
+                              subject_tkt, &auth_indicators, &enc_tkt_reply);
     if (errcode) {
         krb5_klog_syslog(LOG_INFO, _("TGS_REQ : handle_authdata (%d)"),
                          errcode);
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index df670e8..72e830d 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -320,7 +320,8 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
                    krb5_keyblock *server_key, krb5_keyblock *header_key,
                    krb5_kdc_req *req, krb5_const_principal for_user_princ,
                    krb5_enc_tkt_part *enc_tkt_req,
-                   krb5_enc_tkt_part *enc_tkt_reply)
+                   krb5_enc_tkt_part *enc_tkt_reply,
+                   krb5_data ***auth_indicators)
 {
     krb5_error_code ret;
     krb5_authdata **tgt_authdata, **db_authdata = NULL;
@@ -379,7 +380,7 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
                                 server, krbtgt, client_key, server_key,
                                 krbtgt_key, enc_tkt_reply->session,
                                 enc_tkt_reply->times.authtime, tgt_authdata,
-                                &db_authdata);
+                                auth_indicators, &db_authdata);
     if (ret)
         return (ret == KRB5_PLUGIN_OP_NOTSUPP) ? 0 : ret;
 
@@ -824,7 +825,7 @@ handle_authdata(krb5_context context, unsigned int flags,
                 krb5_data *req_pkt, krb5_kdc_req *req,
                 krb5_const_principal for_user_princ,
                 krb5_enc_tkt_part *enc_tkt_req,
-                krb5_data *const *auth_indicators,
+                krb5_data ***auth_indicators,
                 krb5_enc_tkt_part *enc_tkt_reply)
 {
     kdcauthdata_handle *h;
@@ -862,23 +863,26 @@ handle_authdata(krb5_context context, unsigned int flags,
             return ret;
     }
 
+    if (!isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS)) {
+        /* Fetch authdata from the KDB if appropriate. */
+        ret = fetch_kdb_authdata(context, flags, client, server, header_server,
+                                 client_key, server_key, header_key, req,
+                                 for_user_princ, enc_tkt_req, enc_tkt_reply,
+                                 auth_indicators);
+        if (ret)
+            return ret;
+    }
+
     /* Add auth indicators if any were given. */
     if (auth_indicators != NULL && *auth_indicators != NULL &&
         !isflagset(server->attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED)) {
-        ret = add_auth_indicators(context, auth_indicators, server_key,
+        ret = add_auth_indicators(context, *auth_indicators, server_key,
                                   local_tgt, local_tgt_key, enc_tkt_reply);
         if (ret)
             return ret;
     }
 
     if (!isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS)) {
-        /* Fetch authdata from the KDB if appropriate. */
-        ret = fetch_kdb_authdata(context, flags, client, server, header_server,
-                                 client_key, server_key, header_key, req,
-                                 for_user_princ, enc_tkt_req, enc_tkt_reply);
-        if (ret)
-            return ret;
-
         /* Validate and insert AD-SIGNTICKET authdata.  This must happen last
          * since it contains a signature over the other authdata. */
         ret = handle_signticket(context, flags, client, server, local_tgt,
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index f41c0d9..8583a91 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -236,7 +236,7 @@ handle_authdata (krb5_context context,
                  krb5_kdc_req *request,
                  krb5_const_principal for_user_princ,
                  krb5_enc_tkt_part *enc_tkt_request,
-                 krb5_data *const *auth_indicators,
+                 krb5_data ***auth_indicators,
                  krb5_enc_tkt_part *enc_tkt_reply);
 
 /* replay.c */
diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in
index b77bf49..25da081 100644
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -5,7 +5,7 @@ LOCALINCLUDES= -I.
 
 # Keep LIBMAJOR in sync with KRB5_KDB_API_VERSION in include/kdb.h.
 LIBBASE=kdb5
-LIBMAJOR=9
+LIBMAJOR=10
 LIBMINOR=0
 LIBINITFUNC=kdb_init_lock_list
 LIBFINIFUNC=kdb_fini_lock_list
diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c
index b910bd3..3058b47 100644
--- a/src/lib/kdb/kdb5.c
+++ b/src/lib/kdb/kdb5.c
@@ -323,12 +323,7 @@ copy_vtable(const kdb_vftabl *in, kdb_vftabl *out)
     out->refresh_config = in->refresh_config;
     out->check_allowed_to_delegate = in->check_allowed_to_delegate;
     out->free_principal_e_data = in->free_principal_e_data;
-
-    /* Copy fields for minor version 1 (major version 7). */
-    assert(KRB5_KDB_DAL_MAJOR_VERSION == 7);
-    out->get_s4u_x509_principal = NULL;
-    if (in->min_ver >= 1)
-        out->get_s4u_x509_principal = in->get_s4u_x509_principal;
+    out->get_s4u_x509_principal = in->get_s4u_x509_principal;
 
     /* Set defaults for optional fields. */
     if (out->fetch_master_key == NULL)
@@ -2599,6 +2594,7 @@ krb5_db_sign_authdata(krb5_context kcontext, unsigned int flags,
                       krb5_keyblock *client_key, krb5_keyblock *server_key,
                       krb5_keyblock *krbtgt_key, krb5_keyblock *session_key,
                       krb5_timestamp authtime, krb5_authdata **tgt_auth_data,
+                      krb5_data ***auth_indicators,
                       krb5_authdata ***signed_auth_data)
 {
     krb5_error_code status = 0;
@@ -2613,7 +2609,7 @@ krb5_db_sign_authdata(krb5_context kcontext, unsigned int flags,
     return v->sign_authdata(kcontext, flags, client_princ, client, server,
                             krbtgt, client_key, server_key, krbtgt_key,
                             session_key, authtime, tgt_auth_data,
-                            signed_auth_data);
+                            auth_indicators, signed_auth_data);
 }
 
 krb5_error_code
diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c
index 690c025..351bd8c 100644
--- a/src/plugins/kdb/test/kdb_test.c
+++ b/src/plugins/kdb/test/kdb_test.c
@@ -544,9 +544,12 @@ test_sign_authdata(krb5_context context, unsigned int flags,
                    krb5_keyblock *client_key, krb5_keyblock *server_key,
                    krb5_keyblock *krbtgt_key, krb5_keyblock *session_key,
                    krb5_timestamp authtime, krb5_authdata **tgt_auth_data,
+                   krb5_data ***auth_indicators,
                    krb5_authdata ***signed_auth_data)
 {
     krb5_authdata **list, *ad;
+    krb5_data **inds, d;
+    int i, val;
 
     ad = ealloc(sizeof(*ad));
     ad->magic = KV5M_AUTHDATA;
@@ -557,6 +560,24 @@ test_sign_authdata(krb5_context context, unsigned int flags,
     list[0] = ad;
     list[1] = NULL;
     *signed_auth_data = list;
+
+    /* If we see an auth indicator "dbincrX", replace the whole indicator list
+     * with "dbincr{X+1}". */
+    inds = *auth_indicators;
+    for (i = 0; inds != NULL && inds[i] != NULL; i++) {
+        if (inds[i]->length == 7 && memcmp(inds[i]->data, "dbincr", 6) == 0) {
+            val = inds[i]->data[6];
+            k5_free_data_ptr_list(inds);
+            inds = ealloc(2 * sizeof(*inds));
+            d = string2data("dbincr0");
+            check(krb5_copy_data(context, &d, &inds[0]));
+            inds[0]->data[6] = val + 1;
+            inds[1] = NULL;
+            *auth_indicators = inds;
+            break;
+        }
+    }
+
     return 0;
 }
 
@@ -593,7 +614,7 @@ test_check_allowed_to_delegate(krb5_context context,
 
 kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
     KRB5_KDB_DAL_MAJOR_VERSION,             /* major version number */
-    1,                                      /* minor version number */
+    0,                                      /* minor version number */
     test_init,
     test_cleanup,
     test_open,
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index d98974b..9b41bc0 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -228,6 +228,11 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
 if '+97: [indcl]' not in out or '[inds1]' in out:
     fail('correct auth-indicator not seen for S4U2Proxy req')
 
+# Test alteration of auth indicators by KDB module (AS and TGS).
+realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=dummy dbincr1'])
+realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [dbincr2]')
+realm.run(['./adata', 'service/1'], expected_msg='+97: [dbincr3]')
+
 # Test that KDB module authdata is included in an AS request, by
 # default or with an explicit PAC request.
 mark('AS-REQ KDB module authdata')


More information about the cvs-krb5 mailing list