2
Unix SMB/CIFS implementation.
4
Validate the krb5 pac generation routines
6
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program. If not, see <http://www.gnu.org/licenses/>.
24
#include "system/kerberos.h"
25
#include "auth/auth.h"
26
#include "auth/kerberos/kerberos.h"
27
#include "librpc/gen_ndr/ndr_krb5pac.h"
28
#include "samba3/samba3.h"
29
#include "libcli/security/security.h"
30
#include "torture/torture.h"
31
#include "auth/auth_sam_reply.h"
33
static bool torture_pac_self_check(struct torture_context *tctx)
37
struct PAC_DATA *pac_data;
38
struct PAC_LOGON_INFO *logon_info;
39
union netr_Validation validation;
41
/* Generate a nice, arbitary keyblock */
42
uint8_t server_bytes[16];
43
uint8_t krbtgt_bytes[16];
44
krb5_keyblock server_keyblock;
45
krb5_keyblock krbtgt_keyblock;
49
struct smb_krb5_context *smb_krb5_context;
51
struct auth_serversupplied_info *server_info;
52
struct auth_serversupplied_info *server_info_out;
54
krb5_principal client_principal;
55
time_t logon_time = time(NULL);
57
TALLOC_CTX *mem_ctx = tctx;
59
torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx,
63
"smb_krb5_init_context");
65
generate_random_buffer(server_bytes, 16);
66
generate_random_buffer(krbtgt_bytes, 16);
68
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
70
server_bytes, sizeof(server_bytes),
72
torture_assert(tctx, !ret, talloc_asprintf(tctx,
73
"(self test) Server Keyblock encoding failed: %s",
74
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
77
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
79
krbtgt_bytes, sizeof(krbtgt_bytes),
82
char *err = smb_get_krb5_error_message(smb_krb5_context->krb5_context,
85
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
88
torture_fail(tctx, talloc_asprintf(tctx,
89
"(self test) KRBTGT Keyblock encoding failed: %s", err));
92
/* We need an input, and this one requires no underlying database */
93
nt_status = auth_anonymous_server_info(mem_ctx, lp_netbios_name(tctx->lp_ctx), &server_info);
95
if (!NT_STATUS_IS_OK(nt_status)) {
96
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
98
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
100
torture_fail(tctx, "auth_anonymous_server_info");
103
ret = krb5_parse_name_flags(smb_krb5_context->krb5_context,
104
server_info->account_name,
105
KRB5_PRINCIPAL_PARSE_NO_REALM,
108
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
110
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
112
torture_fail(tctx, "krb5_parse_name_flags(norealm)");
115
/* OK, go ahead and make a PAC */
116
ret = kerberos_create_pac(mem_ctx,
117
lp_iconv_convenience(tctx->lp_ctx),
119
smb_krb5_context->krb5_context,
127
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
129
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
131
krb5_free_principal(smb_krb5_context->krb5_context,
134
torture_fail(tctx, talloc_asprintf(tctx,
135
"(self test) PAC encoding failed: %s",
136
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
140
dump_data(10,tmp_blob.data,tmp_blob.length);
142
/* Now check that we can read it back (using full decode and validate) */
143
nt_status = kerberos_decode_pac(mem_ctx,
144
lp_iconv_convenience(tctx->lp_ctx),
147
smb_krb5_context->krb5_context,
153
if (!NT_STATUS_IS_OK(nt_status)) {
154
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
156
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
158
krb5_free_principal(smb_krb5_context->krb5_context,
161
torture_fail(tctx, talloc_asprintf(tctx,
162
"(self test) PAC decoding failed: %s",
163
nt_errstr(nt_status)));
166
/* Now check we can read it back (using Heimdal's pac parsing) */
167
nt_status = kerberos_pac_blob_to_server_info(mem_ctx,
168
lp_iconv_convenience(tctx->lp_ctx),
170
smb_krb5_context->krb5_context,
173
if (!dom_sid_equal(server_info->account_sid,
174
server_info_out->account_sid)) {
175
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
177
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
179
krb5_free_principal(smb_krb5_context->krb5_context,
183
talloc_asprintf(tctx,
184
"(self test) PAC Decode resulted in *different* domain SID: %s != %s",
185
dom_sid_string(mem_ctx, server_info->account_sid),
186
dom_sid_string(mem_ctx, server_info_out->account_sid)));
188
talloc_free(server_info_out);
190
/* Now check that we can read it back (yet again) */
191
nt_status = kerberos_pac_logon_info(mem_ctx,
192
lp_iconv_convenience(tctx->lp_ctx),
195
smb_krb5_context->krb5_context,
202
if (!NT_STATUS_IS_OK(nt_status)) {
203
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
205
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
207
krb5_free_principal(smb_krb5_context->krb5_context,
211
talloc_asprintf(tctx,
212
"(self test) PAC decoding (for logon info) failed: %s",
213
nt_errstr(nt_status)));
216
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
218
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
220
krb5_free_principal(smb_krb5_context->krb5_context,
223
/* And make a server info from the samba-parsed PAC */
224
validation.sam3 = &logon_info->info3;
225
nt_status = make_server_info_netlogon_validation(mem_ctx,
229
if (!NT_STATUS_IS_OK(nt_status)) {
231
talloc_asprintf(tctx,
232
"(self test) PAC decoding (make server info) failed: %s",
233
nt_errstr(nt_status)));
236
if (!dom_sid_equal(server_info->account_sid,
237
server_info_out->account_sid)) {
239
talloc_asprintf(tctx,
240
"(self test) PAC Decode resulted in *different* domain SID: %s != %s",
241
dom_sid_string(mem_ctx, server_info->account_sid),
242
dom_sid_string(mem_ctx, server_info_out->account_sid)));
248
/* This is the PAC generated on my test network, by my test Win2k3 server.
249
-- abartlet 2005-07-04
252
static const uint8_t saved_pac[] = {
253
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
254
0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
255
0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
256
0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
257
0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
258
0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
259
0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
260
0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
261
0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
262
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
263
0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
264
0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
265
0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
266
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267
0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
268
0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269
0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271
0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272
0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
273
0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
274
0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
279
0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
280
0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
281
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
282
0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
283
0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
284
0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
285
0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
286
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287
0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
288
0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
289
0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
290
0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
291
0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
294
/* Check with a known 'well formed' PAC, from my test server */
295
static bool torture_pac_saved_check(struct torture_context *tctx)
298
enum ndr_err_code ndr_err;
299
DATA_BLOB tmp_blob, validate_blob;
300
struct PAC_DATA *pac_data, pac_data2;
301
struct PAC_LOGON_INFO *logon_info;
302
union netr_Validation validation;
303
const char *pac_file, *pac_kdc_key, *pac_member_key;
304
struct auth_serversupplied_info *server_info_out;
306
krb5_keyblock server_keyblock;
307
krb5_keyblock krbtgt_keyblock, *krbtgt_keyblock_p;
308
struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
311
struct smb_krb5_context *smb_krb5_context;
313
const char *principal_string;
314
char *broken_principal_string;
315
krb5_principal client_principal;
316
const char *authtime_string;
318
TALLOC_CTX *mem_ctx = tctx;
320
torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, NULL,
323
"smb_krb5_init_context");
325
pac_kdc_key = torture_setting_string(tctx, "pac_kdc_key",
326
"B286757148AF7FD252C53603A150B7E7");
328
pac_member_key = torture_setting_string(tctx, "pac_member_key",
329
"D217FAEAE5E6B5F95CCC94077AB8A5FC");
331
torture_comment(tctx, "Using pac_kdc_key '%s'\n", pac_kdc_key);
332
torture_comment(tctx, "Using pac_member_key '%s'\n", pac_member_key);
334
/* The krbtgt key in use when the above PAC was generated.
335
* This is an arcfour-hmac-md5 key, extracted with our 'net
337
if (*pac_kdc_key == 0) {
340
krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
342
torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
346
krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
348
torture_fail(tctx, "(saved test) Could not interpret krbsrv key");
351
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
352
ENCTYPE_ARCFOUR_HMAC,
353
krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
355
torture_assert(tctx, !ret,
356
talloc_asprintf(tctx,
357
"(saved test) Server Keyblock encoding failed: %s",
358
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
362
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
363
ENCTYPE_ARCFOUR_HMAC,
364
krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
367
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
370
talloc_asprintf(tctx,
371
"(saved test) Server Keyblock encoding failed: %s",
372
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
375
krbtgt_keyblock_p = &krbtgt_keyblock;
377
krbtgt_keyblock_p = NULL;
380
pac_file = torture_setting_string(tctx, "pac_file", NULL);
382
tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, 0, mem_ctx);
383
torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
385
tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
388
dump_data(10,tmp_blob.data,tmp_blob.length);
390
principal_string = torture_setting_string(tctx, "pac_client_principal",
391
"w2003final$@WIN2K3.THINKER.LOCAL");
393
authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609");
394
authtime = strtoull(authtime_string, NULL, 0);
396
ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
399
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
401
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
404
talloc_asprintf(tctx,
405
"(saved test) parsing of client principal [%s] failed: %s",
407
smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
410
/* Decode and verify the signaure on the PAC */
411
nt_status = kerberos_decode_pac(mem_ctx,
412
lp_iconv_convenience(tctx->lp_ctx),
415
smb_krb5_context->krb5_context,
418
client_principal, authtime, NULL);
419
if (!NT_STATUS_IS_OK(nt_status)) {
420
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
422
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
424
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
426
torture_fail(tctx, talloc_asprintf(tctx,
427
"(saved test) PAC decoding failed: %s",
428
nt_errstr(nt_status)));
431
/* Now check we can read it back (using Heimdal's pac parsing) */
432
nt_status = kerberos_pac_blob_to_server_info(mem_ctx,
433
lp_iconv_convenience(tctx->lp_ctx),
435
smb_krb5_context->krb5_context,
438
if (!NT_STATUS_IS_OK(nt_status)) {
439
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
441
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
443
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
445
torture_fail(tctx, talloc_asprintf(tctx,
446
"(saved test) Heimdal PAC decoding failed: %s",
447
nt_errstr(nt_status)));
451
!dom_sid_equal(dom_sid_parse_talloc(mem_ctx,
452
"S-1-5-21-3048156945-3961193616-3706469200-1005"),
453
server_info_out->account_sid)) {
454
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
456
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
458
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
461
talloc_asprintf(tctx,
462
"(saved test) Heimdal PAC Decode resulted in *different* domain SID: %s != %s",
463
"S-1-5-21-3048156945-3961193616-3706469200-1005",
464
dom_sid_string(mem_ctx, server_info_out->account_sid)));
467
talloc_free(server_info_out);
469
/* Parse the PAC again, for the logon info this time (using Samba4's parsing) */
470
nt_status = kerberos_pac_logon_info(mem_ctx,
471
lp_iconv_convenience(tctx->lp_ctx),
474
smb_krb5_context->krb5_context,
477
client_principal, authtime, NULL);
479
if (!NT_STATUS_IS_OK(nt_status)) {
480
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
482
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
484
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
487
talloc_asprintf(tctx,
488
"(saved test) PAC decoding (for logon info) failed: %s",
489
nt_errstr(nt_status)));
492
validation.sam3 = &logon_info->info3;
493
nt_status = make_server_info_netlogon_validation(mem_ctx,
497
if (!NT_STATUS_IS_OK(nt_status)) {
498
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
500
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
502
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
505
talloc_asprintf(tctx,
506
"(saved test) PAC decoding (make server info) failed: %s",
507
nt_errstr(nt_status)));
511
!dom_sid_equal(dom_sid_parse_talloc(mem_ctx,
512
"S-1-5-21-3048156945-3961193616-3706469200-1005"),
513
server_info_out->account_sid)) {
514
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
516
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
518
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
521
talloc_asprintf(tctx,
522
"(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
523
"S-1-5-21-3048156945-3961193616-3706469200-1005",
524
dom_sid_string(mem_ctx, server_info_out->account_sid)));
527
if (krbtgt_bytes == NULL) {
528
torture_comment(tctx, "skipping PAC encoding tests as non kdc key\n");
529
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
531
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
535
ret = kerberos_encode_pac(mem_ctx,
536
lp_iconv_convenience(tctx->lp_ctx),
538
smb_krb5_context->krb5_context,
544
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
546
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
548
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
550
torture_fail(tctx, "(saved test) PAC push failed");
553
dump_data(10, validate_blob.data, validate_blob.length);
555
/* compare both the length and the data bytes after a
556
* pull/push cycle. This ensures we use the exact same
557
* pointer, padding etc algorithms as win2k3.
559
if (tmp_blob.length != validate_blob.length) {
560
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
562
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
564
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
567
talloc_asprintf(tctx,
568
"(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
569
(unsigned)tmp_blob.length, (unsigned)validate_blob.length));
572
if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
573
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
575
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
577
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
579
DEBUG(0, ("tmp_data:\n"));
580
dump_data(0, tmp_blob.data, tmp_blob.length);
581
DEBUG(0, ("validate_blob:\n"));
582
dump_data(0, validate_blob.data, validate_blob.length);
584
torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
587
ret = kerberos_create_pac(mem_ctx,
588
lp_iconv_convenience(tctx->lp_ctx),
590
smb_krb5_context->krb5_context,
593
client_principal, authtime,
597
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
599
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
601
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
603
torture_fail(tctx, "(saved test) regnerated PAC create failed");
606
dump_data(10,validate_blob.data,validate_blob.length);
608
/* compare both the length and the data bytes after a
609
* pull/push cycle. This ensures we use the exact same
610
* pointer, padding etc algorithms as win2k3.
612
if (tmp_blob.length != validate_blob.length) {
613
ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx,
614
lp_iconv_convenience(tctx->lp_ctx), &pac_data2,
615
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
616
nt_status = ndr_map_error2ntstatus(ndr_err);
617
torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
619
NDR_PRINT_DEBUG(PAC_DATA, pac_data);
621
NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
623
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
625
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
627
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
629
torture_fail(tctx, talloc_asprintf(tctx,
630
"(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
631
(unsigned)tmp_blob.length, (unsigned)validate_blob.length));
634
if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
635
ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx,
636
lp_iconv_convenience(tctx->lp_ctx), &pac_data2,
637
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
638
nt_status = ndr_map_error2ntstatus(ndr_err);
639
torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
641
NDR_PRINT_DEBUG(PAC_DATA, pac_data);
643
NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
645
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
647
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
649
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
651
DEBUG(0, ("tmp_data:\n"));
652
dump_data(0, tmp_blob.data, tmp_blob.length);
653
DEBUG(0, ("validate_blob:\n"));
654
dump_data(0, validate_blob.data, validate_blob.length);
656
torture_fail(tctx, talloc_asprintf(tctx,
657
"(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
660
/* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
661
nt_status = kerberos_decode_pac(mem_ctx,
662
lp_iconv_convenience(tctx->lp_ctx),
665
smb_krb5_context->krb5_context,
670
if (NT_STATUS_IS_OK(nt_status)) {
672
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
674
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
676
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
677
torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
680
/* Break the client principal */
681
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
683
broken_principal_string = talloc_strdup(mem_ctx, principal_string);
684
broken_principal_string[0]++;
686
ret = krb5_parse_name(smb_krb5_context->krb5_context,
687
broken_principal_string, &client_principal);
690
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
692
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
694
torture_fail(tctx, talloc_asprintf(tctx,
695
"(saved test) parsing of broken client principal failed: %s",
696
smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
699
nt_status = kerberos_decode_pac(mem_ctx,
700
lp_iconv_convenience(tctx->lp_ctx),
703
smb_krb5_context->krb5_context,
708
if (NT_STATUS_IS_OK(nt_status)) {
709
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
711
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
713
torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
716
/* Finally... Bugger up the signature, and check we fail the checksum */
717
tmp_blob.data[tmp_blob.length - 2]++;
719
nt_status = kerberos_decode_pac(mem_ctx,
720
lp_iconv_convenience(tctx->lp_ctx),
723
smb_krb5_context->krb5_context,
728
if (NT_STATUS_IS_OK(nt_status)) {
729
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
731
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
733
torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
736
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
738
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
743
struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
745
struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC");
747
torture_suite_add_simple_test(suite, "self check",
748
torture_pac_self_check);
749
torture_suite_add_simple_test(suite, "saved check",
750
torture_pac_saved_check);