Leaked source code of windows server 2003
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

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: module.cpp
  7. //
  8. // Contents: Cert Server Policy Module implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. #include "commctrl.h"
  14. #include "module.h"
  15. #include "policy.h"
  16. #include "celib.h"
  17. // ..\inc
  18. #include "listvw.h"
  19. // help ids
  20. #define _CERTPDEF_
  21. #include "cemmchlp.h"
  22. extern HINSTANCE g_hInstance;
  23. STDMETHODIMP
  24. CCertManagePolicyModuleExchange::GetProperty(
  25. /* [in] */ const BSTR strConfig,
  26. /* [in] */ BSTR strStorageLocation,
  27. /* [in] */ BSTR strPropertyName,
  28. /* [in] */ LONG dwFlags,
  29. /* [retval][out] */ VARIANT __RPC_FAR *pvarProperty)
  30. {
  31. UINT uiStr = 0;
  32. WCHAR const *pwsz = NULL;
  33. if (NULL == pvarProperty)
  34. {
  35. return E_POINTER;
  36. }
  37. VariantInit(pvarProperty);
  38. if (strPropertyName == NULL)
  39. return S_FALSE;
  40. if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_NAME))
  41. uiStr = IDS_MODULE_NAME;
  42. else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_DESCRIPTION))
  43. pwsz = g_wszDescription;
  44. else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_COPYRIGHT))
  45. uiStr = IDS_MODULE_COPYRIGHT;
  46. else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_FILEVER))
  47. uiStr = IDS_MODULE_FILEVER;
  48. else if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_PRODUCTVER))
  49. uiStr = IDS_MODULE_PRODUCTVER;
  50. else
  51. return S_FALSE;
  52. // load string from resource
  53. WCHAR szStr[MAX_PATH];
  54. if (NULL == pwsz)
  55. {
  56. LoadString(g_hInstance, uiStr, szStr, ARRAYSIZE(szStr));
  57. pwsz = szStr;
  58. }
  59. pvarProperty->bstrVal = SysAllocString(pwsz);
  60. if (NULL == pvarProperty->bstrVal)
  61. return E_OUTOFMEMORY;
  62. pvarProperty->vt = VT_BSTR;
  63. return S_OK;
  64. }
  65. STDMETHODIMP
  66. CCertManagePolicyModuleExchange::SetProperty(
  67. /* [in] */ const BSTR strConfig,
  68. /* [in] */ BSTR strStorageLocation,
  69. /* [in] */ BSTR strPropertyName,
  70. /* [in] */ LONG dwFlags,
  71. /* [in] */ VARIANT const __RPC_FAR *pvalProperty)
  72. {
  73. if (strPropertyName == NULL)
  74. return S_FALSE;
  75. if (0 == _wcsicmp(strPropertyName, wszCMM_PROP_DISPLAY_HWND))
  76. {
  77. if (pvalProperty->vt != VT_BSTR)
  78. return E_INVALIDARG;
  79. if (SysStringByteLen(pvalProperty->bstrVal) != sizeof(HWND))
  80. return E_INVALIDARG;
  81. // the value is stored as bytes in the bstr itself, not the bstr ptr
  82. m_hWnd = *(HWND*)pvalProperty->bstrVal;
  83. return S_OK;
  84. }
  85. return S_FALSE;
  86. }
  87. INT_PTR CALLBACK WizPage1DlgProc(
  88. HWND hwndDlg,
  89. UINT uMsg,
  90. WPARAM wParam,
  91. LPARAM lParam);
  92. INT_PTR CALLBACK WizPage2DlgProc(
  93. HWND hwnd,
  94. UINT uMsg,
  95. WPARAM wParam,
  96. LPARAM lParam);
  97. INT_PTR CALLBACK dlgAddURL(
  98. HWND hwnd,
  99. UINT uMsg,
  100. WPARAM wParam,
  101. LPARAM lParam);
  102. typedef struct _POLICY_CONFIGSTRUCT
  103. {
  104. const BSTR* pstrConfig;
  105. ENUM_CATYPES CAType;
  106. HKEY hkeyStorageLocation;
  107. LONG Flags;
  108. DWORD dwPageModified;
  109. } POLICY_CONFIGSTRUCT, *PPOLICY_CONFIGSTRUCT;
  110. // dwPageModified
  111. #define PAGE1 (0x1)
  112. #define PAGE2 (0x2)
  113. void MessageBoxWarnReboot(HWND hwndDlg)
  114. {
  115. WCHAR szText[MAX_PATH], szTitle[MAX_PATH];
  116. LoadString(g_hInstance, IDS_MODULE_NAME, szTitle, ARRAYSIZE(szTitle));
  117. LoadString(g_hInstance, IDS_WARNING_REBOOT, szText, ARRAYSIZE(szText));
  118. MessageBox(hwndDlg, szText, szTitle, MB_OK|MB_ICONINFORMATION);
  119. }
  120. void MessageBoxNoSave(HWND hwndDlg)
  121. {
  122. WCHAR szText[MAX_PATH], szTitle[MAX_PATH];
  123. LoadString(g_hInstance, IDS_MODULE_NAME, szTitle, ARRAYSIZE(szTitle));
  124. LoadString(g_hInstance, IDS_WARNING_NOSAVE, szText, ARRAYSIZE(szText));
  125. MessageBox(hwndDlg, szText, szTitle, MB_OK|MB_ICONINFORMATION);
  126. }
  127. STDMETHODIMP
  128. CCertManagePolicyModuleExchange::Configure(
  129. /* [in] */ const BSTR strConfig,
  130. /* [in] */ BSTR strStorageLocation,
  131. /* [in] */ LONG dwFlags)
  132. {
  133. HRESULT hr;
  134. BSTR strName = NULL;
  135. VARIANT varValue;
  136. VariantInit(&varValue);
  137. ICertServerPolicy *pServer = NULL;
  138. POLICY_CONFIGSTRUCT sConfig = {NULL, ENUM_UNKNOWN_CA, NULL, 0, 0};
  139. BOOL fLocal;
  140. LPWSTR szMachine = NULL;
  141. HKEY hkeyHKLM = NULL;
  142. DWORD dwDisposition;
  143. hr = ceIsConfigLocal(strConfig, &szMachine, &fLocal);
  144. _JumpIfError(hr, Ret, "ceIsConfigLocal");
  145. // use callbacks for info
  146. hr = GetServerCallbackInterface(&pServer, 0); // no context : 0
  147. _JumpIfError(hr, Ret, "GetServerCallbackInterface");
  148. // we need to find out who we're running under
  149. strName = SysAllocString(wszPROPCATYPE);
  150. if (NULL == strName)
  151. {
  152. hr = E_OUTOFMEMORY;
  153. _JumpError(hr, Ret, "SysAllocString");
  154. }
  155. hr = pServer->GetCertificateProperty(
  156. strName,
  157. PROPTYPE_LONG,
  158. &varValue);
  159. _JumpIfError(hr, Ret, "GetCertificateProperty : wszPROPCATYPE");
  160. sConfig.CAType = (ENUM_CATYPES)varValue.lVal;
  161. VariantClear(&varValue);
  162. hr = PopulateRegistryDefaults(fLocal? NULL : szMachine, strStorageLocation);
  163. _PrintIfError(hr, "PopulateRegistryDefaults");
  164. if (!fLocal)
  165. {
  166. hr = RegConnectRegistry(
  167. szMachine,
  168. HKEY_LOCAL_MACHINE,
  169. &hkeyHKLM);
  170. _JumpIfError(hr, Ret, "RegConnectRegistry");
  171. }
  172. // open storage location: write perms if possible
  173. hr = RegCreateKeyEx(
  174. fLocal ? HKEY_LOCAL_MACHINE : hkeyHKLM,
  175. strStorageLocation,
  176. 0,
  177. NULL,
  178. 0,
  179. KEY_READ | KEY_WRITE,
  180. NULL,
  181. &sConfig.hkeyStorageLocation,
  182. &dwDisposition);
  183. if (hr != S_OK)
  184. {
  185. hr = RegOpenKeyEx(
  186. fLocal ? HKEY_LOCAL_MACHINE : hkeyHKLM,
  187. strStorageLocation,
  188. 0,
  189. KEY_READ, // fallback: read-only
  190. &sConfig.hkeyStorageLocation);
  191. _JumpIfError(hr, Ret, "RegOpenKeyEx");
  192. }
  193. sConfig.pstrConfig = &strConfig;
  194. sConfig.Flags = dwFlags;
  195. PROPSHEETPAGE page[2];
  196. ZeroMemory(&page[0], sizeof(PROPSHEETPAGE));
  197. page[0].dwSize = sizeof(PROPSHEETPAGE);
  198. page[0].dwFlags = PSP_DEFAULT;
  199. page[0].hInstance = g_hInstance;
  200. page[0].lParam = (LPARAM)&sConfig;
  201. // make 2nd page exactly the same as this
  202. CopyMemory(&page[1], &page[0], sizeof(PROPSHEETPAGE));
  203. // now page1 vs. page2 diffcs
  204. page[0].pszTemplate = MAKEINTRESOURCE(IDD_POLICYPG1);
  205. page[0].pfnDlgProc = WizPage1DlgProc;
  206. page[1].pszTemplate = MAKEINTRESOURCE(IDD_POLICYPG2);
  207. page[1].pfnDlgProc = WizPage2DlgProc;
  208. PROPSHEETHEADER sSheet;
  209. ZeroMemory(&sSheet, sizeof(PROPSHEETHEADER));
  210. sSheet.dwSize = sizeof(PROPSHEETHEADER);
  211. sSheet.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
  212. sSheet.hwndParent = m_hWnd;
  213. sSheet.pszCaption = MAKEINTRESOURCE(IDS_MODULE_NAME);
  214. sSheet.nPages = ARRAYSIZE(page);
  215. sSheet.ppsp = page;
  216. // finally, invoke the modal sheet
  217. INT_PTR iRet;
  218. iRet = ::PropertySheet(&sSheet);
  219. if ((iRet > 0) && (sConfig.dwPageModified)) // successful modification
  220. {
  221. MessageBoxWarnReboot(NULL);
  222. }
  223. Ret:
  224. if (NULL != strName)
  225. {
  226. SysFreeString(strName);
  227. }
  228. if (sConfig.hkeyStorageLocation)
  229. RegCloseKey(sConfig.hkeyStorageLocation);
  230. if (szMachine)
  231. LocalFree(szMachine);
  232. if (hkeyHKLM)
  233. RegCloseKey(hkeyHKLM);
  234. if (pServer)
  235. pServer->Release();
  236. return hr;
  237. }
  238. CERTSVR_URL_PARSING rgPOSSIBLE_CRL_URLs[] =
  239. {
  240. { L"ldap:", wszREGLDAPREVOCATIONCRLURL_OLD, REVEXT_CDPLDAPURL_OLD | REVEXT_CDPENABLE },
  241. { L"http:", wszREGREVOCATIONCRLURL_OLD, REVEXT_CDPHTTPURL_OLD | REVEXT_CDPENABLE },
  242. { L"ftp:", wszREGFTPREVOCATIONCRLURL_OLD, REVEXT_CDPFTPURL_OLD | REVEXT_CDPENABLE },
  243. { L"file:", wszREGFILEREVOCATIONCRLURL_OLD, REVEXT_CDPFILEURL_OLD | REVEXT_CDPENABLE },
  244. };
  245. CERTSVR_URL_PARSING rgPOSSIBLE_AIA_URLs[] =
  246. {
  247. { L"ldap:", wszREGLDAPISSUERCERTURL_OLD, ISSCERT_LDAPURL_OLD | ISSCERT_ENABLE},
  248. { L"http:", wszREGISSUERCERTURL_OLD, ISSCERT_HTTPURL_OLD | ISSCERT_ENABLE},
  249. { L"ftp:", wszREGFTPISSUERCERTURL_OLD, ISSCERT_FTPURL_OLD | ISSCERT_ENABLE },
  250. { L"file:", wszREGFILEISSUERCERTURL_OLD, ISSCERT_FILEURL_OLD | ISSCERT_ENABLE},
  251. };
  252. void mySetModified(HWND hwndPage, POLICY_CONFIGSTRUCT* psConfig)
  253. {
  254. if (psConfig->dwPageModified != 0)
  255. {
  256. PropSheet_Changed( ::GetParent(hwndPage), hwndPage);
  257. }
  258. else
  259. {
  260. PropSheet_UnChanged( ::GetParent(hwndPage), hwndPage);
  261. }
  262. }
  263. INT_PTR CALLBACK WizPage1DlgProc(
  264. HWND hwndDlg,
  265. UINT uMsg,
  266. WPARAM wParam,
  267. LPARAM lParam)
  268. {
  269. POLICY_CONFIGSTRUCT* psConfig;
  270. BOOL fReturn = FALSE;
  271. HRESULT hr;
  272. switch(uMsg)
  273. {
  274. case WM_INITDIALOG:
  275. {
  276. ::SetWindowLong(hwndDlg, GWL_EXSTYLE, ::GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
  277. PROPSHEETPAGE* ps = (PROPSHEETPAGE *) lParam;
  278. psConfig = (POLICY_CONFIGSTRUCT*)ps->lParam;
  279. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM)psConfig);
  280. DWORD dwRequestDisposition, dwType;
  281. DWORD cbRequestDisposition = sizeof(dwRequestDisposition);
  282. hr = RegQueryValueEx(
  283. psConfig->hkeyStorageLocation,
  284. wszREGREQUESTDISPOSITION,
  285. 0,
  286. &dwType,
  287. (PBYTE)&dwRequestDisposition,
  288. &cbRequestDisposition);
  289. if ((hr != ERROR_SUCCESS) || (dwType != REG_DWORD))
  290. break;
  291. // if disposition includes Issue
  292. if ((dwRequestDisposition & REQDISP_MASK) == REQDISP_ISSUE)
  293. {
  294. // if pending bit set
  295. if (dwRequestDisposition & REQDISP_PENDINGFIRST)
  296. SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_PENDFIRST), BM_SETCHECK, TRUE, BST_CHECKED);
  297. else
  298. SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_ISSUE), BM_SETCHECK, TRUE, BST_CHECKED);
  299. }
  300. // disallow "Pend first" if Enterprise (bug #259346)
  301. if ((psConfig->CAType == ENUM_ENTERPRISE_ROOTCA) ||
  302. (psConfig->CAType == ENUM_ENTERPRISE_SUBCA))
  303. {
  304. EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_PENDFIRST), FALSE);
  305. EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_PENDFIRST), FALSE);
  306. }
  307. psConfig->dwPageModified &= ~PAGE1; // we're virgin
  308. mySetModified(hwndDlg, psConfig);
  309. // no other work to be done
  310. fReturn = TRUE;
  311. break;
  312. }
  313. case WM_HELP:
  314. {
  315. OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG1);
  316. break;
  317. }
  318. case WM_CONTEXTMENU:
  319. {
  320. OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG1);
  321. break;
  322. }
  323. case WM_NOTIFY:
  324. switch( ((LPNMHDR)lParam) -> code)
  325. {
  326. case PSN_APPLY:
  327. {
  328. // grab our LParam
  329. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  330. if (psConfig == NULL)
  331. break;
  332. if (psConfig->dwPageModified & PAGE1)
  333. {
  334. DWORD dwCheckState, dwRequestDisposition;
  335. dwCheckState = (DWORD)SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_ISSUE), BM_GETCHECK, 0, 0);
  336. if (dwCheckState == BST_CHECKED)
  337. dwRequestDisposition = REQDISP_ISSUE;
  338. else
  339. dwRequestDisposition = REQDISP_ISSUE | REQDISP_PENDINGFIRST;
  340. hr = RegSetValueEx(
  341. psConfig->hkeyStorageLocation,
  342. wszREGREQUESTDISPOSITION,
  343. 0,
  344. REG_DWORD,
  345. (PBYTE)&dwRequestDisposition,
  346. sizeof(DWORD));
  347. if (hr != ERROR_SUCCESS)
  348. {
  349. MessageBoxNoSave(hwndDlg);
  350. psConfig->dwPageModified &= ~PAGE1;
  351. }
  352. }
  353. }
  354. break;
  355. case PSN_RESET:
  356. {
  357. // grab our LParam
  358. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  359. if (psConfig == NULL)
  360. break;
  361. psConfig->dwPageModified &= ~PAGE1;
  362. mySetModified(hwndDlg, psConfig);
  363. }
  364. break;
  365. default:
  366. break;
  367. }
  368. break;
  369. case WM_COMMAND:
  370. switch (LOWORD(wParam))
  371. {
  372. case IDC_RADIO_ISSUE:
  373. case IDC_RADIO_PENDFIRST:
  374. {
  375. // grab our LParam
  376. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  377. if (psConfig == NULL)
  378. break;
  379. if (BN_CLICKED == HIWORD(wParam))
  380. {
  381. psConfig->dwPageModified |= PAGE1;
  382. mySetModified(hwndDlg, psConfig);
  383. }
  384. }
  385. break;
  386. default:
  387. break;
  388. }
  389. default:
  390. break;
  391. }
  392. return fReturn;
  393. }
  394. INT_PTR CALLBACK WizPage2DlgProc(
  395. HWND hwndDlg,
  396. UINT uMsg,
  397. WPARAM wParam,
  398. LPARAM lParam)
  399. {
  400. POLICY_CONFIGSTRUCT* psConfig;
  401. HWND hListView;
  402. BOOL fCRLSelection= FALSE;
  403. BOOL fReturn = FALSE;
  404. HRESULT hr;
  405. switch(uMsg)
  406. {
  407. case WM_INITDIALOG:
  408. {
  409. ::SetWindowLong(hwndDlg, GWL_EXSTYLE, ::GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
  410. PROPSHEETPAGE* ps = (PROPSHEETPAGE *) lParam;
  411. psConfig = (POLICY_CONFIGSTRUCT*)ps->lParam;
  412. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM)psConfig);
  413. DWORD dwAllBits, dwType;
  414. DWORD cbDWSize=sizeof(dwAllBits);
  415. LVCOLUMN lvCol;
  416. lvCol.mask = LVCF_FMT | LVCF_TEXT;
  417. lvCol.fmt = LVCFMT_LEFT; // Left-align the column.
  418. lvCol.pszText = L""; // The text for the column.
  419. // get all extension bits -
  420. hr = RegQueryValueEx(
  421. psConfig->hkeyStorageLocation,
  422. wszREGREVOCATIONTYPE, // CDP
  423. 0,
  424. &dwType,
  425. (PBYTE)&dwAllBits,
  426. &cbDWSize);
  427. _PrintIfError(hr, "RegQueryValueEx");
  428. if (dwType != REG_DWORD)
  429. dwAllBits = 0;
  430. // single column defn
  431. hListView = GetDlgItem(hwndDlg, IDC_CRL_LIST);
  432. ListView_SetExtendedListViewStyle(hListView, LVS_EX_CHECKBOXES);
  433. ListView_InsertColumn(hListView, 0, &lvCol);
  434. hr = PopulateListView(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_CRL_URLs, ARRAYSIZE(rgPOSSIBLE_CRL_URLs), dwAllBits);
  435. _PrintIfError(hr, "PopulateListView");
  436. // if none, remove <REMOVE> button
  437. ::EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_CRL), (0 != ListView_GetItemCount(hListView)));
  438. // get all extension bits -
  439. hr = RegQueryValueEx(
  440. psConfig->hkeyStorageLocation,
  441. wszREGISSUERCERTURLFLAGS, // AIA
  442. 0,
  443. &dwType,
  444. (PBYTE)&dwAllBits,
  445. &cbDWSize);
  446. _PrintIfError(hr, "RegQueryValueEx");
  447. if (dwType != REG_DWORD)
  448. dwAllBits = 0;
  449. hListView = GetDlgItem(hwndDlg, IDC_AIA_LIST);
  450. ListView_SetExtendedListViewStyle(hListView, LVS_EX_CHECKBOXES);
  451. ListView_InsertColumn(hListView, 0, &lvCol);
  452. hr = PopulateListView(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_AIA_URLs, ARRAYSIZE(rgPOSSIBLE_AIA_URLs), dwAllBits);
  453. _PrintIfError(hr, "PopulateListView");
  454. // if none, remove <REMOVE> button
  455. ::EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_AIA), (0 != ListView_GetItemCount(hListView)));
  456. psConfig->dwPageModified &= ~PAGE2; // we're virgin
  457. mySetModified(hwndDlg, psConfig);
  458. // no other work to be done
  459. fReturn = TRUE;
  460. break;
  461. }
  462. case WM_HELP:
  463. {
  464. OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG2);
  465. break;
  466. }
  467. case WM_CONTEXTMENU:
  468. {
  469. OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_POLICYPG2);
  470. break;
  471. }
  472. case WM_NOTIFY:
  473. switch( ((LPNMHDR)lParam) -> code)
  474. {
  475. case PSN_APPLY:
  476. {
  477. // grab our LParam
  478. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  479. if (psConfig == NULL)
  480. break;
  481. BOOL fSaveFailed = FALSE;
  482. if (psConfig->dwPageModified & PAGE2)
  483. {
  484. DWORD dwAllBits;
  485. DWORD cbDWSize = sizeof(DWORD);
  486. DWORD dwType;
  487. fSaveFailed = TRUE; // assume failure
  488. hListView = GetDlgItem(hwndDlg, IDC_CRL_LIST);
  489. hr = WriteChanges(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_CRL_URLs, ARRAYSIZE(rgPOSSIBLE_CRL_URLs));
  490. _JumpIfError(hr, saveFailed, "WriteChanges");
  491. hListView = GetDlgItem(hwndDlg, IDC_AIA_LIST);
  492. hr = WriteChanges(hListView, psConfig->hkeyStorageLocation, rgPOSSIBLE_AIA_URLs, ARRAYSIZE(rgPOSSIBLE_AIA_URLs));
  493. _JumpIfError(hr, saveFailed, "WriteChanges");
  494. // get all extension bits - CDP
  495. hr = RegQueryValueEx(
  496. psConfig->hkeyStorageLocation,
  497. wszREGREVOCATIONTYPE,
  498. 0,
  499. &dwType,
  500. (PBYTE)&dwAllBits,
  501. &cbDWSize);
  502. _PrintIfError(hr, "RegQueryValueEx");
  503. if (dwType != REG_DWORD)
  504. dwAllBits = 0;
  505. // set all extension bits -
  506. dwAllBits |= REVEXT_CDPLDAPURL_OLD | REVEXT_CDPHTTPURL_OLD | REVEXT_CDPFTPURL_OLD | REVEXT_CDPFILEURL_OLD | REVEXT_CDPENABLE;
  507. hr = RegSetValueEx(
  508. psConfig->hkeyStorageLocation,
  509. wszREGREVOCATIONTYPE,
  510. 0,
  511. REG_DWORD,
  512. (PBYTE)&dwAllBits,
  513. sizeof(DWORD));
  514. _JumpIfError(hr, saveFailed, "RegSetValue");
  515. // get all extension bits - AIA
  516. hr = RegQueryValueEx(
  517. psConfig->hkeyStorageLocation,
  518. wszREGISSUERCERTURLFLAGS, // AIA
  519. 0,
  520. &dwType,
  521. (PBYTE)&dwAllBits,
  522. &cbDWSize);
  523. _PrintIfError(hr, "RegQueryValueEx");
  524. if (dwType != REG_DWORD)
  525. dwAllBits = 0;
  526. // set all extension bits -
  527. dwAllBits |= ISSCERT_LDAPURL_OLD | ISSCERT_HTTPURL_OLD | ISSCERT_FTPURL_OLD| ISSCERT_FILEURL_OLD | ISSCERT_ENABLE;
  528. hr = RegSetValueEx(
  529. psConfig->hkeyStorageLocation,
  530. wszREGISSUERCERTURLFLAGS, // AIA
  531. 0,
  532. REG_DWORD,
  533. (PBYTE)&dwAllBits,
  534. sizeof(DWORD));
  535. _JumpIfError(hr, saveFailed, "RegSetValue");
  536. // got all the way through the save
  537. fSaveFailed = FALSE;
  538. }
  539. saveFailed:
  540. if (fSaveFailed)
  541. {
  542. MessageBoxNoSave(hwndDlg);
  543. psConfig->dwPageModified &= ~PAGE2;
  544. }
  545. }
  546. break;
  547. case PSN_RESET:
  548. {
  549. // grab our LParam
  550. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  551. if (psConfig == NULL)
  552. break;
  553. psConfig->dwPageModified &= ~PAGE2;
  554. mySetModified(hwndDlg, psConfig);
  555. }
  556. break;
  557. case LVN_ITEMCHANGED:
  558. {
  559. // grab our LParam
  560. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  561. if (psConfig == NULL)
  562. break;
  563. // just catch check/uncheck on existing items
  564. NMLISTVIEW* pParam = (NMLISTVIEW*)lParam;
  565. if ((pParam != NULL) && (pParam->uChanged & CDIS_CHECKED))
  566. {
  567. psConfig->dwPageModified |= PAGE2;
  568. mySetModified(hwndDlg, psConfig);
  569. }
  570. }
  571. break;
  572. default:
  573. break;
  574. }
  575. break;
  576. case WM_COMMAND:
  577. switch (LOWORD(wParam))
  578. {
  579. case IDC_ADD_CRL:
  580. fCRLSelection = TRUE;
  581. // fall through
  582. case IDC_ADD_AIA:
  583. {
  584. // grab our LParam
  585. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  586. if (psConfig == NULL)
  587. break;
  588. LPWSTR szNewURL = NULL;
  589. ADDURL_DIALOGARGS dlgArgs = {
  590. fCRLSelection ? rgPOSSIBLE_CRL_URLs : rgPOSSIBLE_AIA_URLs,
  591. (DWORD)(fCRLSelection ? ARRAYSIZE(rgPOSSIBLE_CRL_URLs) : ARRAYSIZE(rgPOSSIBLE_AIA_URLs)),
  592. &szNewURL};
  593. if (IDOK != DialogBoxParam(
  594. g_hInstance,
  595. MAKEINTRESOURCE(IDD_ADDURL),
  596. hwndDlg,
  597. dlgAddURL,
  598. (LPARAM)&dlgArgs))
  599. break;
  600. if (NULL != szNewURL)
  601. {
  602. hListView = GetDlgItem(hwndDlg, fCRLSelection ? IDC_CRL_LIST : IDC_AIA_LIST);
  603. AddStringToCheckList(
  604. hListView,
  605. szNewURL,
  606. NULL,
  607. TRUE);
  608. LocalFree(szNewURL); szNewURL = NULL;
  609. // enable <REMOVE> button
  610. ::EnableWindow(GetDlgItem(hwndDlg, fCRLSelection ? IDC_REMOVE_CRL : IDC_REMOVE_AIA), TRUE);
  611. psConfig->dwPageModified |= PAGE2;
  612. mySetModified(hwndDlg, psConfig);
  613. }
  614. break;
  615. }
  616. case IDC_REMOVE_CRL:
  617. fCRLSelection = TRUE;
  618. // fall through
  619. case IDC_REMOVE_AIA:
  620. {
  621. // grab our LParam
  622. psConfig = (POLICY_CONFIGSTRUCT*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  623. if (psConfig == NULL)
  624. break;
  625. hListView = GetDlgItem(hwndDlg, fCRLSelection ? IDC_CRL_LIST : IDC_AIA_LIST);
  626. int iSel;
  627. iSel = ListView_GetNextItem(hListView, -1, LVIS_SELECTED);
  628. // no selected item
  629. if (-1 == iSel)
  630. break;
  631. ListView_DeleteItem(hListView, iSel);
  632. ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE);
  633. // if none, remove <REMOVE> button
  634. ::EnableWindow(GetDlgItem(hwndDlg, (fCRLSelection? IDC_REMOVE_CRL : IDC_REMOVE_AIA)), (0 != ListView_GetItemCount(hListView)));
  635. psConfig->dwPageModified |= PAGE2;
  636. mySetModified(hwndDlg, psConfig);
  637. break;
  638. }
  639. default:
  640. break;
  641. }
  642. default:
  643. break;
  644. }
  645. return fReturn;
  646. }
  647. // attempt IA5 encoding
  648. HRESULT
  649. IsValidIA5URL(
  650. IN WCHAR const *pwszURL)
  651. {
  652. HRESULT hr;
  653. BYTE *pb = NULL;
  654. DWORD cb;
  655. CERT_AUTHORITY_INFO_ACCESS caio;
  656. CERT_ACCESS_DESCRIPTION cad;
  657. caio.cAccDescr = 1;
  658. caio.rgAccDescr = &cad;
  659. cad.pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  660. cad.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  661. cad.AccessLocation.pwszURL = const_cast<WCHAR *>(pwszURL);
  662. if (!ceEncodeObject(
  663. X509_ASN_ENCODING,
  664. X509_AUTHORITY_INFO_ACCESS,
  665. &caio,
  666. 0,
  667. FALSE,
  668. &pb,
  669. &cb))
  670. {
  671. hr = ceHLastError();
  672. _JumpIfError(hr, error, "ceEncodeObject");
  673. }
  674. hr = S_OK;
  675. error:
  676. if (NULL != pb)
  677. {
  678. LocalFree(pb);
  679. }
  680. return(hr);
  681. }
  682. INT_PTR CALLBACK dlgAddURL(
  683. HWND hwnd,
  684. UINT uMsg,
  685. WPARAM wParam,
  686. LPARAM lParam)
  687. {
  688. BOOL fReturn = FALSE;
  689. LPWSTR* pszNewURL;
  690. switch(uMsg)
  691. {
  692. case WM_INITDIALOG:
  693. {
  694. ::SetWindowLong(hwnd, GWL_EXSTYLE, ::GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
  695. // stash the ADDURL_DIALOGARGS* we were given
  696. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
  697. break;
  698. }
  699. case WM_HELP:
  700. {
  701. OnDialogHelp((LPHELPINFO) lParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_ADDURL);
  702. break;
  703. }
  704. case WM_CONTEXTMENU:
  705. {
  706. OnDialogContextHelp((HWND)wParam, CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_ADDURL);
  707. break;
  708. }
  709. case WM_COMMAND:
  710. switch (LOWORD(wParam))
  711. {
  712. case IDOK:
  713. {
  714. ADDURL_DIALOGARGS* pArgs;
  715. // snatch the ADDURL_DIALOGARGS* we were given
  716. pArgs = (ADDURL_DIALOGARGS*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  717. if (pArgs == NULL)
  718. break;
  719. WCHAR rgszURL[2*MAX_PATH];
  720. if (0 != GetDlgItemText(hwnd, IDC_EDITURL, rgszURL, (2*MAX_PATH)) )
  721. {
  722. if (-1 == DetermineURLType(
  723. pArgs->rgAllowedURLs,
  724. pArgs->cAllowedURLs,
  725. rgszURL))
  726. {
  727. // not found; bail with message
  728. WCHAR szMsg[MAX_PATH*2];
  729. LoadString(g_hInstance, IDS_INVALID_PREFIX, szMsg, ARRAYSIZE(szMsg));
  730. for(DWORD dw=0; dw<pArgs->cAllowedURLs; dw++)
  731. {
  732. wcscat(szMsg, L"\n");
  733. wcscat(szMsg, pArgs->rgAllowedURLs[dw].szKnownPrefix);
  734. }
  735. MessageBox(hwnd, szMsg, NULL, MB_OK);
  736. return FALSE;
  737. }
  738. DWORD chBadBegin, chBadEnd;
  739. if (S_OK != ValidateTokens(
  740. rgszURL,
  741. &chBadBegin,
  742. &chBadEnd))
  743. {
  744. // not found; bail with message
  745. WCHAR szMsg[MAX_PATH*2];
  746. LoadString(g_hInstance, IDS_INVALID_TOKEN, szMsg, ARRAYSIZE(szMsg));
  747. MessageBox(hwnd, szMsg, NULL, MB_OK);
  748. // set selection starting from where validation failed
  749. SendMessage(GetDlgItem(hwnd, IDC_EDITURL), EM_SETSEL, chBadBegin, chBadEnd);
  750. return FALSE;
  751. }
  752. if (S_OK != IsValidIA5URL(rgszURL))
  753. {
  754. // encoding error; bail with message
  755. WCHAR szMsg[MAX_PATH*2];
  756. LoadString(g_hInstance, IDS_INVALID_ENCODING, szMsg, ARRAYSIZE(szMsg));
  757. MessageBox(hwnd, szMsg, NULL, MB_OK);
  758. // set selection starting from where validation failed
  759. SendMessage(GetDlgItem(hwnd, IDC_EDITURL), EM_SETSEL, -1, -1);
  760. return FALSE;
  761. }
  762. *(pArgs->ppszNewURL) = (LPWSTR) LocalAlloc(LMEM_FIXED, (wcslen(rgszURL)+1)*sizeof(WCHAR));
  763. if(*(pArgs->ppszNewURL) == NULL)
  764. {
  765. return FALSE;
  766. }
  767. wcscpy(*(pArgs->ppszNewURL), rgszURL);
  768. }
  769. }
  770. // fall through for cleanup
  771. case IDCANCEL:
  772. EndDialog(hwnd, LOWORD(wParam));
  773. break;
  774. default:
  775. break;
  776. }
  777. default:
  778. break;
  779. }
  780. return fReturn;
  781. }