mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
b2de5a81bf
Add one use of popt_set_cmdline_credentials(). Fix 80 column limits when cmdline_credentials changes to popt_get_cmdline_credentials(). Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
796 lines
21 KiB
C
796 lines
21 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
|
|
Validate the krb5 pac generation routines
|
|
|
|
Copyright (c) 2016 Andreas Schneider <asn@samba.org>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "system/kerberos.h"
|
|
#include "system/time.h"
|
|
#include "torture/smbtorture.h"
|
|
#include "torture/winbind/proto.h"
|
|
#include "torture/krb5/proto.h"
|
|
#include "auth/credentials/credentials.h"
|
|
#include "lib/cmdline/popt_common.h"
|
|
#include "source4/auth/kerberos/kerberos.h"
|
|
#include "source4/auth/kerberos/kerberos_util.h"
|
|
#include "lib/util/util_net.h"
|
|
|
|
#define krb5_is_app_tag(dat,tag) \
|
|
((dat != NULL) && (dat)->length && \
|
|
((((dat)->data[0] & ~0x20) == ((tag) | 0x40))))
|
|
|
|
#define krb5_is_as_req(dat) krb5_is_app_tag(dat, 10)
|
|
#define krb5_is_as_rep(dat) krb5_is_app_tag(dat, 11)
|
|
#define krb5_is_krb_error(dat) krb5_is_app_tag(dat, 30)
|
|
|
|
enum torture_krb5_test {
|
|
TORTURE_KRB5_TEST_PLAIN,
|
|
TORTURE_KRB5_TEST_PAC_REQUEST,
|
|
TORTURE_KRB5_TEST_BREAK_PW,
|
|
TORTURE_KRB5_TEST_CLOCK_SKEW,
|
|
TORTURE_KRB5_TEST_AES,
|
|
TORTURE_KRB5_TEST_RC4,
|
|
TORTURE_KRB5_TEST_AES_RC4,
|
|
};
|
|
|
|
struct torture_krb5_context {
|
|
struct torture_context *tctx;
|
|
krb5_context krb5_context;
|
|
enum torture_krb5_test test;
|
|
int recv_packet_count;
|
|
krb5_kdc_req *as_req;
|
|
krb5_kdc_rep *as_rep;
|
|
};
|
|
|
|
krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
|
|
|
|
krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
|
|
krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
|
|
|
|
krb5_error_code decode_krb5_padata_sequence(const krb5_data *output, krb5_pa_data ***rep);
|
|
|
|
void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
|
|
void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
|
|
void krb5_free_pa_data(krb5_context ctx, krb5_pa_data **data);
|
|
|
|
static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
|
|
krb5_context context,
|
|
const krb5_data *message)
|
|
{
|
|
krb5_error_code code;
|
|
int nktypes;
|
|
|
|
code = decode_krb5_as_req(message, &test_context->as_req);
|
|
torture_assert_int_equal(test_context->tctx,
|
|
code, 0,
|
|
"decode_as_req failed");
|
|
torture_assert_int_equal(test_context->tctx,
|
|
test_context->as_req->msg_type,
|
|
KRB5_AS_REQ,
|
|
"Not a AS REQ");
|
|
|
|
nktypes = test_context->as_req->nktypes;
|
|
torture_assert_int_not_equal(test_context->tctx,
|
|
nktypes, 0,
|
|
"No keytypes");
|
|
|
|
return true;
|
|
}
|
|
|
|
static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
|
|
void *data,
|
|
const krb5_data *realm,
|
|
const krb5_data *message,
|
|
krb5_data **new_message_out,
|
|
krb5_data **new_reply_out)
|
|
{
|
|
bool ok;
|
|
struct torture_krb5_context *test_context =
|
|
(struct torture_krb5_context *)data;
|
|
|
|
switch (test_context->test)
|
|
{
|
|
case TORTURE_KRB5_TEST_PLAIN:
|
|
case TORTURE_KRB5_TEST_PAC_REQUEST:
|
|
case TORTURE_KRB5_TEST_BREAK_PW:
|
|
case TORTURE_KRB5_TEST_CLOCK_SKEW:
|
|
case TORTURE_KRB5_TEST_AES:
|
|
case TORTURE_KRB5_TEST_RC4:
|
|
case TORTURE_KRB5_TEST_AES_RC4:
|
|
ok = torture_check_krb5_as_req(test_context,
|
|
context,
|
|
message);
|
|
if (!ok) {
|
|
return KRB5KDC_ERR_BADOPTION;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* We need these function to validate packets because our torture macros
|
|
* do a 'return false' on error.
|
|
*/
|
|
static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
|
|
krb5_context context,
|
|
const krb5_data *reply,
|
|
krb5_error_code error_code,
|
|
bool check_pa_data)
|
|
|
|
{
|
|
krb5_error *krb_error;
|
|
krb5_error_code code;
|
|
|
|
code = decode_krb5_error(reply, &krb_error);
|
|
torture_assert_int_equal(test_context->tctx,
|
|
code,
|
|
0,
|
|
"decode_krb5_error failed");
|
|
|
|
torture_assert_int_equal(test_context->tctx,
|
|
krb_error->error,
|
|
error_code - KRB5KDC_ERR_NONE,
|
|
"Got wrong error code");
|
|
|
|
if (check_pa_data) {
|
|
krb5_pa_data **d, **pa_data = NULL;
|
|
bool timestamp_found = false;
|
|
|
|
torture_assert_int_not_equal(test_context->tctx,
|
|
krb_error->e_data.length, 0,
|
|
"No e-data returned");
|
|
|
|
code = decode_krb5_padata_sequence(&krb_error->e_data,
|
|
&pa_data);
|
|
torture_assert_int_equal(test_context->tctx,
|
|
code,
|
|
0,
|
|
"decode_krb5_padata_sequence failed");
|
|
|
|
for (d = pa_data; d != NULL; d++) {
|
|
if ((*d)->pa_type == KRB5_PADATA_ENC_TIMESTAMP) {
|
|
timestamp_found = true;
|
|
break;
|
|
}
|
|
}
|
|
torture_assert(test_context->tctx,
|
|
timestamp_found,
|
|
"Encrypted timestamp not found");
|
|
|
|
krb5_free_pa_data(context, pa_data);
|
|
}
|
|
|
|
krb5_free_error(context, krb_error);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
|
|
krb5_context context,
|
|
const krb5_data *reply)
|
|
{
|
|
krb5_error_code code;
|
|
bool ok;
|
|
|
|
code = decode_krb5_as_rep(reply, &test_context->as_rep);
|
|
torture_assert_int_equal(test_context->tctx,
|
|
code,
|
|
0,
|
|
"decode_krb5_as_rep failed");
|
|
|
|
torture_assert(test_context->tctx,
|
|
test_context->as_rep->ticket->enc_part.kvno,
|
|
"No KVNO set");
|
|
|
|
ok = torture_setting_bool(test_context->tctx,
|
|
"expect_cached_at_rodc",
|
|
false);
|
|
if (ok) {
|
|
torture_assert_int_not_equal(test_context->tctx,
|
|
test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
|
|
0,
|
|
"Did not get a RODC number in the KVNO");
|
|
} else {
|
|
torture_assert_int_equal(test_context->tctx,
|
|
test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
|
|
0,
|
|
"Unexpecedly got a RODC number in the KVNO");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
|
|
krb5_context context,
|
|
const krb5_data *reply,
|
|
krb5_enctype expected_enctype)
|
|
{
|
|
krb5_enctype reply_enctype;
|
|
bool ok;
|
|
|
|
ok = torture_check_krb5_as_rep(test_context,
|
|
context,
|
|
reply);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
|
|
reply_enctype = test_context->as_rep->enc_part.enctype;
|
|
|
|
torture_assert_int_equal(test_context->tctx,
|
|
reply_enctype, expected_enctype,
|
|
"Ticket encrypted with invalid algorithm");
|
|
|
|
return true;
|
|
}
|
|
|
|
static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
|
|
void *data,
|
|
krb5_error_code kdc_code,
|
|
const krb5_data *realm,
|
|
const krb5_data *message,
|
|
const krb5_data *reply,
|
|
krb5_data **new_reply_out)
|
|
{
|
|
struct torture_krb5_context *test_context =
|
|
(struct torture_krb5_context *)data;
|
|
krb5_error_code code;
|
|
bool ok = true;
|
|
|
|
torture_comment(test_context->tctx,
|
|
"PACKET COUNT = %d\n",
|
|
test_context->recv_packet_count);
|
|
|
|
torture_comment(test_context->tctx,
|
|
"KRB5_AS_REP = %d\n",
|
|
krb5_is_as_req(reply));
|
|
|
|
torture_comment(test_context->tctx,
|
|
"KRB5_ERROR = %d\n",
|
|
krb5_is_krb_error(reply));
|
|
|
|
torture_comment(test_context->tctx,
|
|
"KDC ERROR CODE = %d\n",
|
|
kdc_code);
|
|
|
|
switch (test_context->test)
|
|
{
|
|
case TORTURE_KRB5_TEST_PLAIN:
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
} else {
|
|
ok = torture_check_krb5_as_rep(test_context,
|
|
context,
|
|
reply);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_as_rep failed");
|
|
}
|
|
|
|
torture_assert_goto(test_context->tctx,
|
|
test_context->recv_packet_count < 2,
|
|
ok,
|
|
out,
|
|
"Too many packets");
|
|
|
|
break;
|
|
case TORTURE_KRB5_TEST_PAC_REQUEST:
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KRB_ERR_RESPONSE_TOO_BIG,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
} else if (test_context->recv_packet_count == 1) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
} else if (krb5_is_krb_error(reply)) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KRB_ERR_RESPONSE_TOO_BIG,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
} else {
|
|
ok = torture_check_krb5_as_rep(test_context,
|
|
context,
|
|
reply);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_as_rep failed");
|
|
}
|
|
|
|
torture_assert_goto(test_context->tctx,
|
|
test_context->recv_packet_count < 3,
|
|
ok,
|
|
out,
|
|
"Too many packets");
|
|
break;
|
|
case TORTURE_KRB5_TEST_BREAK_PW:
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
} else if (test_context->recv_packet_count == 1) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_FAILED,
|
|
true);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
}
|
|
|
|
torture_assert_goto(test_context->tctx,
|
|
test_context->recv_packet_count < 2,
|
|
ok,
|
|
out,
|
|
"Too many packets");
|
|
break;
|
|
case TORTURE_KRB5_TEST_CLOCK_SKEW:
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
} else if (test_context->recv_packet_count == 1) {
|
|
/*
|
|
* This only works if kdc_timesync 0 is set in krb5.conf
|
|
*
|
|
* See commit 5f39a4438eafd693a3eb8366bbc3901efe62e538
|
|
* in the MIT Kerberos source tree.
|
|
*/
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KRB_AP_ERR_SKEW,
|
|
false);
|
|
torture_assert_goto(test_context->tctx,
|
|
ok,
|
|
ok,
|
|
out,
|
|
"torture_check_krb5_error failed");
|
|
}
|
|
|
|
torture_assert_goto(test_context->tctx,
|
|
test_context->recv_packet_count < 2,
|
|
ok,
|
|
out,
|
|
"Too many packets");
|
|
break;
|
|
case TORTURE_KRB5_TEST_AES:
|
|
torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES\n");
|
|
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
ok = torture_check_krb5_as_rep_enctype(test_context,
|
|
context,
|
|
reply,
|
|
ENCTYPE_AES256_CTS_HMAC_SHA1_96);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
case TORTURE_KRB5_TEST_RC4:
|
|
torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_RC4\n");
|
|
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
ok = torture_check_krb5_as_rep_enctype(test_context,
|
|
context,
|
|
reply,
|
|
ENCTYPE_ARCFOUR_HMAC);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
case TORTURE_KRB5_TEST_AES_RC4:
|
|
torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES_RC4\n");
|
|
|
|
if (test_context->recv_packet_count == 0) {
|
|
ok = torture_check_krb5_error(test_context,
|
|
context,
|
|
reply,
|
|
KRB5KDC_ERR_PREAUTH_REQUIRED,
|
|
false);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
ok = torture_check_krb5_as_rep_enctype(test_context,
|
|
context,
|
|
reply,
|
|
ENCTYPE_AES256_CTS_HMAC_SHA1_96);
|
|
if (!ok) {
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
code = kdc_code;
|
|
out:
|
|
if (!ok) {
|
|
code = EINVAL;
|
|
}
|
|
|
|
/* Cleanup */
|
|
krb5_free_kdc_req(test_context->krb5_context, test_context->as_req);
|
|
krb5_free_kdc_rep(test_context->krb5_context, test_context->as_rep);
|
|
|
|
test_context->recv_packet_count++;
|
|
|
|
return code;
|
|
}
|
|
|
|
static bool torture_krb5_init_context(struct torture_context *tctx,
|
|
enum torture_krb5_test test,
|
|
struct smb_krb5_context **smb_krb5_context)
|
|
{
|
|
krb5_error_code code;
|
|
|
|
struct torture_krb5_context *test_context = talloc_zero(tctx,
|
|
struct torture_krb5_context);
|
|
torture_assert(tctx, test_context != NULL, "Failed to allocate");
|
|
|
|
test_context->test = test;
|
|
test_context->tctx = tctx;
|
|
|
|
code = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
|
|
torture_assert_int_equal(tctx, code, 0, "smb_krb5_init_context failed");
|
|
|
|
test_context->krb5_context = (*smb_krb5_context)->krb5_context;
|
|
|
|
krb5_set_kdc_send_hook((*smb_krb5_context)->krb5_context,
|
|
torture_krb5_pre_send_test,
|
|
test_context);
|
|
|
|
krb5_set_kdc_recv_hook((*smb_krb5_context)->krb5_context,
|
|
torture_krb5_post_recv_test,
|
|
test_context);
|
|
|
|
return true;
|
|
}
|
|
static bool torture_krb5_as_req_creds(struct torture_context *tctx,
|
|
struct cli_credentials *credentials,
|
|
enum torture_krb5_test test)
|
|
{
|
|
krb5_get_init_creds_opt *krb_options = NULL;
|
|
struct smb_krb5_context *smb_krb5_context;
|
|
enum credentials_obtained obtained;
|
|
const char *error_string;
|
|
const char *password;
|
|
krb5_principal principal;
|
|
krb5_error_code code;
|
|
krb5_creds my_creds;
|
|
bool ok;
|
|
|
|
ok = torture_krb5_init_context(tctx, test, &smb_krb5_context);
|
|
torture_assert(tctx, ok, "torture_krb5_init_context failed");
|
|
|
|
code = principal_from_credentials(tctx,
|
|
credentials,
|
|
smb_krb5_context,
|
|
&principal,
|
|
&obtained,
|
|
&error_string);
|
|
torture_assert_int_equal(tctx, code, 0, error_string);
|
|
|
|
password = cli_credentials_get_password(credentials);
|
|
|
|
switch (test)
|
|
{
|
|
case TORTURE_KRB5_TEST_PLAIN:
|
|
break;
|
|
case TORTURE_KRB5_TEST_PAC_REQUEST:
|
|
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
|
|
code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
|
|
&krb_options);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_get_init_creds_opt_alloc failed");
|
|
|
|
code = krb5_get_init_creds_opt_set_pac_request(smb_krb5_context->krb5_context,
|
|
krb_options,
|
|
1);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_get_init_creds_opt_set_pac_request failed");
|
|
#endif
|
|
break;
|
|
case TORTURE_KRB5_TEST_BREAK_PW:
|
|
password = "NOT the password";
|
|
break;
|
|
case TORTURE_KRB5_TEST_CLOCK_SKEW:
|
|
code = krb5_set_real_time(smb_krb5_context->krb5_context,
|
|
time(NULL) + 3600,
|
|
0);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_set_real_time failed");
|
|
break;
|
|
case TORTURE_KRB5_TEST_AES: {
|
|
krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96 };
|
|
|
|
code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
|
|
&krb_options);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_get_init_creds_opt_alloc failed");
|
|
|
|
krb5_get_init_creds_opt_set_etype_list(krb_options,
|
|
etype,
|
|
1);
|
|
break;
|
|
}
|
|
case TORTURE_KRB5_TEST_RC4: {
|
|
krb5_enctype etype[] = { ENCTYPE_ARCFOUR_HMAC };
|
|
|
|
code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
|
|
&krb_options);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_get_init_creds_opt_alloc failed");
|
|
|
|
krb5_get_init_creds_opt_set_etype_list(krb_options,
|
|
etype,
|
|
1);
|
|
break;
|
|
}
|
|
case TORTURE_KRB5_TEST_AES_RC4: {
|
|
krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_ARCFOUR_HMAC };
|
|
|
|
code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
|
|
&krb_options);
|
|
torture_assert_int_equal(tctx,
|
|
code, 0,
|
|
"krb5_get_init_creds_opt_alloc failed");
|
|
|
|
|
|
krb5_get_init_creds_opt_set_etype_list(krb_options,
|
|
etype,
|
|
2);
|
|
break;
|
|
}
|
|
}
|
|
|
|
code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
|
|
&my_creds,
|
|
principal,
|
|
password,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
krb_options);
|
|
krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context,
|
|
krb_options);
|
|
|
|
switch (test)
|
|
{
|
|
case TORTURE_KRB5_TEST_PLAIN:
|
|
case TORTURE_KRB5_TEST_PAC_REQUEST:
|
|
case TORTURE_KRB5_TEST_AES:
|
|
case TORTURE_KRB5_TEST_RC4:
|
|
case TORTURE_KRB5_TEST_AES_RC4:
|
|
torture_assert_int_equal(tctx,
|
|
code,
|
|
0,
|
|
"krb5_get_init_creds_password failed");
|
|
break;
|
|
case TORTURE_KRB5_TEST_BREAK_PW:
|
|
torture_assert_int_equal(tctx,
|
|
code,
|
|
KRB5KDC_ERR_PREAUTH_FAILED,
|
|
"krb5_get_init_creds_password should "
|
|
"have failed");
|
|
return true;
|
|
case TORTURE_KRB5_TEST_CLOCK_SKEW:
|
|
torture_assert_int_equal(tctx,
|
|
code,
|
|
KRB5KRB_AP_ERR_SKEW,
|
|
"krb5_get_init_creds_password should "
|
|
"have failed");
|
|
return true;
|
|
}
|
|
|
|
krb5_free_cred_contents(smb_krb5_context->krb5_context,
|
|
&my_creds);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_PLAIN);
|
|
}
|
|
|
|
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
|
|
static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
|
|
{
|
|
bool ok;
|
|
|
|
ok = torture_setting_bool(tctx, "expect_rodc", false);
|
|
if (ok) {
|
|
torture_skip(tctx,
|
|
"This test needs further investigation in the "
|
|
"RODC case against a Windows DC, in particular "
|
|
"with non-cached users");
|
|
}
|
|
return torture_krb5_as_req_creds(tctx, popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_PAC_REQUEST);
|
|
}
|
|
#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
|
|
|
|
static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_BREAK_PW);
|
|
}
|
|
|
|
static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_CLOCK_SKEW);
|
|
}
|
|
|
|
static bool torture_krb5_as_req_aes(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_AES);
|
|
}
|
|
|
|
static bool torture_krb5_as_req_rc4(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_RC4);
|
|
}
|
|
|
|
static bool torture_krb5_as_req_aes_rc4(struct torture_context *tctx)
|
|
{
|
|
return torture_krb5_as_req_creds(tctx,
|
|
popt_get_cmdline_credentials(),
|
|
TORTURE_KRB5_TEST_AES_RC4);
|
|
}
|
|
|
|
NTSTATUS torture_krb5_init(TALLOC_CTX *ctx)
|
|
{
|
|
struct torture_suite *suite =
|
|
torture_suite_create(ctx, "krb5");
|
|
struct torture_suite *kdc_suite = torture_suite_create(suite, "kdc");
|
|
suite->description = talloc_strdup(suite, "Kerberos tests");
|
|
kdc_suite->description = talloc_strdup(kdc_suite, "Kerberos KDC tests");
|
|
|
|
torture_suite_add_simple_test(kdc_suite,
|
|
"as-req-cmdline",
|
|
torture_krb5_as_req_cmdline);
|
|
|
|
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
|
|
/* Only available with MIT Kerveros 1.15 and newer */
|
|
torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
|
|
torture_krb5_as_req_pac_request);
|
|
#endif
|
|
|
|
torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
|
|
torture_krb5_as_req_break_pw);
|
|
|
|
/* This only works if kdc_timesync 0 is set in krb5.conf */
|
|
torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
|
|
torture_krb5_as_req_clock_skew);
|
|
|
|
#if 0
|
|
torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
|
|
#endif
|
|
torture_suite_add_simple_test(kdc_suite,
|
|
"as-req-aes",
|
|
torture_krb5_as_req_aes);
|
|
|
|
torture_suite_add_simple_test(kdc_suite,
|
|
"as-req-rc4",
|
|
torture_krb5_as_req_rc4);
|
|
|
|
torture_suite_add_simple_test(kdc_suite,
|
|
"as-req-aes-rc4",
|
|
torture_krb5_as_req_aes_rc4);
|
|
|
|
torture_suite_add_suite(suite, kdc_suite);
|
|
|
|
torture_register_suite(ctx, suite);
|
|
|
|
return NT_STATUS_OK;
|
|
}
|