Source code of Windows XP (NT5)
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.

816 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. security.cpp
  5. Abstract:
  6. WWW Security Property Page
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "wincrypt.h"
  18. #include "w3scfg.h"
  19. #include "security.h"
  20. #include "authent.h"
  21. #include "seccom.h"
  22. #include "ipdomdlg.h"
  23. #include "cryptui.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. //
  30. // CW3SecurityPage property page
  31. //
  32. IMPLEMENT_DYNCREATE(CW3SecurityPage, CInetPropertyPage)
  33. CW3SecurityPage::CW3SecurityPage(
  34. IN CInetPropertySheet * pSheet,
  35. IN BOOL fHome,
  36. IN DWORD dwAttributes
  37. )
  38. /*++
  39. Routine Description:
  40. Constructor
  41. Arguments:
  42. CInetPropertySheet * pSheet : Sheet object
  43. BOOL fHome : TRUE if this is a home directory
  44. DWORD dwAttributes : Attributes
  45. Return Value:
  46. N/A
  47. --*/
  48. : CInetPropertyPage(CW3SecurityPage::IDD, pSheet,
  49. IS_FILE(dwAttributes)
  50. ? IDS_TAB_FILE_SECURITY
  51. : IDS_TAB_DIR_SECURITY
  52. ),
  53. m_oblAccessList(),
  54. m_fU2Installed(FALSE),
  55. m_fIpDirty(FALSE),
  56. m_fHome(fHome),
  57. //
  58. // By default, we grant access
  59. //
  60. m_fOldDefaultGranted(TRUE),
  61. m_fDefaultGranted(TRUE)
  62. {
  63. #if 0 // Keep class wizard happy
  64. //{{AFX_DATA_INIT(CW3SecurityPage)
  65. m_fUseNTMapper = FALSE;
  66. //}}AFX_DATA_INIT
  67. #endif // 0
  68. }
  69. CW3SecurityPage::~CW3SecurityPage()
  70. /*++
  71. Routine Description:
  72. Destructor
  73. Arguments:
  74. N/A
  75. Return Value:
  76. N/A
  77. --*/
  78. {
  79. }
  80. void
  81. CW3SecurityPage::DoDataExchange(
  82. IN CDataExchange * pDX
  83. )
  84. /*++
  85. Routine Description:
  86. Initialise/Store control data
  87. Arguments:
  88. CDataExchange * pDX - DDX/DDV control structure
  89. Return Value:
  90. None
  91. --*/
  92. {
  93. CInetPropertyPage::DoDataExchange(pDX);
  94. //{{AFX_DATA_MAP(CW3SecurityPage)
  95. DDX_Check(pDX, IDC_CHECK_ENABLE_DS, m_fUseNTMapper);
  96. DDX_Control(pDX, IDC_ICON_SECURE, m_icon_Secure);
  97. DDX_Control(pDX, IDC_STATIC_SSL_PROMPT, m_static_SSLPrompt);
  98. DDX_Control(pDX, IDC_CHECK_ENABLE_DS, m_check_EnableDS);
  99. DDX_Control(pDX, IDC_BUTTON_GET_CERTIFICATES, m_button_GetCertificates);
  100. DDX_Control(pDX, IDC_VIEW_CERTIFICATE, m_button_ViewCertificates);
  101. DDX_Control(pDX, IDC_BUTTON_COMMUNICATIONS, m_button_Communications);
  102. //}}AFX_DATA_MAP
  103. }
  104. //
  105. // Message Map
  106. //
  107. BEGIN_MESSAGE_MAP(CW3SecurityPage, CInetPropertyPage)
  108. //{{AFX_MSG_MAP(CW3SecurityPage)
  109. ON_BN_CLICKED(IDC_BUTTON_AUTHENTICATION, OnButtonAuthentication)
  110. ON_BN_CLICKED(IDC_BUTTON_COMMUNICATIONS, OnButtonCommunications)
  111. ON_BN_CLICKED(IDC_BUTTON_IP_SECURITY, OnButtonIpSecurity)
  112. ON_BN_CLICKED(IDC_BUTTON_GET_CERTIFICATES, OnButtonGetCertificates)
  113. ON_BN_CLICKED(IDC_VIEW_CERTIFICATE, OnButtonViewCertificates)
  114. //}}AFX_MSG_MAP
  115. ON_BN_CLICKED(IDC_CHECK_ENABLE_DS, OnItemChanged)
  116. END_MESSAGE_MAP()
  117. /* virtual */
  118. HRESULT
  119. CW3SecurityPage::FetchLoadedValues()
  120. /*++
  121. Routine Description:
  122. Move configuration data from sheet to dialog controls
  123. Arguments:
  124. None
  125. Return Value:
  126. HRESULT
  127. --*/
  128. {
  129. CError err;
  130. BEGIN_META_DIR_READ(CW3Sheet)
  131. FETCH_DIR_DATA_FROM_SHEET(m_dwAuthFlags);
  132. FETCH_DIR_DATA_FROM_SHEET(m_dwSSLAccessPermissions);
  133. FETCH_DIR_DATA_FROM_SHEET(m_strBasicDomain);
  134. FETCH_DIR_DATA_FROM_SHEET(m_strAnonUserName);
  135. FETCH_DIR_DATA_FROM_SHEET(m_strAnonPassword);
  136. FETCH_DIR_DATA_FROM_SHEET(m_fPasswordSync);
  137. FETCH_DIR_DATA_FROM_SHEET(m_fU2Installed);
  138. FETCH_DIR_DATA_FROM_SHEET(m_fUseNTMapper);
  139. END_META_DIR_READ(err)
  140. //
  141. // First we need to read in the hash and the name of the store. If either
  142. // is not there then there is no certificate.
  143. //
  144. BEGIN_META_INST_READ(CW3Sheet)
  145. FETCH_INST_DATA_FROM_SHEET(m_strCertStoreName);
  146. FETCH_INST_DATA_FROM_SHEET(m_strCTLIdentifier);
  147. FETCH_INST_DATA_FROM_SHEET(m_strCTLStoreName);
  148. END_META_INST_READ(err)
  149. //
  150. // Build the IPL list
  151. //
  152. err = BuildIplOblistFromBlob(
  153. GetIPL(),
  154. m_oblAccessList,
  155. m_fDefaultGranted
  156. );
  157. m_fOldDefaultGranted = m_fDefaultGranted;
  158. return err;
  159. }
  160. /* virtual */
  161. HRESULT
  162. CW3SecurityPage::SaveInfo()
  163. /*++
  164. Routine Description:
  165. Save the information on this property page
  166. Arguments:
  167. None
  168. Return Value:
  169. Error return code
  170. --*/
  171. {
  172. ASSERT(IsDirty());
  173. TRACEEOLID("Saving W3 security page now...");
  174. CError err;
  175. //
  176. // Check to see if the ip access list needs saving.
  177. //
  178. BOOL fIplDirty = m_fIpDirty || (m_fOldDefaultGranted != m_fDefaultGranted);
  179. //
  180. // Use m_ notation because the message crackers require it
  181. //
  182. CBlob m_ipl;
  183. if (fIplDirty)
  184. {
  185. BuildIplBlob(m_oblAccessList, m_fDefaultGranted, m_ipl);
  186. }
  187. BeginWaitCursor();
  188. BEGIN_META_DIR_WRITE(CW3Sheet)
  189. STORE_DIR_DATA_ON_SHEET(m_dwSSLAccessPermissions)
  190. STORE_DIR_DATA_ON_SHEET(m_dwAuthFlags)
  191. STORE_DIR_DATA_ON_SHEET(m_strBasicDomain)
  192. if (fIplDirty)
  193. {
  194. STORE_DIR_DATA_ON_SHEET(m_ipl)
  195. }
  196. STORE_DIR_DATA_ON_SHEET(m_strAnonUserName)
  197. STORE_DIR_DATA_ON_SHEET(m_fPasswordSync)
  198. STORE_DIR_DATA_ON_SHEET(m_fUseNTMapper)
  199. if (m_fPasswordSync)
  200. {
  201. //
  202. // Delete password
  203. //
  204. // CODEWORK: Shouldn't need to know ID number.
  205. // Implement m_fDelete flag in CMP template maybe?
  206. //
  207. FLAG_DIR_DATA_FOR_DELETION(MD_ANONYMOUS_PWD);
  208. }
  209. else
  210. {
  211. STORE_DIR_DATA_ON_SHEET(m_strAnonPassword);
  212. }
  213. END_META_DIR_WRITE(err)
  214. if (err.Succeeded())
  215. {
  216. BEGIN_META_INST_WRITE(CW3Sheet)
  217. if ( m_strCTLIdentifier.IsEmpty() )
  218. {
  219. FLAG_INST_DATA_FOR_DELETION( MD_SSL_CTL_IDENTIFIER )
  220. }
  221. else
  222. {
  223. STORE_INST_DATA_ON_SHEET(m_strCTLIdentifier)
  224. }
  225. if ( m_strCTLStoreName.IsEmpty() )
  226. {
  227. FLAG_INST_DATA_FOR_DELETION( MD_SSL_CTL_STORE_NAME )
  228. }
  229. else
  230. {
  231. STORE_INST_DATA_ON_SHEET(m_strCTLStoreName)
  232. }
  233. END_META_INST_WRITE(err)
  234. }
  235. EndWaitCursor();
  236. if (err.Succeeded())
  237. {
  238. m_fIpDirty = FALSE;
  239. m_fOldDefaultGranted = m_fDefaultGranted;
  240. }
  241. return err;
  242. }
  243. BOOL
  244. CW3SecurityPage::FetchSSLState()
  245. /*++
  246. Routine Description:
  247. Obtain the state of the dialog depending on whether certificates
  248. are installed or not.
  249. Arguments:
  250. None
  251. Return Value:
  252. TRUE if certificates are installed, FALSE otherwise
  253. --*/
  254. {
  255. BeginWaitCursor();
  256. m_fCertInstalled = ::IsCertInstalledOnServer(
  257. GetServerName(),
  258. QueryInstance()
  259. );
  260. EndWaitCursor();
  261. return m_fCertInstalled;
  262. }
  263. void
  264. CW3SecurityPage::SetSSLControlState()
  265. /*++
  266. Routine Description:
  267. Enable/disable supported controls depending on what's installed.
  268. Only available on non-master instance nodes.
  269. Arguments:
  270. None
  271. Return Value:
  272. None
  273. --*/
  274. {
  275. m_static_SSLPrompt.EnableWindow(!IsMasterInstance());
  276. m_button_GetCertificates.EnableWindow(
  277. !IsMasterInstance()
  278. && m_fHome
  279. && IsLocal()
  280. );
  281. m_button_Communications.EnableWindow(
  282. !IsMasterInstance()
  283. && IsSSLSupported()
  284. && FetchSSLState()
  285. );
  286. m_button_ViewCertificates.EnableWindow(m_fCertInstalled);
  287. }
  288. //
  289. // Message Handlers
  290. //
  291. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  292. BOOL
  293. CW3SecurityPage::OnSetActive()
  294. /*++
  295. Routine Description:
  296. Page got activated -- set the SSL state depending on whether a
  297. certificate is installed or not.
  298. Arguments:
  299. None
  300. Return Value:
  301. TRUE to activate the page, FALSE otherwise.
  302. --*/
  303. {
  304. //
  305. // Enable/disable ssl controls
  306. //
  307. SetSSLControlState();
  308. return CInetPropertyPage::OnSetActive();
  309. }
  310. BOOL
  311. CW3SecurityPage::OnInitDialog()
  312. /*++
  313. Routine Description:
  314. WM_INITDIALOG handler. Initialize the dialog.
  315. Arguments:
  316. None.
  317. Return Value:
  318. TRUE if no focus is to be set automatically, FALSE if the focus
  319. is already set.
  320. --*/
  321. {
  322. CInetPropertyPage::OnInitDialog();
  323. //
  324. // Initialize certificate authorities ocx
  325. //
  326. CRect rc(0, 0, 0, 0);
  327. m_ocx_CertificateAuthorities.Create(
  328. _T("CertWiz"),
  329. WS_BORDER,
  330. rc,
  331. this,
  332. IDC_APPSCTRL
  333. );
  334. GetDlgItem(IDC_GROUP_IP)->EnableWindow(HasIPAccessCheck());
  335. GetDlgItem(IDC_ICON_IP)->EnableWindow(HasIPAccessCheck());
  336. GetDlgItem(IDC_STATIC_IP)->EnableWindow(HasIPAccessCheck());
  337. GetDlgItem(IDC_BUTTON_IP_SECURITY)->EnableWindow(HasIPAccessCheck());
  338. GetDlgItem(IDC_BUTTON_AUTHENTICATION)->EnableWindow(!m_fU2Installed);
  339. //
  340. // Configure for either master or non-master display.
  341. //
  342. m_check_EnableDS.ShowWindow(IsMasterInstance() ? SW_SHOW : SW_HIDE);
  343. m_check_EnableDS.EnableWindow(
  344. HasAdminAccess()
  345. && IsMasterInstance()
  346. && HasNTCertMapper()
  347. );
  348. #define SHOW_NON_MASTER(x)\
  349. (x).ShowWindow(IsMasterInstance() ? SW_HIDE : SW_SHOW)
  350. SHOW_NON_MASTER(m_static_SSLPrompt);
  351. SHOW_NON_MASTER(m_icon_Secure);
  352. SHOW_NON_MASTER(m_button_GetCertificates);
  353. SHOW_NON_MASTER(m_button_Communications);
  354. SHOW_NON_MASTER(m_button_ViewCertificates);
  355. #undef SHOW_NON_MASTER
  356. return TRUE;
  357. }
  358. void
  359. CW3SecurityPage::OnButtonAuthentication()
  360. /*++
  361. Routine Description:
  362. 'Authentication' button hander
  363. Arguments:
  364. None
  365. Return Value:
  366. None
  367. --*/
  368. {
  369. CAuthenticationDlg dlg(
  370. GetServerName(),
  371. QueryInstance(),
  372. m_strBasicDomain,
  373. m_dwAuthFlags,
  374. m_dwSSLAccessPermissions,
  375. m_strAnonUserName,
  376. m_strAnonPassword,
  377. m_fPasswordSync,
  378. HasAdminAccess(),
  379. HasDigest(),
  380. this
  381. );
  382. DWORD dwOldAccess = m_dwSSLAccessPermissions;
  383. DWORD dwOldAuth = m_dwAuthFlags;
  384. CString strOldDomain = m_strBasicDomain;
  385. CString strOldUserName = m_strAnonUserName;
  386. CString strOldPassword = m_strAnonPassword;
  387. BOOL fOldPasswordSync = m_fPasswordSync;
  388. if (dlg.DoModal() == IDOK)
  389. {
  390. //
  391. // See if anything has changed
  392. //
  393. if (dwOldAccess != m_dwSSLAccessPermissions
  394. || dwOldAuth != m_dwAuthFlags
  395. || m_strBasicDomain != strOldDomain
  396. || m_strAnonUserName != strOldUserName
  397. || m_strAnonPassword != strOldPassword
  398. || m_fPasswordSync != fOldPasswordSync
  399. )
  400. {
  401. //
  402. // Mark as dirty
  403. //
  404. OnItemChanged();
  405. }
  406. }
  407. }
  408. void
  409. CW3SecurityPage::OnButtonCommunications()
  410. /*++
  411. Routine Description:
  412. 'Communications' button handler
  413. Arguments:
  414. None
  415. Return Value:
  416. None
  417. --*/
  418. {
  419. //
  420. // Prep the flag for if we can edit CTLs or not
  421. //
  422. BOOL fEditCTLs = IsMasterInstance() || m_fHome;
  423. //
  424. // Prep the communications dialog
  425. //
  426. CSecCommDlg dlg(
  427. GetServerName(),
  428. QueryInstanceMetaPath(),
  429. m_strBasicDomain,
  430. m_dwAuthFlags,
  431. m_dwSSLAccessPermissions,
  432. IsMasterInstance(),
  433. IsSSLSupported(),
  434. IsSSL128Supported(),
  435. m_fU2Installed,
  436. m_strCTLIdentifier,
  437. m_strCTLStoreName,
  438. fEditCTLs,
  439. IsLocal(),
  440. this
  441. );
  442. DWORD dwOldAccess = m_dwSSLAccessPermissions;
  443. DWORD dwOldAuth = m_dwAuthFlags;
  444. if (dlg.DoModal() == IDOK)
  445. {
  446. //
  447. // See if anything has changed
  448. //
  449. if (dwOldAccess != m_dwSSLAccessPermissions
  450. || dwOldAuth != m_dwAuthFlags
  451. )
  452. {
  453. //
  454. // Mark as dirty
  455. //
  456. OnItemChanged();
  457. }
  458. //
  459. // See if the CTL information has changed
  460. //
  461. if (dlg.m_bCTLDirty)
  462. {
  463. m_strCTLIdentifier = dlg.m_strCTLIdentifier;
  464. m_strCTLStoreName = dlg.m_strCTLStoreName;
  465. OnItemChanged();
  466. }
  467. }
  468. }
  469. void
  470. CW3SecurityPage::OnButtonIpSecurity()
  471. /*++
  472. Routine Description:
  473. 'tcpip' button handler
  474. Arguments:
  475. None
  476. Return Value:
  477. None
  478. --*/
  479. {
  480. CIPDomainDlg dlg(
  481. m_fIpDirty,
  482. m_fDefaultGranted,
  483. m_fOldDefaultGranted,
  484. m_oblAccessList,
  485. this
  486. );
  487. if (dlg.DoModal() == IDOK)
  488. {
  489. //
  490. // Rebuild the list. Temporarily reset ownership, otherwise
  491. // RemoveAll() will destroy the pointers which are shared with the
  492. // new list.
  493. //
  494. BOOL fOwn = m_oblAccessList.SetOwnership(FALSE);
  495. m_oblAccessList.RemoveAll();
  496. m_oblAccessList.AddTail(&dlg.GetAccessList());
  497. m_oblAccessList.SetOwnership(fOwn);
  498. if (m_fIpDirty || m_fOldDefaultGranted != m_fDefaultGranted)
  499. {
  500. OnItemChanged();
  501. }
  502. }
  503. }
  504. void
  505. CW3SecurityPage::OnButtonGetCertificates()
  506. /*++
  507. Routine Description:
  508. "get certicate" button handler
  509. Arguments:
  510. None
  511. Return Value:
  512. None
  513. --*/
  514. {
  515. m_ocx_CertificateAuthorities.SetMachineName(GetServerName());
  516. m_ocx_CertificateAuthorities.SetServerInstance(QueryInstanceMetaPath());
  517. m_ocx_CertificateAuthorities.DoClick();
  518. //
  519. // There may now be a certificate. See if we should enable the edit button.
  520. //
  521. SetSSLControlState();
  522. }
  523. void
  524. CW3SecurityPage::OnButtonViewCertificates()
  525. /*++
  526. Routine Description:
  527. "view certicate" button handler
  528. Arguments:
  529. None
  530. Return Value:
  531. None
  532. --*/
  533. {
  534. HCERTSTORE hStore = NULL;
  535. PCCERT_CONTEXT pCert = NULL;
  536. CMetaKey key(GetServerName(),
  537. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  538. METADATA_MASTER_ROOT_HANDLE,
  539. QueryInstanceMetaPath());
  540. if (key.Succeeded())
  541. {
  542. CString store_name;
  543. CBlob hash;
  544. if ( SUCCEEDED(key.QueryValue(MD_SSL_CERT_STORE_NAME, store_name))
  545. && SUCCEEDED(key.QueryValue(MD_SSL_CERT_HASH, hash))
  546. )
  547. {
  548. hStore = CertOpenStore(
  549. CERT_STORE_PROV_SYSTEM,
  550. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
  551. NULL,
  552. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  553. store_name
  554. );
  555. if (hStore != NULL)
  556. {
  557. // Now we need to find cert by hash
  558. CRYPT_HASH_BLOB crypt_hash;
  559. crypt_hash.cbData = hash.GetSize();
  560. crypt_hash.pbData = hash.GetData();
  561. pCert = CertFindCertificateInStore(
  562. hStore,
  563. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  564. 0, CERT_FIND_HASH, (LPVOID)&crypt_hash, NULL);
  565. }
  566. }
  567. }
  568. if (pCert)
  569. {
  570. BOOL fPropertiesChanged;
  571. CRYPTUI_VIEWCERTIFICATE_STRUCT vcs;
  572. HCERTSTORE hCertStore = ::CertDuplicateStore(hStore);
  573. ::ZeroMemory (&vcs, sizeof (vcs));
  574. vcs.dwSize = sizeof (vcs);
  575. vcs.hwndParent = GetParent()->GetSafeHwnd();
  576. vcs.dwFlags = 0;
  577. vcs.cStores = 1;
  578. vcs.rghStores = &hCertStore;
  579. vcs.pCertContext = pCert;
  580. ::CryptUIDlgViewCertificate(&vcs, &fPropertiesChanged);
  581. ::CertCloseStore (hCertStore, 0);
  582. }
  583. else
  584. {
  585. }
  586. if (pCert != NULL)
  587. ::CertFreeCertificateContext(pCert);
  588. if (hStore != NULL)
  589. ::CertCloseStore(hStore, 0);
  590. }
  591. void
  592. CW3SecurityPage::OnItemChanged()
  593. /*++
  594. Routine Description:
  595. All EN_CHANGE messages map to this function
  596. Arguments:
  597. None
  598. Return Value:
  599. None
  600. --*/
  601. {
  602. SetModified(TRUE);
  603. }