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.

747 lines
13 KiB

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