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.

846 lines
13 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. security.cpp
  5. Abstract:
  6. FTP 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 "ftpsht.h"
  23. #include "fvdir.h"
  24. #include "fsecure.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. //
  31. // Needed for granted/denied icons
  32. //
  33. //#include "..\comprop\resource.h"
  34. IMPLEMENT_DYNCREATE(CFtpSecurityPage, CInetPropertyPage)
  35. CFtpSecurityPage::CFtpSecurityPage(
  36. IN CInetPropertySheet * pSheet
  37. )
  38. /*++
  39. Routine Description:
  40. Constructor
  41. Arguments:
  42. CInetPropertySheet * pSheet : Sheet object
  43. Return Value:
  44. N/A
  45. --*/
  46. : CInetPropertyPage(
  47. CFtpSecurityPage::IDD,
  48. pSheet,
  49. USE_DEFAULT_CAPTION,
  50. TRUE // Enable enhanced fonts
  51. ),
  52. m_ListBoxRes(
  53. IDB_ACCESS,
  54. m_list_IpAddresses.nBitmaps
  55. ),
  56. m_oblAccessList(),
  57. m_list_IpAddresses(TRUE),
  58. m_fIpDirty(FALSE),
  59. m_fOldDefaultGranted(TRUE),
  60. m_fDefaultGranted(TRUE) // By default, we grant access
  61. {
  62. #if 0 // Keep class wizard happy
  63. //{{AFX_DATA_INIT(CFtpSecurityPage)
  64. m_nGrantedDenied = 0;
  65. //}}AFX_DATA_INIT
  66. #endif // 0
  67. m_list_IpAddresses.AttachResources(&m_ListBoxRes);
  68. }
  69. CFtpSecurityPage::~CFtpSecurityPage()
  70. /*++
  71. Routine Description:
  72. Destructor
  73. Arguments:
  74. N/A
  75. Return Value:
  76. N/A
  77. --*/
  78. {
  79. //
  80. // The access list will clean itself up
  81. //
  82. }
  83. void
  84. CFtpSecurityPage::DoDataExchange(
  85. IN CDataExchange * pDX
  86. )
  87. /*++
  88. Routine Description:
  89. Initialise/Store control data
  90. Arguments:
  91. CDataExchange * pDX - DDX/DDV control structure
  92. Return Value:
  93. None
  94. --*/
  95. {
  96. CInetPropertyPage::DoDataExchange(pDX);
  97. //{{AFX_DATA_MAP(CFtpSecurityPage)
  98. DDX_Control(pDX, IDC_BUTTON_REMOVE, m_button_Remove);
  99. DDX_Control(pDX, IDC_BUTTON_EDIT, m_button_Edit);
  100. DDX_Control(pDX, IDC_BUTTON_ADD, m_button_Add);
  101. DDX_Control(pDX, IDC_ICON_GRANTED, m_icon_Granted);
  102. DDX_Control(pDX, IDC_ICON_DENIED, m_icon_Denied);
  103. DDX_Control(pDX, IDC_RADIO_GRANTED, m_radio_Granted);
  104. DDX_Radio(pDX, IDC_RADIO_GRANTED, m_nGrantedDenied);
  105. //}}AFX_DATA_MAP
  106. //
  107. // Private DDX/DDV Routines
  108. //
  109. DDX_Control(pDX, IDC_RADIO_DENIED, m_radio_Denied);
  110. DDX_Control(pDX, IDC_LIST_IP_ADDRESSES, m_list_IpAddresses);
  111. }
  112. //
  113. // Message Map
  114. //
  115. BEGIN_MESSAGE_MAP(CFtpSecurityPage, CInetPropertyPage)
  116. //{{AFX_MSG_MAP(CFtpSecurityPage)
  117. ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
  118. ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
  119. ON_BN_CLICKED(IDC_BUTTON_REMOVE, OnButtonRemove)
  120. ON_BN_CLICKED(IDC_RADIO_GRANTED, OnRadioGranted)
  121. ON_BN_CLICKED(IDC_RADIO_DENIED, OnRadioDenied)
  122. ON_LBN_DBLCLK(IDC_LIST_IP_ADDRESSES, OnDblclkListIpAddresses)
  123. ON_LBN_ERRSPACE(IDC_LIST_IP_ADDRESSES, OnErrspaceListIpAddresses)
  124. ON_LBN_SELCHANGE(IDC_LIST_IP_ADDRESSES, OnSelchangeListIpAddresses)
  125. ON_WM_VKEYTOITEM()
  126. //}}AFX_MSG_MAP
  127. END_MESSAGE_MAP()
  128. /* virtual */
  129. HRESULT
  130. CFtpSecurityPage::FetchLoadedValues()
  131. /*++
  132. Routine Description:
  133. Move configuration data from sheet to dialog controls
  134. Arguments:
  135. None
  136. Return Value:
  137. HRESULT
  138. --*/
  139. {
  140. m_nGrantedDenied = 0;
  141. //
  142. // Build the IPL list
  143. //
  144. CError err(BuildIplOblistFromBlob(
  145. ((CFtpSheet *)GetSheet())->GetDirectoryProperties().m_ipl,
  146. m_oblAccessList,
  147. m_fDefaultGranted
  148. ));
  149. err.MessageBoxOnFailure();
  150. m_nGrantedDenied = m_fDefaultGranted ? DEFAULT_GRANTED : DEFAULT_DENIED;
  151. m_fOldDefaultGranted = m_fDefaultGranted;
  152. return S_OK;
  153. }
  154. /* virtual */
  155. HRESULT
  156. CFtpSecurityPage::SaveInfo()
  157. /*++
  158. Routine Description:
  159. Save the information on this property page
  160. Arguments:
  161. None
  162. Return Value:
  163. Error return code
  164. --*/
  165. {
  166. ASSERT(IsDirty());
  167. TRACEEOLID("Saving FTP security page now...");
  168. BOOL fIplDirty = m_fIpDirty || (m_fOldDefaultGranted != m_fDefaultGranted);
  169. //
  170. // Use m_ notation because the message crackers require it.
  171. //
  172. CBlob m_ipl;
  173. if (fIplDirty)
  174. {
  175. BuildIplBlob(m_oblAccessList, m_fDefaultGranted, m_ipl);
  176. }
  177. CError err;
  178. BeginWaitCursor();
  179. BEGIN_META_DIR_WRITE(CFtpSheet)
  180. if (fIplDirty)
  181. {
  182. STORE_DIR_DATA_ON_SHEET(m_ipl);
  183. }
  184. END_META_DIR_WRITE(err)
  185. EndWaitCursor();
  186. if (err.Succeeded())
  187. {
  188. m_fIpDirty = FALSE;
  189. m_fOldDefaultGranted = m_fDefaultGranted;
  190. }
  191. return err;
  192. }
  193. //
  194. // Message Handlers
  195. //
  196. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  197. void
  198. CFtpSecurityPage::OnButtonAdd()
  199. /*++
  200. Routine Description:
  201. 'Add' button handler
  202. Arguments:
  203. None
  204. Return Value:
  205. None
  206. --*/
  207. {
  208. if (ShowPropertiesDialog(TRUE) == IDOK)
  209. {
  210. SetControlStates();
  211. m_fIpDirty = TRUE;
  212. OnItemChanged();
  213. }
  214. }
  215. void
  216. CFtpSecurityPage::OnButtonEdit()
  217. /*++
  218. Routine Description:
  219. 'Edit' button handler
  220. Arguments:
  221. None
  222. Return Value:
  223. None
  224. --*/
  225. {
  226. if (ShowPropertiesDialog(FALSE) == IDOK)
  227. {
  228. SetControlStates();
  229. m_fIpDirty = TRUE;
  230. OnItemChanged();
  231. }
  232. }
  233. void
  234. CFtpSecurityPage::OnButtonRemove()
  235. /*++
  236. Routine Description:
  237. 'Remove' button handler
  238. Arguments:
  239. None
  240. Return Value:
  241. None
  242. --*/
  243. {
  244. int nSel = 0;
  245. int nCurSel = m_list_IpAddresses.GetCurSel();
  246. while (m_list_IpAddresses.GetNextSelectedItem(&nSel))
  247. {
  248. m_oblAccessList.RemoveIndex(nSel);
  249. m_list_IpAddresses.DeleteString(nSel);
  250. }
  251. m_fIpDirty = TRUE;
  252. OnItemChanged();
  253. if (nCurSel > 0)
  254. {
  255. --nCurSel;
  256. }
  257. m_list_IpAddresses.SetCurSel(nCurSel);
  258. if (!SetControlStates())
  259. {
  260. m_button_Add.SetFocus();
  261. }
  262. }
  263. BOOL
  264. CFtpSecurityPage::SetControlStates()
  265. /*++
  266. Routine Description:
  267. Set the enabled status of the controls depending on the current
  268. state of the dialog
  269. Arguments:
  270. None
  271. Return Value:
  272. TRUE if at least one item is currently selected in the listbox
  273. --*/
  274. {
  275. BOOL fSomeSelection = m_list_IpAddresses.GetSelCount() > 0;
  276. m_button_Edit.EnableWindow(m_list_IpAddresses.GetSelCount() == 1);
  277. m_button_Remove.EnableWindow(m_list_IpAddresses.GetSelCount() > 0);
  278. return fSomeSelection;
  279. }
  280. void
  281. CFtpSecurityPage::FillListBox(
  282. IN CIPAccessDescriptor * pSelection OPTIONAL
  283. )
  284. /*++
  285. Routine Description:
  286. Populate the listbox with the access list
  287. entries
  288. Arguments:
  289. CIPAccessDescriptor * pSelection : Item to be selected or NULL.
  290. Return Value:
  291. None
  292. --*/
  293. {
  294. CObListIter obli(m_oblAccessList);
  295. const CIPAccessDescriptor * pAccess;
  296. m_list_IpAddresses.SetRedraw(FALSE);
  297. m_list_IpAddresses.ResetContent();
  298. int cItems = 0 ;
  299. int nSel = LB_ERR, nItem;
  300. for ( /**/ ; pAccess = (CIPAccessDescriptor *)obli.Next(); ++cItems)
  301. {
  302. //
  303. // We only list those not adhering to the default
  304. //
  305. if (pAccess->HasAccess() != m_fDefaultGranted)
  306. {
  307. nItem = m_list_IpAddresses.AddItem(pAccess);
  308. if (pAccess == pSelection)
  309. {
  310. //
  311. // Found item to be selected
  312. //
  313. nSel = nItem;
  314. }
  315. }
  316. }
  317. m_list_IpAddresses.SetCurSel(nSel);
  318. m_list_IpAddresses.SetRedraw(TRUE);
  319. }
  320. DWORD
  321. CFtpSecurityPage::SortAccessList()
  322. /*++
  323. Routine Description:
  324. Sorting the access list by grant denied and ip address
  325. FillListBox() should be called after this because
  326. the listbox will no longer reflect the true status
  327. of the list of directories.
  328. Arguments:
  329. None
  330. Return Value:
  331. Error return code
  332. --*/
  333. {
  334. BeginWaitCursor();
  335. DWORD dw = m_oblAccessList.Sort(
  336. (CObjectPlus::PCOBJPLUS_ORDER_FUNC)&CIPAccessDescriptor::OrderByAddress);
  337. EndWaitCursor();
  338. return dw;
  339. }
  340. INT_PTR
  341. CFtpSecurityPage::ShowPropertiesDialog(
  342. IN BOOL fAdd
  343. )
  344. /*++
  345. Routine Description:
  346. Bring up the dialog used for add or edit. Return the value returned
  347. by the dialog
  348. Arguments:
  349. BOOL fAdd : If TRUE, create new item. Otherwise, edit existing item
  350. Return Value:
  351. Dialog return code (IDOK/IDCANCEL)
  352. --*/
  353. {
  354. //
  355. // Bring up the dialog
  356. //
  357. CIPAccessDescriptor * pAccess = NULL;
  358. int nCurSel = LB_ERR;
  359. if (!fAdd)
  360. {
  361. //
  362. // Edit existing entry -- there better be only one...
  363. //
  364. pAccess = m_list_IpAddresses.GetSelectedItem();
  365. ASSERT(pAccess != NULL);
  366. if (pAccess == NULL)
  367. {
  368. //
  369. // Double click?
  370. //
  371. return IDCANCEL;
  372. }
  373. }
  374. CIPAccessDlg dlgAccess(
  375. m_fDefaultGranted,
  376. pAccess,
  377. &m_oblAccessList,
  378. this
  379. );
  380. INT_PTR nReturn = dlgAccess.DoModal();
  381. if (nReturn == IDOK)
  382. {
  383. CError err;
  384. ASSERT(pAccess != NULL);
  385. if (pAccess == NULL)
  386. {
  387. err = ERROR_NOT_ENOUGH_MEMORY;
  388. }
  389. else
  390. {
  391. try
  392. {
  393. if (fAdd)
  394. {
  395. m_oblAccessList.AddTail(pAccess);
  396. }
  397. SortAccessList();
  398. FillListBox(pAccess);
  399. }
  400. catch(CMemoryException * e)
  401. {
  402. err = ERROR_NOT_ENOUGH_MEMORY;
  403. e->Delete();
  404. }
  405. }
  406. err.MessageBoxOnFailure();
  407. }
  408. return nReturn;
  409. }
  410. void
  411. CFtpSecurityPage::OnDblclkListIpAddresses()
  412. /*++
  413. Routine Description:
  414. Map listbox double click to the edit button
  415. Arguments:
  416. None
  417. Return Value:
  418. None
  419. --*/
  420. {
  421. OnButtonEdit();
  422. }
  423. void
  424. CFtpSecurityPage::OnErrspaceListIpAddresses()
  425. /*++
  426. Routine Description:
  427. Handle error condition in the ip address listbox
  428. Arguments:
  429. None
  430. Return Value:
  431. None
  432. --*/
  433. {
  434. SetControlStates();
  435. }
  436. void
  437. CFtpSecurityPage::OnSelchangeListIpAddresses()
  438. /*++
  439. Routine Description:
  440. Handle change in the selection of the listbox
  441. Arguments:
  442. None
  443. Return Value:
  444. None
  445. --*/
  446. {
  447. SetControlStates();
  448. }
  449. void
  450. CFtpSecurityPage::OnItemChanged()
  451. /*++
  452. Routine Description:
  453. All EN_CHANGE messages map to this function
  454. Arguments:
  455. None
  456. Return Value:
  457. None
  458. --*/
  459. {
  460. SetModified(TRUE);
  461. }
  462. BOOL
  463. CFtpSecurityPage::OnInitDialog()
  464. /*++
  465. Routine Description:
  466. WM_INITDIALOG handler. Initialize the dialog.
  467. Arguments:
  468. None.
  469. Return Value:
  470. TRUE if focus is to be set automatically, FALSE if the focus
  471. is already set.
  472. --*/
  473. {
  474. CInetPropertyPage::OnInitDialog();
  475. m_icon_Granted.SetIcon(::AfxGetApp()->LoadIcon(IDI_GRANTED));
  476. m_icon_Denied.SetIcon(::AfxGetApp()->LoadIcon(IDI_DENIED));
  477. m_list_IpAddresses.Initialize();
  478. m_list_IpAddresses.EnableWindow(HasIPAccessCheck());
  479. m_button_Add.EnableWindow(HasIPAccessCheck());
  480. GetDlgItem(IDC_RADIO_GRANTED)->EnableWindow(HasIPAccessCheck());
  481. GetDlgItem(IDC_RADIO_DENIED)->EnableWindow(HasIPAccessCheck());
  482. GetDlgItem(IDC_ICON_GRANTED)->EnableWindow(HasIPAccessCheck());
  483. GetDlgItem(IDC_ICON_DENIED)->EnableWindow(HasIPAccessCheck());
  484. FillListBox();
  485. SetControlStates();
  486. return TRUE;
  487. }
  488. void
  489. CFtpSecurityPage::OnRadioGranted()
  490. /*++
  491. Routine Description:
  492. Granted by default has been selected.
  493. Refill the listbox with items that have
  494. been explicitly denied. Although we can
  495. only have a deny list or a grant list,
  496. we keep both of them around until it comes
  497. time to saving the information.
  498. Arguments:
  499. None
  500. Return Value:
  501. None
  502. --*/
  503. {
  504. if (!m_fDefaultGranted)
  505. {
  506. m_fDefaultGranted = TRUE;
  507. FillListBox();
  508. OnItemChanged();
  509. SetControlStates();
  510. }
  511. }
  512. void
  513. CFtpSecurityPage::OnRadioDenied()
  514. /*++
  515. Routine Description:
  516. As above, but reverse granted and denied
  517. Arguments:
  518. None
  519. Return Value:
  520. None
  521. --*/
  522. {
  523. if (m_fDefaultGranted)
  524. {
  525. m_fDefaultGranted = FALSE;
  526. FillListBox();
  527. OnItemChanged();
  528. SetControlStates();
  529. }
  530. }
  531. int
  532. CFtpSecurityPage::OnVKeyToItem(
  533. IN UINT nKey,
  534. IN CListBox * pListBox,
  535. IN UINT nIndex
  536. )
  537. /*++
  538. Routine Description:
  539. Map insert and delete keys for the listbox
  540. Arguments:
  541. UINT nKey : Key pressed
  542. CListBox * pListBox : Listbox
  543. UINT nIndex : Index selected
  544. Return Value:
  545. -2 if fully handled, -1 if partially handled, 0+ if not
  546. handled at all
  547. --*/
  548. {
  549. switch(nKey)
  550. {
  551. case VK_DELETE:
  552. OnButtonRemove();
  553. break;
  554. case VK_INSERT:
  555. OnButtonAdd();
  556. break;
  557. default:
  558. //
  559. // Not completely handled by this function, let
  560. // windows handle the remaining default action.
  561. //
  562. return -1;
  563. }
  564. //
  565. // No further action is neccesary.
  566. //
  567. return -2;
  568. }