📄 pac.c
字号:
torture_fail(tctx, talloc_asprintf(tctx, "(saved test) Server Keyblock encoding failed: %s", smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); } pac_file = torture_setting_string(tctx, "pac_file", NULL); if (pac_file) { tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx); torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file); } else { tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac)); } dump_data(10,tmp_blob.data,tmp_blob.length); principal_string = torture_setting_string(tctx, "pac_client_principal", "w2003final$@WIN2K3.THINKER.LOCAL"); authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609"); authtime = strtoull(authtime_string, NULL, 0); ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string, &client_principal); if (ret) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) parsing of client principal [%s] failed: %s", principal_string, smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); } /* Decode and verify the signaure on the PAC */ nt_status = kerberos_decode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data, tmp_blob, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime, NULL); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC decoding failed: %s", nt_errstr(nt_status))); } /* Parse the PAC again, for the logon info this time */ nt_status = kerberos_pac_logon_info(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &logon_info, tmp_blob, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime, NULL); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC decoding (for logon info) failed: %s", nt_errstr(nt_status))); } validation.sam3 = &logon_info->info3; nt_status = make_server_info_netlogon_validation(mem_ctx, "", 3, &validation, &server_info_out); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC decoding (make server info) failed: %s", nt_errstr(nt_status))); } if (!pac_file && !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, "S-1-5-21-3048156945-3961193616-3706469200-1005"), server_info_out->account_sid)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC Decode resulted in *different* domain SID: %s != %s", "S-1-5-21-3048156945-3961193616-3706469200-1005", dom_sid_string(mem_ctx, server_info_out->account_sid))); } ret = kerberos_encode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), pac_data, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, &validate_blob); if (ret != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, "(saved test) PAC push failed"); } dump_data(10, validate_blob.data, validate_blob.length); /* compare both the length and the data bytes after a * pull/push cycle. This ensures we use the exact same * pointer, padding etc algorithms as win2k3. */ if (tmp_blob.length != validate_blob.length) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]", (unsigned)tmp_blob.length, (unsigned)validate_blob.length)); } if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); DEBUG(0, ("tmp_data:\n")); dump_data(0, tmp_blob.data, tmp_blob.length); DEBUG(0, ("validate_blob:\n")); dump_data(0, validate_blob.data, validate_blob.length); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length)); } ret = kerberos_create_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), server_info_out, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime, &validate_blob); if (ret != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, "(saved test) regnerated PAC create failed"); } dump_data(10,validate_blob.data,validate_blob.length); /* compare both the length and the data bytes after a * pull/push cycle. This ensures we use the exact same * pointer, padding etc algorithms as win2k3. */ if (tmp_blob.length != validate_blob.length) { ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data2, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); nt_status = ndr_map_error2ntstatus(ndr_err); torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC"); NDR_PRINT_DEBUG(PAC_DATA, pac_data); NDR_PRINT_DEBUG(PAC_DATA, &pac_data2); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]", (unsigned)tmp_blob.length, (unsigned)validate_blob.length)); } if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) { ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data2, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); nt_status = ndr_map_error2ntstatus(ndr_err); torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC"); NDR_PRINT_DEBUG(PAC_DATA, pac_data); NDR_PRINT_DEBUG(PAC_DATA, &pac_data2); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); DEBUG(0, ("tmp_data:\n")); dump_data(0, tmp_blob.data, tmp_blob.length); DEBUG(0, ("validate_blob:\n")); dump_data(0, validate_blob.data, validate_blob.length); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length)); } /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */ nt_status = kerberos_decode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data, tmp_blob, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime + 1, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)"); } /* Break the client principal */ krb5_free_principal(smb_krb5_context->krb5_context, client_principal); broken_principal_string = talloc_strdup(mem_ctx, principal_string); broken_principal_string[0]++; ret = krb5_parse_name(smb_krb5_context->krb5_context, broken_principal_string, &client_principal); if (ret) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, talloc_asprintf(tctx, "(saved test) parsing of broken client principal failed: %s", smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); } nt_status = kerberos_decode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data, tmp_blob, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal"); } /* Finally... Bugger up the signature, and check we fail the checksum */ tmp_blob.data[tmp_blob.length - 2]++; nt_status = kerberos_decode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_data, tmp_blob, smb_krb5_context->krb5_context, &krbtgt_keyblock, &server_keyblock, client_principal, authtime, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum"); } krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); return true;}struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx){ struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC"); torture_suite_add_simple_test(suite, "self check", torture_pac_self_check); torture_suite_add_simple_test(suite, "saved check", torture_pac_saved_check); return suite;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -