lib/krb5: add TGS-REQ PA-DATA e.g. FOR_USER also to the outer req
We can't rely on having every KDC support FAST and should still support S4U2Self against such a KDC. We also have the order of the PA-DATA elements "corrected", KRB5_PADATA_TGS_REQ followed by KRB5_PADATA_FX_FAST and finally KRB5_PADATA_FOR_USER. While the inner PA-DATA only contains KRB5_PADATA_FOR_USER. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15002 Signed-off-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:

committed by
Jeffrey Altman

parent
422419ddde
commit
7b75136113
@@ -461,14 +461,15 @@ _krb5_fast_create_armor(krb5_context context,
|
||||
krb5_error_code
|
||||
_krb5_fast_wrap_req(krb5_context context,
|
||||
struct krb5_fast_state *state,
|
||||
krb5_data *checksum_data,
|
||||
KDC_REQ *req)
|
||||
{
|
||||
PA_FX_FAST_REQUEST fxreq;
|
||||
krb5_error_code ret;
|
||||
KrbFastReq fastreq;
|
||||
krb5_data data, aschecksum_data;
|
||||
krb5_data data, aschecksum_data, tgschecksum_data;
|
||||
const krb5_data *checksum_data = NULL;
|
||||
size_t size = 0;
|
||||
krb5_boolean readd_padata_to_outer = FALSE;
|
||||
|
||||
if (state->flags & KRB5_FAST_DISABLED) {
|
||||
_krb5_debug(context, 10, "fast disabled, not doing any fast wrapping");
|
||||
@@ -479,6 +480,7 @@ _krb5_fast_wrap_req(krb5_context context,
|
||||
memset(&fastreq, 0, sizeof(fastreq));
|
||||
krb5_data_zero(&data);
|
||||
krb5_data_zero(&aschecksum_data);
|
||||
krb5_data_zero(&tgschecksum_data);
|
||||
|
||||
if (state->armor_crypto == NULL)
|
||||
return check_fast(context, state);
|
||||
@@ -517,8 +519,6 @@ _krb5_fast_wrap_req(krb5_context context,
|
||||
ALLOC(req->req_body.till, 1);
|
||||
*req->req_body.till = 0;
|
||||
|
||||
heim_assert(checksum_data == NULL, "checksum data not NULL");
|
||||
|
||||
ASN1_MALLOC_ENCODE(KDC_REQ_BODY,
|
||||
aschecksum_data.data,
|
||||
aschecksum_data.length,
|
||||
@@ -529,14 +529,63 @@ _krb5_fast_wrap_req(krb5_context context,
|
||||
heim_assert(aschecksum_data.length == size, "ASN.1 internal error");
|
||||
|
||||
checksum_data = &aschecksum_data;
|
||||
|
||||
if (req->padata) {
|
||||
ret = copy_METHOD_DATA(req->padata, &fastreq.padata);
|
||||
free_METHOD_DATA(req->padata);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
const PA_DATA *tgs_req_ptr = NULL;
|
||||
int tgs_req_idx = 0;
|
||||
size_t i;
|
||||
|
||||
heim_assert(req->padata != NULL, "req->padata is NULL");
|
||||
|
||||
tgs_req_ptr = krb5_find_padata(req->padata->val,
|
||||
req->padata->len,
|
||||
KRB5_PADATA_TGS_REQ,
|
||||
&tgs_req_idx);
|
||||
heim_assert(tgs_req_ptr != NULL, "KRB5_PADATA_TGS_REQ not found");
|
||||
heim_assert(tgs_req_idx == 0, "KRB5_PADATA_TGS_REQ not first");
|
||||
|
||||
tgschecksum_data.data = tgs_req_ptr->padata_value.data;
|
||||
tgschecksum_data.length = tgs_req_ptr->padata_value.length;
|
||||
checksum_data = &tgschecksum_data;
|
||||
|
||||
/*
|
||||
* Now copy all remaining once to
|
||||
* the fastreq.padata and clear
|
||||
* them in the outer req first,
|
||||
* and remember to readd them later.
|
||||
*/
|
||||
readd_padata_to_outer = TRUE;
|
||||
|
||||
for (i = 1; i < req->padata->len; i++) {
|
||||
PA_DATA *val = &req->padata->val[i];
|
||||
|
||||
ret = krb5_padata_add(context,
|
||||
&fastreq.padata,
|
||||
val->padata_type,
|
||||
val->padata_value.data,
|
||||
val->padata_value.length);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("malloc: out of memory", ""));
|
||||
goto out;
|
||||
}
|
||||
val->padata_value.data = NULL;
|
||||
val->padata_value.length = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only TGS-REQ remaining
|
||||
*/
|
||||
req->padata->len = 1;
|
||||
}
|
||||
|
||||
if (req->padata) {
|
||||
ret = copy_METHOD_DATA(req->padata, &fastreq.padata);
|
||||
free_METHOD_DATA(req->padata);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
if (req->padata == NULL) {
|
||||
ALLOC(req->padata, 1);
|
||||
if (req->padata == NULL) {
|
||||
ret = krb5_enomem(context);
|
||||
@@ -592,6 +641,27 @@ _krb5_fast_wrap_req(krb5_context context,
|
||||
goto out;
|
||||
krb5_data_zero(&data);
|
||||
|
||||
if (readd_padata_to_outer) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < fastreq.padata.len; i++) {
|
||||
PA_DATA *val = &fastreq.padata.val[i];
|
||||
|
||||
ret = krb5_padata_add(context,
|
||||
req->padata,
|
||||
val->padata_type,
|
||||
val->padata_value.data,
|
||||
val->padata_value.length);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("malloc: out of memory", ""));
|
||||
goto out;
|
||||
}
|
||||
val->padata_value.data = NULL;
|
||||
val->padata_value.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free_KrbFastReq(&fastreq);
|
||||
free_PA_FX_FAST_REQUEST(&fxreq);
|
||||
|
@@ -239,20 +239,6 @@ init_tgs_req (krb5_context context,
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (padata) {
|
||||
if (t->padata == NULL) {
|
||||
ALLOC(t->padata, 1);
|
||||
if (t->padata == NULL) {
|
||||
ret = krb5_enomem(context);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = copy_METHOD_DATA(padata, t->padata);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = krb5_auth_con_init(context, &ac);
|
||||
if(ret)
|
||||
@@ -278,14 +264,6 @@ init_tgs_req (krb5_context context,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (t->padata == NULL) {
|
||||
ALLOC(t->padata, 1);
|
||||
if (t->padata == NULL) {
|
||||
ret = krb5_enomem(context);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = make_pa_tgs_req(context,
|
||||
&ac,
|
||||
&t->req_body,
|
||||
@@ -295,19 +273,17 @@ init_tgs_req (krb5_context context,
|
||||
if(ret)
|
||||
goto fail;
|
||||
|
||||
if (state) {
|
||||
state->armor_ac = ac;
|
||||
ret = _krb5_fast_create_armor(context, state, NULL);
|
||||
state->armor_ac = NULL;
|
||||
if (ret)
|
||||
goto fail;
|
||||
/*
|
||||
* Add KRB5_PADATA_TGS_REQ first
|
||||
* followed by all others.
|
||||
*/
|
||||
|
||||
ret = _krb5_fast_wrap_req(context, state, &tgs_req, t);
|
||||
if (ret)
|
||||
if (t->padata == NULL) {
|
||||
ALLOC(t->padata, 1);
|
||||
if (t->padata == NULL) {
|
||||
ret = krb5_enomem(context);
|
||||
goto fail;
|
||||
|
||||
/* Its ok if there is no fast in the TGS-REP, older heimdal only support it in the AS code path */
|
||||
state->flags &= ~KRB5_FAST_EXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
ret = krb5_padata_add(context, t->padata, KRB5_PADATA_TGS_REQ,
|
||||
@@ -317,6 +293,48 @@ init_tgs_req (krb5_context context,
|
||||
|
||||
krb5_data_zero(&tgs_req);
|
||||
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < padata->len; i++) {
|
||||
const PA_DATA *val1 = &padata->val[i];
|
||||
PA_DATA val2;
|
||||
|
||||
ret = copy_PA_DATA(val1, &val2);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("malloc: out of memory", ""));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = krb5_padata_add(context, t->padata,
|
||||
val2.padata_type,
|
||||
val2.padata_value.data,
|
||||
val2.padata_value.length);
|
||||
if (ret) {
|
||||
free_PA_DATA(&val2);
|
||||
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("malloc: out of memory", ""));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state) {
|
||||
state->armor_ac = ac;
|
||||
ret = _krb5_fast_create_armor(context, state, NULL);
|
||||
state->armor_ac = NULL;
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = _krb5_fast_wrap_req(context, state, t);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* Its ok if there is no fast in the TGS-REP, older heimdal only support it in the AS code path */
|
||||
state->flags &= ~KRB5_FAST_EXPECTED;
|
||||
}
|
||||
|
||||
ret = krb5_auth_con_getlocalsubkey(context, ac, subkey);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
@@ -3392,7 +3392,6 @@ init_creds_step(krb5_context context,
|
||||
|
||||
ret = _krb5_fast_wrap_req(context,
|
||||
&ctx->fast_state,
|
||||
NULL,
|
||||
&req2);
|
||||
|
||||
krb5_data_free(&checksum_data);
|
||||
|
Reference in New Issue
Block a user