登录时未通过凭据提供程序加载 KSP(密钥存储提供程序)

2023-11-30

我正在创建一个 Windows 凭据提供程序,以使用此处所述的证书登录到 Windows 域article。 这意味着创建一个自定义 KSP,在创建身份验证包时将由 LsaLogonUser 调用。

我设法创建自定义 KSP 并在直接调用 LsaLogonUser 的独立应用程序中成功测试它。 基本上创建身份验证包并将其传递给 LsaLogonUser,加载 KSP,调用一堆函数并对用户进行身份验证,在状态代码和加载的用户配置文件上返回成功结果。

但是,当我在凭证上的 GetSerialization 期间使用相同的身份验证包时,KSP 甚至不会加载,并且我收到 ReportResult(NTSTATUS ntsStatus, NTSTATUS ntsSubstatus, ....) 报告的 0xc000000d (参数不正确) nts 状态。

这是我在测试中使用的 GetSerialization 的代码:

    HRESULT AOCredential::GetSerialization(
    CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *pcpgsr,
    CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcs,
    PWSTR *ppwszOptionalStatusText,
    CREDENTIAL_PROVIDER_STATUS_ICON *pcpsiOptionalStatusIcon
)
{
    UNREFERENCED_PARAMETER(ppwszOptionalStatusText);
    UNREFERENCED_PARAMETER(pcpsiOptionalStatusIcon);

    HRESULT hr;

    ULONG ulAuthPackage;
    hr = RetrieveKerberosAuthPackage(&ulAuthPackage);

    if (SUCCEEDED(hr))
    {
        InitialiseKerbCertificateLogon(&pcpcs->rgbSerialization, &pcpcs->cbSerialization); // this package actually worked when calling LsaLogonUser function directly (the KSP gets loaded and the authentication succeeds)

        pcpcs->ulAuthenticationPackage = ulAuthPackage;
        pcpcs->clsidCredentialProvider = CLSID_CallsignProvider;
        *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
    }

    return hr;
}

我的问题是为什么当直接从 LsaLogonUser 调用身份验证包时加载 KSP,而不是在 Windows 登录期间从凭据提供程序调用身份验证包。

InitialiseKerbCertificateLogon 代码是:

void InitialiseKerbCertificateLogon(PWSTR domain, PWSTR username, LPBYTE* authInfo, ULONG *authInfoLength)
{
    WCHAR szCardName[] = L"";
    WCHAR szContainerName[] = L"Default";
    WCHAR szReaderName[] = L"";
    WCHAR szCspName[] = CS_KSP_NAME;
    WCHAR szPin[] = CS_TEST_PIN;
    ULONG ulPinByteLen = (ULONG)(wcslen(szPin) * sizeof(WCHAR));
    WCHAR szUserName[] = CS_TEST_USERNAME;
    ULONG ulUserByteLen = (ULONG)(wcslen(szUserName) * sizeof(WCHAR));
    WCHAR szDomainName[] = CS_TEST_DOMAIN;
    ULONG ulDomainByteLen = (ULONG)(wcslen(szDomainName) * sizeof(WCHAR));
    LPBYTE pbAuthInfo = NULL;
    ULONG  ulAuthInfoLen = 0;
    KERB_CERTIFICATE_LOGON *pKerbCertLogon;
    KERB_SMARTCARD_CSP_INFO *pKerbCspInfo;
    LPBYTE pbDomainBuffer, pbUserBuffer, pbPinBuffer;
    LPBYTE pbCspData;
    LPBYTE pbCspDataContent;

    ULONG ulCspDataLen = (ULONG)(sizeof(KERB_SMARTCARD_CSP_INFO) - sizeof(TCHAR) +
        (wcslen(szCardName) + 1) * sizeof(WCHAR) +
        (wcslen(szCspName) + 1) * sizeof(WCHAR) +
        (wcslen(szContainerName) + 1) * sizeof(WCHAR) +
        (wcslen(szReaderName) + 1) * sizeof(WCHAR));

    ulAuthInfoLen = sizeof(KERB_CERTIFICATE_LOGON) +
        ulDomainByteLen + sizeof(WCHAR) +
        ulUserByteLen + sizeof(WCHAR) +
        ulPinByteLen + sizeof(WCHAR) +
        ulCspDataLen;

    pbAuthInfo = (LPBYTE)CoTaskMemAlloc(ulAuthInfoLen);
    ZeroMemory(pbAuthInfo, ulAuthInfoLen);

    pbDomainBuffer = pbAuthInfo + sizeof(KERB_CERTIFICATE_LOGON);
    pbUserBuffer = pbDomainBuffer + ulDomainByteLen + sizeof(WCHAR);
    pbPinBuffer = pbUserBuffer + ulUserByteLen + sizeof(WCHAR);
    pbCspData = pbPinBuffer + ulPinByteLen + sizeof(WCHAR);

    memcpy(pbDomainBuffer, szDomainName, ulDomainByteLen);
    memcpy(pbUserBuffer, szUserName, ulUserByteLen);
    memcpy(pbPinBuffer, szPin, ulPinByteLen);

    pKerbCertLogon = (KERB_CERTIFICATE_LOGON*)pbAuthInfo;

    pKerbCertLogon->MessageType = KerbCertificateLogon;
    pKerbCertLogon->DomainName.Length = (USHORT)ulDomainByteLen;
    pKerbCertLogon->DomainName.MaximumLength = (USHORT)(ulDomainByteLen + sizeof(WCHAR));
    pKerbCertLogon->DomainName.Buffer = (PWSTR)pbDomainBuffer;
    pKerbCertLogon->UserName.Length = (USHORT)ulUserByteLen;
    pKerbCertLogon->UserName.MaximumLength = (USHORT)(ulUserByteLen + sizeof(WCHAR));
    pKerbCertLogon->UserName.Buffer = (PWSTR)pbUserBuffer;
    pKerbCertLogon->Pin.Length = (USHORT)ulPinByteLen;
    pKerbCertLogon->Pin.MaximumLength = (USHORT)(ulPinByteLen + sizeof(WCHAR));
    pKerbCertLogon->Pin.Buffer = (PWSTR)pbPinBuffer;

    pKerbCertLogon->CspDataLength = ulCspDataLen;
    pKerbCertLogon->CspData = pbCspData;

    pKerbCspInfo = (KERB_SMARTCARD_CSP_INFO*)pbCspData;
    pKerbCspInfo->dwCspInfoLen = ulCspDataLen;
    pKerbCspInfo->MessageType = 1;
    pKerbCspInfo->KeySpec = AT_KEYEXCHANGE;
    pKerbCspInfo->nCardNameOffset = 0;
    pKerbCspInfo->nReaderNameOffset = pKerbCspInfo->nCardNameOffset + (ULONG)wcslen(szCardName) + 1;
    pKerbCspInfo->nContainerNameOffset = pKerbCspInfo->nReaderNameOffset + (ULONG)wcslen(szReaderName) + 1;
    pKerbCspInfo->nCSPNameOffset = pKerbCspInfo->nContainerNameOffset + (ULONG)wcslen(szContainerName) + 1;

    pbCspDataContent = pbCspData + sizeof(KERB_SMARTCARD_CSP_INFO) - sizeof(TCHAR);
    memcpy(pbCspDataContent + (pKerbCspInfo->nCardNameOffset * sizeof(WCHAR)), szCardName, wcslen(szCardName) * sizeof(WCHAR));
    memcpy(pbCspDataContent + (pKerbCspInfo->nReaderNameOffset * sizeof(WCHAR)), szReaderName, wcslen(szReaderName) * sizeof(WCHAR));
    memcpy(pbCspDataContent + (pKerbCspInfo->nContainerNameOffset * sizeof(WCHAR)), szContainerName, wcslen(szContainerName) * sizeof(WCHAR));
    memcpy(pbCspDataContent + (pKerbCspInfo->nCSPNameOffset * sizeof(WCHAR)), szCspName, wcslen(szCspName) * sizeof(WCHAR));

    *authInfo = pbAuthInfo;
    *authInfoLength = ulAuthInfoLen;
}

来自微软的文档KERB_CERTIFICATE_LOGON结构:

UNICODE_STRING类型的成员中存储的指针是相对的 到结构的开头并且不是绝对内存 指针。

但文档并没有告诉你CspData指针也应该相对于结构的开头......

你打电话时LsaLogonUser对于具有绝对内存指针的数据,它也可以工作,当指针是相对的时也是如此。当数据被序列化时,仅适用于所有相对的指针。

有时(取决于 CREDENTIAL_PROVIDER_USAGE_SCENARIO)您应该使用 KERB_CERTIFICATE_UNLOCK_LOGON 而不是 KERB_CERTIFICATE_LOGON。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

登录时未通过凭据提供程序加载 KSP(密钥存储提供程序) 的相关文章

  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 如何修复错误:“检测到无法访问的代码”

    我有以下代码 private string GetAnswer private int CountLeapYears DateTime startDate return count String answer GetAnswer Respo
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 如何向 Mono.ZeroConf 注册服务?

    我正在尝试测试 ZeroConf 示例http www mono project com Mono Zeroconf http www mono project com Mono Zeroconf 我正在运行 OpenSuse 11 和 M
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • 保证复制省略是否适用于函数参数?

    如果我理解正确的话 从 C 17 开始 这段代码现在要求不进行任何复制 Foo myfunc void return Foo auto foo myfunc no copy 函数参数也是如此吗 下面的代码中的副本会被优化掉吗 Foo myf
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 条件类型定义

    如果我有一小段这样的代码 template
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • winform c# 中的弹出窗口

    我正在开发一个需要弹出窗口的项目 但问题是我还希望能够通过表单设计器在此弹出窗口中添加文本框等 所以基本上我有一个按钮 当您单击它时 它将打开我在表单设计器中设计的另一个窗口 我一直在谷歌搜索 但还没有找到我需要的东西 所以我希望你们能帮助
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work

随机推荐

  • XMLWriter (PHP) 的编码问题

    采用这个简单的 PHP 代码 xmlWriter new XMLWriter xmlWriter gt openURI php output xmlWriter gt startDocument 1 0 utf 8 xmlWriter gt
  • 如何在 C 代码中转到上一行

    如果对于下面的代码 printf HEllo n do not change this line printf b bworld 我需要一个输出 Helloworld 在一行中 但这效果不太好 有人可以解释一下原因吗 以及其他转义序列 如果
  • 如何获取mongodb中子文档之间的日期差异?

    下面是数组 CDF UTILITYTYPE D1 G1 12387835 G22 NAME L1 D5 EVENT CODE 13 TIME 29 05 2022 13 26 00
  • 来自 PreferenceActivity 的 webview.clearCache

    我有preferences xml 它在我的PreferencesActivity 扩展中使用 我在 xml 中有另一个首选项 我想用它来清除 webview 的缓存 它有一个键 但我无法通过按我的首选项中的条目来弄清楚如何触发 webvi
  • 我希望我的 RecyclerView 不回收某些项目

    我正在使用一个RecyclerView里面有异质的景色 如本教程所示 我在 RecyclerView 中有一些项目也是 RecyclerView 太难想象了 假设我想复制 Play 商店的布局 一个大的 RecyclerView 具有垂直线
  • docker 构建期间名称解析失败

    我遇到一个问题 在发出 docker build 命令时收到以下错误 curl 6 Could not resolve host dl yarnpkg com gpg no valid OpenPGP data found 这是我的 Doc
  • iOS 上某些页面的背景图像模糊

    我有一个网站http basement recordings com 使用 wordpress 构建 我对背景图像有一个问题 在 iO 上 在某些页面 例如娱乐和活动 上 背景图像看起来模糊 不清晰 Chrome 和 Safari 上都会出
  • Linux 和 I/O 完成端口?

    使用winsock 您可以将套接字或单独的I O 操作配置为 重叠 这意味着执行 I O 的调用会立即返回 而实际操作则由单独的工作线程异步完成 Winsock 还提供 完成端口 据我了解 完成端口充当句柄 套接字 的多路复用器 如果句柄不
  • 行结束符区别适用于 html 表单吗?

    我知道文件使用的行结尾因操作系统而异 我想知道 如果用户将文本粘贴到 http 表单输入 例如文本区域 中 发送的行结束字符是否以相同的方式取决于操作系统 不 浏览器应该规范行结尾
  • 如何将 CSV 数据文件加载到 R 中以与 quantmod 一起使用

    我是 R 新手 刚刚开始使用它 我目前正在尝试 quantmod 包 quantmod 包似乎可以完成我想做的大部分事情 但是 我不想使用 getSymbols 函数将数据获取到 R 中 相反 我想使用我自己的数据 存储为本地磁盘上的 cs
  • 当滚动窗格包裹文本窗格时,如何防止 JScrollPane 箭头键处理移动插入符

    我有以下要求 我需要一个可滚动的 JTextPane 用户可以在此文本窗格中键入内容 或者可以将用户未键入的文本插入其中 想想类似于 IM 窗口的东西 尽管窗口必须可滚动以允许用户查看先前键入的文本 但插入符号永远不应该从文本末尾的位置移动
  • 解析非预定义参数

    有没有可以在Python中解析sys argv中随机键值对的库 例如 python run py v1 k1 v2 k2 v3 k3 应该返回给我一个像 v1 gt k1 v2 gt k2 v3 gt k3 这样的字典 在编译时我不知道那些
  • 在 IE 中使用 => 时出现语法错误 [重复]

    这个问题在这里已经有答案了 我有以下 JavaScript 代码行 var res Object keys packages filter e gt packages e true 上面的代码在除 IE 之外的所有其他浏览器中都可以正常运行
  • Nifi:如何编写自定义处理器

    我想写nifi处理器 可以从hdfs目录读取xml文件 然后将其数据提取到flowfile属性中 如果有两个 nifi 处理器可以获取该文件并读取数据或向其中写入内容的情况我怎样才能进行文件锁定这样一次只有一个处理器可以使用它 您能给我推荐
  • 在 Angular 2 中使用 ComponentResolver 加载组件时注入不同的提供程序

    我们可以在动态加载组件时注入不同的提供程序吗 我的组件 Component moduleId module id selector my component template div my component div providers M
  • Wikidata+SPARQL:根据股票代码查找公司

    我正在尝试使用 sparql 根据股票代码查找公司 此查询将列出企业及其股票代码 基本查询 SELECT DISTINCT id idLabel ticker WHERE id wdt P31 wdt P279 wd Q4830453 id
  • 如何防止ViewFlipper循环

    我正在开发一个应用程序 其中我使用ViewFlipper与定制OnTouch执行 在里面ViewFlipper 我有大约 20 张图像供用户翻阅 这工作正常 但如果我在该系列中的第 20 个图像处翻转屏幕 它会返回到第一个图像 我想防止Vi
  • AES 姜饼

    This是我的 AES 代码 在 Gingerbread 下 在 2 2 上加密数据然后尝试在 2 3 上解密后出现以下错误 Caused by javax crypto BadPaddingException pad block corr
  • VBA 使用循环引用文本框或标签

    我正在尝试替换以下内容 txt1 Text txt2 Text txt3 Text txt4 text continues for quite awhile With Dim cCont As Control For Each cCont
  • 登录时未通过凭据提供程序加载 KSP(密钥存储提供程序)

    我正在创建一个 Windows 凭据提供程序 以使用此处所述的证书登录到 Windows 域article 这意味着创建一个自定义 KSP 在创建身份验证包时将由 LsaLogonUser 调用 我设法创建自定义 KSP 并在直接调用 Ls