566 lines
12 KiB
C++
566 lines
12 KiB
C++
#include "gptext.h"
|
|
#include <initguid.h>
|
|
#include <iadsp.h>
|
|
#include "ipsecext.h"
|
|
|
|
|
|
#define GPEXT_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{e437bc1c-aa7d-11d2-a382-00c04f991e27}")
|
|
|
|
#define POLICY_PATH TEXT("Software\\Policies\\Microsoft\\Windows\\IPSec\\GPTIPSECPolicy")
|
|
|
|
LPWSTR GetAttributes[] = {L"ipsecOwnersReference", L"ipsecName", L"description"};
|
|
|
|
|
|
HRESULT
|
|
RegisterIPSEC(void)
|
|
{
|
|
HKEY hKey;
|
|
LONG lResult;
|
|
DWORD dwDisp, dwValue;
|
|
TCHAR szBuffer[512];
|
|
|
|
|
|
lResult = RegCreateKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
GPEXT_PATH,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisp
|
|
);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
return lResult;
|
|
}
|
|
|
|
LoadString (g_hInstance, IDS_IPSEC_NAME, szBuffer, ARRAYSIZE(szBuffer));
|
|
|
|
RegSetValueEx (
|
|
hKey,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)szBuffer,
|
|
(lstrlen(szBuffer) + 1) * sizeof(TCHAR)
|
|
);
|
|
|
|
RegSetValueEx (
|
|
hKey,
|
|
TEXT("ProcessGroupPolicy"),
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)TEXT("ProcessIPSECPolicy"),
|
|
(lstrlen(TEXT("ProcessIPSECPolicy")) + 1) * sizeof(TCHAR)
|
|
);
|
|
|
|
szBuffer[0] = L'\0';
|
|
wcscpy(szBuffer, L"gptext.dll");
|
|
|
|
RegSetValueEx (
|
|
hKey,
|
|
TEXT("DllName"),
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(LPBYTE)szBuffer,
|
|
(lstrlen(szBuffer) + 1) * sizeof(TCHAR)
|
|
);
|
|
|
|
dwValue = 1;
|
|
RegSetValueEx (
|
|
hKey,
|
|
TEXT("NoUserPolicy"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(dwValue));
|
|
|
|
RegSetValueEx (
|
|
hKey,
|
|
TEXT("NoGPOListChanges"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(dwValue));
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
UnregisterIPSEC(void)
|
|
{
|
|
|
|
RegDeleteKey (HKEY_LOCAL_MACHINE, GPEXT_PATH);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
ProcessIPSECPolicy(
|
|
IN DWORD dwFlags, // GPO_INFO_FLAGS
|
|
IN HANDLE hToken, // User or machine token
|
|
IN HKEY hKeyRoot, // Root of registry
|
|
IN PGROUP_POLICY_OBJECT pDeletedGPOList, // Linked list of deleted GPOs
|
|
IN PGROUP_POLICY_OBJECT pChangedGPOList, // Linked list of changed GPOs
|
|
IN ASYNCCOMPLETIONHANDLE pHandle, // For asynchronous completion
|
|
IN BOOL *pbAbort, // If true, then abort GPO processing
|
|
IN PFNSTATUSMESSAGECALLBACK pStatusCallback // Callback function for displaying status messages
|
|
)
|
|
|
|
{
|
|
|
|
WCHAR szIPSECPolicy[MAX_PATH];
|
|
WCHAR szIPSECPolicyName[MAX_PATH];
|
|
WCHAR szIPSECPolicyDescription[512];
|
|
HRESULT hr = S_OK;
|
|
PGROUP_POLICY_OBJECT pGPO = NULL;
|
|
|
|
//
|
|
// Call CoInitialize for all the COM work we're doing
|
|
//
|
|
|
|
hr = CoInitializeEx(NULL,0);
|
|
if (FAILED(hr)) {
|
|
goto error;
|
|
}
|
|
|
|
memset(szIPSECPolicy, 0, sizeof(WCHAR)*MAX_PATH);
|
|
memset(szIPSECPolicyName, 0, sizeof(WCHAR)*MAX_PATH);
|
|
memset(szIPSECPolicyDescription, 0, sizeof(WCHAR)*512);
|
|
|
|
|
|
//
|
|
// First process the Deleted GPO List. If there is a single
|
|
// entry on the GPO list, just delete the entire list.
|
|
// Example Rex->Cassius->Brutus. If the delete List has
|
|
// Cassius to be deleted, then really, we shouldn't be deleting
|
|
// our registry entry because we're interested in Brutus which
|
|
// has not be deleted. But in our case, the pChangedGPOList will
|
|
// have all the information, so Brutus gets written back in the
|
|
// next stage.
|
|
//
|
|
|
|
if (pDeletedGPOList) {
|
|
|
|
|
|
DeleteIPSECPolicyFromRegistry();
|
|
|
|
}
|
|
|
|
|
|
pGPO = pChangedGPOList;
|
|
|
|
//
|
|
// Since IPSEC is really interested in the last
|
|
// GPO only, loop through till we hit the last
|
|
// GPO and write that GPO only. In this case, Brutus now
|
|
// gets written back into the registry.
|
|
//
|
|
|
|
if (pChangedGPOList) {
|
|
|
|
while (pGPO->pNext)
|
|
{
|
|
|
|
pGPO = pGPO->pNext;
|
|
}
|
|
|
|
//
|
|
// Now write the last GPOs information
|
|
//
|
|
|
|
hr = RetrieveIPSECPolicyFromDS(
|
|
pGPO,
|
|
szIPSECPolicy,
|
|
szIPSECPolicyName,
|
|
szIPSECPolicyDescription
|
|
);
|
|
if (FAILED(hr)) {
|
|
|
|
goto error;
|
|
}
|
|
|
|
|
|
hr = WriteIPSECPolicyToRegistry(
|
|
szIPSECPolicy,
|
|
szIPSECPolicyName,
|
|
szIPSECPolicyDescription
|
|
);
|
|
if (FAILED(hr)) {
|
|
goto error;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
PingPolicyAgent();
|
|
|
|
CoUninitialize();
|
|
|
|
return(ERROR_SUCCESS);
|
|
|
|
error:
|
|
|
|
return(ERROR_POLICY_OBJECT_NOT_FOUND);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CreateChildPath(
|
|
LPWSTR pszParentPath,
|
|
LPWSTR pszChildComponent,
|
|
BSTR * ppszChildPath
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IADsPathname *pPathname = NULL;
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_Pathname,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IADsPathname,
|
|
(void**)&pPathname
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pPathname->Set(pszParentPath, ADS_SETTYPE_FULL);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pPathname->AddLeafElement(pszChildComponent);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pPathname->Retrieve(ADS_FORMAT_X500, ppszChildPath);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
error:
|
|
if (pPathname) {
|
|
pPathname->Release();
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
RetrieveIPSECPolicyFromDS(
|
|
PGROUP_POLICY_OBJECT pGPOInfo,
|
|
LPWSTR pszIPSecPolicy,
|
|
LPWSTR pszIPSecPolicyName,
|
|
LPWSTR pszIPSecPolicyDescription
|
|
)
|
|
{
|
|
LPWSTR pszMachinePath = NULL;
|
|
BSTR pszMicrosoftPath = NULL;
|
|
BSTR pszWindowsPath = NULL;
|
|
BSTR pszIpsecPath = NULL;
|
|
IDirectoryObject * pDirectoryObject = NULL;
|
|
IDirectoryObject * pIpsecObject = NULL;
|
|
BOOL bFound = FALSE;
|
|
|
|
|
|
LPWSTR pszOwnersReference = L"ipsecOwnersReference";
|
|
|
|
HRESULT hr = S_OK;
|
|
PADS_ATTR_INFO pAttributeEntries = NULL;
|
|
DWORD dwNumAttributesReturned = 0;
|
|
|
|
DWORD i = 0;
|
|
PADS_ATTR_INFO pAttributeEntry = NULL;
|
|
|
|
|
|
pszMachinePath = pGPOInfo->lpDSPath;
|
|
|
|
// Build the fully qualified ADsPath for my object
|
|
|
|
hr = CreateChildPath(
|
|
pszMachinePath,
|
|
L"cn=Microsoft",
|
|
&pszMicrosoftPath
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = CreateChildPath(
|
|
pszMicrosoftPath,
|
|
L"cn=Windows",
|
|
&pszWindowsPath
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = CreateChildPath(
|
|
pszWindowsPath,
|
|
L"cn=ipsec",
|
|
&pszIpsecPath
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = ADsGetObject(
|
|
pszIpsecPath,
|
|
IID_IDirectoryObject,
|
|
(void **)&pIpsecObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pIpsecObject->GetObjectAttributes(
|
|
GetAttributes,
|
|
3,
|
|
&pAttributeEntries,
|
|
&dwNumAttributesReturned
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (dwNumAttributesReturned == 0) {
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
//
|
|
// Process the PathName
|
|
//
|
|
|
|
for (i = 0; i < dwNumAttributesReturned; i++) {
|
|
|
|
pAttributeEntry = pAttributeEntries + i;
|
|
if (!_wcsicmp(pAttributeEntry->pszAttrName, L"ipsecOwnersReference")) {
|
|
|
|
wcscpy(pszIPSecPolicy, L"LDAP://");
|
|
wcscat(pszIPSecPolicy, pAttributeEntry->pADsValues->DNString);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bFound) {
|
|
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// Process the name
|
|
//
|
|
|
|
for (i = 0; i < dwNumAttributesReturned; i++) {
|
|
|
|
pAttributeEntry = pAttributeEntries + i;
|
|
if (!_wcsicmp(pAttributeEntry->pszAttrName, L"ipsecName")) {
|
|
wcscat(pszIPSecPolicyName, pAttributeEntry->pADsValues->DNString);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Process the description
|
|
//
|
|
|
|
for (i = 0; i < dwNumAttributesReturned; i++) {
|
|
|
|
pAttributeEntry = pAttributeEntries + i;
|
|
if (!_wcsicmp(pAttributeEntry->pszAttrName, L"description")) {
|
|
wcscat(pszIPSecPolicyDescription, pAttributeEntry->pADsValues->DNString);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
error:
|
|
|
|
if (pAttributeEntries) {
|
|
|
|
FreeADsMem(pAttributeEntries);
|
|
}
|
|
|
|
if (pIpsecObject) {
|
|
pIpsecObject->Release();
|
|
}
|
|
|
|
if (pszMicrosoftPath) {
|
|
SysFreeString(pszMicrosoftPath);
|
|
}
|
|
|
|
if (pszWindowsPath) {
|
|
SysFreeString(pszWindowsPath);
|
|
}
|
|
|
|
if (pszIpsecPath) {
|
|
SysFreeString(pszIpsecPath);
|
|
}
|
|
|
|
return(hr);
|
|
|
|
}
|
|
|
|
|
|
DWORD
|
|
DeleteIPSECPolicyFromRegistry(
|
|
)
|
|
{
|
|
|
|
DWORD dwError = 0;
|
|
HKEY hKey = NULL;
|
|
DWORD dwDisp = 0;
|
|
|
|
|
|
dwError = RegCreateKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Policies\\Microsoft\\Windows\\IPSec"),
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisp
|
|
);
|
|
if (dwError) {
|
|
goto error;
|
|
}
|
|
|
|
|
|
dwError = RegDeleteKey(
|
|
hKey,
|
|
L"GPTIPSECPolicy"
|
|
);
|
|
|
|
/*
|
|
dwError = RegDeleteValue(
|
|
hKey,
|
|
TEXT("DSIPSECPolicyPath")
|
|
);
|
|
|
|
dwError = RegDeleteValue(
|
|
hKey,
|
|
TEXT("DSIPSECPolicyName")
|
|
);*/
|
|
error:
|
|
|
|
if (hKey) {
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
}
|
|
|
|
return(dwError);
|
|
}
|
|
|
|
DWORD
|
|
WriteIPSECPolicyToRegistry(
|
|
LPWSTR pszIPSecPolicyPath,
|
|
LPWSTR pszIPSecPolicyName,
|
|
LPWSTR pszIPSecPolicyDescription
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
DWORD dwDisp = 0;
|
|
HKEY hKey = NULL;
|
|
DWORD dwFlags = 1;
|
|
|
|
dwError = RegCreateKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
POLICY_PATH,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisp
|
|
);
|
|
if (dwError) {
|
|
goto error;
|
|
}
|
|
|
|
|
|
if (pszIPSecPolicyPath && *pszIPSecPolicyPath) {
|
|
|
|
dwError = RegSetValueEx (
|
|
hKey,
|
|
TEXT("DSIPSECPolicyPath"),
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)pszIPSecPolicyPath,
|
|
(lstrlen(pszIPSecPolicyPath) + 1) * sizeof(TCHAR)
|
|
);
|
|
|
|
dwFlags = 1;
|
|
|
|
dwError = RegSetValueEx (
|
|
hKey,
|
|
TEXT("DSIPSECPolicyFlags"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwFlags,
|
|
sizeof(dwFlags)
|
|
);
|
|
|
|
}
|
|
|
|
|
|
if (pszIPSecPolicyName && *pszIPSecPolicyName) {
|
|
|
|
dwError = RegSetValueEx (
|
|
hKey,
|
|
TEXT("DSIPSECPolicyName"),
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)pszIPSecPolicyName,
|
|
(lstrlen(pszIPSecPolicyName) + 1) * sizeof(TCHAR)
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pszIPSecPolicyDescription && *pszIPSecPolicyDescription) {
|
|
|
|
dwError = RegSetValueEx (
|
|
hKey,
|
|
TEXT("DSIPSECPolicyDescription"),
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)pszIPSecPolicyDescription,
|
|
(lstrlen(pszIPSecPolicyDescription) + 1) * sizeof(TCHAR)
|
|
);
|
|
}
|
|
|
|
error:
|
|
|
|
if (hKey) {
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
}
|
|
|
|
return(dwError);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
PingPolicyAgent(
|
|
)
|
|
{
|
|
HANDLE hPolicyChangeEvent = NULL;
|
|
|
|
hPolicyChangeEvent = OpenEvent(
|
|
EVENT_ALL_ACCESS,
|
|
FALSE,
|
|
L"IPSEC_POLICY_CHANGE_EVENT"
|
|
);
|
|
|
|
if (hPolicyChangeEvent) {
|
|
SetEvent(hPolicyChangeEvent);
|
|
CloseHandle(hPolicyChangeEvent);
|
|
}
|
|
}
|