|
|
// 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
}
|