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.

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