2
0
mirror of https://github.com/tenrok/Rfid-Credential-Provider.git synced 2026-05-21 13:24:13 +03:00
Files
2019-11-29 15:55:40 +03:00

317 lines
7.4 KiB
C++

#ifndef WIN32_NO_STATUS
#include <ntstatus.h>
#define WIN32_NO_STATUS
#endif
#include <tchar.h>
#include "RfidCredential.h"
#include "guid.h"
#include <iostream>
#include <ntstatus.h>
#include <subauth.h>
#include "Logger.h"
extern HINSTANCE hInstance;
typedef int (WINAPI* PFRUNGATEFRAMEWORKPWDRESET) (HWND, PWSTR, PWSTR, PWSTR);
RfidCredential::RfidCredential() :
_cRef(1),
_pCredProvCredentialEvents(NULL)
{
DllAddRef();
ZeroMemory(_rgCredProvFieldDescriptors, sizeof(_rgCredProvFieldDescriptors));
ZeroMemory(_rgFieldStatePairs, sizeof(_rgFieldStatePairs));
ZeroMemory(_rgFieldStrings, sizeof(_rgFieldStrings));
}
RfidCredential::~RfidCredential()
{
for (int i = 0; i < ARRAYSIZE(_rgFieldStrings); i++)
{
CoTaskMemFree(_rgFieldStrings[i]);
CoTaskMemFree(_rgCredProvFieldDescriptors[i].pszLabel);
}
DllRelease();
}
bool RfidCredential::lastLoginFailed;
KERB_LOGON_SUBMIT_TYPE RfidCredential::lockType;
HRESULT RfidCredential::Initialize(
const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR* rgcpfd,
const FIELD_STATE_PAIR* rgfsp,
PWSTR pwzUsername,
PWSTR pwzPassword,
PWSTR pwzDomain
)
{
UNREFERENCED_PARAMETER(pwzPassword);
HRESULT hr = S_OK;
for (DWORD i = 0; SUCCEEDED(hr) && i < ARRAYSIZE(_rgCredProvFieldDescriptors); i++)
{
_rgFieldStatePairs[i] = rgfsp[i];
hr = FieldDescriptorCopy(rgcpfd[i], &_rgCredProvFieldDescriptors[i]);
}
username = pwzUsername;
password = pwzPassword;
domain = pwzDomain;
LPWSTR loginString;
if (username && domain) {
loginString = new wchar_t[10 + wcslen(username) + wcslen(password)];
wsprintf(loginString, L"Login as %s\\%s", domain, username);
}
if (SUCCEEDED(hr))
{
hr = SHStrDupW(L"RFID", &_rgFieldStrings[SFI_TITLE]);
}
if (SUCCEEDED(hr))
{
if (!username)
{
hr = SHStrDupW(L"Swipe your registered RFID credential now.", &_rgFieldStrings[SFI_DETAILS]);
}
else
{
hr = SHStrDupW(loginString, &_rgFieldStrings[SFI_DETAILS]);
}
}
if (SUCCEEDED(hr))
{
if (!username)
{
hr = SHStrDupW(L"Swipe your token", &_rgFieldStrings[SFI_MINIDETAILS]);
}
else
{
hr = SHStrDupW(loginString, &_rgFieldStrings[SFI_MINIDETAILS]);
}
}
return S_OK;
}
HRESULT RfidCredential::Advise(ICredentialProviderCredentialEvents* pcpce)
{
if (_pCredProvCredentialEvents != nullptr)
{
_pCredProvCredentialEvents->Release();
}
_pCredProvCredentialEvents = pcpce;
_pCredProvCredentialEvents->AddRef();
return S_OK;
}
HRESULT RfidCredential::UnAdvise()
{
if (_pCredProvCredentialEvents)
{
_pCredProvCredentialEvents->Release();
}
_pCredProvCredentialEvents = nullptr;
return S_OK;
}
HRESULT RfidCredential::SetSelected(BOOL* pbAutoLogon)
{
if (username && password && domain && !this->lastLoginFailed)
{
*pbAutoLogon = TRUE;
}
else
{
*pbAutoLogon = FALSE;
if (this->lastLoginFailed)
{
if (_pCredProvCredentialEvents != nullptr)
{
_pCredProvCredentialEvents->SetFieldString(this, SFI_MINIDETAILS, L"Login credentials were invalid.");
_pCredProvCredentialEvents->SetFieldString(this, SFI_DETAILS, L"Login details were invalid. You will need to login with a different credential to update them.");
_pCredProvCredentialEvents->SetFieldBitmap(this, SFI_TILEIMAGE, LoadBitmap(HINST_THISDLL, MAKEINTRESOURCE(104)));
}
}
}
return S_OK;
}
HRESULT RfidCredential::SetDeselected()
{
HRESULT hr = S_OK;
return hr;
}
HRESULT RfidCredential::GetFieldState(DWORD dwFieldID, CREDENTIAL_PROVIDER_FIELD_STATE* pcpfs, CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE* pcpfis)
{
HRESULT hr;
if ((dwFieldID < ARRAYSIZE(_rgFieldStatePairs)) && pcpfs && pcpfis)
{
*pcpfs = _rgFieldStatePairs[dwFieldID].cpfs;
*pcpfis = _rgFieldStatePairs[dwFieldID].cpfis;
hr = S_OK;
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
HRESULT RfidCredential::GetStringValue(DWORD dwFieldID, PWSTR* ppwsz)
{
HRESULT hr;
if (dwFieldID < ARRAYSIZE(_rgCredProvFieldDescriptors) && ppwsz)
{
hr = SHStrDupW(_rgFieldStrings[dwFieldID], ppwsz);
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
HRESULT RfidCredential::GetBitmapValue(DWORD dwFieldID, HBITMAP* phbmp)
{
HRESULT hr;
if ((SFI_TILEIMAGE == dwFieldID) && phbmp)
{
HBITMAP hbmp;
if (username && password && domain && !this->lastLoginFailed)
{
hbmp = LoadBitmap(HINST_THISDLL, MAKEINTRESOURCE(102));
}
else
{
hbmp = LoadBitmap(HINST_THISDLL, MAKEINTRESOURCE(101));
}
if (hbmp != NULL)
{
hr = S_OK;
*phbmp = hbmp;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
HRESULT RfidCredential::GetSubmitButtonValue(DWORD dwFieldID, DWORD* pdwAdjacentTo)
{
return E_INVALIDARG;
}
HRESULT RfidCredential::SetStringValue(DWORD dwFieldID, PCWSTR pwz)
{
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(pwz);
return E_NOTIMPL;
}
HRESULT RfidCredential::GetCheckboxValue(DWORD dwFieldID, BOOL* pbChecked, PWSTR* ppwszLabel)
{
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(pbChecked);
UNREFERENCED_PARAMETER(ppwszLabel);
return E_NOTIMPL;
}
HRESULT RfidCredential::GetComboBoxValueCount(DWORD dwFieldID, DWORD* pcItems, DWORD* pdwSelectedItem)
{
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(pcItems);
UNREFERENCED_PARAMETER(pdwSelectedItem);
return E_NOTIMPL;
}
HRESULT RfidCredential::GetComboBoxValueAt(DWORD dwFieldID, DWORD dwItem, PWSTR* ppwszItem)
{
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(dwItem);
UNREFERENCED_PARAMETER(ppwszItem);
return E_NOTIMPL;
}
HRESULT RfidCredential::SetCheckboxValue(DWORD dwFieldID, BOOL bChecked)
{
UNREFERENCED_PARAMETER(dwFieldID);
UNREFERENCED_PARAMETER(bChecked);
return E_NOTIMPL;
}
HRESULT RfidCredential::SetComboBoxSelectedValue(DWORD dwFieldId, DWORD dwSelectedItem)
{
UNREFERENCED_PARAMETER(dwFieldId);
UNREFERENCED_PARAMETER(dwSelectedItem);
return E_NOTIMPL;
}
HRESULT RfidCredential::CommandLinkClicked(DWORD dwFieldID)
{
UNREFERENCED_PARAMETER(dwFieldID);
return E_NOTIMPL;
}
HRESULT RfidCredential::GetSerialization(
CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs,
PWSTR* ppwzOptionalStatusText,
CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon
)
{
UNREFERENCED_PARAMETER(ppwzOptionalStatusText);
UNREFERENCED_PARAMETER(pcpsiOptionalStatusIcon);
KERB_INTERACTIVE_LOGON kil;
ZeroMemory(&kil, sizeof(kil));
HRESULT hr;
this->lastLoginFailed = true;
//WCHAR wsz[MAX_COMPUTERNAME_LENGTH+1];
//DWORD cch = ARRAYSIZE(wsz);
//GetComputerNameW(wsz, &cch);
hr = UnicodeStringInitWithString(domain, &kil.LogonDomainName);
hr = UnicodeStringInitWithString(username, &kil.UserName);
hr = UnicodeStringInitWithString(password, &kil.Password);
if (SUCCEEDED(hr))
{
kil.MessageType = lockType;
hr = KerbInteractiveLogonPack(kil, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);
if (SUCCEEDED(hr))
{
ULONG ulAuthPackage;
hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
if (SUCCEEDED(hr))
{
pcpcs->ulAuthenticationPackage = ulAuthPackage;
pcpcs->clsidCredentialProvider = CLSID_RfidProvider;
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
}
}
}
else
{
DWORD dwErr = GetLastError();
hr = HRESULT_FROM_WIN32(dwErr);
}
return hr;
}
HRESULT RfidCredential::ReportResult(
NTSTATUS ntsStatus,
NTSTATUS ntsSubstatus,
PWSTR* ppwszOptionalStatusText,
CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon
)
{
UNREFERENCED_PARAMETER(ntsSubstatus);
UNREFERENCED_PARAMETER(ppwszOptionalStatusText);
UNREFERENCED_PARAMETER(pcpsiOptionalStatusIcon);
return E_NOTIMPL;
}