1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s4:torture/krb5/kdc-heimdal: Automatically determine AS-REP enctype to check against

This enables us to more easily switch to a different algorithm to find
the strongest key in _kdc_find_etype().

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Joseph Sutton 2021-06-21 14:14:48 +12:00 committed by Stefan Metzmacher
parent ab221c1b3e
commit bf71fa038e
3 changed files with 104 additions and 12 deletions

View File

@ -291,10 +291,6 @@
^samba4.winbind.struct.lookup_name_sid\(ad_member:local\)
^samba4.winbind.struct.getdcname\(nt4_member:local\) # Works in other modes, just not against the classic/NT4 DC
#
# Differences in our KDC compared to windows
#
^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally
#
# This will fail against the classic DC, because it requires kerberos
#
^samba4.winbind.pac.*\(nt4_member:local\) # No KDC on a classic DC
@ -333,7 +329,7 @@
#
^samba4.smb.signing.*disabled.*client-protection=off.*\(ad_dc\)
# fl2000dc doesn't support AES
^samba4.krb5.kdc.*as-req-aes.*fl2000dc
^samba4.krb5.kdc.*as-req-aes.fl2000dc
# nt4_member and ad_member don't support ntlmv1 (not even over SMB1)
^samba3.blackbox.smbclient_auth.plain.*option=clientntlmv2auth=no.member.creds.*as.user.*_member
^samba3.blackbox.smbclient_auth.plain.*option=clientntlmv2auth=no.*mNT1.member.creds.*as.user.*_member

View File

@ -641,3 +641,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2008r2dc
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2003dc
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2008r2dc
# Differences in our KDC compared to windows
#
^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally
#
# fl2000dc doesn't support AES
^samba4.krb5.kdc.*as-req-aes.*fl2000dc

View File

@ -204,11 +204,12 @@ static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
const krb5_data *reply,
krb5_enctype expected_enctype)
const krb5_enctype* allowed_enctypes)
{
ENCTYPE reply_enctype = { 0 };
size_t used = 0;
int rc;
int expected_enctype = ETYPE_NULL;
rc = decode_AS_REP(reply->data,
reply->length,
@ -230,8 +231,84 @@ static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_
test_context->as_rep.ticket.enc_part.kvno,
"Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
reply_enctype = test_context->as_rep.enc_part.etype;
if (test_context->as_req.padata) {
/*
* If the AS-REQ contains a PA-ENC-TIMESTAMP, then
* that encryption type is used to determine the reply
* enctype.
*/
int i = 0;
const PA_DATA *pa = krb5_find_padata(test_context->as_req.padata->val,
test_context->as_req.padata->len,
KRB5_PADATA_ENC_TIMESTAMP,
&i);
if (pa) {
EncryptedData ed;
size_t len;
krb5_error_code ret = decode_EncryptedData(pa->padata_value.data,
pa->padata_value.length,
&ed, &len);
torture_assert_int_equal(test_context->tctx,
ret,
0,
"decode_EncryptedData failed");
expected_enctype = ed.etype;
free_EncryptedData(&ed);
}
}
if (expected_enctype == ETYPE_NULL) {
/*
* Otherwise, find the strongest enctype contained in
* the AS-REQ supported enctypes list.
*/
const krb5_enctype *p = NULL;
for (p = krb5_kerberos_enctypes(NULL); *p != (krb5_enctype)ETYPE_NULL; ++p) {
int j;
if ((*p == (krb5_enctype)ETYPE_AES256_CTS_HMAC_SHA1_96 ||
*p == (krb5_enctype)ETYPE_AES128_CTS_HMAC_SHA1_96) &&
!test_context->as_req.req_body.kdc_options.canonicalize)
{
/*
* AES encryption types are only used here when
* we set the canonicalize flag, as the salt
* needs to match.
*/
continue;
}
for (j = 0; j < test_context->as_req.req_body.etype.len; ++j) {
krb5_enctype etype = test_context->as_req.req_body.etype.val[j];
if (*p == etype) {
expected_enctype = etype;
break;
}
}
if (expected_enctype != (krb5_enctype)ETYPE_NULL) {
break;
}
}
}
{
/* Ensure the enctype to check against is an expected type. */
const krb5_enctype *p = NULL;
bool found = false;
for (p = allowed_enctypes; *p != (krb5_enctype)ETYPE_NULL; ++p) {
if (*p == expected_enctype) {
found = true;
break;
}
}
torture_assert(test_context->tctx,
found,
"Calculated enctype not in allowed list");
}
reply_enctype = test_context->as_rep.enc_part.etype;
torture_assert_int_equal(test_context->tctx,
reply_enctype, expected_enctype,
"Ticket encrypted with invalid algorithm");
@ -310,7 +387,7 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
if (test_context->packet_count == 0) {
ok = torture_check_krb5_error(test_context,
recv_buf,
KRB5KRB_ERR_RESPONSE_TOO_BIG,
KRB5KDC_ERR_PREAUTH_REQUIRED,
false);
torture_assert(test_context->tctx,
ok,
@ -318,7 +395,7 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
} else if (test_context->packet_count == 1) {
ok = torture_check_krb5_error(test_context,
recv_buf,
KRB5KDC_ERR_PREAUTH_REQUIRED,
KRB5KRB_ERR_RESPONSE_TOO_BIG,
false);
torture_assert(test_context->tctx,
ok,
@ -411,9 +488,13 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
ok,
"torture_check_krb5_error failed");
} else {
const krb5_enctype allowed_enctypes[] = {
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_NULL
};
ok = torture_check_krb5_as_rep_enctype(test_context,
recv_buf,
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96);
allowed_enctypes);
torture_assert(test_context->tctx,
ok,
"torture_check_krb5_as_rep_enctype failed");
@ -443,9 +524,13 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
ok,
"torture_check_krb5_error failed");
} else {
const krb5_enctype allowed_enctypes[] = {
KRB5_ENCTYPE_ARCFOUR_HMAC_MD5,
ETYPE_NULL
};
ok = torture_check_krb5_as_rep_enctype(test_context,
recv_buf,
KRB5_ENCTYPE_ARCFOUR_HMAC_MD5);
allowed_enctypes);
torture_assert(test_context->tctx,
ok,
"torture_check_krb5_as_rep_enctype failed");
@ -475,9 +560,14 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
ok,
"torture_check_krb5_error failed");
} else {
const krb5_enctype allowed_enctypes[] = {
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
KRB5_ENCTYPE_ARCFOUR_HMAC_MD5,
ETYPE_NULL
};
ok = torture_check_krb5_as_rep_enctype(test_context,
recv_buf,
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96);
allowed_enctypes);
torture_assert(test_context->tctx,
ok,
"torture_check_krb5_as_rep_enctype failed");