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.

443 lines
14 KiB

  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2002.
  5. //
  6. // File: NewIssuanceOIDDlg.cpp
  7. //
  8. // Contents: Implementation of CNewIssuanceOIDDlg
  9. //
  10. //----------------------------------------------------------------------------
  11. // NewIssuanceOIDDlg.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include <wchar.h>
  15. #include "NewIssuanceOIDDlg.h"
  16. #include "PolicyOID.h"
  17. extern POLICY_OID_LIST g_policyOIDList;
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CNewIssuanceOIDDlg dialog
  25. CNewIssuanceOIDDlg::CNewIssuanceOIDDlg(CWnd* pParent)
  26. : CHelpDialog(CNewIssuanceOIDDlg::IDD, pParent),
  27. m_bEdit (false),
  28. m_bDirty (false),
  29. m_bInInitDialog (false)
  30. {
  31. //{{AFX_DATA_INIT(CNewIssuanceOIDDlg)
  32. m_oidFriendlyName = _T("");
  33. m_oidValue = _T("");
  34. m_CPSValue = _T("");
  35. //}}AFX_DATA_INIT
  36. }
  37. CNewIssuanceOIDDlg::CNewIssuanceOIDDlg(CWnd* pParent,
  38. const CString& szDisplayName,
  39. const CString& szOID,
  40. const CString& szCPS)
  41. : CHelpDialog(CNewIssuanceOIDDlg::IDD, pParent),
  42. m_bEdit (true),
  43. m_bDirty (false),
  44. m_originalOidFriendlyName (szDisplayName),
  45. m_oidFriendlyName (szDisplayName),
  46. m_oidValue (szOID),
  47. m_CPSValue (szCPS),
  48. m_originalCPSValue (szCPS)
  49. {
  50. }
  51. void CNewIssuanceOIDDlg::DoDataExchange(CDataExchange* pDX)
  52. {
  53. CHelpDialog::DoDataExchange(pDX);
  54. //{{AFX_DATA_MAP(CNewIssuanceOIDDlg)
  55. DDX_Control(pDX, IDC_NEW_ISSUANCE_OID_VALUE, m_oidValueEdit);
  56. DDX_Control(pDX, IDC_CPS_EDIT, m_CPSEdit);
  57. DDX_Text(pDX, IDC_NEW_ISSUANCE_OID_NAME, m_oidFriendlyName);
  58. DDV_MaxChars(pDX, m_oidFriendlyName, MAX_TEMPLATE_NAME_LEN);
  59. DDX_Text(pDX, IDC_NEW_ISSUANCE_OID_VALUE, m_oidValue);
  60. DDV_MaxChars(pDX, m_oidValue, MAX_OID_LEN);
  61. DDX_Text(pDX, IDC_CPS_EDIT, m_CPSValue);
  62. //}}AFX_DATA_MAP
  63. }
  64. BEGIN_MESSAGE_MAP(CNewIssuanceOIDDlg, CHelpDialog)
  65. //{{AFX_MSG_MAP(CNewIssuanceOIDDlg)
  66. ON_EN_CHANGE(IDC_NEW_ISSUANCE_OID_NAME, OnChangeNewOidName)
  67. ON_EN_CHANGE(IDC_NEW_ISSUANCE_OID_VALUE, OnChangeNewOidValue)
  68. ON_NOTIFY(EN_LINK, IDC_CPS_EDIT, OnClickedURL )
  69. ON_EN_CHANGE(IDC_CPS_EDIT, OnChangeCpsEdit)
  70. //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CNewIssuanceOIDDlg message handlers
  74. BOOL CNewIssuanceOIDDlg::OnInitDialog()
  75. {
  76. _TRACE (1, L"Entering CNewIssuanceOIDDlg::OnInitDialog\n");
  77. m_bInInitDialog = true;
  78. CHelpDialog::OnInitDialog();
  79. m_CPSEdit.SendMessage (EM_AUTOURLDETECT, TRUE);
  80. m_CPSEdit.SetEventMask (ENM_CHANGE | ENM_LINK | ENM_UPDATE);
  81. // If the URL starts with "http://" or "https://", then make the URL hot.
  82. if ( StartsWithHTTP (m_CPSValue) )
  83. {
  84. CHARFORMAT2 charFormat2;
  85. ::ZeroMemory (&charFormat2, sizeof (charFormat2));
  86. charFormat2.cbSize = sizeof (charFormat2);
  87. charFormat2.dwMask = CFM_LINK;
  88. charFormat2.dwEffects = CFE_LINK;
  89. size_t cchVal = m_CPSValue.GetLength ();
  90. // skip the header when looking for common invalid URL characters
  91. size_t cchColonWhackWhack = m_CPSValue.Find (L':') + 3;
  92. CString szBufAfterColonWhackWhack = ((PCWSTR) m_CPSValue) + cchColonWhackWhack;
  93. // cchInvalidChars is relative to the substring, not the entire URL
  94. size_t cchInvalidChars = szBufAfterColonWhackWhack.FindOneOf (L" %<>\"#{}|\\^~[]'");
  95. if ( -1 != cchInvalidChars )
  96. {
  97. // add back the length of the header so that cchInvalidChars is
  98. // relative to the entire URL
  99. cchInvalidChars += cchColonWhackWhack;
  100. cchVal = min (cchVal, cchInvalidChars);
  101. }
  102. m_CPSEdit.SendMessage (EM_SETSEL, 0, cchVal);
  103. VERIFY (0 != m_CPSEdit.SendMessage (EM_SETCHARFORMAT, SCF_SELECTION,
  104. (LPARAM) &charFormat2));
  105. }
  106. PWSTR pwszOID = 0;
  107. if ( m_bEdit )
  108. {
  109. CString text;
  110. VERIFY (text.LoadString (IDS_EDIT_ISSUANCE_POLICY));
  111. SetWindowText (text);
  112. m_oidValueEdit.SetReadOnly ();
  113. VERIFY (text.LoadString (IDS_NEW_ISSUANCE_POLICY_HINT));
  114. SetDlgItemText (IDC_NEW_ISSUANCE_POLICY_HINT, text);
  115. }
  116. else
  117. {
  118. HRESULT hr = CAOIDCreateNew
  119. (CERT_OID_TYPE_ISSUER_POLICY,
  120. 0,
  121. &pwszOID);
  122. _ASSERT (SUCCEEDED(hr));
  123. if ( SUCCEEDED (hr) )
  124. {
  125. m_szOriginalOID = pwszOID;
  126. m_oidValue = pwszOID;
  127. LocalFree (pwszOID);
  128. }
  129. else
  130. {
  131. _TRACE (0, L"CAOIDCreateNew (CERT_OID_TYPE_ISSUER_POLICY) failed: 0x%x\n",
  132. hr);
  133. }
  134. }
  135. UpdateData (FALSE);
  136. // Don't allow rename for OIDS returned by CryptoAPI
  137. if ( m_bEdit )
  138. {
  139. for (POSITION nextPos = g_policyOIDList.GetHeadPosition (); nextPos; )
  140. {
  141. CPolicyOID* pPolicyOID = g_policyOIDList.GetNext (nextPos);
  142. if ( pPolicyOID )
  143. {
  144. if ( pPolicyOID->GetOIDW () == m_oidValue )
  145. {
  146. if ( !pPolicyOID->CanRename () )
  147. {
  148. GetDlgItem (IDC_NEW_ISSUANCE_OID_NAME)->EnableWindow (FALSE);
  149. }
  150. break;
  151. }
  152. }
  153. }
  154. }
  155. EnableControls ();
  156. m_bInInitDialog = false;
  157. _TRACE (-1, L"Leaving CNewIssuanceOIDDlg::OnInitDialog\n");
  158. return TRUE; // return TRUE unless you set the focus to a control
  159. // EXCEPTION: OCX Property Pages should return FALSE
  160. }
  161. void CNewIssuanceOIDDlg::EnableControls()
  162. {
  163. UpdateData (TRUE);
  164. if ( m_oidFriendlyName.IsEmpty () || m_oidValue.IsEmpty () || !m_bDirty )
  165. GetDlgItem (IDOK)->EnableWindow (FALSE);
  166. else
  167. GetDlgItem (IDOK)->EnableWindow (TRUE);
  168. }
  169. void CNewIssuanceOIDDlg::OnChangeNewOidName()
  170. {
  171. if ( !m_bInInitDialog )
  172. {
  173. m_bDirty = true;
  174. EnableControls ();
  175. }
  176. }
  177. void CNewIssuanceOIDDlg::OnChangeNewOidValue()
  178. {
  179. if ( !m_bInInitDialog )
  180. {
  181. m_bDirty = true;
  182. EnableControls ();
  183. }
  184. }
  185. void CNewIssuanceOIDDlg::OnCancel()
  186. {
  187. if ( !m_bEdit )
  188. {
  189. HRESULT hr = CAOIDDelete (m_szOriginalOID);
  190. _ASSERT (SUCCEEDED(hr));
  191. if ( FAILED (hr) )
  192. {
  193. _TRACE (0, L"CAOIDDelete (%s) failed: 0x%x\n",
  194. (PCWSTR) m_szOriginalOID, hr);
  195. }
  196. }
  197. CHelpDialog::OnCancel();
  198. }
  199. bool CNewIssuanceOIDDlg::StartsWithHTTP (const CString& szURL) const
  200. {
  201. bool bStartsWithHTTP = false;
  202. const PWSTR szHTTPfs = L"http://";
  203. const PWSTR szHTTPSfs = L"https://";
  204. const PWSTR szHTTPbs = L"http:\\\\";
  205. const PWSTR szHTTPSbs = L"https:\\\\";
  206. static size_t cchHTTPfs = wcslen (szHTTPfs);
  207. static size_t cchHTTPSfs = wcslen (szHTTPSfs);
  208. static size_t cchHTTPbs = wcslen (szHTTPbs);
  209. static size_t cchHTTPSbs = wcslen (szHTTPSbs);
  210. if ( 0 == _wcsnicmp (szURL, szHTTPfs, cchHTTPfs) ||
  211. 0 == _wcsnicmp (szURL, szHTTPSfs, cchHTTPSfs) ||
  212. 0 ==_wcsnicmp (szURL, szHTTPbs, cchHTTPbs) ||
  213. 0 == _wcsnicmp (szURL, szHTTPSbs, cchHTTPSbs) )
  214. {
  215. bStartsWithHTTP = true;
  216. }
  217. return bStartsWithHTTP;
  218. }
  219. void CNewIssuanceOIDDlg::OnOK()
  220. {
  221. CThemeContextActivator activator;
  222. UpdateData (TRUE);
  223. // validate the CPS - it must begin with "http://" or "https:// or be empty"
  224. if ( !m_CPSValue.IsEmpty () && !StartsWithHTTP (m_CPSValue) )
  225. {
  226. CString text;
  227. CString caption;
  228. VERIFY (caption.LoadString (IDS_CERTTMPL));
  229. VERIFY (text.LoadString (IDS_CPS_MUST_START_WITH_HTTP_OR_HTTPS));
  230. MessageBox (text, caption, MB_OK);
  231. GetDlgItem (IDOK)->EnableWindow (FALSE);
  232. m_CPSEdit.SetFocus ();
  233. return;
  234. }
  235. // validate oid
  236. int errorTypeStrID = 0;
  237. if ( !OIDHasValidFormat (m_oidValue, errorTypeStrID) )
  238. {
  239. CString text;
  240. CString caption;
  241. CString errorType;
  242. VERIFY (caption.LoadString (IDS_CERTTMPL));
  243. if ( errorTypeStrID )
  244. VERIFY (errorType.LoadString (errorTypeStrID));
  245. // security review 2/21/2002 BryanWal ok
  246. text.FormatMessage (IDS_OID_FORMAT_INVALID, m_oidValue, errorType);
  247. MessageBox (text, caption, MB_OK);
  248. GetDlgItem (IDOK)->EnableWindow (FALSE);
  249. m_oidValueEdit.SetFocus ();
  250. return;
  251. }
  252. if ( !m_bEdit && m_szOriginalOID != m_oidValue )
  253. {
  254. HRESULT hr = CAOIDDelete (m_szOriginalOID);
  255. _ASSERT (SUCCEEDED(hr));
  256. if ( SUCCEEDED (hr) )
  257. {
  258. hr = CAOIDAdd (CERT_OID_TYPE_ISSUER_POLICY,
  259. 0,
  260. m_oidValue);
  261. if ( FAILED (hr) )
  262. {
  263. CString text;
  264. CString caption;
  265. VERIFY (caption.LoadString (IDS_CERTTMPL));
  266. // security review 2/21/2002 BryanWal ok
  267. text.FormatMessage (IDS_CANNOT_ADD_ISSUANCE_OID, GetSystemMessage (hr));
  268. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  269. _TRACE (0, L"CAOIDAdd (%s) failed: 0x%x\n",
  270. (PCWSTR) m_oidValue, hr);
  271. return;
  272. }
  273. }
  274. else
  275. {
  276. _TRACE (0, L"CAOIDDelete (%s) failed: 0x%x\n",
  277. (PCWSTR) m_szOriginalOID, hr);
  278. return;
  279. }
  280. }
  281. HRESULT hr = S_OK;
  282. // If we're editing, don't save the value if it hasn't changed
  283. if ( (m_bEdit && m_originalOidFriendlyName != m_oidFriendlyName) || !m_bEdit )
  284. hr = CAOIDSetProperty (m_oidValue, CERT_OID_PROPERTY_DISPLAY_NAME,
  285. m_oidFriendlyName.IsEmpty () ? 0 : ((LPVOID) (LPCWSTR) m_oidFriendlyName));
  286. if ( SUCCEEDED (hr) )
  287. {
  288. if ( SUCCEEDED (hr) )
  289. {
  290. // Update the OID list
  291. for (POSITION nextPos = g_policyOIDList.GetHeadPosition (); nextPos; )
  292. {
  293. CPolicyOID* pPolicyOID = g_policyOIDList.GetNext (nextPos);
  294. if ( pPolicyOID &&
  295. pPolicyOID->IsIssuanceOID () &&
  296. m_oidValue == pPolicyOID->GetOIDW ())
  297. {
  298. pPolicyOID->SetDisplayName (m_oidFriendlyName);
  299. }
  300. }
  301. }
  302. if ( (m_bEdit && m_originalCPSValue != m_CPSValue) || !m_bEdit )
  303. hr = CAOIDSetProperty (m_oidValue, CERT_OID_PROPERTY_CPS,
  304. m_CPSValue.IsEmpty () ? 0 : ((LPVOID) (LPCWSTR) m_CPSValue));
  305. if ( FAILED (hr) )
  306. {
  307. CString text;
  308. CString caption;
  309. VERIFY (caption.LoadString (IDS_CERTTMPL));
  310. // security review 2/21/2002 BryanWal ok
  311. text.FormatMessage (IDS_CANNOT_WRITE_CPS, GetSystemMessage (hr));
  312. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  313. _TRACE (0, L"CAOIDSetProperty (%s, CERT_OID_PROPERTY_CPS, %s) failed: 0x%x\n",
  314. (PCWSTR) m_oidValue, (PCWSTR) m_CPSValue, hr);
  315. return;
  316. }
  317. }
  318. else
  319. {
  320. CString text;
  321. CString caption;
  322. VERIFY (caption.LoadString (IDS_CERTTMPL));
  323. // security review 2/21/2002 BryanWal ok
  324. text.FormatMessage (IDS_CANNOT_WRITE_DISPLAY_NAME, GetSystemMessage (hr));
  325. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  326. _TRACE (0, L"CAOIDSetProperty (%s, CERT_OID_PROPERTY_DISPLAY_NAME, %s) failed: 0x%x\n",
  327. (PCWSTR) m_oidValue, (PCWSTR) m_oidFriendlyName, hr);
  328. return;
  329. }
  330. CHelpDialog::OnOK();
  331. }
  332. void CNewIssuanceOIDDlg::DoContextHelp (HWND hWndControl)
  333. {
  334. _TRACE(-1, L"Entering CNewIssuanceOIDDlg::DoContextHelp\n");
  335. // Display context help for a control
  336. if ( !::WinHelp (
  337. hWndControl,
  338. GetContextHelpFile (),
  339. HELP_WM_HELP,
  340. (DWORD_PTR) g_aHelpIDs_IDD_NEW_ISSUANCE_OID) )
  341. {
  342. _TRACE(-1, L"WinHelp () failed: 0x%x\n", GetLastError ());
  343. }
  344. _TRACE(-1, L"Leaving CNewIssuanceOIDDlg::DoContextHelp\n");
  345. }
  346. void CNewIssuanceOIDDlg::OnClickedURL( NMHDR * pNMHDR, LRESULT * pResult )
  347. {
  348. ENLINK *pEnlink = reinterpret_cast< ENLINK * >( pNMHDR );
  349. if ( pEnlink->msg == WM_LBUTTONUP )
  350. {
  351. UpdateData (TRUE);
  352. CString strCPSText;
  353. CString strURL;
  354. // pEnlink->chrg.cpMin and pEnlink->chrg.cpMax delimit the URL string.
  355. strURL = m_CPSValue.Mid (pEnlink->chrg.cpMin, pEnlink->chrg.cpMax - pEnlink->chrg.cpMin);
  356. // Displaying the URL may take time, so show the hourglass cursor.
  357. CWaitCursor waitCursor;
  358. // // security review 2/21/2002 BryanWal
  359. // ISSUE
  360. // NTRAID 551040 Security: Cert Templates: issuance OID CPS should be restricted to http or https types
  361. if ( ShellExecute( this->m_hWnd, _T("open"), strURL, NULL, NULL, SW_SHOWDEFAULT ) <= (HINSTANCE) 32 )
  362. {
  363. CThemeContextActivator activator;
  364. AfxMessageBox( IDS_BROWSER_ERROR );
  365. }
  366. }
  367. *pResult = 0;
  368. }
  369. void CNewIssuanceOIDDlg::OnChangeCpsEdit()
  370. {
  371. if ( !m_bInInitDialog )
  372. {
  373. m_bDirty = true;
  374. EnableControls ();
  375. }
  376. }