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"
32 static bool torture_pac_self_check(struct torture_context *tctx)
36 struct PAC_DATA *pac_data;
37 struct PAC_LOGON_INFO *logon_info;
38 union netr_Validation validation;
40 /* Generate a nice, arbitary keyblock */
41 uint8_t server_bytes[16];
42 uint8_t krbtgt_bytes[16];
43 krb5_keyblock server_keyblock;
44 krb5_keyblock krbtgt_keyblock;
48 struct smb_krb5_context *smb_krb5_context;
50 struct auth_serversupplied_info *server_info;
51 struct auth_serversupplied_info *server_info_out;
53 krb5_principal client_principal;
54 time_t logon_time = time(NULL);
56 TALLOC_CTX *mem_ctx = tctx;
58 torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx,
61 "smb_krb5_init_context");
63 generate_random_buffer(server_bytes, 16);
64 generate_random_buffer(krbtgt_bytes, 16);
66 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
68 server_bytes, sizeof(server_bytes),
70 torture_assert(tctx, !ret, talloc_asprintf(tctx,
71 "(self test) Server Keyblock encoding failed: %s",
72 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
75 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
77 krbtgt_bytes, sizeof(krbtgt_bytes),
80 char *err = smb_get_krb5_error_message(smb_krb5_context->krb5_context,
83 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
86 torture_fail(tctx, talloc_asprintf(tctx,
87 "(self test) KRBTGT Keyblock encoding failed: %s", err));
90 /* We need an input, and this one requires no underlying database */
91 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
93 if (!NT_STATUS_IS_OK(nt_status)) {
94 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
96 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
98 torture_fail(tctx, "auth_anonymous_server_info");
101 ret = krb5_parse_name_flags(smb_krb5_context->krb5_context,
102 server_info->account_name,
103 KRB5_PRINCIPAL_PARSE_NO_REALM,
106 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
108 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
110 torture_fail(tctx, "krb5_parse_name_flags(norealm)");
113 /* OK, go ahead and make a PAC */
114 ret = kerberos_create_pac(mem_ctx, server_info,
115 smb_krb5_context->krb5_context,
123 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
125 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
127 krb5_free_principal(smb_krb5_context->krb5_context,
130 torture_fail(tctx, talloc_asprintf(tctx,
131 "(self test) PAC encoding failed: %s",
132 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
136 dump_data(10,tmp_blob.data,tmp_blob.length);
138 /* Now check that we can read it back */
139 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
141 smb_krb5_context->krb5_context,
147 if (!NT_STATUS_IS_OK(nt_status)) {
148 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
150 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
152 krb5_free_principal(smb_krb5_context->krb5_context,
155 torture_fail(tctx, talloc_asprintf(tctx,
156 "(self test) PAC decoding failed: %s",
157 nt_errstr(nt_status)));
160 /* Now check that we can read it back */
161 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
163 smb_krb5_context->krb5_context,
170 if (!NT_STATUS_IS_OK(nt_status)) {
171 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
173 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
175 krb5_free_principal(smb_krb5_context->krb5_context,
179 talloc_asprintf(tctx,
180 "(self test) PAC decoding (for logon info) failed: %s",
181 nt_errstr(nt_status)));
184 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
186 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
188 krb5_free_principal(smb_krb5_context->krb5_context,
191 validation.sam3 = &logon_info->info3;
192 nt_status = make_server_info_netlogon_validation(mem_ctx,
196 if (!NT_STATUS_IS_OK(nt_status)) {
198 talloc_asprintf(tctx,
199 "(self test) PAC decoding (make server info) failed: %s",
200 nt_errstr(nt_status)));
203 if (!dom_sid_equal(server_info->account_sid,
204 server_info_out->account_sid)) {
206 talloc_asprintf(tctx,
207 "(self test) PAC Decode resulted in *different* domain SID: %s != %s",
208 dom_sid_string(mem_ctx, server_info->account_sid),
209 dom_sid_string(mem_ctx, server_info_out->account_sid)));
215 /* This is the PAC generated on my test network, by my test Win2k3 server.
216 -- abartlet 2005-07-04
219 static const uint8_t saved_pac[] = {
220 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
221 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
222 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
223 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
224 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
225 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
226 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
227 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
228 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
229 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
232 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
233 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
235 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
240 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
241 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
246 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
247 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
248 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
249 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
250 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
251 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
252 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
253 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
255 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
256 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
257 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
258 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
261 /* Check with a known 'well formed' PAC, from my test server */
262 static bool torture_pac_saved_check(struct torture_context *tctx)
265 DATA_BLOB tmp_blob, validate_blob;
266 struct PAC_DATA *pac_data, pac_data2;
267 struct PAC_LOGON_INFO *logon_info;
268 union netr_Validation validation;
269 const char *pac_file, *pac_kdc_key, *pac_member_key;
270 struct auth_serversupplied_info *server_info_out;
272 krb5_keyblock server_keyblock;
273 krb5_keyblock krbtgt_keyblock;
274 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
277 struct smb_krb5_context *smb_krb5_context;
279 const char *principal_string;
280 char *broken_principal_string;
281 krb5_principal client_principal;
282 const char *authtime_string;
284 TALLOC_CTX *mem_ctx = tctx;
286 torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, NULL,
288 "smb_krb5_init_context");
290 pac_kdc_key = torture_setting_string(tctx, "pac_kdc_key",
291 "B286757148AF7FD252C53603A150B7E7");
293 pac_member_key = torture_setting_string(tctx, "pac_member_key",
294 "D217FAEAE5E6B5F95CCC94077AB8A5FC");
296 torture_comment(tctx, "Using pac_kdc_key '%s'\n", pac_kdc_key);
297 torture_comment(tctx, "Using pac_member_key '%s'\n", pac_member_key);
299 /* The krbtgt key in use when the above PAC was generated.
300 * This is an arcfour-hmac-md5 key, extracted with our 'net
302 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
304 torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
307 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
309 torture_fail(tctx, "(saved test) Could not interpret krbsrv key");
312 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
313 ENCTYPE_ARCFOUR_HMAC,
314 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
316 torture_assert(tctx, !ret,
317 talloc_asprintf(tctx,
318 "(saved test) Server Keyblock encoding failed: %s",
319 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
322 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
323 ENCTYPE_ARCFOUR_HMAC,
324 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
327 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
330 talloc_asprintf(tctx,
331 "(saved test) Server Keyblock encoding failed: %s",
332 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
336 pac_file = torture_setting_string(tctx, "pac_file", NULL);
338 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
339 torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
341 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
344 dump_data(10,tmp_blob.data,tmp_blob.length);
346 principal_string = torture_setting_string(tctx, "pac_client_principal",
347 "w2003final$@WIN2K3.THINKER.LOCAL");
349 authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609");
350 authtime = strtoull(authtime_string, NULL, 0);
352 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
355 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
357 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
360 talloc_asprintf(tctx,
361 "(saved test) parsing of client principal [%s] failed: %s",
363 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
366 /* Decode and verify the signaure on the PAC */
367 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
369 smb_krb5_context->krb5_context,
372 client_principal, authtime, NULL);
373 if (!NT_STATUS_IS_OK(nt_status)) {
374 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
376 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
378 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
380 torture_fail(tctx, talloc_asprintf(tctx,
381 "(saved test) PAC decoding failed: %s",
382 nt_errstr(nt_status)));
385 /* Parse the PAC again, for the logon info this time */
386 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
388 smb_krb5_context->krb5_context,
391 client_principal, authtime, NULL);
393 if (!NT_STATUS_IS_OK(nt_status)) {
394 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
396 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
398 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
401 talloc_asprintf(tctx,
402 "(saved test) PAC decoding (for logon info) failed: %s",
403 nt_errstr(nt_status)));
406 validation.sam3 = &logon_info->info3;
407 nt_status = make_server_info_netlogon_validation(mem_ctx,
411 if (!NT_STATUS_IS_OK(nt_status)) {
412 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
414 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
416 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
419 talloc_asprintf(tctx,
420 "(saved test) PAC decoding (make server info) failed: %s",
421 nt_errstr(nt_status)));
425 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx,
426 "S-1-5-21-3048156945-3961193616-3706469200-1005"),
427 server_info_out->account_sid)) {
428 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
430 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
432 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
435 talloc_asprintf(tctx,
436 "(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
437 "S-1-5-21-3048156945-3961193616-3706469200-1005",
438 dom_sid_string(mem_ctx, server_info_out->account_sid)));
441 ret = kerberos_encode_pac(mem_ctx,
443 smb_krb5_context->krb5_context,
449 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
451 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
453 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
455 torture_fail(tctx, "(saved test) PAC push failed");
458 dump_data(10, validate_blob.data, validate_blob.length);
460 /* compare both the length and the data bytes after a
461 * pull/push cycle. This ensures we use the exact same
462 * pointer, padding etc algorithms as win2k3.
464 if (tmp_blob.length != validate_blob.length) {
465 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
467 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
469 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
472 talloc_asprintf(tctx,
473 "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
474 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
477 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
478 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
480 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
482 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
484 DEBUG(0, ("tmp_data:\n"));
485 dump_data(0, tmp_blob.data, tmp_blob.length);
486 DEBUG(0, ("validate_blob:\n"));
487 dump_data(0, validate_blob.data, validate_blob.length);
489 torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
492 ret = kerberos_create_pac(mem_ctx,
494 smb_krb5_context->krb5_context,
497 client_principal, authtime,
501 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
503 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
505 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
507 torture_fail(tctx, "(saved test) regnerated PAC create failed");
510 dump_data(10,validate_blob.data,validate_blob.length);
512 /* compare both the length and the data bytes after a
513 * pull/push cycle. This ensures we use the exact same
514 * pointer, padding etc algorithms as win2k3.
516 if (tmp_blob.length != validate_blob.length) {
517 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
518 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
519 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
521 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
523 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
525 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
527 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
529 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
531 torture_fail(tctx, talloc_asprintf(tctx,
532 "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
533 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
536 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
537 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
538 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
539 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
541 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
543 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
545 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
547 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
549 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
551 DEBUG(0, ("tmp_data:\n"));
552 dump_data(0, tmp_blob.data, tmp_blob.length);
553 DEBUG(0, ("validate_blob:\n"));
554 dump_data(0, validate_blob.data, validate_blob.length);
556 torture_fail(tctx, talloc_asprintf(tctx,
557 "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
560 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
561 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
563 smb_krb5_context->krb5_context,
568 if (NT_STATUS_IS_OK(nt_status)) {
570 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
572 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
574 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
575 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
578 /* Break the client principal */
579 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
581 broken_principal_string = talloc_strdup(mem_ctx, principal_string);
582 broken_principal_string[0]++;
584 ret = krb5_parse_name(smb_krb5_context->krb5_context,
585 broken_principal_string, &client_principal);
588 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
590 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
592 torture_fail(tctx, talloc_asprintf(tctx,
593 "(saved test) parsing of broken client principal failed: %s",
594 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
597 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
599 smb_krb5_context->krb5_context,
604 if (NT_STATUS_IS_OK(nt_status)) {
605 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
607 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
609 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
612 /* Finally... Bugger up the signature, and check we fail the checksum */
613 tmp_blob.data[tmp_blob.length - 2]++;
615 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
617 smb_krb5_context->krb5_context,
622 if (NT_STATUS_IS_OK(nt_status)) {
623 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
625 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
627 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
630 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
632 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
637 _PUBLIC_ struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
639 struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC");
641 torture_suite_add_simple_test(suite, "self check",
642 torture_pac_self_check);
644 torture_suite_add_simple_test(suite, "saved check",
645 torture_pac_saved_check);