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 enum ndr_err_code ndr_err;
266 DATA_BLOB tmp_blob, validate_blob;
267 struct PAC_DATA *pac_data, pac_data2;
268 struct PAC_LOGON_INFO *logon_info;
269 union netr_Validation validation;
270 const char *pac_file, *pac_kdc_key, *pac_member_key;
271 struct auth_serversupplied_info *server_info_out;
273 krb5_keyblock server_keyblock;
274 krb5_keyblock krbtgt_keyblock;
275 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
278 struct smb_krb5_context *smb_krb5_context;
280 const char *principal_string;
281 char *broken_principal_string;
282 krb5_principal client_principal;
283 const char *authtime_string;
285 TALLOC_CTX *mem_ctx = tctx;
287 torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, NULL,
289 "smb_krb5_init_context");
291 pac_kdc_key = torture_setting_string(tctx, "pac_kdc_key",
292 "B286757148AF7FD252C53603A150B7E7");
294 pac_member_key = torture_setting_string(tctx, "pac_member_key",
295 "D217FAEAE5E6B5F95CCC94077AB8A5FC");
297 torture_comment(tctx, "Using pac_kdc_key '%s'\n", pac_kdc_key);
298 torture_comment(tctx, "Using pac_member_key '%s'\n", pac_member_key);
300 /* The krbtgt key in use when the above PAC was generated.
301 * This is an arcfour-hmac-md5 key, extracted with our 'net
303 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
305 torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
308 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
310 torture_fail(tctx, "(saved test) Could not interpret krbsrv key");
313 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
314 ENCTYPE_ARCFOUR_HMAC,
315 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
317 torture_assert(tctx, !ret,
318 talloc_asprintf(tctx,
319 "(saved test) Server Keyblock encoding failed: %s",
320 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
323 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
324 ENCTYPE_ARCFOUR_HMAC,
325 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
328 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
331 talloc_asprintf(tctx,
332 "(saved test) Server Keyblock encoding failed: %s",
333 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
337 pac_file = torture_setting_string(tctx, "pac_file", NULL);
339 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
340 torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
342 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
345 dump_data(10,tmp_blob.data,tmp_blob.length);
347 principal_string = torture_setting_string(tctx, "pac_client_principal",
348 "w2003final$@WIN2K3.THINKER.LOCAL");
350 authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609");
351 authtime = strtoull(authtime_string, NULL, 0);
353 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
356 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
358 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
361 talloc_asprintf(tctx,
362 "(saved test) parsing of client principal [%s] failed: %s",
364 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
367 /* Decode and verify the signaure on the PAC */
368 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
370 smb_krb5_context->krb5_context,
373 client_principal, authtime, NULL);
374 if (!NT_STATUS_IS_OK(nt_status)) {
375 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
377 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
379 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
381 torture_fail(tctx, talloc_asprintf(tctx,
382 "(saved test) PAC decoding failed: %s",
383 nt_errstr(nt_status)));
386 /* Parse the PAC again, for the logon info this time */
387 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
389 smb_krb5_context->krb5_context,
392 client_principal, authtime, NULL);
394 if (!NT_STATUS_IS_OK(nt_status)) {
395 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
397 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
399 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
402 talloc_asprintf(tctx,
403 "(saved test) PAC decoding (for logon info) failed: %s",
404 nt_errstr(nt_status)));
407 validation.sam3 = &logon_info->info3;
408 nt_status = make_server_info_netlogon_validation(mem_ctx,
412 if (!NT_STATUS_IS_OK(nt_status)) {
413 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
415 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
417 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
420 talloc_asprintf(tctx,
421 "(saved test) PAC decoding (make server info) failed: %s",
422 nt_errstr(nt_status)));
426 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx,
427 "S-1-5-21-3048156945-3961193616-3706469200-1005"),
428 server_info_out->account_sid)) {
429 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
431 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
433 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
436 talloc_asprintf(tctx,
437 "(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
438 "S-1-5-21-3048156945-3961193616-3706469200-1005",
439 dom_sid_string(mem_ctx, server_info_out->account_sid)));
442 ret = kerberos_encode_pac(mem_ctx,
444 smb_krb5_context->krb5_context,
450 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
452 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
454 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
456 torture_fail(tctx, "(saved test) PAC push failed");
459 dump_data(10, validate_blob.data, validate_blob.length);
461 /* compare both the length and the data bytes after a
462 * pull/push cycle. This ensures we use the exact same
463 * pointer, padding etc algorithms as win2k3.
465 if (tmp_blob.length != validate_blob.length) {
466 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
468 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
470 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
473 talloc_asprintf(tctx,
474 "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
475 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
478 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
479 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
481 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
483 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
485 DEBUG(0, ("tmp_data:\n"));
486 dump_data(0, tmp_blob.data, tmp_blob.length);
487 DEBUG(0, ("validate_blob:\n"));
488 dump_data(0, validate_blob.data, validate_blob.length);
490 torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
493 ret = kerberos_create_pac(mem_ctx,
495 smb_krb5_context->krb5_context,
498 client_principal, authtime,
502 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
504 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
506 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
508 torture_fail(tctx, "(saved test) regnerated PAC create failed");
511 dump_data(10,validate_blob.data,validate_blob.length);
513 /* compare both the length and the data bytes after a
514 * pull/push cycle. This ensures we use the exact same
515 * pointer, padding etc algorithms as win2k3.
517 if (tmp_blob.length != validate_blob.length) {
518 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
519 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
520 nt_status = ndr_map_error2ntstatus(ndr_err);
521 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
523 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
525 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
527 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
529 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
531 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
533 torture_fail(tctx, talloc_asprintf(tctx,
534 "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
535 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
538 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
539 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
540 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
541 nt_status = ndr_map_error2ntstatus(ndr_err);
542 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
544 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
546 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
548 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
550 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
552 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
554 DEBUG(0, ("tmp_data:\n"));
555 dump_data(0, tmp_blob.data, tmp_blob.length);
556 DEBUG(0, ("validate_blob:\n"));
557 dump_data(0, validate_blob.data, validate_blob.length);
559 torture_fail(tctx, talloc_asprintf(tctx,
560 "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
563 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
564 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
566 smb_krb5_context->krb5_context,
571 if (NT_STATUS_IS_OK(nt_status)) {
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);
578 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
581 /* Break the client principal */
582 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
584 broken_principal_string = talloc_strdup(mem_ctx, principal_string);
585 broken_principal_string[0]++;
587 ret = krb5_parse_name(smb_krb5_context->krb5_context,
588 broken_principal_string, &client_principal);
591 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
593 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
595 torture_fail(tctx, talloc_asprintf(tctx,
596 "(saved test) parsing of broken client principal failed: %s",
597 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
600 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
602 smb_krb5_context->krb5_context,
607 if (NT_STATUS_IS_OK(nt_status)) {
608 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
610 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
612 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
615 /* Finally... Bugger up the signature, and check we fail the checksum */
616 tmp_blob.data[tmp_blob.length - 2]++;
618 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
620 smb_krb5_context->krb5_context,
625 if (NT_STATUS_IS_OK(nt_status)) {
626 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
628 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
630 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
633 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
635 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
640 _PUBLIC_ struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
642 struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC");
644 torture_suite_add_simple_test(suite, "self check",
645 torture_pac_self_check);
647 torture_suite_add_simple_test(suite, "saved check",
648 torture_pac_saved_check);