windows-nt/Source/XPSP1/NT/inetsrv/iis/ui/itools/keyring/nkchseca.cpp
2020-09-26 16:20:57 +08:00

519 lines
14 KiB
C++

// NKChseCA.cpp : implementation file
//
#include "stdafx.h"
#include "keyring.h"
#include "NKChseCA.h"
#include "certcli.h"
#include "OnlnAuth.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNKPages dialog
CNKPages::CNKPages( UINT nIDCaption )
: CPropertyPage( nIDCaption )
{
}
// resource strings
#define SZ_PARAMETERS "Software\\Microsoft\\Keyring\\Parameters"
//---------------------------------------------------------------------------
void CNKPages::OnFinish()
{}
//---------------------------------------------------------------------------
// returns TRUE if it was able get the value
BOOL CNKPages::FGetStoredString( CString &sz, LPCSTR szValueName )
{
// start by opening the key
DWORD err;
HKEY hKey;
err = RegOpenKeyEx(
HKEY_CURRENT_USER, // handle of open key
SZ_PARAMETERS, // address of name of subkey to open
0, // reserved
KEY_READ, // security access mask
&hKey // address of handle of open key
);
ASSERT(err == ERROR_SUCCESS);
if ( err != ERROR_SUCCESS )
return FALSE;
// prepare to get the value
LPTSTR pszValue;
pszValue = sz.GetBuffer( MAX_PATH+1 );
// get the value of the item in the key
DWORD type;
DWORD cbData = MAX_PATH;
err = RegQueryValueEx(
hKey, // handle of key to query
szValueName, // name of value to query
NULL, // reserved
&type, // address of buffer for value type
(PUCHAR)pszValue, // address of data buffer
&cbData // address of data buffer size
);
// release the string so we can use it
sz.ReleaseBuffer();
// all done, close the key before leaving
if ( hKey )
RegCloseKey( hKey );
// check to see if we got the value
if ( err != ERROR_SUCCESS )
return FALSE;
// return any errors
return TRUE;
}
//---------------------------------------------------------------------------
void CNKPages::SetStoredString( CString &sz, LPCSTR szValueName )
{
// start by opening the key
DWORD err;
HKEY hKey;
err = RegOpenKeyEx(
HKEY_CURRENT_USER, // handle of open key
SZ_PARAMETERS, // address of name of subkey to open
0, // reserved
KEY_ALL_ACCESS, // security access mask
&hKey // address of handle of open key
);
ASSERT(err == ERROR_SUCCESS);
if ( err != ERROR_SUCCESS )
return;
// set the value of the item in the key
err = RegSetValueEx
(
hKey, // handle of key to query
szValueName, // name of value to query
NULL, // reserved
REG_SZ, // address of buffer for value type
(PUCHAR)(LPCTSTR)sz, // address of data buffer
sz.GetLength() + 1 // data buffer size
);
// all done, close the key before leaving
if ( hKey )
RegCloseKey( hKey );
}
/////////////////////////////////////////////////////////////////////////////
// CNKChooseCA dialog
CNKChooseCA::CNKChooseCA(CWnd* pParent /*=NULL*/)
: CNKPages(CNKChooseCA::IDD)
{
//{{AFX_DATA_INIT(CNKChooseCA)
m_nkca_sz_file = _T("");
m_nkca_radio = -1;
m_nkca_sz_online = _T("");
//}}AFX_DATA_INIT
}
void CNKChooseCA::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNKChooseCA)
DDX_Control(pDX, IDC_NK_CA_ONLINE, m_nkca_ccombo_online);
DDX_Control(pDX, IDC_NK_CA_FILE, m_nkca_cedit_file);
DDX_Control(pDX, IDC_NK_CA_BROWSE, m_nkca_btn_browse);
DDX_Control(pDX, IDC_BK_CA_PROPERTIES, m_nkca_btn_properties);
DDX_Text(pDX, IDC_NK_CA_FILE, m_nkca_sz_file);
DDX_Radio(pDX, IDC_NK_CA_FILE_RADIO, m_nkca_radio);
DDX_CBString(pDX, IDC_NK_CA_ONLINE, m_nkca_sz_online);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CNKChooseCA, CDialog)
//{{AFX_MSG_MAP(CNKChooseCA)
ON_BN_CLICKED(IDC_NK_CA_ONLINE_RADIO, OnNkCaOnlineRadio)
ON_BN_CLICKED(IDC_NK_CA_FILE_RADIO, OnNkCaFileRadio)
ON_BN_CLICKED(IDC_NK_CA_BROWSE, OnNkCaBrowse)
ON_BN_CLICKED(IDC_BK_CA_PROPERTIES, OnBkCaProperties)
ON_CBN_SELCHANGE(IDC_NK_CA_ONLINE, OnSelchangeNkCaOnline)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#define SZ_TARGET_CA "TARGET_CA"
#define SZ_FILE_BASED "FILE_BASED"
//---------------------------------------------------------------------------
void CNKChooseCA::OnFinish()
{
try
{
CString szCA;
// if we are targeting a manual/remote ca, loat the "FileBased" string
if ( m_nkca_radio == 0 )
szCA = SZ_FILE_BASED;
// othewise, it should be the name of the chosen online ca
else
szCA = m_nkca_sz_online;
// now store that value away
SetStoredString( szCA, SZ_TARGET_CA );
}
catch (CException e)
{
}
}
//----------------------------------------------------------------
BOOL CNKChooseCA::OnInitDialog( )
{
// load the default file name
m_nkca_sz_file.LoadString( IDS_DEFAULT_REQUEST_FILE );
// default to targeting the request towards a file
m_nkca_radio = 0;
// call the base oninit
CPropertyPage::OnInitDialog();
// Initialze the list of available online authorties. Record how many there were
DWORD numCA = InitOnlineList();
// now get the default authority used from last time
CString szLastCA;
BOOL fGotLastCA = FGetStoredString( szLastCA, SZ_TARGET_CA );
// if there were no online authorities, disable that option
if ( numCA == 0 )
GetDlgItem(IDC_NK_CA_ONLINE_RADIO)->EnableWindow(FALSE);
// initialze to the appropriate item
if ( (numCA == 0) || (szLastCA == SZ_FILE_BASED) )
{
// by default, select the first item in the list
m_nkca_ccombo_online.SetCurSel(0);
// set up windows
m_nkca_ccombo_online.EnableWindow( FALSE );
m_nkca_btn_properties.EnableWindow( FALSE );
// finish getting ready by calling OnNkCaFileRadio
OnNkCaFileRadio();
}
else
// there are items in the online dropdown
{
// by default, select the first item in the list
m_nkca_ccombo_online.SetCurSel(0);
// if we retrieved a default from last time, select that
if ( fGotLastCA )
m_nkca_ccombo_online.SelectString( -1, szLastCA );
// since there are online authorities available, default to them
m_nkca_radio = 1;
UpdateData( FALSE );
// finish getting ready by calling OnNkCaOnlineRadio
OnNkCaOnlineRadio();
}
// return 0 to say we set the default item
// return 1 to just select the default default item
return 1;
}
//----------------------------------------------------------------
// returns the number of items in the dropdown
DWORD CNKChooseCA::GetSelectedCA( CString &szCA)
{
ASSERT( m_nkca_radio == 1 );
// this becomes easy
szCA = m_nkca_sz_online;
return ERROR_SUCCESS;
/*
// now load up the registry key
CString szRegKeyName;
szRegKeyName.LoadString( IDS_CA_LOCATION );
// and open the key
DWORD err;
HKEY hKey;
err = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // handle of open key
szRegKeyName, // address of name of subkey to open
0, // reserved
KEY_READ, // security access mask
&hKey // address of handle of open key
);
ASSERT(err == ERROR_SUCCESS);
if ( err != ERROR_SUCCESS )
{
szGUID.Empty();
return err;
}
// prepare to get the name
LPTSTR pGUID;
pGUID = szGUID.GetBuffer( MAX_PATH+1 );
// get the value of the item in the key
DWORD type;
DWORD cbData = MAX_PATH;
err = RegQueryValueEx(
hKey, // handle of key to query
m_nkca_sz_online, // name of value to query
NULL, // reserved
&type, // address of buffer for value type
(PUCHAR)pGUID, // address of data buffer
&cbData // address of data buffer size
);
// release the string so we can use it
szGUID.ReleaseBuffer();
// all done, close the key before leaving
if ( hKey )
RegCloseKey( hKey );
ASSERT(err == ERROR_SUCCESS);
if ( err != ERROR_SUCCESS )
szGUID.Empty();
// return any errors
return err;
*/
}
//----------------------------------------------------------------
// returns the number of items in the dropdown
WORD CNKChooseCA::InitOnlineList()
{
DWORD err;
CString szRegKeyName;
HKEY hKey;
DWORD cbCAName = MAX_PATH+1;
CString szCAName;
LPTSTR pCAName;
FILETIME filetime;
WORD i = 0;
CWaitCursor waitcursor;
// load the registry key name
szRegKeyName.LoadString( IDS_CA_LOCATION );
// open the registry key, if it exists
err = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // handle of open key
szRegKeyName, // address of name of subkey to open
0, // reserved
KEY_READ, // security access mask
&hKey // address of handle of open key
);
// if we did not open the key for any reason (say... it doesn't exist)
// then leave right away
if ( err != ERROR_SUCCESS )
return FALSE;
// set up the buffers
pCAName = szCAName.GetBuffer( MAX_PATH+1 );
// each onling authority sets up a key under "Certificate Authorities"
// the title of that key is the title that shows up in the list. The
// key itself contains the CLSIDs of the necessary class factories to
// instantiate the com objects that we need to do all this stuff
// we opened the key. Now we enumerate the values and reconnect the machines
while ( RegEnumKeyEx(hKey, i, pCAName,
&cbCAName, NULL, NULL,
0, &filetime) == ERROR_SUCCESS )
{
// add the name of the certificate authority to the list
m_nkca_ccombo_online.AddString( pCAName );
// increment the number found counter
i++;
cbCAName = MAX_PATH+1;
}
// release the name buffers
szCAName.ReleaseBuffer();
// all done, close the key before leaving
RegCloseKey( hKey );
// return how many we found
return i;
}
//----------------------------------------------------------------
BOOL CNKChooseCA::OnSetActive()
{
CString sz;
sz.LoadString(IDS_TITLE_CREATE_WIZ);
m_pPropSheet->SetTitle( sz );
m_pPropSheet->SetWizardButtons( PSWIZB_NEXT );
return CPropertyPage::OnSetActive();
}
/////////////////////////////////////////////////////////////////////////////
// CNKChooseCA message handlers
//----------------------------------------------------------------
BOOL CNKChooseCA::OnKillActive()
{
UpdateData( TRUE );
// if the target is an online certificate authority - we don't have to bother
// with checking the file.
if ( m_nkca_radio == 1 )
return TRUE;
// get the attributes of the specified file
DWORD dwAttrib = GetFileAttributes( m_nkca_sz_file );
// we actually want the function to fail - then the file doesn't exist
if ( dwAttrib == 0xFFFFFFFF )
return TRUE;
// if the name is a directory, or system file, don't allow it
if ( (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) || (dwAttrib & FILE_ATTRIBUTE_SYSTEM) )
{
AfxMessageBox( IDS_BAD_FILE_NAME );
// set the focus back to the file name
m_nkca_cedit_file.SetFocus();
return FALSE;
}
// ah. Well the file already exits. Warn the user
CString szWarning;
AfxFormatString1( szWarning, IDS_FILE_EXISTS, m_nkca_sz_file );
if ( AfxMessageBox( szWarning, MB_YESNO ) == IDYES )
return TRUE;
// set the focus back to the file name
m_nkca_cedit_file.SetFocus();
return FALSE;
}
//----------------------------------------------------------------
void CNKChooseCA::OnNkCaFileRadio()
{
// enable the file related items
m_nkca_cedit_file.EnableWindow( TRUE );
m_nkca_btn_browse.EnableWindow( TRUE );
// disable the online related items
m_nkca_ccombo_online.EnableWindow( FALSE );
m_nkca_btn_properties.EnableWindow( FALSE );
}
//----------------------------------------------------------------
void CNKChooseCA::OnNkCaOnlineRadio()
{
// disable the file related items
m_nkca_cedit_file.EnableWindow( FALSE );
m_nkca_btn_browse.EnableWindow( FALSE );
// enable the online related items
m_nkca_ccombo_online.EnableWindow( TRUE );
m_nkca_btn_properties.EnableWindow( TRUE );
}
//----------------------------------------------------------------
void CNKChooseCA::OnNkCaBrowse()
{
UpdateData( TRUE );
CFileDialog cfdlg(FALSE, _T("txt"), m_nkca_sz_file);
CString szFilter;
WORD i = 0;
LPSTR lpszBuffer;
// prepare the filter string
szFilter.LoadString( IDS_CERTIFICATE_FILTER );
// replace the "!" characters with nulls
lpszBuffer = szFilter.GetBuffer(MAX_PATH+1);
while( lpszBuffer[i] )
{
if ( lpszBuffer[i] == _T('!') )
lpszBuffer[i] = _T('\0'); // yes, set \0 on purpose
i++;
}
// prep the dialog
cfdlg.m_ofn.lpstrFilter = lpszBuffer;
// we prompt for the overwrite when the "Next" button is pushed
cfdlg.m_ofn.Flags &= ~OFN_OVERWRITEPROMPT;
// run the dialog
if ( cfdlg.DoModal() == IDOK )
{
// get the path for the file from the dialog
m_nkca_sz_file = cfdlg.GetPathName();
UpdateData( FALSE );
}
// release the buffer in the filter string
szFilter.ReleaseBuffer(60);
}
//----------------------------------------------------------------
void CNKChooseCA::OnBkCaProperties()
{
HRESULT hErr;
// get the string for the CA
CString szCA;
UpdateData( TRUE );
if ( GetSelectedCA(szCA) != ERROR_SUCCESS )
{
AfxMessageBox( IDS_LOAD_CA_ERR );
return;
}
// prepare the authority object
COnlineAuthority authority;
if ( !authority.FInitSZ(szCA) )
{
AfxMessageBox( IDS_CA_NO_INTERFACE );
return;
}
// run the UI
BSTR bstr;
hErr = authority.pIConfig->GetConfig(0, &bstr);
// save the config string
if ( SUCCEEDED(hErr ) )
authority.FSetPropertyString( bstr );
// clean up
SysFreeString( bstr );
}
//----------------------------------------------------------------
void CNKChooseCA::OnSelchangeNkCaOnline()
{
// check if there are stored preferences for the selected ca server
}