2025-11-28 00:35:46 +09:00

169 lines
6.8 KiB
C++

#pragma once
#include <vector>
#include <string>
#include <map>
#include <fstream>
#include <windows.h>
#include <winrt/Microsoft.UI.Xaml.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include <App.xaml.h>
#include "PluginRegistrationManager.h"
#include <CredentialListViewModel.h>
#include <Credential.h>
#include <wil/registry.h>
#include <wil/registry_helpers.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/base.h>
namespace winrt {
using namespace winrt::Microsoft::UI::Xaml::Controls;
}
const DWORD maxWebAuthnWStringSize = 64;
constexpr wchar_t c_pluginLocalAppDataDBDir[] = L"CredentialsDB";
constexpr wchar_t c_credentialsFileName[] = L"credentials.dat";
struct PluginCredentialDetailsDeleter {
void operator()(EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS p) {
delete[](p->pbCredentialId);
free(p->pwszRpId);
free(p->pwszRpName);
delete[](p->pbUserId);
free(p->pwszUserName);
free(p->pwszUserDisplayName);
}
};
using unique_plugin_credential_details = std::unique_ptr<EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS, PluginCredentialDetailsDeleter>;
struct CredentialDetailsDeleter {
void operator()(PWEBAUTHN_CREDENTIAL_DETAILS p) {
delete[](p->pbCredentialID);
delete[](p->pUserInformation->pbId);
delete[](reinterpret_cast<PBYTE>(const_cast<PWSTR>(p->pRpInformation->pwszId)));
delete[](reinterpret_cast<PBYTE>(const_cast<PWSTR>(p->pRpInformation->pwszName)));
delete[](reinterpret_cast<PBYTE>(const_cast<PWSTR>(p->pUserInformation->pwszName)));
delete[](reinterpret_cast<PBYTE>(const_cast<PWSTR>(p->pUserInformation->pwszDisplayName)));
delete p->pUserInformation;
delete p->pRpInformation;
}
};
using unique_credential_details = std::unique_ptr<WEBAUTHN_CREDENTIAL_DETAILS, CredentialDetailsDeleter>;
namespace winrt::PasskeyManager::implementation
{
class PluginCredentialManager
{
public:
static PluginCredentialManager& getInstance()
{
static PluginCredentialManager instance;
return instance;
}
HRESULT Initialize()
{
if (!m_initialized)
{
ReloadRegistryValues();
ReloadCredentialManager();
m_initialized = true;
return S_OK;
}
RETURN_HR(E_FAIL);
}
bool IsLocalCredentialMetadataLoaded()
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
return m_localCredentialsLoaded;
}
bool IsCachedCredentialsMetadataLoaded()
{
std::lock_guard<std::mutex> lock(m_pluginCachedCredentialsOperationMutex);
return m_cachedCredentialsLoaded;
}
void ReloadRegistryValues()
{
std::lock_guard<std::mutex> lock(m_pluginOperationConfigMutex);
auto opt = wil::reg::try_get_value_dword(HKEY_CURRENT_USER, c_pluginRegistryPath, c_windowsPluginSilentOperationRegKeyName);
m_silentOperation = opt.value_or(m_silentOperation) != 0;
opt = wil::reg::try_get_value_dword(HKEY_CURRENT_USER, c_pluginRegistryPath, c_windowsPluginVaultLockedRegKeyName);
m_vaultLocked = opt.value_or(m_vaultLocked) != 0;
}
HRESULT AddAllPluginCredentials();
HRESULT AddPluginCredentialById(const std::vector<std::vector<UINT8>> &credentialIdList);
HRESULT DeleteAllPluginCredentials();
HRESULT DeletePluginCredentialById(const std::vector<std::vector<UINT8>> &credentialIdList, bool deleteEverywhere);
HRESULT RefreshAutofillPluginCredentialsList();
bool IsPluginCredentialIdAutofillSupported(DWORD cbCredentialId, PBYTE pbCredentialId) const;
// Local credential metadata management
bool GetCredentialStorageFilePath(std::wstring& filePath);
bool SaveCredentialMetadataToMockDB(const WEBAUTHN_CREDENTIAL_DETAILS& newCredential);
void GetLocalCredsByRpIdAndAllowList(PCWSTR rpId, PWEBAUTHN_CREDENTIAL_EX* ppCredentialList, DWORD pcCredentials, std::vector<const WEBAUTHN_CREDENTIAL_DETAILS *>& matchingCredentials);
bool ResetLocalCredentialsStore();
DWORD GetLocalCredentialCount()
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
return static_cast<DWORD>(m_pluginLocalCredentialMetadataMap.size());
}
DWORD GetCachedCredentialCount()
{
std::lock_guard<std::mutex> lock(m_pluginCachedCredentialsOperationMutex);
return static_cast<DWORD>(m_pluginCachedCredentialMetadataMap.size());
}
void ReloadCredentialManager()
{
LoadSavedCredentialsFromMockDatabase();
RefreshAutofillPluginCredentialsList();
}
bool GetCredentialStorageFolderPath(std::wstring& outPath)
{
Windows::Storage::ApplicationData appData = Windows::Storage::ApplicationData::Current();
Windows::Storage::StorageFolder localFolder = appData.LocalFolder();
std::wstring localFolderPath = localFolder.Path().c_str();
outPath = localFolderPath + L"\\" + c_pluginLocalAppDataDBDir;
return true;
}
// UI Related Functions
std::vector< winrt::com_ptr<Credential>> GetCredentialListViewModel();
// Plugin Operations Toggles
HRESULT SetVaultLock(bool lock);
bool GetVaultLock();
HRESULT SetSilentOperation(bool silent);
bool GetSilentOperation();
private:
PluginCredentialManager();
~PluginCredentialManager();
PluginCredentialManager(const PluginCredentialManager&) = delete;
PluginCredentialManager& operator=(const PluginCredentialManager&) = delete;
bool m_initialized = false;
//Local Credential Metadata Management
bool LoadSavedCredentialsFromMockDatabase();
bool RecreateCredentialMetadataFile();
std::mutex m_pluginLocalCredentialsOperationMutex;
_Guarded_by_(m_pluginLocalCredentialsOperationMutex) bool m_localCredentialsLoaded = false;
_Guarded_by_(m_pluginLocalCredentialsOperationMutex) std::map<std::vector<UINT8>, unique_credential_details> m_pluginLocalCredentialMetadataMap;
//Cached Credential Metadata Management
std::mutex m_pluginCachedCredentialsOperationMutex;
_Guarded_by_(m_pluginCachedCredentialsOperationMutex) bool m_cachedCredentialsLoaded = false;
_Guarded_by_(m_pluginCachedCredentialsOperationMutex) std::map<std::vector<UINT8>, unique_plugin_credential_details> m_pluginCachedCredentialMetadataMap;
std::mutex m_pluginOperationConfigMutex;
_Guarded_by_(m_pluginOperationConfigMutex) bool m_vaultLocked = false;
_Guarded_by_(m_pluginOperationConfigMutex) bool m_silentOperation = false;
wil::unique_hmodule m_webAuthnDll;
};
}