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