You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
935 lines
29 KiB
935 lines
29 KiB
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: module.cpp
|
|
//
|
|
// Contents: Cert Server Policy Module implementation
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
#include "commctrl.h"
|
|
#include "module.h"
|
|
#include "policy.h"
|
|
|
|
#include "celib.h"
|
|
|
|
// ..\inc
|
|
#include "listvw.h"
|
|
|
|
// help ids
|
|
#define _CERTPDEF_
|
|
#include "cemmchlp.h"
|
|
|
|
extern HINSTANCE g_hInstance;
|
|
|
|
|
|
STDMETHODIMP
|
|
CCertManagePolicyModuleExchange::GetProperty(
|
|
/* [in] */ const BSTR strConfig,
|
|
/* [in] */ BSTR strStorageLocation,
|
|
/* [in] */ BSTR strPropertyName,
|
|
/* [in] */ LONG dwFlags,
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarProperty)
|
|
{
|
|
UINT uiStr = 0;
|
|
WCHAR const *pwsz = NULL;
|
|
|
|
if (NULL == pvarProperty)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
VariantInit(pvarProperty);
|
|
|
|
if (strPropertyName == NULL)
|
|
return S_FALSE;
|
|
|
|
if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_NAME))
|
|
uiStr = IDS_MODULE_NAME;
|
|
else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_DESCRIPTION))
|
|
pwsz = g_wszDescription;
|
|
else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_COPYRIGHT))
|
|
uiStr = IDS_MODULE_COPYRIGHT;
|
|
else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_FILEVER))
|
|
uiStr = IDS_MODULE_FILEVER;
|
|
else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_PRODUCTVER))
|
|
uiStr = IDS_MODULE_PRODUCTVER;
|
|
else
|
|
return S_FALSE;
|
|
|
|
// load string from resource
|
|
WCHAR szStr[MAX_PATH];
|
|
|
|
if (NULL == pwsz)
|
|
{
|
|
LoadString(g_hInstance, uiStr, szStr, ARRAYSIZE(szStr));
|
|
pwsz = szStr;
|
|
}
|
|
|
|
pvarProperty->bstrVal = SysAllocString(pwsz);
|
|
if (NULL == pvarProperty->bstrVal)
|
|
return E_OUTOFMEMORY;
|
|
|
|
pvarProperty->vt = VT_BSTR;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCertManagePolicyModuleExchange::SetProperty(
|
|
/* [in] */ const BSTR strConfig,
|
|
/* [in] */ BSTR strStorageLocation,
|
|
/* [in] */ BSTR strPropertyName,
|
|
/* [in] */ LONG dwFlags,
|
|
/* [in] */ VARIANT const __RPC_FAR *pvalProperty)
|
|
{
|
|
if (strPropertyName == NULL)
|
|
return S_FALSE;
|
|
if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_DISPLAY_HWND))
|
|
{
|
|
if (pvalProperty->vt != VT_BSTR)
|
|
return E_INVALIDARG;
|
|
|
|
if (SysStringByteLen(pvalProperty->bstrVal) != sizeof(HWND))
|
|
return E_INVALIDARG;
|
|
|
|
// the value is stored as bytes in the bstr itself, not the bstr ptr
|
|
m_hWnd = *(HWND*)pvalProperty->bstrVal;
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
INT_PTR CALLBACK WizPage1DlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
INT_PTR CALLBACK WizPage2DlgProc(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
INT_PTR CALLBACK dlgAddURL(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
typedef struct _POLICY_CONFIGSTRUCT
|
|
{
|
|
const BSTR* pstrConfig;
|
|
ENUM_CATYPES CAType;
|
|
HKEY hkeyStorageLocation;
|
|
LONG Flags;
|
|
|
|
DWORD dwPageModified;
|
|
} POLICY_CONFIGSTRUCT, *PPOLICY_CONFIGSTRUCT;
|
|
|
|
// dwPageModified
|
|
#define PAGE1 (0x1)
|
|
#define PAGE2 (0x2)
|
|
|
|
|
|
void MessageBoxWarnReboot(HWND hwndDlg)
|
|
{
|
|
WCHAR szText[MAX_PATH], szTitle[MAX_PATH];
|
|
|
|
LoadString(g_hInstance, IDS_MODULE_NAME, szTitle, ARRAYSIZE(szTitle));
|
|
LoadString(g_hInstance, IDS_WARNING_REBOOT, szText, ARRAYSIZE(szText));
|
|
MessageBox(hwndDlg, szText, szTitle, MB_OK|MB_ICONINFORMATION);
|
|
}
|
|
|
|
void MessageBoxNoSave(HWND hwndDlg)
|
|
{
|
|
WCHAR szText[MAX_PATH], szTitle[MAX_PATH];
|
|
|
|
LoadString(g_hInstance, IDS_MODULE_NAME, szTitle, ARRAYSIZE(szTitle));
|
|
LoadString(g_hInstance, IDS_WARNING_NOSAVE, szText, ARRAYSIZE(szText));
|
|
MessageBox(hwndDlg, szText, szTitle, MB_OK|MB_ICONINFORMATION);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCertManagePolicyModuleExchange::Configure(
|
|
/* [in] */ const BSTR strConfig,
|
|
/* [in] */ BSTR strStorageLocation,
|
|
/* [in] */ LONG dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
BSTR strName = NULL;
|
|
VARIANT varValue;
|
|
VariantInit(&varValue);
|
|
|
|
ICertServerPolicy *pServer = NULL;
|
|
POLICY_CONFIGSTRUCT sConfig = {NULL, ENUM_UNKNOWN_CA, NULL, 0, 0};
|
|
|
|
BOOL fLocal;
|
|
LPWSTR szMachine = NULL;
|
|
HKEY hkeyHKLM = NULL;
|
|
DWORD dwDisposition;
|
|
|
|
hr = ceIsConfigLocal(strConfig, &szMachine, &fLocal);
|
|
_JumpIfError(hr, Ret, "ceIsConfigLocal");
|
|
|
|
// use callbacks for info
|
|
hr = GetServerCallbackInterface(&pServer, 0); // no context : 0
|
|
_JumpIfError(hr, Ret, "GetServerCallbackInterface");
|
|
|
|
// we need to find out who we're running under
|
|
|
|
strName = SysAllocString(wszPROPCATYPE);
|
|
if (NULL == strName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, Ret, "SysAllocString");
|
|
}
|
|
hr = pServer->GetCertificateProperty(
|
|
strName,
|
|
PROPTYPE_LONG,
|
|
&varValue);
|
|
_JumpIfError(hr, Ret, "GetCertificateProperty : wszPROPCATYPE");
|
|
|
|
sConfig.CAType = (ENUM_CATYPES)varValue.lVal;
|
|
VariantClear(&varValue);
|
|
|
|
hr = PopulateRegistryDefaults(fLocal? NULL : szMachine, strStorageLocation);
|
|
_PrintIfError(hr, "PopulateRegistryDefaults");
|
|
|
|
if (!fLocal)
|
|
{
|
|
hr = RegConnectRegistry(
|
|
szMachine,
|
|
HKEY_LOCAL_MACHINE,
|
|
&hkeyHKLM);
|
|
_JumpIfError(hr, Ret, "RegConnectRegistry");
|
|
}
|
|
|
|
// open storage location: write perms if possible
|
|
hr = RegCreateKeyEx(
|
|
fLocal ? HKEY_LOCAL_MACHINE : hkeyHKLM,
|
|
strStorageLocation,
|
|
0,
|
|
NULL,
|
|
0,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&sConfig.hkeyStorageLocation,
|
|
&dwDisposition);
|
|
if (hr != S_OK)
|
|
{
|
|
hr = RegOpenKeyEx(
|
|
fLocal ? HKEY_LOCAL_MACHINE : hkeyHKLM,
|
|
strStorageLocation,
|
|
0,
|
|
KEY_READ, // fallback: read-only
|
|
&sConfig.hkeyStorageLocation);
|
|
_JumpIfError(hr, Ret, "RegOpenKeyEx");
|
|
}
|
|
|
|
sConfig.pstrConfig = &strConfig;
|
|
sConfig.Flags = dwFlags;
|
|
|
|
|
|
PROPSHEETPAGE page[2];
|
|
ZeroMemory(&page[0], sizeof(PROPSHEETPAGE));
|
|
page[0].dwSize = sizeof(PROPSHEETPAGE);
|
|
page[0].dwFlags = PSP_DEFAULT;
|
|
page[0].hInstance = g_hInstance;
|
|
page[0].lParam = (LPARAM)&sConfig;
|
|
|
|
// make 2nd page exactly the same as this
|
|
CopyMemory(&page[1], &page[0], sizeof(PROPSHEETPAGE));
|
|
|
|
// now page1 vs. page2 diffcs
|
|
page[0].pszTemplate = MAKEINTRESOURCE(IDD_POLICYPG1);
|
|
page[0].pfnDlgProc = WizPage1DlgProc;
|
|
|
|
page[1].pszTemplate = MAKEINTRESOURCE(IDD_POLICYPG2);
|
|
page[1].pfnDlgProc = WizPage2DlgProc;
|
|
|
|
|
|
|
|
PROPSHEETHEADER sSheet;
|
|
ZeroMemory(&sSheet, sizeof(PROPSHEETHEADER));
|
|
sSheet.dwSize = sizeof(PROPSHEETHEADER);
|
|
sSheet.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
|
|
sSheet.hwndParent = m_hWnd;
|
|
sSheet.pszCaption = MAKEINTRESOURCE(IDS_MODULE_NAME);
|
|
sSheet.nPages = ARRAYSIZE(page);
|
|
sSheet.ppsp = page;
|
|
|
|
|
|
// finally, invoke the modal sheet
|
|
INT_PTR iRet;
|
|
iRet = ::PropertySheet(&sSheet);
|
|
|
|
if ((iRet > 0) && (sConfig.dwPageModified)) // successful modification
|
|
{
|
|
MessageBoxWarnReboot(NULL);
|
|
}
|
|
|
|
Ret:
|
|
if (NULL != strName)
|
|
{
|
|
SysFreeString(strName);
|
|
}
|
|
if (sConfig.hkeyStorageLocation)
|
|
RegCloseKey(sConfig.hkeyStorageLocation);
|
|
|
|
if (szMachine)
|
|
LocalFree(szMachine);
|
|
|
|
if (hkeyHKLM)
|
|
RegCloseKey(hkeyHKLM);
|
|
|
|
if (pServer)
|
|
pServer->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
CERTSVR_URL_PARSING rgPOSSIBLE_CRL_URLs[] =
|
|
{
|
|
{ L"ldap:", wszREGLDAPREVOCATIONCRLURL_OLD, REVEXT_CDPLDAPURL_OLD | REVEXT_CDPENABLE },
|
|
{ L"http:", wszREGREVOCATIONCRLURL_OLD, REVEXT_CDPHTTPURL_OLD | REVEXT_CDPENABLE },
|
|
{ L"ftp:", wszREGFTPREVOCATIONCRLURL_OLD, REVEXT_CDPFTPURL_OLD | REVEXT_CDPENABLE },
|
|
{ L"file:", wszREGFILEREVOCATIONCRLURL_OLD, REVEXT_CDPFILEURL_OLD | REVEXT_CDPENABLE },
|
|
};
|
|
|
|
|
|
CERTSVR_URL_PARSING rgPOSSIBLE_AIA_URLs[] =
|
|
{
|
|
{ L"ldap:", wszREGLDAPISSUERCERTURL_OLD, ISSCERT_LDAPURL_OLD | ISSCERT_ENABLE},
|
|
{ L"http:", wszREGISSUERCERTURL_OLD, ISSCERT_HTTPURL_OLD | ISSCERT_ENABLE},
|
|
{ L"ftp:", wszREGFTPISSUERCERTURL_OLD, ISSCERT_FTPURL_OLD | ISSCERT_ENABLE },
|
|
{ L"file:", wszREGFILEISSUERCERTURL_OLD, ISSCERT_FILEURL_OLD | ISSCERT_ENABLE},
|
|
};
|
|
|
|
|
|
void mySetModified(HWND hwndPage, POLICY_CONFIGSTRUCT* psConfig)
|
|
{
|
|
if (psConfig->dwPageModified != 0)
|
|
{
|
|
PropSheet_Changed( ::GetParent(hwndPage), hwndPage);
|
|
}
|
|
else
|
|
{
|
|
PropSheet_UnChanged( ::GetParent(hwndPage), hwndPage);
|
|
}
|
|
}
|
|
|
|
INT_PTR CALLBACK WizPage1DlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
POLICY_CONFIGSTRUCT* psConfig;
|
|
BOOL fReturn = FALSE;
|
|
HRESULT hr;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
::SetWindowLong(hwndDlg, GWL_EXSTYLE, ::GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
|
|
|
|
PROPSHEETPAGE* ps = (PROPSHEETPAGE *) lParam;
|
|
psConfig = (POLICY_CONFIGSTRUCT*)ps->lParam;
|
|
|
|
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM)psConfig);
|
|
|
|
DWORD dwRequestDisposition, dwType;
|
|
DWORD cbRequestDisposition = sizeof(dwRequestDisposition);
|
|
hr = RegQueryValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGREQUESTDISPOSITION,
|
|
0,
|
|
&dwType,
|
|
(PBYTE)&dwRequestDisposition,
|
|
&cbRequestDisposition);
|
|
if ((hr != ERROR_SUCCESS) || (dwType != REG_DWORD))
|
|
break;
|
|
|
|
// if disposition includes Issue
|
|
if ((dwRequestDisposition & REQDISP_MASK) == REQDISP_ISSUE)
|
|
{
|
|
// if pending bit set
|
|
if (dwRequestDisposition & REQDISP_PENDINGFIRST)
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_PENDFIRST), BM_SETCHECK, TRUE, BST_CHECKED);
|
|
else
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_ISSUE), BM_SETCHECK, TRUE, BST_CHECKED);
|
|
}
|
|
|
|
// disallow "Pend first" if Enterprise (bug #259346)
|
|
if ((psConfig->CAType == ENUM_ENTERPRISE_ROOTCA) ||
|
|
(psConfig->CAType == ENUM_ENTERPRISE_SUBCA))
|
|
{
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_PENDFIRST), FALSE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_PENDFIRST), FALSE);
|
|
}
|
|
|
|
psConfig->dwPageModified &= ~PAGE1; // we're virgin
|
|
mySetModified(hwndDlg, psConfig);
|
|
|
|
// no other work to be done
|
|
fReturn = TRUE;
|
|
break;
|
|
}
|
|
case WM_HELP:
|
|
{
|
|
OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG1);
|
|
break;
|
|
}
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG1);
|
|
break;
|
|
}
|
|
case WM_NOTIFY:
|
|
switch( ((LPNMHDR)lParam) -> code)
|
|
{
|
|
case PSN_APPLY:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
if (psConfig->dwPageModified & PAGE1)
|
|
{
|
|
DWORD dwCheckState, dwRequestDisposition;
|
|
dwCheckState = (DWORD)SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_ISSUE), BM_GETCHECK, 0, 0);
|
|
|
|
if (dwCheckState == BST_CHECKED)
|
|
dwRequestDisposition = REQDISP_ISSUE;
|
|
else
|
|
dwRequestDisposition = REQDISP_ISSUE | REQDISP_PENDINGFIRST;
|
|
|
|
hr = RegSetValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGREQUESTDISPOSITION,
|
|
0,
|
|
REG_DWORD,
|
|
(PBYTE)&dwRequestDisposition,
|
|
sizeof(DWORD));
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
MessageBoxNoSave(hwndDlg);
|
|
psConfig->dwPageModified &= ~PAGE1;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case PSN_RESET:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
psConfig->dwPageModified &= ~PAGE1;
|
|
mySetModified(hwndDlg, psConfig);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_RADIO_ISSUE:
|
|
case IDC_RADIO_PENDFIRST:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
if (BN_CLICKED == HIWORD(wParam))
|
|
{
|
|
psConfig->dwPageModified |= PAGE1;
|
|
mySetModified(hwndDlg, psConfig);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK WizPage2DlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
POLICY_CONFIGSTRUCT* psConfig;
|
|
HWND hListView;
|
|
BOOL fCRLSelection= FALSE;
|
|
BOOL fReturn = FALSE;
|
|
HRESULT hr;
|
|
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
::SetWindowLong(hwndDlg, GWL_EXSTYLE, ::GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
|
|
|
|
PROPSHEETPAGE* ps = (PROPSHEETPAGE *) lParam;
|
|
psConfig = (POLICY_CONFIGSTRUCT*)ps->lParam;
|
|
|
|
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM)psConfig);
|
|
|
|
DWORD dwAllBits, dwType;
|
|
DWORD cbDWSize=sizeof(dwAllBits);
|
|
|
|
LVCOLUMN lvCol;
|
|
lvCol.mask = LVCF_FMT | LVCF_TEXT;
|
|
lvCol.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvCol.pszText = L""; // The text for the column.
|
|
|
|
// get all extension bits -
|
|
hr = RegQueryValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGREVOCATIONTYPE, // CDP
|
|
0,
|
|
&dwType,
|
|
(PBYTE)&dwAllBits,
|
|
&cbDWSize);
|
|
_PrintIfError(hr, "RegQueryValueEx");
|
|
if (dwType != REG_DWORD)
|
|
dwAllBits = 0;
|
|
|
|
// single column defn
|
|
hListView = GetDlgItem(hwndDlg, IDC_CRL_LIST);
|
|
ListView_SetExtendedListViewStyle(hListView, LVS_EX_CHECKBOXES);
|
|
ListView_InsertColumn(hListView, 0, &lvCol);
|
|
hr = PopulateListView(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_CRL_URLs, ARRAYSIZE(rgPOSSIBLE_CRL_URLs), dwAllBits);
|
|
_PrintIfError(hr, "PopulateListView");
|
|
|
|
// if none, remove <REMOVE> button
|
|
::EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_CRL), (0 != ListView_GetItemCount(hListView)));
|
|
|
|
|
|
// get all extension bits -
|
|
hr = RegQueryValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGISSUERCERTURLFLAGS, // AIA
|
|
0,
|
|
&dwType,
|
|
(PBYTE)&dwAllBits,
|
|
&cbDWSize);
|
|
_PrintIfError(hr, "RegQueryValueEx");
|
|
if (dwType != REG_DWORD)
|
|
dwAllBits = 0;
|
|
|
|
|
|
hListView = GetDlgItem(hwndDlg, IDC_AIA_LIST);
|
|
ListView_SetExtendedListViewStyle(hListView, LVS_EX_CHECKBOXES);
|
|
ListView_InsertColumn(hListView, 0, &lvCol);
|
|
hr = PopulateListView(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_AIA_URLs, ARRAYSIZE(rgPOSSIBLE_AIA_URLs), dwAllBits);
|
|
_PrintIfError(hr, "PopulateListView");
|
|
|
|
// if none, remove <REMOVE> button
|
|
::EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_AIA), (0 != ListView_GetItemCount(hListView)));
|
|
|
|
psConfig->dwPageModified &= ~PAGE2; // we're virgin
|
|
mySetModified(hwndDlg, psConfig);
|
|
|
|
// no other work to be done
|
|
fReturn = TRUE;
|
|
break;
|
|
}
|
|
case WM_HELP:
|
|
{
|
|
OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG2);
|
|
break;
|
|
}
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG2);
|
|
break;
|
|
}
|
|
case WM_NOTIFY:
|
|
switch( ((LPNMHDR)lParam) -> code)
|
|
{
|
|
case PSN_APPLY:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
BOOL fSaveFailed = FALSE;
|
|
|
|
if (psConfig->dwPageModified & PAGE2)
|
|
{
|
|
DWORD dwAllBits;
|
|
DWORD cbDWSize = sizeof(DWORD);
|
|
DWORD dwType;
|
|
|
|
fSaveFailed = TRUE; // assume failure
|
|
|
|
hListView = GetDlgItem(hwndDlg, IDC_CRL_LIST);
|
|
hr = WriteChanges(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_CRL_URLs, ARRAYSIZE(rgPOSSIBLE_CRL_URLs));
|
|
_JumpIfError(hr, saveFailed, "WriteChanges");
|
|
|
|
hListView = GetDlgItem(hwndDlg, IDC_AIA_LIST);
|
|
hr = WriteChanges(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_AIA_URLs, ARRAYSIZE(rgPOSSIBLE_AIA_URLs));
|
|
_JumpIfError(hr, saveFailed, "WriteChanges");
|
|
|
|
// get all extension bits - CDP
|
|
hr = RegQueryValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGREVOCATIONTYPE,
|
|
0,
|
|
&dwType,
|
|
(PBYTE)&dwAllBits,
|
|
&cbDWSize);
|
|
_PrintIfError(hr, "RegQueryValueEx");
|
|
if (dwType != REG_DWORD)
|
|
dwAllBits = 0;
|
|
|
|
// set all extension bits -
|
|
dwAllBits |= REVEXT_CDPLDAPURL_OLD | REVEXT_CDPHTTPURL_OLD | REVEXT_CDPFTPURL_OLD | REVEXT_CDPFILEURL_OLD | REVEXT_CDPENABLE;
|
|
hr = RegSetValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGREVOCATIONTYPE,
|
|
0,
|
|
REG_DWORD,
|
|
(PBYTE)&dwAllBits,
|
|
sizeof(DWORD));
|
|
_JumpIfError(hr, saveFailed, "RegSetValue");
|
|
|
|
|
|
|
|
// get all extension bits - AIA
|
|
hr = RegQueryValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGISSUERCERTURLFLAGS, // AIA
|
|
0,
|
|
&dwType,
|
|
(PBYTE)&dwAllBits,
|
|
&cbDWSize);
|
|
_PrintIfError(hr, "RegQueryValueEx");
|
|
if (dwType != REG_DWORD)
|
|
dwAllBits = 0;
|
|
|
|
// set all extension bits -
|
|
dwAllBits |= ISSCERT_LDAPURL_OLD | ISSCERT_HTTPURL_OLD | ISSCERT_FTPURL_OLD| ISSCERT_FILEURL_OLD | ISSCERT_ENABLE;
|
|
hr = RegSetValueEx(
|
|
psConfig->hkeyStorageLocation,
|
|
wszREGISSUERCERTURLFLAGS, // AIA
|
|
0,
|
|
REG_DWORD,
|
|
(PBYTE)&dwAllBits,
|
|
sizeof(DWORD));
|
|
_JumpIfError(hr, saveFailed, "RegSetValue");
|
|
|
|
// got all the way through the save
|
|
fSaveFailed = FALSE;
|
|
}
|
|
saveFailed:
|
|
if (fSaveFailed)
|
|
{
|
|
MessageBoxNoSave(hwndDlg);
|
|
psConfig->dwPageModified &= ~PAGE2;
|
|
}
|
|
}
|
|
break;
|
|
case PSN_RESET:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
psConfig->dwPageModified &= ~PAGE2;
|
|
mySetModified(hwndDlg, psConfig);
|
|
}
|
|
break;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
// just catch check/uncheck on existing items
|
|
NMLISTVIEW* pParam = (NMLISTVIEW*)lParam;
|
|
if ((pParam != NULL) && (pParam->uChanged & CDIS_CHECKED))
|
|
{
|
|
psConfig->dwPageModified |= PAGE2;
|
|
mySetModified(hwndDlg, psConfig);
|
|
}
|
|
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_ADD_CRL:
|
|
fCRLSelection = TRUE;
|
|
// fall through
|
|
case IDC_ADD_AIA:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
LPWSTR szNewURL = NULL;
|
|
|
|
ADDURL_DIALOGARGS dlgArgs = {
|
|
fCRLSelection ? rgPOSSIBLE_CRL_URLs : rgPOSSIBLE_AIA_URLs,
|
|
(DWORD)(fCRLSelection ? ARRAYSIZE(rgPOSSIBLE_CRL_URLs) : ARRAYSIZE(rgPOSSIBLE_AIA_URLs)),
|
|
&szNewURL};
|
|
|
|
if (IDOK != DialogBoxParam(
|
|
g_hInstance,
|
|
MAKEINTRESOURCE(IDD_ADDURL),
|
|
hwndDlg,
|
|
dlgAddURL,
|
|
(LPARAM)&dlgArgs))
|
|
break;
|
|
|
|
if (NULL != szNewURL)
|
|
{
|
|
hListView = GetDlgItem(hwndDlg, fCRLSelection ? IDC_CRL_LIST : IDC_AIA_LIST);
|
|
|
|
AddStringToCheckList(
|
|
hListView,
|
|
szNewURL,
|
|
NULL,
|
|
TRUE);
|
|
|
|
LocalFree(szNewURL); szNewURL = NULL;
|
|
|
|
// enable <REMOVE> button
|
|
::EnableWindow(GetDlgItem(hwndDlg, fCRLSelection ? IDC_REMOVE_CRL : IDC_REMOVE_AIA), TRUE);
|
|
|
|
psConfig->dwPageModified |= PAGE2;
|
|
mySetModified(hwndDlg, psConfig);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case IDC_REMOVE_CRL:
|
|
fCRLSelection = TRUE;
|
|
// fall through
|
|
case IDC_REMOVE_AIA:
|
|
{
|
|
// grab our LParam
|
|
psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
if (psConfig == NULL)
|
|
break;
|
|
|
|
hListView = GetDlgItem(hwndDlg, fCRLSelection ? IDC_CRL_LIST : IDC_AIA_LIST);
|
|
|
|
int iSel;
|
|
iSel = ListView_GetNextItem(hListView, -1, LVIS_SELECTED);
|
|
|
|
// no selected item
|
|
if (-1 == iSel)
|
|
break;
|
|
|
|
ListView_DeleteItem(hListView, iSel);
|
|
ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE);
|
|
|
|
// if none, remove <REMOVE> button
|
|
::EnableWindow(GetDlgItem(hwndDlg, (fCRLSelection? IDC_REMOVE_CRL : IDC_REMOVE_AIA)), (0 != ListView_GetItemCount(hListView)));
|
|
|
|
psConfig->dwPageModified |= PAGE2;
|
|
mySetModified(hwndDlg, psConfig);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
|
|
// attempt IA5 encoding
|
|
|
|
HRESULT
|
|
IsValidIA5URL(
|
|
IN WCHAR const *pwszURL)
|
|
{
|
|
HRESULT hr;
|
|
BYTE *pb = NULL;
|
|
DWORD cb;
|
|
CERT_AUTHORITY_INFO_ACCESS caio;
|
|
CERT_ACCESS_DESCRIPTION cad;
|
|
|
|
caio.cAccDescr = 1;
|
|
caio.rgAccDescr = &cad;
|
|
|
|
cad.pszAccessMethod = szOID_PKIX_CA_ISSUERS;
|
|
cad.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
|
|
cad.AccessLocation.pwszURL = const_cast<WCHAR *>(pwszURL);
|
|
|
|
if (!ceEncodeObject(
|
|
X509_ASN_ENCODING,
|
|
X509_AUTHORITY_INFO_ACCESS,
|
|
&caio,
|
|
0,
|
|
FALSE,
|
|
&pb,
|
|
&cb))
|
|
{
|
|
hr = ceHLastError();
|
|
_JumpIfError(hr, error, "ceEncodeObject");
|
|
}
|
|
hr = S_OK;
|
|
|
|
error:
|
|
if (NULL != pb)
|
|
{
|
|
LocalFree(pb);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK dlgAddURL(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
LPWSTR* pszNewURL;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
::SetWindowLong(hwnd, GWL_EXSTYLE, ::GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
|
|
|
|
// stash the ADDURL_DIALOGARGS* we were given
|
|
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
|
|
break;
|
|
}
|
|
case WM_HELP:
|
|
{
|
|
OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_ADDURL);
|
|
break;
|
|
}
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_ADDURL);
|
|
break;
|
|
}
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
{
|
|
ADDURL_DIALOGARGS* pArgs;
|
|
|
|
// snatch the ADDURL_DIALOGARGS* we were given
|
|
pArgs = (ADDURL_DIALOGARGS*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
if (pArgs == NULL)
|
|
break;
|
|
|
|
WCHAR rgszURL[2*MAX_PATH];
|
|
if (0 != GetDlgItemText(hwnd, IDC_EDITURL, rgszURL, (2*MAX_PATH)) )
|
|
{
|
|
if (-1 == DetermineURLType(
|
|
pArgs->rgAllowedURLs,
|
|
pArgs->cAllowedURLs,
|
|
rgszURL))
|
|
{
|
|
// not found; bail with message
|
|
WCHAR szMsg[MAX_PATH*2];
|
|
LoadString(g_hInstance, IDS_INVALID_PREFIX, szMsg, ARRAYSIZE(szMsg));
|
|
for(DWORD dw=0; dw<pArgs->cAllowedURLs; dw++)
|
|
{
|
|
wcscat(szMsg, L"\n");
|
|
wcscat(szMsg, pArgs->rgAllowedURLs[dw].szKnownPrefix);
|
|
}
|
|
MessageBox(hwnd, szMsg, NULL, MB_OK);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD chBadBegin, chBadEnd;
|
|
if (S_OK != ValidateTokens(
|
|
rgszURL,
|
|
&chBadBegin,
|
|
&chBadEnd))
|
|
{
|
|
// not found; bail with message
|
|
WCHAR szMsg[MAX_PATH*2];
|
|
LoadString(g_hInstance, IDS_INVALID_TOKEN, szMsg, ARRAYSIZE(szMsg));
|
|
MessageBox(hwnd, szMsg, NULL, MB_OK);
|
|
|
|
// set selection starting from where validation failed
|
|
SendMessage(GetDlgItem(hwnd, IDC_EDITURL), EM_SETSEL, chBadBegin, chBadEnd);
|
|
return FALSE;
|
|
}
|
|
|
|
if (S_OK != IsValidIA5URL(rgszURL))
|
|
{
|
|
// encoding error; bail with message
|
|
WCHAR szMsg[MAX_PATH*2];
|
|
LoadString(g_hInstance, IDS_INVALID_ENCODING, szMsg, ARRAYSIZE(szMsg));
|
|
MessageBox(hwnd, szMsg, NULL, MB_OK);
|
|
|
|
// set selection starting from where validation failed
|
|
SendMessage(GetDlgItem(hwnd, IDC_EDITURL), EM_SETSEL, -1, -1);
|
|
return FALSE;
|
|
}
|
|
|
|
*(pArgs->ppszNewURL) = (LPWSTR) LocalAlloc(LMEM_FIXED, (wcslen(rgszURL)+1)*sizeof(WCHAR));
|
|
if(*(pArgs->ppszNewURL) == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
wcscpy(*(pArgs->ppszNewURL), rgszURL);
|
|
}
|
|
}
|
|
// fall through for cleanup
|
|
case IDCANCEL:
|
|
EndDialog(hwnd, LOWORD(wParam));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return fReturn;
|
|
}
|