kdc: allow GSS error tokens in PA reply

If GSS_Accept_sec_context() returns an error status and error token, ensure we
include the error token in the PA-GSS padata in the KRB-ERROR reply, rather
than bailing out early.
This commit is contained in:
Luke Howard
2021-08-15 15:39:58 +10:00
parent 432fe0ad56
commit df9e74b292
2 changed files with 24 additions and 33 deletions

View File

@@ -41,6 +41,8 @@
#include "gss_preauth_authorizer_plugin.h"
struct gss_client_params {
OM_uint32 major_status;
OM_uint32 minor_status;
gss_ctx_id_t context_handle;
gss_name_t initiator_name;
gss_OID mech_type;
@@ -215,6 +217,8 @@ _kdc_gss_rd_padata(astgs_request_t r,
goto out;
}
gcp->major_status = GSS_S_NO_CONTEXT;
ret = pa_gss_get_context_state(r, gcp);
if (ret)
goto out;
@@ -242,6 +246,10 @@ _kdc_gss_rd_padata(astgs_request_t r,
&gcp->flags,
&gcp->lifetime,
NULL); /* delegated_cred_handle */
gcp->major_status = major;
gcp->minor_status = minor;
if (GSS_ERROR(major)) {
pa_gss_display_status(r, major, minor, gcp,
"Failed to accept GSS security context");
@@ -256,7 +264,7 @@ _kdc_gss_rd_padata(astgs_request_t r,
goto out;
}
*open = (major == GSS_S_COMPLETE);
*open = (gcp->major_status == GSS_S_COMPLETE);
out:
gss_release_cred(&minor, &cred);
@@ -567,26 +575,7 @@ _kdc_gss_mk_pa_reply(astgs_request_t r,
krb5_error_code ret;
const KDC_REQ *req = &r->req;
OM_uint32 major, minor;
int open;
major = gss_inquire_context(&minor,
gcp->context_handle,
NULL, /* initiator_name */
NULL, /* target_name */
NULL, /* lifetime_req */
NULL, /* mech_type */
NULL, /* ctx_flags */
NULL, /* locally_initiated */
&open);
if (GSS_ERROR(major)) {
pa_gss_display_status(r, major, minor, gcp,
"Failed to inquire GSS context");
ret = _krb5_gss_map_error(major, minor);
goto out;
}
if (open) {
if (gcp->major_status == GSS_S_COMPLETE) {
krb5_enctype enctype;
uint32_t kfe = 0;
krb5_keyblock *reply_key = NULL;
@@ -611,23 +600,28 @@ _kdc_gss_mk_pa_reply(astgs_request_t r,
krb5_free_keyblock_contents(r->context, &r->reply_key);
r->reply_key = *reply_key;
free(reply_key);
} else {
} else if (gcp->major_status == GSS_S_CONTINUE_NEEDED) {
ret = pa_gss_set_context_state(r, gcp);
if (ret)
goto out;
}
/* only return padata in error case if we have an error token */
if (!GSS_ERROR(gcp->major_status) || gcp->output_token.length) {
ret = krb5_padata_add(r->context, &r->outpadata, KRB5_PADATA_GSS,
gcp->output_token.value, gcp->output_token.length);
if (ret)
goto out;
}
/* token is now owned by outpadata */
gcp->output_token.length = 0;
gcp->output_token.value = NULL;
if (!open)
if (gcp->major_status == GSS_S_CONTINUE_NEEDED)
ret = KRB5_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED;
else
ret = _krb5_gss_map_error(gcp->major_status, gcp->minor_status);
out:
return ret;

View File

@@ -514,14 +514,11 @@ pa_gss_validate(astgs_request_t r, const PA_DATA *pa)
gss_client_params *gcp = NULL;
char *client_name = NULL;
krb5_error_code ret;
int open;
int open = 0;
ret = _kdc_gss_rd_padata(r, pa, &gcp, &open);
if (ret) {
_kdc_r_log(r, 4, "Failed to decode GSS PA-DATA -- %s",
r->cname);
goto out;
}
if (ret && gcp == NULL)
return ret;
if (open) {
ret = _kdc_gss_check_client(r, gcp, &client_name);