我正在尝试从我的自定义凭据提供程序实现本地登录。为此,我尝试使用MSV1_0
身份验证包,但它总是失败,并产生INVALID_PARAMETER
状态。
代码看起来是这样的:
static void _UnicodeStringPackedUnicodeStringCopy(
const UNICODE_STRING& rus,
PWSTR pwzBuffer,
UNICODE_STRING* pus
) {
pus->Length = rus.Length;
pus->MaximumLength = rus.Length;
pus->Buffer = pwzBuffer;
CopyMemory(pus->Buffer, rus.Buffer, pus->Length);
}
HRESULT LsaInitStringW(PUNICODE_STRING pszDestinationString, PCWSTR pszSourceString)
{
size_t cchLength;
HRESULT hr = StringCchLengthW(pszSourceString, USHORT_MAX, &cchLength);
if (SUCCEEDED(hr))
{
USHORT usLength;
hr = SizeTToUShort(cchLength, &usLength);
if (SUCCEEDED(hr))
{
pszDestinationString->Buffer = (PWCHAR)pszSourceString;
pszDestinationString->Length = usLength * sizeof(WCHAR);
pszDestinationString->MaximumLength = pszDestinationString->Length + 1;
hr = S_OK;
}
}
return hr;
}
HRESULT MsvLogonPack(
const MSV1_0_INTERACTIVE_LOGON& milIn,
BYTE** prgb,
DWORD* pcb
) {
size_t cb = sizeof(milIn)
+ milIn.LogonDomainName.Length
+ milIn.UserName.Length
+ milIn.Password.Length;
MSV1_0_INTERACTIVE_LOGON* milOut = (MSV1_0_INTERACTIVE_LOGON*)CoTaskMemAlloc(cb);
if (!milOut) {
return E_OUTOFMEMORY;
}
milOut->MessageType = milIn.MessageType;
BYTE *pbBuffer = (BYTE*)milOut + sizeof(*milOut);
_UnicodeStringPackedUnicodeStringCopy(milIn.LogonDomainName, (PWSTR)pbBuffer, &milOut->LogonDomainName);
pbBuffer += milOut->LogonDomainName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.UserName, (PWSTR)pbBuffer, &milOut->UserName);
pbBuffer += milOut->UserName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.Password, (PWSTR)pbBuffer, &milOut->Password);
pbBuffer += milOut->Password.Length;
if (pbBuffer != (BYTE*)milOut + cb) {
return E_ABORT;
}
*prgb = (BYTE*)milOut;
*pcb = cb;
return S_OK;
}
HRESULT GetMsvPackage(ULONG * pulAuthPackage) {
HRESULT hr;
HANDLE hLsa;
NTSTATUS status = LsaConnectUntrusted(&hLsa);
if (SUCCEEDED(HRESULT_FROM_NT(status))) {
ULONG ulAuthPackage;
LSA_STRING lsaszKerberosName;
LsaInitString(&lsaszKerberosName, MSV1_0_PACKAGE_NAME);
status = LsaLookupAuthenticationPackage(hLsa, &lsaszKerberosName, &ulAuthPackage);
if (SUCCEEDED(HRESULT_FROM_NT(status))) {
*pulAuthPackage = ulAuthPackage;
hr = S_OK;
}
else {
hr = HRESULT_FROM_NT(status);
}
LsaDeregisterLogonProcess(hLsa);
}
else {
hr = HRESULT_FROM_NT(status);
}
return hr;
}
HRESULT MyCredential::CompleteAuthentication(CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs,
PWSTR* ppwszOptionalStatusText,
CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon) {
HRESULT hr;
pcpcs->clsidCredentialProvider = CLSID_MyProvider;
MSV1_0_INTERACTIVE_LOGON mil;
mil.MessageType = MsV1_0WorkstationUnlockLogon;
hr = LsaInitStringW(&mil.LogonDomainName, L"");
if (SUCCEEDED(hr)) hr = LsaInitStringW(&mil.UserName, L"tester");
if (SUCCEEDED(hr)) hr = LsaInitStringW(&mil.Password, L"12345");
if (SUCCEEDED(hr)) {
hr = MsvLogonPack(mil, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);
if (SUCCEEDED(hr)) {
ULONG ulAuthPackage;
hr = GetMsvPackage(&ulAuthPackage);
if (SUCCEEDED(hr)) {
pcpcs->ulAuthenticationPackage = ulAuthPackage;
}
}
}
return hr;
}
这将继续提供INVALID_PARAMETER
状态,其子状态为0。我尝试用MsV1_0WorkstationUnlockLogon
替换MsV1_0InteractiveLogon
,得到的状态是STATUS_LOGON_FAILURE
,而子状态是INTERNAL_ERROR
。
有什么建议可以解决这个问题?
发布于 2020-02-11 22:35:54
经过一些研究和尝试,我找到了问题所在。问题在于Unicode字符串是绝对的,而它们被要求相对于结构的开始。所以我把它们设为相对的:
_UnicodeStringPackedUnicodeStringCopy(milIn.LogonDomainName, (PWSTR)pbBuffer, &milOut->LogonDomainName);
milOut->LogonDomainName.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->LogonDomainName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.UserName, (PWSTR)pbBuffer, &milOut->UserName);
milOut->UserName.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->UserName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.Password, (PWSTR)pbBuffer, &milOut->Password);
milOut->Password.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->Password.Length;
出于某种原因,KERB_CERTIFICATE_LOGON structure中记录了此行为,但MSV1_0_INTERACTIVE_LOGON中未记录此行为。
https://stackoverflow.com/questions/60169250
复制相似问题