gpt4 book ai didi

c++ - KSP( key 存储提供程序)未通过凭据提供程序在登录时加载

转载 作者:行者123 更新时间:2023-11-30 02:30:38 24 4
gpt4 key购买 nike

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

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

但是,当我在凭证上的 GetSerialization 期间使用相同的身份验证包时,KSP 甚至没有加载,我得到 ReportResult(NTSTATUS ntsStatus, NTSTATUS ntsSubstatus, ... .) 在 ntsStatus 上。

这是我在测试中使用的 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 登录期间从 Credential Provider 调用。

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 结构的文档:

The pointers stored in the members of UNICODE_STRING type are relative to the beginning of the structure and are not absolute memory pointers.

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

当您使用带有绝对内存指针的数据调用 LsaLogonUser 时,它将起作用,当指针是相对的时也是如此。当数据被序列化时,将仅适用于所有相关指针。

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

关于c++ - KSP( key 存储提供程序)未通过凭据提供程序在登录时加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38398905/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com