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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "system/kerberos.h"
26 #include "auth/auth.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_krb5pac.h"
29 #include "samba3/samba3.h"
30 #include "libcli/security/security.h"
31 #include "torture/torture.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
, &smb_krb5_context
),
60 "smb_krb5_init_context");
62 generate_random_buffer(server_bytes
, 16);
63 generate_random_buffer(krbtgt_bytes
, 16);
65 ret
= krb5_keyblock_init(smb_krb5_context
->krb5_context
,
67 server_bytes
, sizeof(server_bytes
),
69 torture_assert(tctx
, !ret
, talloc_asprintf(tctx
,
70 "(self test) Server Keyblock encoding failed: %s",
71 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
,
74 ret
= krb5_keyblock_init(smb_krb5_context
->krb5_context
,
76 krbtgt_bytes
, sizeof(krbtgt_bytes
),
79 char *err
= smb_get_krb5_error_message(smb_krb5_context
->krb5_context
,
82 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
85 torture_fail(tctx
, talloc_asprintf(tctx
,
86 "(self test) KRBTGT Keyblock encoding failed: %s", err
));
89 /* We need an input, and this one requires no underlying database */
90 nt_status
= auth_anonymous_server_info(mem_ctx
, &server_info
);
92 if (!NT_STATUS_IS_OK(nt_status
)) {
93 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
95 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
97 torture_fail(tctx
, "auth_anonymous_server_info");
100 ret
= krb5_parse_name_flags(smb_krb5_context
->krb5_context
,
101 server_info
->account_name
,
102 KRB5_PRINCIPAL_PARSE_NO_REALM
,
105 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
107 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
109 torture_fail(tctx
, "krb5_parse_name_flags(norealm)");
112 /* OK, go ahead and make a PAC */
113 ret
= kerberos_create_pac(mem_ctx
, server_info
,
114 smb_krb5_context
->krb5_context
,
122 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
124 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
126 krb5_free_principal(smb_krb5_context
->krb5_context
,
129 torture_fail(tctx
, talloc_asprintf(tctx
,
130 "(self test) PAC encoding failed: %s",
131 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
,
135 dump_data(10,tmp_blob
.data
,tmp_blob
.length
);
137 /* Now check that we can read it back */
138 nt_status
= kerberos_decode_pac(mem_ctx
, &pac_data
,
140 smb_krb5_context
->krb5_context
,
146 if (!NT_STATUS_IS_OK(nt_status
)) {
147 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
149 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
151 krb5_free_principal(smb_krb5_context
->krb5_context
,
154 torture_fail(tctx
, talloc_asprintf(tctx
,
155 "(self test) PAC decoding failed: %s",
156 nt_errstr(nt_status
)));
159 /* Now check that we can read it back */
160 nt_status
= kerberos_pac_logon_info(mem_ctx
, &logon_info
,
162 smb_krb5_context
->krb5_context
,
169 if (!NT_STATUS_IS_OK(nt_status
)) {
170 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
172 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
174 krb5_free_principal(smb_krb5_context
->krb5_context
,
178 talloc_asprintf(tctx
,
179 "(self test) PAC decoding (for logon info) failed: %s",
180 nt_errstr(nt_status
)));
183 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
185 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
187 krb5_free_principal(smb_krb5_context
->krb5_context
,
190 validation
.sam3
= &logon_info
->info3
;
191 nt_status
= make_server_info_netlogon_validation(mem_ctx
,
195 if (!NT_STATUS_IS_OK(nt_status
)) {
197 talloc_asprintf(tctx
,
198 "(self test) PAC decoding (make server info) failed: %s",
199 nt_errstr(nt_status
)));
202 if (!dom_sid_equal(server_info
->account_sid
,
203 server_info_out
->account_sid
)) {
205 talloc_asprintf(tctx
,
206 "(self test) PAC Decode resulted in *different* domain SID: %s != %s",
207 dom_sid_string(mem_ctx
, server_info
->account_sid
),
208 dom_sid_string(mem_ctx
, server_info_out
->account_sid
)));
214 /* This is the PAC generated on my test network, by my test Win2k3 server.
215 -- abartlet 2005-07-04
218 static const uint8_t saved_pac
[] = {
219 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
220 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
221 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
222 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
223 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
224 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
225 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
226 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
227 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
228 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
231 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
232 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
234 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
239 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
240 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
245 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
246 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
247 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
248 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
249 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
250 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
251 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
252 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
254 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
255 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
256 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
257 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
260 /* Check with a known 'well formed' PAC, from my test server */
261 static bool torture_pac_saved_check(struct torture_context
*tctx
)
264 DATA_BLOB tmp_blob
, validate_blob
;
265 struct PAC_DATA
*pac_data
, pac_data2
;
266 struct PAC_LOGON_INFO
*logon_info
;
267 union netr_Validation validation
;
268 const char *pac_file
, *pac_kdc_key
, *pac_member_key
;
269 struct auth_serversupplied_info
*server_info_out
;
271 krb5_keyblock server_keyblock
;
272 krb5_keyblock krbtgt_keyblock
;
273 struct samr_Password
*krbtgt_bytes
, *krbsrv_bytes
;
276 struct smb_krb5_context
*smb_krb5_context
;
278 const char *principal_string
;
279 krb5_principal client_principal
;
280 const char *authtime_string
;
282 TALLOC_CTX
*mem_ctx
= tctx
;
284 torture_assert(tctx
, 0 == smb_krb5_init_context(mem_ctx
, &smb_krb5_context
),
285 "smb_krb5_init_context");
287 pac_kdc_key
= torture_setting_string(tctx
, "pac_kdc_key",
288 "B286757148AF7FD252C53603A150B7E7");
290 pac_member_key
= torture_setting_string(tctx
, "pac_member_key",
291 "D217FAEAE5E6B5F95CCC94077AB8A5FC");
293 torture_comment(tctx
, "Using pac_kdc_key '%s'\n", pac_kdc_key
);
294 torture_comment(tctx
, "Using pac_member_key '%s'\n", pac_member_key
);
296 /* The krbtgt key in use when the above PAC was generated.
297 * This is an arcfour-hmac-md5 key, extracted with our 'net
299 krbtgt_bytes
= smbpasswd_gethexpwd(mem_ctx
, pac_kdc_key
);
301 torture_fail(tctx
, "(saved test) Could not interpret krbtgt key");
304 krbsrv_bytes
= smbpasswd_gethexpwd(mem_ctx
, pac_member_key
);
306 torture_fail(tctx
, "(saved test) Could not interpret krbsrv key");
309 ret
= krb5_keyblock_init(smb_krb5_context
->krb5_context
,
310 ENCTYPE_ARCFOUR_HMAC
,
311 krbsrv_bytes
->hash
, sizeof(krbsrv_bytes
->hash
),
313 torture_assert(tctx
, !ret
,
314 talloc_asprintf(tctx
,
315 "(saved test) Server Keyblock encoding failed: %s",
316 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
,
319 ret
= krb5_keyblock_init(smb_krb5_context
->krb5_context
,
320 ENCTYPE_ARCFOUR_HMAC
,
321 krbtgt_bytes
->hash
, sizeof(krbtgt_bytes
->hash
),
324 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
327 talloc_asprintf(tctx
,
328 "(saved test) Server Keyblock encoding failed: %s",
329 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
,
333 pac_file
= torture_setting_string(tctx
, "pac_file", NULL
);
335 tmp_blob
.data
= (uint8_t *)file_load(pac_file
, &tmp_blob
.length
, mem_ctx
);
336 torture_comment(tctx
, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob
.length
, pac_file
);
338 tmp_blob
= data_blob_talloc(mem_ctx
, saved_pac
, sizeof(saved_pac
));
341 dump_data(10,tmp_blob
.data
,tmp_blob
.length
);
343 principal_string
= torture_setting_string(tctx
, "pac_client_principal",
344 "w2003final$@WIN2K3.THINKER.LOCAL");
346 authtime_string
= torture_setting_string(tctx
, "pac_authtime", "1120440609");
347 authtime
= strtoull(authtime_string
, NULL
, 0);
349 ret
= krb5_parse_name(smb_krb5_context
->krb5_context
, principal_string
,
352 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
354 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
357 talloc_asprintf(tctx
,
358 "(saved test) parsing of client principal [%s] failed: %s",
360 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
, ret
, mem_ctx
)));
363 /* Decode and verify the signaure on the PAC */
364 nt_status
= kerberos_decode_pac(mem_ctx
, &pac_data
,
366 smb_krb5_context
->krb5_context
,
369 client_principal
, authtime
, NULL
);
370 if (!NT_STATUS_IS_OK(nt_status
)) {
371 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
373 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
375 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
377 torture_fail(tctx
, talloc_asprintf(tctx
,
378 "(saved test) PAC decoding failed: %s",
379 nt_errstr(nt_status
)));
382 /* Parse the PAC again, for the logon info this time */
383 nt_status
= kerberos_pac_logon_info(mem_ctx
, &logon_info
,
385 smb_krb5_context
->krb5_context
,
388 client_principal
, authtime
, NULL
);
390 if (!NT_STATUS_IS_OK(nt_status
)) {
391 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
393 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
395 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
398 talloc_asprintf(tctx
,
399 "(saved test) PAC decoding (for logon info) failed: %s",
400 nt_errstr(nt_status
)));
403 validation
.sam3
= &logon_info
->info3
;
404 nt_status
= make_server_info_netlogon_validation(mem_ctx
,
408 if (!NT_STATUS_IS_OK(nt_status
)) {
409 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
411 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
413 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
416 talloc_asprintf(tctx
,
417 "(saved test) PAC decoding (make server info) failed: %s",
418 nt_errstr(nt_status
)));
422 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx
,
423 "S-1-5-21-3048156945-3961193616-3706469200-1005"),
424 server_info_out
->account_sid
)) {
425 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
427 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
429 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
432 talloc_asprintf(tctx
,
433 "(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
434 "S-1-5-21-3048156945-3961193616-3706469200-1005",
435 dom_sid_string(mem_ctx
, server_info_out
->account_sid
)));
438 ret
= kerberos_encode_pac(mem_ctx
,
440 smb_krb5_context
->krb5_context
,
446 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
448 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
450 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
452 torture_fail(tctx
, "(saved test) PAC push failed");
455 dump_data(10, validate_blob
.data
, validate_blob
.length
);
457 /* compare both the length and the data bytes after a
458 * pull/push cycle. This ensures we use the exact same
459 * pointer, padding etc algorithms as win2k3.
461 if (tmp_blob
.length
!= validate_blob
.length
) {
462 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
464 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
466 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
469 talloc_asprintf(tctx
,
470 "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
471 (unsigned)tmp_blob
.length
, (unsigned)validate_blob
.length
));
474 if (memcmp(tmp_blob
.data
, validate_blob
.data
, tmp_blob
.length
) != 0) {
475 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
477 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
479 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
481 DEBUG(0, ("tmp_data:\n"));
482 dump_data(0, tmp_blob
.data
, tmp_blob
.length
);
483 DEBUG(0, ("validate_blob:\n"));
484 dump_data(0, validate_blob
.data
, validate_blob
.length
);
486 torture_fail(tctx
, talloc_asprintf(tctx
, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob
.length
));
489 ret
= kerberos_create_pac(mem_ctx
,
491 smb_krb5_context
->krb5_context
,
494 client_principal
, authtime
,
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
);
504 torture_fail(tctx
, "(saved test) regnerated PAC create failed");
507 dump_data(10,validate_blob
.data
,validate_blob
.length
);
509 /* compare both the length and the data bytes after a
510 * pull/push cycle. This ensures we use the exact same
511 * pointer, padding etc algorithms as win2k3.
513 if (tmp_blob
.length
!= validate_blob
.length
) {
514 nt_status
= ndr_pull_struct_blob(&validate_blob
, mem_ctx
, &pac_data2
,
515 (ndr_pull_flags_fn_t
)ndr_pull_PAC_DATA
);
516 torture_assert_ntstatus_ok(tctx
, nt_status
, "can't parse the PAC");
518 NDR_PRINT_DEBUG(PAC_DATA
, pac_data
);
520 NDR_PRINT_DEBUG(PAC_DATA
, &pac_data2
);
522 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
524 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
526 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
528 torture_fail(tctx
, talloc_asprintf(tctx
,
529 "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
530 (unsigned)tmp_blob
.length
, (unsigned)validate_blob
.length
));
533 if (memcmp(tmp_blob
.data
, validate_blob
.data
, tmp_blob
.length
) != 0) {
534 nt_status
= ndr_pull_struct_blob(&validate_blob
, mem_ctx
, &pac_data2
,
535 (ndr_pull_flags_fn_t
)ndr_pull_PAC_DATA
);
536 torture_assert_ntstatus_ok(tctx
, nt_status
, "can't parse the PAC");
538 NDR_PRINT_DEBUG(PAC_DATA
, pac_data
);
540 NDR_PRINT_DEBUG(PAC_DATA
, &pac_data2
);
542 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
544 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
546 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
548 DEBUG(0, ("tmp_data:\n"));
549 dump_data(0, tmp_blob
.data
, tmp_blob
.length
);
550 DEBUG(0, ("validate_blob:\n"));
551 dump_data(0, validate_blob
.data
, validate_blob
.length
);
553 torture_fail(tctx
, talloc_asprintf(tctx
,
554 "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob
.length
));
557 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
558 nt_status
= kerberos_decode_pac(mem_ctx
, &pac_data
,
560 smb_krb5_context
->krb5_context
,
565 if (NT_STATUS_IS_OK(nt_status
)) {
567 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
569 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
571 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
572 torture_fail(tctx
, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
575 /* Break the client principal */
576 krb5_free_principal(smb_krb5_context
->krb5_context
, client_principal
);
578 ret
= krb5_parse_name(smb_krb5_context
->krb5_context
,
579 "not the right principal", &client_principal
);
582 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
584 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
586 torture_fail(tctx
, talloc_asprintf(tctx
,
587 "(saved test) parsing of bogus client principal failed: %s",
588 smb_get_krb5_error_message(smb_krb5_context
->krb5_context
, ret
, mem_ctx
)));
591 nt_status
= kerberos_decode_pac(mem_ctx
, &pac_data
,
593 smb_krb5_context
->krb5_context
,
598 if (NT_STATUS_IS_OK(nt_status
)) {
599 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
601 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
603 torture_fail(tctx
, "(saved test) PAC decoding DID NOT fail on modified principal");
606 /* Finally... Bugger up the signature, and check we fail the checksum */
607 tmp_blob
.data
[tmp_blob
.length
- 2]++;
609 nt_status
= kerberos_decode_pac(mem_ctx
, &pac_data
,
611 smb_krb5_context
->krb5_context
,
616 if (NT_STATUS_IS_OK(nt_status
)) {
617 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
619 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
621 torture_fail(tctx
, "(saved test) PAC decoding DID NOT fail on broken checksum");
624 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
626 krb5_free_keyblock_contents(smb_krb5_context
->krb5_context
,
631 _PUBLIC_
struct torture_suite
*torture_pac(TALLOC_CTX
*mem_ctx
)
633 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "PAC");
635 torture_suite_add_simple_test(suite
, "self check",
636 torture_pac_self_check
);
638 torture_suite_add_simple_test(suite
, "saved check",
639 torture_pac_saved_check
);