From e81bcb71f31bc644d0e85dd499c2b64210bfb38e Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Thu, 23 Dec 2021 15:31:12 +1100 Subject: [PATCH] kdc: add finalize_reply API to windc plugin Allow a windc plugin to finalize the KDC reply (including the encrypted ticket and reply parts) before encoding for transmission. --- kdc/kerberos5.c | 7 +++++++ kdc/krb5tgs.c | 4 ++++ kdc/windc.c | 24 ++++++++++++++++++++++++ kdc/windc_plugin.h | 6 +++++- tests/plugin/windc.c | 10 +++++++++- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/kdc/kerberos5.c b/kdc/kerberos5.c index 3e9dffdc8..48f025eb5 100644 --- a/kdc/kerberos5.c +++ b/kdc/kerberos5.c @@ -2745,6 +2745,13 @@ _kdc_as_rep(astgs_request_t r) } } + /* + * Last chance for plugins to update reply + */ + ret = _kdc_finalize_reply(r); + if (ret) + goto out; + /* * Don't send kvno from client entry if the pre-authentication * mechanism replaced the reply key. diff --git a/kdc/krb5tgs.c b/kdc/krb5tgs.c index 598855231..c98dab3a9 100644 --- a/kdc/krb5tgs.c +++ b/kdc/krb5tgs.c @@ -841,6 +841,10 @@ tgs_make_reply(astgs_request_t r, } } + ret = _kdc_finalize_reply(r); + if (ret) + goto out; + /* It is somewhat unclear where the etype in the following encryption should come from. What we have is a session key in the passed tgt, and a list of preferred etypes diff --git a/kdc/windc.c b/kdc/windc.c index d386b4604..81efd623a 100644 --- a/kdc/windc.c +++ b/kdc/windc.c @@ -234,6 +234,30 @@ _kdc_check_access(astgs_request_t r, METHOD_DATA *method_data) return ret; } +static krb5_error_code KRB5_LIB_CALL +finalize(krb5_context context, const void *plug, void *plugctx, void *userctx) +{ + krb5plugin_windc_ftable *ft = (krb5plugin_windc_ftable *)plug; + + if (ft->finalize_reply == NULL) + return KRB5_PLUGIN_NO_HANDLE; + return ft->finalize_reply((void *)plug, (astgs_request_t)userctx); +} + +krb5_error_code +_kdc_finalize_reply(astgs_request_t r) +{ + krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE; + + if (have_plugin) + ret = _krb5_plugin_run_f(r->context, &windc_plugin_data, 0, r, finalize); + + if (ret == KRB5_PLUGIN_NO_HANDLE) + ret = 0; + + return ret; +} + uintptr_t KRB5_CALLCONV kdc_get_instance(const char *libname) { diff --git a/kdc/windc_plugin.h b/kdc/windc_plugin.h index 0c2448492..9f5a35507 100644 --- a/kdc/windc_plugin.h +++ b/kdc/windc_plugin.h @@ -37,6 +37,7 @@ #define HEIMDAL_KDC_WINDC_PLUGIN_H 1 #include +#include /* * The PAC generate function should allocate a krb5_pac using @@ -77,8 +78,10 @@ typedef krb5_error_code hdb_entry_ex *, const char *, KDC_REQ *, METHOD_DATA *); +typedef krb5_error_code +(KRB5_CALLCONV *krb5plugin_windc_finalize_reply)(void *, astgs_request_t r); -#define KRB5_WINDC_PLUGIN_MINOR 7 +#define KRB5_WINDC_PLUGIN_MINOR 8 #define KRB5_WINDC_PLUGING_MINOR KRB5_WINDC_PLUGIN_MINOR typedef struct krb5plugin_windc_ftable { @@ -88,6 +91,7 @@ typedef struct krb5plugin_windc_ftable { krb5plugin_windc_pac_generate pac_generate; krb5plugin_windc_pac_verify pac_verify; krb5plugin_windc_client_access client_access; + krb5plugin_windc_finalize_reply finalize_reply; } krb5plugin_windc_ftable; #endif /* HEIMDAL_KDC_WINDC_PLUGIN_H */ diff --git a/tests/plugin/windc.c b/tests/plugin/windc.c index 8acbf2908..7096b963b 100644 --- a/tests/plugin/windc.c +++ b/tests/plugin/windc.c @@ -107,13 +107,21 @@ client_access(void *ctx, return 0; } +static krb5_error_code KRB5_CALLCONV +finalize_reply(void *ctx, astgs_request_t r) +{ + krb5_warnx(r->context, "finalize_reply"); + return 0; +} + static krb5plugin_windc_ftable windc = { KRB5_WINDC_PLUGING_MINOR, windc_init, windc_fini, pac_generate, pac_verify, - client_access + client_access, + finalize_reply }; static const krb5plugin_windc_ftable *const windc_plugins[] = {