From e1ab0307177ceb928e9b75c419661b3d4730a7f2 Mon Sep 17 00:00:00 2001 From: "Roland C. Dowdeswell" Date: Thu, 28 May 2026 16:56:18 +0100 Subject: [PATCH] kdc: reject kx509 requests when disabled Fixes #1378. --- kdc/kx509.c | 31 ++++++++++++------------------- tests/kdc/Makefile.am | 1 + tests/kdc/check-pkinit.in | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/kdc/kx509.c b/kdc/kx509.c index 29c9d64e3..03cdc9b8a 100644 --- a/kdc/kx509.c +++ b/kdc/kx509.c @@ -399,7 +399,6 @@ mk_error_response(krb5_context context, Kx509Response rep; const char *msg; char *freeme0 = NULL; - char *freeme1 = NULL; va_list ap; if (code != 0) { @@ -417,9 +416,6 @@ mk_error_response(krb5_context context, va_end(ap); } - if (!reqctx->config->enable_kx509) - code = KRB5KDC_ERR_POLICY; - /* Make sure we only send RFC4120 and friends wire protocol error codes */ if (code) { if (code == KX509_ERR_NONE) { @@ -441,12 +437,6 @@ mk_error_response(krb5_context context, msg = freeme0; va_end(ap); - if (!reqctx->config->enable_kx509 && - asprintf(&freeme1, "kx509 service is disabled (%s)", msg) > -1 && - freeme1 != NULL) { - msg = freeme1; - } - rep.hash = NULL; rep.certificate = NULL; rep.error_code = code; @@ -468,7 +458,6 @@ mk_error_response(krb5_context context, free(rep.e_text); free(rep.hash); free(freeme0); - free(freeme1); return ret; } @@ -900,14 +889,15 @@ _kdc_do_kx509(kx509_req_context r) if (r->req.authenticator.length == 0) { /* * Unauthenticated kx509 service availability probe. - * - * mk_error_response() will check whether the service is enabled and - * possibly change the error code and message. */ is_probe = 1; kdc_audit_addkv((kdc_request_t)r, 0, "probe", "unauthenticated"); - ret = mk_error_response(r->context, r, 4, 0, - "kx509 service is available"); + if (!r->config->enable_kx509) + ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY, + "kx509 service is disabled"); + else + ret = mk_error_response(r->context, r, 4, 0, + "kx509 service is available"); goto out; } @@ -938,6 +928,12 @@ _kdc_do_kx509(kx509_req_context r) * Provided we got the session key, errors past this point will be * authenticated. */ + if (ret == 0 && !r->config->enable_kx509) { + ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY, + "kx509 service is disabled"); + goto out; + } + if (ret == 0) ret = krb5_ticket_get_client(r->context, ticket, &cprincipal); @@ -983,9 +979,6 @@ _kdc_do_kx509(kx509_req_context r) if (r->req.pk_key.length == 0) { /* * The request is an authenticated kx509 service availability probe. - * - * mk_error_response() will check whether the service is enabled and - * possibly change the error code and message. */ is_probe = 1; kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated"); diff --git a/tests/kdc/Makefile.am b/tests/kdc/Makefile.am index 6de1c4a1b..86e60a793 100644 --- a/tests/kdc/Makefile.am +++ b/tests/kdc/Makefile.am @@ -361,6 +361,7 @@ CLEANFILES= \ krb5-master2.conf \ krb5-pkinit-win.conf \ krb5-pkinit.conf \ + krb5-pkinit-no-kx509.conf \ krb5-pkinit2.conf \ krb5-bx509.conf \ krb5-httpkadmind.conf \ diff --git a/tests/kdc/check-pkinit.in b/tests/kdc/check-pkinit.in index b1370a44a..d9ad4b738 100644 --- a/tests/kdc/check-pkinit.in +++ b/tests/kdc/check-pkinit.in @@ -195,6 +195,8 @@ ${hxtool} issue-certificate \ --certificate="FILE:kx509-template.crt" || exit 1 echo foo > ${objdir}/foopassword +sed 's/enable_kx509 = true/enable_kx509 = false/g' \ + "${objdir}/krb5-pkinit.conf" > "${objdir}/krb5-pkinit-no-kx509.conf" || exit 1 echo Starting kdc ; > messages.log KRB5_CONFIG="${objdir}/krb5-pkinit2.conf" @@ -283,6 +285,26 @@ fi echo "Check kx509 certificate acquisition" ${kx509} -s || { ec=1 ; eval "${testfailed}"; } ${kx509} -o PEM-FILE:${objdir}/kx509.pem || { ec=1 ; eval "${testfailed}"; } +${kx509} -K FILE:${keyfile2} \ + -o PEM-FILE:${objdir}/kx509-keyed.pem || { ec=1 ; eval "${testfailed}"; } + +echo "Restarting kdc with kx509 disabled ($kdcpid)" +sh ${leaks_kill} kdc $kdcpid || ec=1 +KRB5_CONFIG="${objdir}/krb5-pkinit-no-kx509.conf" +${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; } +kdcpid=`getpid kdc` + +echo "Check kx509 cannot be bypassed when disabled"; > messages.log +${kx509} -K FILE:${keyfile2} \ + -o PEM-FILE:${objdir}/kx509-disabled.pem 2>/dev/null && \ + { echo "kx509 succeeded while [kdc] enable_kx509 was false"; ec=1 ; eval "${testfailed}"; } + +echo "Restarting kdc with kx509 enabled ($kdcpid)" +sh ${leaks_kill} kdc $kdcpid || ec=1 +KRB5_CONFIG="${objdir}/krb5-pkinit.conf" +${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; } +kdcpid=`getpid kdc` + ${kdestroy} echo "Check PKINIT w/ kx509 certificate"