1458 lines
48 KiB
C++
1458 lines
48 KiB
C++
|
// Map11Pge.cpp : implementation file
|
||
|
//
|
||
|
|
||
|
// Certificate mappings storage has changed for IIS6.
|
||
|
// CERTMAP.OCX however has to support downlevel admin
|
||
|
// of IIS5, IIS5.1
|
||
|
//
|
||
|
// NSEPM support was removed from IIS6 and 1to1 client certificate
|
||
|
// mapping information is now stored under <site>/Cert11/Mappings
|
||
|
// node directly in the metabase
|
||
|
// Functions with IIS6 postfix access new location
|
||
|
// for 1to1 client certificate mappings storage
|
||
|
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include <iadmw.h>
|
||
|
#include "certmap.h"
|
||
|
|
||
|
// persistence and mapping includes
|
||
|
#include "WrapMaps.h"
|
||
|
//#include "wrpprsis.h"
|
||
|
//#include "admutil.h"
|
||
|
|
||
|
#include "ListRow.h"
|
||
|
#include "ChkLstCt.h"
|
||
|
|
||
|
#include "wrapmb.h"
|
||
|
|
||
|
// mapping page includes
|
||
|
#include "brwsdlg.h"
|
||
|
#include "EdtOne11.h"
|
||
|
#include "Ed11Maps.h"
|
||
|
#include "Map11Pge.h"
|
||
|
|
||
|
#include "CrackCrt.h"
|
||
|
|
||
|
#include <iiscnfgp.h>
|
||
|
//#include "WrpMBWrp.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define COL_NUM_ENABLED 0
|
||
|
#define COL_NUM_NAME 1
|
||
|
#define COL_NUM_NTACCOUNT 2
|
||
|
|
||
|
#define MB_EXTEND_KEY _T("Cert11")
|
||
|
#define MB_EXTEND_KEY_MAPS _T("Cert11/Mappings")
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CMap11Page property page
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CMap11Page, CPropertyPage)
|
||
|
|
||
|
CMap11Page::CMap11Page() : CPropertyPage(CMap11Page::IDD),
|
||
|
m_MapsInMetabase( 0 )
|
||
|
{
|
||
|
//{{AFX_DATA_INIT(CMap11Page)
|
||
|
m_csz_i_c = _T("");
|
||
|
m_csz_i_o = _T("");
|
||
|
m_csz_i_ou = _T("");
|
||
|
m_csz_s_c = _T("");
|
||
|
m_csz_s_cn = _T("");
|
||
|
m_csz_s_l = _T("");
|
||
|
m_csz_s_o = _T("");
|
||
|
m_csz_s_ou = _T("");
|
||
|
m_csz_s_s = _T("");
|
||
|
m_fIsIIS6 = TRUE;
|
||
|
//}}AFX_DATA_INIT
|
||
|
}
|
||
|
|
||
|
CMap11Page::~CMap11Page()
|
||
|
{
|
||
|
ResetMappingList();
|
||
|
}
|
||
|
|
||
|
void CMap11Page::DoDataExchange(CDataExchange* pDX)
|
||
|
{
|
||
|
CPropertyPage::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CMap11Page)
|
||
|
DDX_Control(pDX, IDC_ADD, m_cbutton_add);
|
||
|
DDX_Control(pDX, IDC_ISSUER, m_cbutton_grp_issuer);
|
||
|
DDX_Control(pDX, IDC_ISSUED_TO, m_cbutton_grp_issuedto);
|
||
|
DDX_Control(pDX, IDC_LIST, m_clistctrl_list);
|
||
|
DDX_Control(pDX, IDC_EDIT_11MAP, m_cbutton_editmap);
|
||
|
DDX_Control(pDX, IDC_DELETE, m_cbutton_delete);
|
||
|
DDX_Text(pDX, IDC_I_C, m_csz_i_c);
|
||
|
DDX_Text(pDX, IDC_I_O, m_csz_i_o);
|
||
|
DDX_Text(pDX, IDC_I_OU, m_csz_i_ou);
|
||
|
DDX_Text(pDX, IDC_S_C, m_csz_s_c);
|
||
|
DDX_Text(pDX, IDC_S_CN, m_csz_s_cn);
|
||
|
DDX_Text(pDX, IDC_S_L, m_csz_s_l);
|
||
|
DDX_Text(pDX, IDC_S_O, m_csz_s_o);
|
||
|
DDX_Text(pDX, IDC_S_OU, m_csz_s_ou);
|
||
|
DDX_Text(pDX, IDC_S_S, m_csz_s_s);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CMap11Page, CPropertyPage)
|
||
|
//{{AFX_MSG_MAP(CMap11Page)
|
||
|
ON_BN_CLICKED(IDC_ADD, OnAdd)
|
||
|
ON_BN_CLICKED(IDC_DELETE, OnDelete)
|
||
|
ON_BN_CLICKED(IDC_EDIT_11MAP, OnEdit11map)
|
||
|
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList)
|
||
|
ON_NOTIFY(NM_DBLCLK, IDC_LIST, OnDblclkList)
|
||
|
//}}AFX_MSG_MAP
|
||
|
ON_COMMAND(ID_HELP_FINDER, DoHelp)
|
||
|
ON_COMMAND(ID_HELP, DoHelp)
|
||
|
ON_COMMAND(ID_CONTEXT_HELP, DoHelp)
|
||
|
ON_COMMAND(ID_DEFAULT_HELP, DoHelp)
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::DoHelp()
|
||
|
{
|
||
|
WinHelpDebug(HIDD_CERTMAP_MAIN_BASIC);
|
||
|
WinHelp( HIDD_CERTMAP_MAIN_BASIC );
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// initialization routines
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// FInitMapper is called by the routine instantiating this page. After the object
|
||
|
// is first created is when it is called. It allows us to fail gracefully.
|
||
|
BOOL CMap11Page::FInit(IMSAdminBase* pMB)
|
||
|
{
|
||
|
m_pMB = pMB;
|
||
|
|
||
|
// check if it's for older than iis6 version
|
||
|
m_fIsIIS6 = TRUE;
|
||
|
if (IsLegacyMetabase(pMB)){m_fIsIIS6 = FALSE;}
|
||
|
|
||
|
if ( !m_fIsIIS6 )
|
||
|
{
|
||
|
// IIS5.1 and older saved cert mappings through NSEPM
|
||
|
m_szMBPath = m_szMBPath + SZ_NAMESPACE_EXTENTION;
|
||
|
}
|
||
|
|
||
|
|
||
|
// this has become a simple place
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::OnInitDialog()
|
||
|
{
|
||
|
//call the parental oninitdialog
|
||
|
BOOL f = CPropertyPage::OnInitDialog();
|
||
|
|
||
|
// if the initinalization (sp?) succeeded, init the list and other items
|
||
|
if ( f )
|
||
|
{
|
||
|
// init the contents of the list
|
||
|
FInitMappingList();
|
||
|
|
||
|
// Fill the mapping list with the stored items
|
||
|
FillMappingList();
|
||
|
|
||
|
// set the initial button states
|
||
|
EnableDependantButtons();
|
||
|
}
|
||
|
|
||
|
// set any changes in the info into place
|
||
|
UpdateData(FALSE);
|
||
|
|
||
|
// return the answer
|
||
|
return f;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::FInitMappingList()
|
||
|
{
|
||
|
CString sz;
|
||
|
int i;
|
||
|
|
||
|
// setup the friendly name column
|
||
|
sz.Empty();
|
||
|
i = m_clistctrl_list.InsertColumn( COL_NUM_ENABLED, sz, LVCFMT_LEFT, 20 );
|
||
|
|
||
|
// setup the friendly name column
|
||
|
sz.LoadString( IDS_LIST11_NAME );
|
||
|
|
||
|
i = m_clistctrl_list.InsertColumn( COL_NUM_NAME, sz, LVCFMT_LEFT, 105 );
|
||
|
|
||
|
// setup the account column
|
||
|
sz.LoadString( IDS_LIST11_ACCOUNT );
|
||
|
|
||
|
i = m_clistctrl_list.InsertColumn( COL_NUM_NTACCOUNT, sz, LVCFMT_LEFT, 195 );
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::FillMappingList()
|
||
|
{
|
||
|
// reset the mapping list - get rid of anything in there now
|
||
|
ResetMappingList();
|
||
|
|
||
|
// read in the mappings - it adds them to the list
|
||
|
FReadMappings();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//BOOL CMap11Page::FAddMappingToList( C11Mapping* pMap, DWORD iList )
|
||
|
BOOL CMap11Page::FAddMappingToList( C11Mapping* pMap )
|
||
|
{
|
||
|
CString sz;
|
||
|
int i;
|
||
|
DWORD iList;
|
||
|
|
||
|
// if requested, make sure the mapping is added to the end of the list
|
||
|
iList = m_clistctrl_list.GetItemCount();
|
||
|
|
||
|
// get the appropriate "enabled" string
|
||
|
BOOL fEnabled;
|
||
|
pMap->GetMapEnabled( &fEnabled );
|
||
|
if ( fEnabled )
|
||
|
sz.LoadString( IDS_ENABLED );
|
||
|
else
|
||
|
sz.Empty();
|
||
|
|
||
|
// add the friendly name of the mapping
|
||
|
// create the new entry in the list box. Do not sort on this entry - yet
|
||
|
i = m_clistctrl_list.InsertItem( iList, sz );
|
||
|
|
||
|
// add the friendly name of the mapping
|
||
|
pMap->GetMapName( sz );
|
||
|
// create the new entry in the list box. Do not sort on this entry - yet
|
||
|
m_clistctrl_list.SetItemText( i, COL_NUM_NAME, sz );
|
||
|
|
||
|
// add the account name of the mapping
|
||
|
pMap->GetNTAccount( sz );
|
||
|
m_clistctrl_list.SetItemText( i, COL_NUM_NTACCOUNT, sz );
|
||
|
|
||
|
// attach the pointer to the mapping as the private data in the list.
|
||
|
m_clistctrl_list.SetItemData( i, (UINT_PTR)pMap );
|
||
|
|
||
|
// return whether or not the insertion succeeded
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::EnableDependantButtons()
|
||
|
{
|
||
|
// the whole purpose of this routine is to gray or activate
|
||
|
// the edit and delete buttons depending on whether or not anything
|
||
|
// is selected. So start by getting the selection count
|
||
|
if ( m_clistctrl_list.GetSelectedCount() > 0 )
|
||
|
{
|
||
|
// there are items selected
|
||
|
m_cbutton_editmap.EnableWindow( TRUE );
|
||
|
m_cbutton_delete.EnableWindow( TRUE );
|
||
|
EnableCrackDisplay( TRUE );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// nope. Nothing selected
|
||
|
m_cbutton_editmap.EnableWindow( FALSE );
|
||
|
m_cbutton_delete.EnableWindow( FALSE );
|
||
|
}
|
||
|
|
||
|
// always enable the add button
|
||
|
m_cbutton_add.EnableWindow( TRUE );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::EditOneMapping( C11Mapping* pUpdateMap )
|
||
|
{
|
||
|
CEditOne11MapDlg mapdlg;
|
||
|
|
||
|
// prepare the mapping dialog
|
||
|
pUpdateMap->GetMapName( mapdlg.m_sz_mapname );
|
||
|
pUpdateMap->GetMapEnabled( &mapdlg.m_bool_enable );
|
||
|
pUpdateMap->GetNTAccount( mapdlg.m_sz_accountname );
|
||
|
pUpdateMap->GetNTPassword( mapdlg.m_sz_password );
|
||
|
|
||
|
// run the mapping dialog
|
||
|
if ( mapdlg.DoModal() == IDOK )
|
||
|
{
|
||
|
// update its friendly name
|
||
|
pUpdateMap->SetMapName( mapdlg.m_sz_mapname );
|
||
|
|
||
|
// set the NT account field of the mapping object
|
||
|
pUpdateMap->SetNTAccount( mapdlg.m_sz_accountname );
|
||
|
|
||
|
// set the NT account password field of the mapping object
|
||
|
CString csTempString;
|
||
|
mapdlg.m_sz_password.CopyTo(csTempString);
|
||
|
pUpdateMap->SetNTPassword( csTempString );
|
||
|
|
||
|
// set whether or not the mapping is enabled
|
||
|
pUpdateMap->SetMapEnabled( mapdlg.m_bool_enable );
|
||
|
|
||
|
// NOTE: the caller is resposible for calling UpdateMappingInDispList
|
||
|
// as the mapping in question may not yet be in the display list
|
||
|
|
||
|
// this mapping has changed. Mark it to be saved
|
||
|
MarkToSave( pUpdateMap );
|
||
|
|
||
|
// return true because the user said "OK"
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// return FALSE because the user did not say "OK"
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::EditMultipleMappings()
|
||
|
{
|
||
|
CEdit11Mappings mapdlg;
|
||
|
C11Mapping* pUpdate11Map;
|
||
|
BOOL fSetInitialState = FALSE;
|
||
|
BOOL fEnable;
|
||
|
|
||
|
|
||
|
// scan the list of seleted items for the proper initial enable button state
|
||
|
// loop through the selected items, setting each one's mapping
|
||
|
int iList = -1;
|
||
|
while( (iList = m_clistctrl_list.GetNextItem( iList, LVNI_SELECTED )) >= 0 )
|
||
|
{
|
||
|
// get the mapping item for updating purposes
|
||
|
pUpdate11Map = GetMappingInDisplay( iList );
|
||
|
ASSERT( pUpdate11Map );
|
||
|
if ( !pUpdate11Map )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// get the enable state of the mapping
|
||
|
pUpdate11Map->GetMapEnabled( &fEnable );
|
||
|
|
||
|
// if this is the first time, just set the initial state
|
||
|
if ( !fSetInitialState )
|
||
|
{
|
||
|
mapdlg.m_int_enable = fEnable;
|
||
|
fSetInitialState = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// if it is different, then go indeterminate and break
|
||
|
if ( fEnable != mapdlg.m_int_enable )
|
||
|
{
|
||
|
mapdlg.m_int_enable = 2;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// run the mapping dialog
|
||
|
if ( mapdlg.DoModal() == IDOK )
|
||
|
{
|
||
|
// loop through the selected items, setting each one's mapping
|
||
|
int iList = -1;
|
||
|
while( (iList = m_clistctrl_list.GetNextItem( iList, LVNI_SELECTED )) >= 0 )
|
||
|
{
|
||
|
// get the mapping item for updating purposes
|
||
|
pUpdate11Map = GetMappingInDisplay( iList );
|
||
|
if ( !pUpdate11Map )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// set the enable flag if requested
|
||
|
switch ( mapdlg.m_int_enable )
|
||
|
{
|
||
|
case 0: // disable
|
||
|
pUpdate11Map->SetMapEnabled( FALSE );
|
||
|
break;
|
||
|
case 1: // enable
|
||
|
pUpdate11Map->SetMapEnabled( TRUE );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// set the NT account field of the mapping object
|
||
|
pUpdate11Map->SetNTAccount( mapdlg.m_sz_accountname );
|
||
|
|
||
|
// set the NT account password field of the mapping object
|
||
|
CString csTempString;
|
||
|
mapdlg.m_sz_password.CopyTo(csTempString);
|
||
|
pUpdate11Map->SetNTPassword( csTempString );
|
||
|
|
||
|
// update it in the list control too
|
||
|
UpdateMappingInDispList( iList, pUpdate11Map );
|
||
|
|
||
|
// this mapping has changed. Mark it to be saved
|
||
|
MarkToSave( pUpdate11Map );
|
||
|
}
|
||
|
|
||
|
// activate the apply button
|
||
|
SetModified();
|
||
|
|
||
|
// return true because the user said "OK"
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// return FALSE because the user did not say "OK"
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::UpdateMappingInDispList( DWORD iList, C11Mapping* pMap )
|
||
|
{
|
||
|
CString sz;
|
||
|
|
||
|
// verify the index and the pointer!
|
||
|
ASSERT( pMap == GetMappingInDisplay(iList) );
|
||
|
|
||
|
// get the appropriate "enabled" string
|
||
|
BOOL fEnabled;
|
||
|
pMap->GetMapEnabled( &fEnabled );
|
||
|
if ( fEnabled )
|
||
|
sz.LoadString( IDS_ENABLED );
|
||
|
else
|
||
|
sz.Empty();
|
||
|
|
||
|
// update the "Enabled" indicator
|
||
|
m_clistctrl_list.SetItemText( iList, COL_NUM_ENABLED, sz );
|
||
|
|
||
|
// update the mapping name
|
||
|
pMap->GetMapName( sz );
|
||
|
m_clistctrl_list.SetItemText( iList, COL_NUM_NAME, sz );
|
||
|
|
||
|
// update the account name
|
||
|
pMap->GetNTAccount( sz );
|
||
|
m_clistctrl_list.SetItemText( iList, COL_NUM_NTACCOUNT, sz );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::ResetMappingList()
|
||
|
{
|
||
|
// first, delete all the mapping objects in the list
|
||
|
DWORD cbList = m_clistctrl_list.GetItemCount();
|
||
|
for ( DWORD iList = 0; iList < cbList; iList++ )
|
||
|
DeleteMapping( GetMappingInDisplay(iList) );
|
||
|
|
||
|
// reset the mapping list - get rid of anything in there now
|
||
|
m_clistctrl_list.DeleteAllItems();
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::MarkToSave( C11Mapping* pSaveMap, BOOL fSave )
|
||
|
{
|
||
|
// first, we see if it is already in the list. If it is, we have nothing to do
|
||
|
// unless fSave is set to false, then we remove it from the list
|
||
|
DWORD cbItemsInList = (DWORD)m_rgbSave.GetSize();
|
||
|
for ( DWORD i = 0; i < cbItemsInList; i++ )
|
||
|
{
|
||
|
if ( pSaveMap == (C11Mapping*)m_rgbSave[i] )
|
||
|
{
|
||
|
// go away if fSave, otherwise, double check it isn't
|
||
|
// anywhere else in the list
|
||
|
if ( fSave )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// remove the item from the list
|
||
|
m_rgbSave.RemoveAt(i);
|
||
|
// don't skip now as the list slid down
|
||
|
cbItemsInList--;
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// since it is not there, we should add it, if fSave is true
|
||
|
if ( fSave )
|
||
|
m_rgbSave.Add( (CObject*)pSaveMap );
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CMap11Page message handlers
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::OnOK()
|
||
|
{
|
||
|
// this has gotten much simpler
|
||
|
FWriteMappings();
|
||
|
CPropertyPage::OnOK();
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::OnApply()
|
||
|
{
|
||
|
// this has gotten much simpler
|
||
|
BOOL f = FWriteMappings();
|
||
|
// rebuild the display
|
||
|
FillMappingList();
|
||
|
return f;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// when the user pushes the add button, ask them to load a certificate, then
|
||
|
// add it to the list as a mapping
|
||
|
void CMap11Page::OnAdd()
|
||
|
{
|
||
|
|
||
|
// put this in a try/catch to make errors easier to deal with
|
||
|
try {
|
||
|
CString szFilter;
|
||
|
szFilter.LoadString( IDS_KEY_OR_CERT_FILE_FILTER );
|
||
|
|
||
|
// prepare the file dialog variables
|
||
|
CFileDialog cfdlg(TRUE, NULL, NULL,
|
||
|
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
|
||
|
(LPCTSTR)szFilter);
|
||
|
// Disable hook to get Windows 2000 style dialog
|
||
|
cfdlg.m_ofn.Flags &= ~(OFN_ENABLEHOOK);
|
||
|
// run the dialog
|
||
|
if ( cfdlg.DoModal() == IDOK )
|
||
|
{
|
||
|
// add the certificate to the mapping list
|
||
|
if ( FAddCertificateFile( cfdlg.GetPathName() ) )
|
||
|
{
|
||
|
// activate the apply button
|
||
|
SetModified();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch ( CException * pException )
|
||
|
{
|
||
|
pException->Delete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::OnDelete()
|
||
|
{
|
||
|
C11Mapping* pKillMap;
|
||
|
|
||
|
// ask the user to confirm this decision
|
||
|
if ( AfxMessageBox(IDS_CONFIRM_DELETE, MB_OKCANCEL) != IDOK )
|
||
|
return;
|
||
|
|
||
|
// loop through the selected items. Remove each from the list,
|
||
|
// then mark it to be deleted.
|
||
|
int iList = -1;
|
||
|
while( (iList = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED )) >= 0 )
|
||
|
{
|
||
|
// get the mapping
|
||
|
pKillMap = GetMappingInDisplay( iList );
|
||
|
|
||
|
// remove it from the list
|
||
|
m_clistctrl_list.DeleteItem( iList );
|
||
|
|
||
|
// if it has not yet been applied to the metabase, continue
|
||
|
|
||
|
if ( (!m_fIsIIS6 && pKillMap->iMD == NEW_OBJECT ) ||
|
||
|
( m_fIsIIS6 && pKillMap->QueryNodeName() == "" /*NEW_OBJECT*/ ) )
|
||
|
{
|
||
|
// since this mapping never existed, we can just remove it from the add/edit lists
|
||
|
MarkToSave( pKillMap, FALSE );
|
||
|
|
||
|
// go to the next selected object
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// mark the item to be deleted from the metabase
|
||
|
m_rgbDelete.Add( (CObject*)pKillMap );
|
||
|
}
|
||
|
|
||
|
// activate the apply button
|
||
|
SetModified();
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::OnEdit11map()
|
||
|
{
|
||
|
int iList;
|
||
|
C11Mapping* pUpdateMap;
|
||
|
|
||
|
// what happens here depends on if just one mapping is selected, or many
|
||
|
switch( m_clistctrl_list.GetSelectedCount() )
|
||
|
{
|
||
|
case 0: // do nothing - should not get here because button grays out
|
||
|
ASSERT( FALSE );
|
||
|
break;
|
||
|
|
||
|
case 1: // get the mapping for update and run single edit dialog
|
||
|
// get index of the selected list item
|
||
|
iList = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED );
|
||
|
ASSERT( iList >= 0 );
|
||
|
|
||
|
|
||
|
// get the mapping item for updating purposes
|
||
|
pUpdateMap = GetMappingInDisplay( iList );
|
||
|
if ( !pUpdateMap )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// edit the mapping, update it if successful, delete if not
|
||
|
if ( EditOneMapping(pUpdateMap) )
|
||
|
{
|
||
|
UpdateMappingInDispList( iList, pUpdateMap );
|
||
|
// activate the apply button
|
||
|
SetModified();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default: // run the multi edit dialog
|
||
|
EditMultipleMappings();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
{
|
||
|
*pResult = 0;
|
||
|
|
||
|
// if something in the list was double clicked, edit it
|
||
|
if ( m_clistctrl_list.GetSelectedCount() > 0 )
|
||
|
OnEdit11map();
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
{
|
||
|
C11Mapping* pSelMap;
|
||
|
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||
|
*pResult = 0;
|
||
|
|
||
|
// enable the correct items
|
||
|
EnableDependantButtons();
|
||
|
|
||
|
// fill in the cracked information for the selected mapping - if there is only one
|
||
|
if ( m_clistctrl_list.GetSelectedCount() == 1 )
|
||
|
{
|
||
|
// get index of the selected list item
|
||
|
int i = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED );
|
||
|
ASSERT( i >= 0 );
|
||
|
|
||
|
// get the mapper index for the item
|
||
|
pSelMap = GetMappingInDisplay( i );
|
||
|
if ( pSelMap )
|
||
|
{
|
||
|
DisplayCrackedMap( pSelMap );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// either multiple, or no mappings selected
|
||
|
EnableCrackDisplay( FALSE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//================================================================================
|
||
|
// special display
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::DisplayCrackedMap( C11Mapping* pMap )
|
||
|
{
|
||
|
PUCHAR pCert;
|
||
|
DWORD cbCert;
|
||
|
CString sz;
|
||
|
|
||
|
// obtain a reference to the certificate
|
||
|
if ( !pMap->GetCertificate( &pCert, &cbCert ) )
|
||
|
return FALSE;
|
||
|
|
||
|
// crack the certificate
|
||
|
CCrackedCert cracker;
|
||
|
if ( !cracker.CrackCert( pCert, cbCert ) )
|
||
|
return FALSE;
|
||
|
|
||
|
// fill in all the fields
|
||
|
cracker.GetIssuerCountry( sz );
|
||
|
m_csz_i_c = sz;
|
||
|
|
||
|
cracker.GetIssuerOrganization( sz );
|
||
|
m_csz_i_o = sz;
|
||
|
|
||
|
cracker.GetIssuerUnit( sz );
|
||
|
m_csz_i_ou = sz;
|
||
|
|
||
|
cracker.GetSubjectCountry( sz );
|
||
|
m_csz_s_c = sz;
|
||
|
|
||
|
cracker.GetSubjectCommonName( sz );
|
||
|
m_csz_s_cn = sz;
|
||
|
|
||
|
cracker.GetSubjectLocality( sz );
|
||
|
m_csz_s_l = sz;
|
||
|
|
||
|
cracker.GetSubjectOrganization( sz );
|
||
|
m_csz_s_o = sz;
|
||
|
|
||
|
cracker.GetSubjectUnit( sz );
|
||
|
m_csz_s_ou = sz;
|
||
|
|
||
|
cracker.GetSubjectState( sz );
|
||
|
m_csz_s_s = sz;
|
||
|
|
||
|
UpdateData( FALSE );
|
||
|
|
||
|
// return success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::ClearCrackDisplay()
|
||
|
{
|
||
|
m_csz_i_c.Empty();
|
||
|
m_csz_i_o.Empty();
|
||
|
m_csz_i_ou.Empty();
|
||
|
m_csz_s_c.Empty();
|
||
|
m_csz_s_cn.Empty();
|
||
|
m_csz_s_l.Empty();
|
||
|
m_csz_s_o.Empty();
|
||
|
m_csz_s_ou.Empty();
|
||
|
m_csz_s_s.Empty();
|
||
|
UpdateData( FALSE );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::EnableCrackDisplay( BOOL fEnable )
|
||
|
{
|
||
|
if ( !fEnable )
|
||
|
ClearCrackDisplay();
|
||
|
m_cbutton_grp_issuer.EnableWindow( fEnable );
|
||
|
m_cbutton_grp_issuedto.EnableWindow( fEnable );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::FReadMappings()
|
||
|
{
|
||
|
|
||
|
if ( m_fIsIIS6 )
|
||
|
{
|
||
|
return FReadMappingsIIS6();
|
||
|
}
|
||
|
BOOL f;
|
||
|
C11Mapping* pMap;
|
||
|
DWORD cbData;
|
||
|
PVOID pData;
|
||
|
DWORD fEnabled;
|
||
|
CString sz;
|
||
|
BOOL fRet = TRUE;
|
||
|
|
||
|
// before messing with the metabase, prepare the strings we will need
|
||
|
CString szBasePath = m_szMBPath + _T('/');
|
||
|
CString szRelativePath = MB_EXTEND_KEY_MAPS;
|
||
|
CString szObjectPath = m_szMBPath + _T('/') + szRelativePath;
|
||
|
CString szMapPath;
|
||
|
|
||
|
// prepare the metabase wrappers
|
||
|
CWrapMetaBase mbWrap;
|
||
|
f = mbWrap.FInit(m_pMB);
|
||
|
|
||
|
// open the base object
|
||
|
f = mbWrap.Open( szObjectPath, METADATA_PERMISSION_READ );
|
||
|
ASSERT( f );
|
||
|
if ( !f )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// for now, at least, we are reading in all the mappings. reset the m_nNamer counter
|
||
|
// so that we end up with a somewhat accurate reading of the last number-name in the list.
|
||
|
m_MapsInMetabase = 0;
|
||
|
|
||
|
// Loop the items in the metabase, adding each to the napper.
|
||
|
DWORD index = 0;
|
||
|
CString szEnum;
|
||
|
while ( mbWrap.EnumObjects(_T(""), szEnum.GetBuffer(MAX_PATH*sizeof(WCHAR)),
|
||
|
MAX_PATH*sizeof(WCHAR), index) )
|
||
|
{
|
||
|
szEnum.ReleaseBuffer();
|
||
|
|
||
|
// keep track of the number of mappings we encounter
|
||
|
m_MapsInMetabase++;
|
||
|
|
||
|
// build the final mapping object path
|
||
|
szMapPath.Format( _T("/%s"), szEnum );
|
||
|
|
||
|
// make a new mapping object
|
||
|
pMap = PNewMapping();
|
||
|
|
||
|
if (pMap == NULL) {
|
||
|
SetLastError(E_OUTOFMEMORY);
|
||
|
fRet = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// install the object name into the mapping
|
||
|
pMap->iMD = m_MapsInMetabase;
|
||
|
|
||
|
// get the certificate
|
||
|
pData = mbWrap.GetData( szMapPath, MD_MAPCERT, IIS_MD_UT_SERVER, BINARY_METADATA, &cbData );
|
||
|
if ( pData )
|
||
|
{
|
||
|
// set the data into place
|
||
|
pMap->SetCertificate( (PUCHAR)pData, cbData );
|
||
|
// free the buffer
|
||
|
mbWrap.FreeWrapData( pData );
|
||
|
}
|
||
|
|
||
|
// get the NT Account - a string
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
if ( Get11String( &mbWrap, szMapPath, MD_MAPNTACCT, sz) )
|
||
|
{
|
||
|
pMap->SetNTAccount( sz );
|
||
|
}
|
||
|
|
||
|
// get the NT Password
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
if ( Get11String( &mbWrap, szMapPath, MD_MAPNTPWD, sz) )
|
||
|
{
|
||
|
pMap->SetNTPassword( sz );
|
||
|
}
|
||
|
|
||
|
// get the Enabled flag
|
||
|
if ( mbWrap.GetDword( szMapPath, MD_MAPENABLED, IIS_MD_UT_SERVER, &fEnabled) )
|
||
|
pMap->SetMapEnabled( (fEnabled > 0) );
|
||
|
|
||
|
// get the mapping name
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
if ( Get11String( &mbWrap, szMapPath, MD_MAPNAME, sz) )
|
||
|
{
|
||
|
pMap->SetMapName( sz );
|
||
|
}
|
||
|
|
||
|
// add the mapping to the list
|
||
|
FAddMappingToList( pMap );
|
||
|
|
||
|
// increment the index
|
||
|
index++;
|
||
|
}
|
||
|
szEnum.ReleaseBuffer();
|
||
|
|
||
|
// close the mapping object
|
||
|
mbWrap.Close();
|
||
|
|
||
|
// return success
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// IMPORTANT: There is a bug in the mapping namespace extension where, even
|
||
|
// though we are using the unicode metabase interface, all the strings are
|
||
|
// expected to be ansi. This means that we cannont use the wrapmb getstring
|
||
|
// and setstring calls with regards to the nsmp extetention. That is why
|
||
|
// there are these two string wrapper classes that
|
||
|
|
||
|
// also, all the strings used here are IIS_MD_UT_SERVER, so we can elimiate that parameter.
|
||
|
BOOL CMap11Page::Get11String(CWrapMetaBase* pmb, LPCTSTR pszPath, DWORD dwPropID, CString& sz)
|
||
|
{
|
||
|
DWORD dwcb;
|
||
|
BOOL fAnswer = FALSE;
|
||
|
|
||
|
// get the string using the self-allocating get data process
|
||
|
// that that it is cast as ANSI so the sz gets it right.
|
||
|
// NOTE: This must be gotten as an ANSI string!
|
||
|
PCHAR pchar = (PCHAR)pmb->GetData( pszPath, dwPropID, IIS_MD_UT_SERVER, STRING_METADATA, &dwcb );
|
||
|
if ( pchar )
|
||
|
{
|
||
|
// set the answer
|
||
|
sz = pchar;
|
||
|
|
||
|
fAnswer = TRUE;
|
||
|
// clean up
|
||
|
pmb->FreeWrapData( pchar );
|
||
|
}
|
||
|
|
||
|
// return the answer
|
||
|
return fAnswer;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
/* INTRINSA suppress=null_pointers, uninitialized */
|
||
|
BOOL CMap11Page::Set11String(CWrapMetaBase* pmb, LPCTSTR pszPath, DWORD dwPropID, CString& sz, DWORD dwFlags )
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
// Easy. Just set it as data
|
||
|
// Make sure it is set back as an ANSI string though
|
||
|
LPSTR pA = T2A((LPTSTR)(LPCTSTR)sz);
|
||
|
return pmb->SetData( pszPath, dwPropID, IIS_MD_UT_SERVER, STRING_METADATA,
|
||
|
(PVOID)pA, strlen(pA)+1, dwFlags );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// we only need to write out the mappings that have been either changed or added.
|
||
|
|
||
|
// Thoughts on further optimizations: The bare minimum info about where to find
|
||
|
// a mapping in the metabase could be stored in the metabase. Then, the mappings
|
||
|
// would only be loaded when they were added to be edited or displayed in the
|
||
|
// cracked list. The private data for each item in the list would have to have
|
||
|
// some sort of reference to a position in the metabase.
|
||
|
|
||
|
BOOL CMap11Page::FWriteMappings()
|
||
|
{
|
||
|
if ( m_fIsIIS6 )
|
||
|
{
|
||
|
return FWriteMappingsIIS6();
|
||
|
}
|
||
|
|
||
|
BOOL f;
|
||
|
DWORD i,j;
|
||
|
DWORD cMappings;
|
||
|
C11Mapping* pMap;
|
||
|
C11Mapping* pMapTemp;
|
||
|
|
||
|
CString sz;
|
||
|
DWORD dwEnabled;
|
||
|
PUCHAR pCert;
|
||
|
DWORD cbCert;
|
||
|
DWORD iList;
|
||
|
CStrPassword cspTempPassword;
|
||
|
|
||
|
// before messing with the metabase, prepare the strings we will need
|
||
|
CString szTempPath;
|
||
|
CString szBasePath = m_szMBPath + _T("/Cert11");
|
||
|
CString szRelativePath = _T("/Mappings");
|
||
|
CString szObjectPath = szRelativePath + _T('/');
|
||
|
|
||
|
// prepare the base metabase wrapper
|
||
|
CWrapMetaBase mbBase;
|
||
|
f = mbBase.FInit(m_pMB);
|
||
|
if ( !f )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// first, we have to open the Cert11 object. If it doesn't exist
|
||
|
// then we have to add it tothe metabase
|
||
|
if ( !mbBase.Open( szBasePath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
// Cert11 does not exist - open the namespace base and add it
|
||
|
szTempPath = m_szMBPath + _T('/');
|
||
|
if ( !mbBase.Open( szTempPath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE; // serious problems if we can't open the base
|
||
|
}
|
||
|
|
||
|
// add the Cert11 object
|
||
|
szTempPath = _T("Cert11");
|
||
|
f = mbBase.AddObject( szTempPath );
|
||
|
mbBase.Close();
|
||
|
if ( !f )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_CANTADD );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// try again to open the Cert11. Fail if it doesn't work
|
||
|
if ( !mbBase.Open( szBasePath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========
|
||
|
// start by deleting all the mappings in the to-be-deleted list
|
||
|
cMappings = (DWORD)m_rgbDelete.GetSize();
|
||
|
|
||
|
// only bother if there are items waiting to be deleted
|
||
|
if ( cMappings > 0 )
|
||
|
{
|
||
|
// get the count of mappings in the display list
|
||
|
DWORD cList = m_clistctrl_list.GetItemCount();
|
||
|
|
||
|
// sort the mappings, in decending order
|
||
|
for ( i = 0; i < cMappings-1; i++ )
|
||
|
{
|
||
|
pMap = (C11Mapping*)m_rgbDelete[i];
|
||
|
for ( j = i; j < cMappings; j++ )
|
||
|
{
|
||
|
pMapTemp = (C11Mapping*)m_rgbDelete[j];
|
||
|
if ( pMap->iMD < pMapTemp->iMD )
|
||
|
{
|
||
|
m_rgbDelete.SetAt( i, (CObject*)pMapTemp );
|
||
|
m_rgbDelete.SetAt( j, (CObject*)pMap );
|
||
|
pMap = pMapTemp;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// loop the mappings, deleting each from the metabase
|
||
|
for ( i = 0; i < cMappings; i++ )
|
||
|
{
|
||
|
// get the mapping object
|
||
|
pMap = (C11Mapping*)m_rgbDelete[i];
|
||
|
if ( !pMap || (pMap->iMD == NEW_OBJECT) )
|
||
|
continue;
|
||
|
|
||
|
// build the relative path to the object in question.
|
||
|
szObjectPath.Format( _T("%s/%d"), szRelativePath, pMap->iMD );
|
||
|
|
||
|
// delete that mapping's object from the metabase
|
||
|
f = mbBase.DeleteObject( szObjectPath );
|
||
|
|
||
|
// decrement the number of maps in the metabase
|
||
|
m_MapsInMetabase--;
|
||
|
|
||
|
// loop the items in the list, decrementing the index of those
|
||
|
// that are above it. Yes - this is non-optimal, but its what
|
||
|
// has to be done for now
|
||
|
for ( iList = 0; iList < cList; iList++ )
|
||
|
{
|
||
|
pMapTemp = GetMappingInDisplay(iList);
|
||
|
if ( (pMapTemp->iMD > pMap->iMD) && (pMapTemp->iMD != NEW_OBJECT) )
|
||
|
pMapTemp->iMD--;
|
||
|
}
|
||
|
|
||
|
// since we will no longer be needing this mapping, delete it
|
||
|
DeleteMapping( pMap );
|
||
|
}
|
||
|
|
||
|
// reset the to-be-deleted list
|
||
|
m_rgbDelete.RemoveAll();
|
||
|
}
|
||
|
|
||
|
//==========
|
||
|
// get the number mappings in the to-be-saved list
|
||
|
cMappings = (DWORD)m_rgbSave.GetSize();
|
||
|
|
||
|
// loop the mappings, adding each to the metabase
|
||
|
for ( i = 0; i < cMappings; i++ )
|
||
|
{
|
||
|
// get the mapping object
|
||
|
pMap = (C11Mapping*)m_rgbSave[i];
|
||
|
ASSERT( pMap );
|
||
|
|
||
|
// if the object is already in the metabase, just open it.
|
||
|
if ( pMap->iMD != NEW_OBJECT )
|
||
|
{
|
||
|
// build the relative path to the object
|
||
|
szObjectPath.Format( _T("%s/%d"), szRelativePath, pMap->iMD );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// set up the name of the new mapping as one higher
|
||
|
// than the number of mappings in the metabase
|
||
|
pMap->iMD = m_MapsInMetabase + 1;
|
||
|
|
||
|
// build the relative path to the object
|
||
|
szObjectPath.Format( _T("%s/%d"), szRelativePath, pMap->iMD );
|
||
|
|
||
|
// add the mapping object to the base
|
||
|
f = mbBase.AddObject( szObjectPath );
|
||
|
if ( f )
|
||
|
{
|
||
|
// increment the number of maps in the metabase
|
||
|
m_MapsInMetabase++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// write the object's parameters
|
||
|
if ( f )
|
||
|
{
|
||
|
// save the certificate
|
||
|
if ( pMap->GetCertificate(&pCert, &cbCert) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = mbBase.SetData( szObjectPath, MD_MAPCERT, IIS_MD_UT_SERVER, BINARY_METADATA,
|
||
|
pCert, cbCert, METADATA_SECURE | METADATA_INHERIT );
|
||
|
}
|
||
|
|
||
|
// save the NTAccount
|
||
|
if ( pMap->GetNTAccount(sz) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = Set11String(&mbBase, szObjectPath, MD_MAPNTACCT, sz, METADATA_SECURE);
|
||
|
}
|
||
|
|
||
|
// save the password - secure
|
||
|
if ( pMap->GetNTPassword(cspTempPassword) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
CString csTempPassword;
|
||
|
cspTempPassword.CopyTo(csTempPassword);
|
||
|
f = Set11String(&mbBase, szObjectPath, MD_MAPNTPWD, csTempPassword, METADATA_SECURE);
|
||
|
}
|
||
|
|
||
|
// save the map's name
|
||
|
if ( pMap->GetMapName(sz) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = Set11String(&mbBase, szObjectPath, MD_MAPNAME, sz);
|
||
|
}
|
||
|
|
||
|
// save the Enabled flag
|
||
|
// server reads the flag as the value of the dword
|
||
|
if ( pMap->GetMapEnabled(&f) )
|
||
|
{
|
||
|
dwEnabled = (DWORD)f;
|
||
|
f = mbBase.SetDword( szObjectPath, MD_MAPENABLED, IIS_MD_UT_SERVER, dwEnabled );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close the base object
|
||
|
mbBase.Close();
|
||
|
|
||
|
// save the metabase
|
||
|
mbBase.Save();
|
||
|
|
||
|
// reset the to-be-saved list
|
||
|
m_rgbSave.RemoveAll();
|
||
|
|
||
|
// return success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
BOOL CMap11Page::FReadMappingsIIS6()
|
||
|
{
|
||
|
BOOL f;
|
||
|
C11Mapping* pMap;
|
||
|
DWORD cbData;
|
||
|
PVOID pData;
|
||
|
DWORD fEnabled;
|
||
|
WCHAR * pChar = NULL;
|
||
|
BOOL fRet = TRUE;
|
||
|
|
||
|
// before messing with the metabase, prepare the strings we will need
|
||
|
CString szBasePath = m_szMBPath + _T('/');
|
||
|
CString szRelativePath = MB_EXTEND_KEY_MAPS;
|
||
|
CString szObjectPath = m_szMBPath + _T('/') + szRelativePath;
|
||
|
CString szMapPath;
|
||
|
|
||
|
// prepare the metabase wrappers
|
||
|
CWrapMetaBase mbWrap;
|
||
|
f = mbWrap.FInit(m_pMB);
|
||
|
|
||
|
// open the base object
|
||
|
f = mbWrap.Open( szObjectPath, METADATA_PERMISSION_READ );
|
||
|
ASSERT( f );
|
||
|
if ( !f )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// for now, at least, we are reading in all the mappings. reset the m_nNamer counter
|
||
|
// so that we end up with a somewhat accurate reading of the last number-name in the list.
|
||
|
m_MapsInMetabase = 0;
|
||
|
|
||
|
// Loop the items in the metabase, adding each to the napper.
|
||
|
DWORD index = 0;
|
||
|
CString szEnum;
|
||
|
while ( mbWrap.EnumObjects(_T(""), szEnum.GetBuffer(MAX_PATH*sizeof(WCHAR)),
|
||
|
MAX_PATH*sizeof(WCHAR), index) )
|
||
|
{
|
||
|
szEnum.ReleaseBuffer();
|
||
|
|
||
|
// keep track of the number of mappings we encounter
|
||
|
m_MapsInMetabase++;
|
||
|
|
||
|
// build the final mapping object path
|
||
|
szMapPath.Format( _T("/%s"), szEnum );
|
||
|
|
||
|
// make a new mapping object
|
||
|
pMap = PNewMapping();
|
||
|
|
||
|
if (pMap == NULL) {
|
||
|
SetLastError(E_OUTOFMEMORY);
|
||
|
fRet = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// install the object name into the mapping
|
||
|
pMap->SetNodeName( szEnum );
|
||
|
|
||
|
// get the certificate
|
||
|
pData = mbWrap.GetData( szMapPath, MD_MAPCERT, IIS_MD_UT_SERVER, BINARY_METADATA, &cbData );
|
||
|
if ( pData )
|
||
|
{
|
||
|
// set the data into place
|
||
|
pMap->SetCertificate( (PUCHAR)pData, cbData );
|
||
|
// free the buffer
|
||
|
mbWrap.FreeWrapData( pData );
|
||
|
}
|
||
|
|
||
|
// get the NT Account - a string
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
|
||
|
if ( pChar = (WCHAR *) mbWrap.GetData( szMapPath, MD_MAPNTACCT, IIS_MD_UT_SERVER, STRING_METADATA, &cbData ) )
|
||
|
{
|
||
|
pMap->SetNTAccount( pChar );
|
||
|
// free the buffer
|
||
|
mbWrap.FreeWrapData( pChar );
|
||
|
}
|
||
|
|
||
|
// get the NT Password
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
if ( pChar = (WCHAR *) mbWrap.GetData( szMapPath, MD_MAPNTPWD, IIS_MD_UT_SERVER, STRING_METADATA, &cbData ) )
|
||
|
{
|
||
|
pMap->SetNTPassword( pChar );
|
||
|
// free the buffer
|
||
|
mbWrap.FreeWrapData( pChar );
|
||
|
}
|
||
|
|
||
|
|
||
|
// get the Enabled flag
|
||
|
if ( mbWrap.GetDword( szMapPath, MD_MAPENABLED, IIS_MD_UT_SERVER, &fEnabled) )
|
||
|
pMap->SetMapEnabled( (fEnabled > 0) );
|
||
|
|
||
|
// get the mapping name
|
||
|
cbData = METADATA_MAX_NAME_LEN;
|
||
|
if ( pChar = (WCHAR *) mbWrap.GetData( szMapPath, MD_MAPNAME, IIS_MD_UT_SERVER, STRING_METADATA, &cbData ) )
|
||
|
{
|
||
|
pMap->SetMapName( pChar );
|
||
|
// free the buffer
|
||
|
mbWrap.FreeWrapData( pChar );
|
||
|
}
|
||
|
|
||
|
// add the mapping to the list
|
||
|
FAddMappingToList( pMap );
|
||
|
|
||
|
// increment the index
|
||
|
index++;
|
||
|
}
|
||
|
szEnum.ReleaseBuffer();
|
||
|
|
||
|
// close the mapping object
|
||
|
mbWrap.Close();
|
||
|
|
||
|
// return success
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// we only need to write out the mappings that have been either changed or added.
|
||
|
// This function is based on FWriteMappings() function. Minimum changes were made
|
||
|
// to support IIS6 format of IIS 1to1 client certificate mappings
|
||
|
|
||
|
|
||
|
BOOL CMap11Page::FWriteMappingsIIS6()
|
||
|
{
|
||
|
BOOL f;
|
||
|
DWORD i,j;
|
||
|
DWORD cMappings;
|
||
|
C11Mapping* pMap;
|
||
|
C11Mapping* pMapTemp;
|
||
|
|
||
|
CString sz;
|
||
|
DWORD dwEnabled;
|
||
|
PUCHAR pCert;
|
||
|
DWORD cbCert;
|
||
|
DWORD iList;
|
||
|
CStrPassword cspTempPassword;
|
||
|
|
||
|
// before messing with the metabase, prepare the strings we will need
|
||
|
CString szTempPath;
|
||
|
CString szBasePath = m_szMBPath + _T('/')+ MB_EXTEND_KEY_MAPS;
|
||
|
CString szObjectPath = "";
|
||
|
|
||
|
// prepare the base metabase wrapper
|
||
|
CWrapMetaBase mbBase;
|
||
|
f = mbBase.FInit(m_pMB);
|
||
|
if ( !f )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// first, we have to open the Cert11Mappings object. If it doesn't exist
|
||
|
// then we have to add it to the metabase
|
||
|
if ( !mbBase.Open( szBasePath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
// Cert11Mappings does not exist - open the namespace base and add it
|
||
|
szTempPath = m_szMBPath + _T('/');
|
||
|
if ( !mbBase.Open( szTempPath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE; // serious problems if we can't open the base
|
||
|
}
|
||
|
|
||
|
// add the Cert11Mappings object
|
||
|
szTempPath = MB_EXTEND_KEY_MAPS;
|
||
|
f = mbBase.AddObject( szTempPath );
|
||
|
mbBase.Close();
|
||
|
if ( !f )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_CANTADD );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// try again to open the Cert11Mappings. Fail if it doesn't work
|
||
|
if ( !mbBase.Open( szBasePath, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) )
|
||
|
{
|
||
|
AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========
|
||
|
// start by deleting all the mappings in the to-be-deleted list
|
||
|
cMappings = (DWORD)m_rgbDelete.GetSize();
|
||
|
|
||
|
// only bother if there are items waiting to be deleted
|
||
|
if ( cMappings > 0 )
|
||
|
{
|
||
|
// get the count of mappings in the display list
|
||
|
DWORD cList = m_clistctrl_list.GetItemCount();
|
||
|
|
||
|
|
||
|
// loop the mappings, deleting each from the metabase
|
||
|
for ( i = 0; i < cMappings; i++ )
|
||
|
{
|
||
|
// get the mapping object
|
||
|
pMap = (C11Mapping*)m_rgbDelete[i];
|
||
|
if ( !pMap || (pMap->QueryNodeName() == "" /*NEW_OBJECT*/) )
|
||
|
continue;
|
||
|
|
||
|
// build the relative path to the object in question.
|
||
|
szObjectPath.Format( _T("%s"), pMap->QueryNodeName() );
|
||
|
|
||
|
// delete that mapping's object from the metabase
|
||
|
f = mbBase.DeleteObject( szObjectPath );
|
||
|
|
||
|
// decrement the number of maps in the metabase
|
||
|
m_MapsInMetabase--;
|
||
|
|
||
|
// since we will no longer be needing this mapping, delete it
|
||
|
DeleteMapping( pMap );
|
||
|
}
|
||
|
|
||
|
// reset the to-be-deleted list
|
||
|
m_rgbDelete.RemoveAll();
|
||
|
}
|
||
|
|
||
|
//==========
|
||
|
// get the number mappings in the to-be-saved list
|
||
|
cMappings = (DWORD)m_rgbSave.GetSize();
|
||
|
|
||
|
// loop the mappings, adding each to the metabase
|
||
|
for ( i = 0; i < cMappings; i++ )
|
||
|
{
|
||
|
// get the mapping object
|
||
|
pMap = (C11Mapping*)m_rgbSave[i];
|
||
|
ASSERT( pMap );
|
||
|
|
||
|
// if the object is already in the metabase, just open it.
|
||
|
if ( pMap->QueryNodeName() != "" /*NEW_OBJECT*/ )
|
||
|
{
|
||
|
// build the relative path to the object
|
||
|
szObjectPath.Format( _T("%s"), pMap->QueryNodeName() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// set up the name of the new mapping node to be equal
|
||
|
// to SHA1 hash of the certificate
|
||
|
|
||
|
pMap->SetNodeName( pMap->QueryCertHash() );
|
||
|
// build the relative path to the object
|
||
|
szObjectPath.Format( _T("%s"), pMap->QueryNodeName() );
|
||
|
|
||
|
if ( !szObjectPath.IsEmpty() )
|
||
|
{
|
||
|
// add the mapping object to the base
|
||
|
f = mbBase.AddObject( szObjectPath );
|
||
|
if ( f )
|
||
|
{
|
||
|
// increment the number of maps in the metabase
|
||
|
m_MapsInMetabase++;
|
||
|
}
|
||
|
// reset error of Adding object
|
||
|
// most likely node already exists
|
||
|
// CODEWORK: 04/08/02 jaroslad - this function is very optimistic
|
||
|
// it ignores errors that happen during process of saving mapping data
|
||
|
f = TRUE;
|
||
|
}
|
||
|
}
|
||
|
// write the object's parameters
|
||
|
if ( f && !szObjectPath.IsEmpty() )
|
||
|
{
|
||
|
// save the certificate
|
||
|
if ( pMap->GetCertificate(&pCert, &cbCert) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = mbBase.SetData( szObjectPath, MD_MAPCERT, IIS_MD_UT_SERVER, BINARY_METADATA,
|
||
|
pCert, cbCert, 0 );
|
||
|
}
|
||
|
|
||
|
// save the NTAccount
|
||
|
if ( pMap->GetNTAccount(sz) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = mbBase.SetString(szObjectPath, MD_MAPNTACCT, IIS_MD_UT_SERVER, sz, 0 );
|
||
|
}
|
||
|
|
||
|
// save the password - secure
|
||
|
if ( pMap->GetNTPassword(cspTempPassword) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
CString csTempPassword;
|
||
|
cspTempPassword.CopyTo(csTempPassword);
|
||
|
f = mbBase.SetString(szObjectPath, MD_MAPNTPWD, IIS_MD_UT_SERVER,
|
||
|
csTempPassword, METADATA_SECURE);
|
||
|
}
|
||
|
|
||
|
// save the map's name
|
||
|
if ( pMap->GetMapName(sz) )
|
||
|
{
|
||
|
// set the data into place in the object
|
||
|
f = mbBase.SetString(szObjectPath, MD_MAPNAME, IIS_MD_UT_SERVER, sz, 0);
|
||
|
}
|
||
|
|
||
|
// save the Enabled flag
|
||
|
// server reads the flag as the value of the dword
|
||
|
if ( pMap->GetMapEnabled(&f) )
|
||
|
{
|
||
|
dwEnabled = (DWORD)f;
|
||
|
f = mbBase.SetDword( szObjectPath, MD_MAPENABLED, IIS_MD_UT_SERVER, dwEnabled, 0 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close the base object
|
||
|
mbBase.Close();
|
||
|
|
||
|
// save the metabase
|
||
|
mbBase.Save();
|
||
|
|
||
|
// reset the to-be-saved list
|
||
|
m_rgbSave.RemoveAll();
|
||
|
|
||
|
// return success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
C11Mapping* CMap11Page::PNewMapping()
|
||
|
{
|
||
|
// the way it should be
|
||
|
return new C11Mapping();
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void CMap11Page::DeleteMapping( C11Mapping* pMap )
|
||
|
{
|
||
|
// the way it should be
|
||
|
delete pMap;
|
||
|
}
|