From a6bd9b64ea8a6853945f9fa0ca734573c77c8df0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Mar 2024 13:19:06 +0100 Subject: [PATCH] lib/krb5: add KRB5_AUTHDATA_TARGET_PRINCIPAL for gssapi exchanges Signed-off-by: Stefan Metzmacher --- lib/krb5/build_auth.c | 88 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/lib/krb5/build_auth.c b/lib/krb5/build_auth.c index 0ca33d3359..ae757f7b04 100644 --- a/lib/krb5/build_auth.c +++ b/lib/krb5/build_auth.c @@ -119,9 +119,90 @@ add_ap_options(krb5_context context, return ret; } +static krb5_error_code +add_target_principal(krb5_context context, + krb5_const_principal server, + krb5_authdata *auth_data) +{ + krb5_error_code ret; + AuthorizationDataElement ade; + char *s, *s2 = NULL; + size_t s2_len; + + if (server == NULL) { + return 0; + } + + ret = krb5_unparse_name_flags(context, server, + KRB5_PRINCIPAL_UNPARSE_DISPLAY, + &s); + if (ret) + return ret; + + { + size_t ucs2_len; + uint16_t *ucs2; + unsigned int flags; + + ret = wind_utf8ucs2_length(s, &ucs2_len); + if (ret) { + krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s); + free(s); + return ret; + } + + ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len); + if (ucs2 == NULL) { + free(s); + return krb5_enomem(context); + } + + ret = wind_utf8ucs2(s, ucs2, &ucs2_len); + if (ret) { + free(ucs2); + krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s); + free(s); + return ret; + } else + free(s); + + s2_len = (ucs2_len + 1) * 2; + s2 = malloc(s2_len); + if (s2 == NULL) { + free(ucs2); + return krb5_enomem(context); + } + + flags = WIND_RW_LE; + ret = wind_ucs2write(ucs2, ucs2_len, + &flags, s2, &s2_len); + free(ucs2); + if (ret) { + free(s2); + krb5_set_error_message(context, ret, "Failed to write to UCS-2 buffer"); + return ret; + } + + /* + * we do not want zero termination + */ + s2_len = ucs2_len * 2; + } + + ade.ad_type = KRB5_AUTHDATA_TARGET_PRINCIPAL; + ade.ad_data.length = s2_len; + ade.ad_data.data = s2; + + ret = add_AuthorizationData(auth_data, &ade); + free(s2); + + return ret; +} + static krb5_error_code make_ap_authdata(krb5_context context, krb5_boolean channel_bound, + krb5_const_principal server, krb5_authdata **auth_data) { krb5_error_code ret; @@ -147,6 +228,12 @@ make_ap_authdata(krb5_context context, return ret; } + ret = add_target_principal(context, server, &ad); + if (ret) { + free_AuthorizationData(&ad); + return ret; + } + ASN1_MALLOC_ENCODE(AuthorizationData, ir.data, ir.length, &ad, &len, ret); if (ret) { free_AuthorizationData(&ad); @@ -229,6 +316,7 @@ _krb5_build_authenticator (krb5_context context, */ ret = make_ap_authdata(context, channel_bound, + cred->server, &auth.authorization_data); if (ret) goto fail;