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.
3578 lines
94 KiB
3578 lines
94 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows NT
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1995 - 1998
|
|
//
|
|
// File: cepsetup.cpp
|
|
//
|
|
// Contents: The setup code for MSCEP
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "global.hxx"
|
|
#include <dbgdef.h>
|
|
#include "objsel.h"
|
|
#include "setuputil.h"
|
|
#include "cepsetup.h"
|
|
#include "resource.h"
|
|
#include "wincred.h"
|
|
#include "netlib.h"
|
|
#include "dsrole.h"
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Global data
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
|
|
HMODULE g_hModule=NULL;
|
|
UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
|
|
|
|
//-----------------------------------------------------------------------
|
|
//CN has to be the 1st item and O the third in the following list and C is the last item. No other requirements for
|
|
//the order
|
|
//-----------------------------------------------------------------------
|
|
|
|
CEP_ENROLL_INFO g_rgRAEnrollInfo[RA_INFO_COUNT]=
|
|
{L"CN=", IDC_ENROLL_NAME,
|
|
L"E=", IDC_ENROLL_EMAIL,
|
|
L"O=", IDC_ENROLL_COMPANY,
|
|
L"OU=", IDC_ENROLL_DEPARTMENT,
|
|
L"L=", IDC_ENROLL_CITY,
|
|
L"S=", IDC_ENROLL_STATE,
|
|
L"C=", IDC_ENROLL_COUNTRY,
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//the key length table
|
|
//-----------------------------------------------------------------------
|
|
DWORD g_rgdwKeyLength[] =
|
|
{
|
|
512,
|
|
1024,
|
|
2048,
|
|
4096,
|
|
};
|
|
|
|
DWORD g_dwKeyLengthCount=sizeof(g_rgdwKeyLength)/sizeof(g_rgdwKeyLength[0]);
|
|
|
|
DWORD g_rgdwSmallKeyLength[] =
|
|
{
|
|
128,
|
|
256,
|
|
512,
|
|
1024,
|
|
};
|
|
|
|
DWORD g_dwSmallKeyLengthCount=sizeof(g_rgdwSmallKeyLength)/sizeof(g_rgdwSmallKeyLength[0]);
|
|
|
|
//the list of possible default key lenght in the order of preference
|
|
DWORD g_rgdwDefaultKey[] =
|
|
{
|
|
1024,
|
|
2048,
|
|
512,
|
|
256,
|
|
4096,
|
|
128
|
|
};
|
|
|
|
DWORD g_dwDefaultKeyCount=sizeof(g_rgdwDefaultKey)/sizeof(g_rgdwDefaultKey[0]);
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
//The winProc for each of the setup wizard page
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Welcome
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//App_ID
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_App_ID(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
|
|
|
|
//by default, we use local machine account
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_CHECKED, 0);
|
|
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_UNCHECKED, 0);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_APP_ID_RADIO1:
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_CHECKED, 0);
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_UNCHECKED, 0);
|
|
break;
|
|
|
|
case IDC_APP_ID_RADIO2:
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_UNCHECKED, 0);
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_CHECKED, 0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//check for the application identity options
|
|
if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_APP_ID_RADIO1, BM_GETCHECK, 0, 0))
|
|
{
|
|
pCEPWizardInfo->fLocalSystem=TRUE;
|
|
|
|
//skip the account page and goes to the challege page directly
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CHALLENGE);
|
|
}
|
|
else
|
|
{
|
|
pCEPWizardInfo->fLocalSystem=FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Account
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_Account(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
WCHAR wszText[MAX_STRING_SIZE];
|
|
int idsText=IDS_ACCOUNT_INTRO_STD;
|
|
int idsErr=0;
|
|
DWORD dwChar=0;
|
|
DWORD dwDomainChar=0;
|
|
DWORD dwWinStatus=0;
|
|
WCHAR wszUser[CREDUI_MAX_USERNAME_LENGTH+1];
|
|
WCHAR wszDomain[CREDUI_MAX_USERNAME_LENGTH+1];
|
|
HRESULT hr=S_OK;
|
|
int idsHrErr=0;
|
|
BOOL fMember=FALSE;
|
|
SID_NAME_USE SidName;
|
|
PRIVILEGE_SET ps;
|
|
DWORD dwPSSize=0;
|
|
DWORD dwSize=0;
|
|
BOOL fAccessAllowed = FALSE;
|
|
DWORD grantAccess=0;
|
|
GENERIC_MAPPING GenericMapping={
|
|
ACTRL_DS_OPEN | ACTRL_DS_LIST | ACTRL_DS_SELF | ACTRL_DS_READ_PROP,
|
|
ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
|
|
ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
|
|
ACTRL_DS_OPEN | ACTRL_DS_LIST | ACTRL_DS_SELF | ACTRL_DS_READ_PROP | ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
|
|
};
|
|
|
|
|
|
LPWSTR pwszObjectPicker=NULL;
|
|
LPWSTR pwszConfirm=NULL;
|
|
LPWSTR pwszAccount=NULL;
|
|
LPWSTR pwszIIS=NULL; //"xiaohs4\IIS_WPG"
|
|
LPWSTR pwszDomain=NULL;
|
|
LPWSTR pwszComputerName=NULL;
|
|
PSID pSidIIS=NULL;
|
|
HCERTTYPE hCertType=NULL;
|
|
PSECURITY_DESCRIPTOR pCertTypeSD=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
|
|
|
|
//update the intro statement based on the type of the CA
|
|
if(pCEPWizardInfo->fEnterpriseCA)
|
|
idsText=IDS_ACCOUNT_INTRO_ENT;
|
|
|
|
if(LoadStringU(g_hModule, idsText, wszText, MAX_STRING_SIZE))
|
|
{
|
|
SetDlgItemTextU(hwndDlg, IDC_ACCOUNT_INTRO, wszText);
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
//user wants to browse for the account name
|
|
if(LOWORD(wParam) == IDC_ACCOUNT_BROWSE)
|
|
{
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(CEPGetAccountNameFromPicker(hwndDlg,
|
|
pCEPWizardInfo->pIDsObjectPicker,
|
|
&pwszObjectPicker))
|
|
{
|
|
//set the account name in the edit box
|
|
SetDlgItemTextU(hwndDlg, IDC_ACCOUNT_NAME, pwszObjectPicker);
|
|
free(pwszObjectPicker);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//free the information
|
|
if(pCEPWizardInfo->pwszUserName)
|
|
{
|
|
free(pCEPWizardInfo->pwszUserName);
|
|
pCEPWizardInfo->pwszUserName=NULL;
|
|
}
|
|
|
|
if(pCEPWizardInfo->pwszPassword)
|
|
{
|
|
SecureZeroMemory(pCEPWizardInfo->pwszPassword, sizeof(WCHAR) * wcslen(pCEPWizardInfo->pwszPassword));
|
|
free(pCEPWizardInfo->pwszPassword);
|
|
pCEPWizardInfo->pwszPassword=NULL;
|
|
}
|
|
|
|
if(pCEPWizardInfo->hAccountToken)
|
|
{
|
|
CloseHandle(pCEPWizardInfo->hAccountToken);
|
|
pCEPWizardInfo->hAccountToken=NULL;
|
|
}
|
|
|
|
//get the account name
|
|
if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_NAME, WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
idsErr=IDS_ACCOUNT_EMPTY;
|
|
goto Account_Done;
|
|
}
|
|
|
|
pCEPWizardInfo->pwszUserName=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL==(pCEPWizardInfo->pwszUserName))
|
|
goto Account_Done;
|
|
|
|
GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_NAME, pCEPWizardInfo->pwszUserName, dwChar+1);
|
|
|
|
//get the password
|
|
if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_PASSWORD, WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
idsErr=IDS_PASSWORD_EMPTY;
|
|
goto Account_Done;
|
|
}
|
|
|
|
pCEPWizardInfo->pwszPassword=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL==(pCEPWizardInfo->pwszPassword))
|
|
goto Account_Done;
|
|
|
|
*(pCEPWizardInfo->pwszPassword)=L'\0';
|
|
|
|
GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_PASSWORD, pCEPWizardInfo->pwszPassword, dwChar+1);
|
|
|
|
//get the confirm
|
|
if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_CONFIRM, WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
idsErr=IDS_PASSWORD_NO_MATCH;
|
|
goto Account_Done;
|
|
}
|
|
|
|
pwszConfirm=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL==pwszConfirm)
|
|
goto Account_Done;
|
|
|
|
GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_CONFIRM, pwszConfirm, dwChar+1);
|
|
|
|
//Verify the password match
|
|
if(0 != wcscmp(pwszConfirm, pCEPWizardInfo->pwszPassword))
|
|
{
|
|
idsErr=IDS_PASSWORD_NO_MATCH;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//Verify the user name are correctly formatted
|
|
wszDomain[0]=L'\0';
|
|
|
|
if(NO_ERROR != CredUIParseUserNameW(
|
|
pCEPWizardInfo->pwszUserName,
|
|
wszUser,
|
|
sizeof(wszUser)/sizeof(WCHAR),
|
|
wszDomain,
|
|
sizeof(wszDomain)/sizeof(WCHAR)))
|
|
{
|
|
idsErr=IDS_INVALID_NAME;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//Verify the account does exist. Obtain the account's token
|
|
//Interactive logon is required on a non-dc machine
|
|
if(FALSE == pCEPWizardInfo->fDC)
|
|
{
|
|
if(!LogonUserW(
|
|
wszUser,
|
|
wszDomain,
|
|
pCEPWizardInfo->pwszPassword,
|
|
LOGON32_LOGON_INTERACTIVE,
|
|
LOGON32_PROVIDER_DEFAULT,
|
|
&(pCEPWizardInfo->hAccountToken)))
|
|
{
|
|
idsHrErr=IDS_FAIL_LOGON_USER;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//do a network logon to obtain the impersonation handle
|
|
if(pCEPWizardInfo->hAccountToken)
|
|
{
|
|
CloseHandle(pCEPWizardInfo->hAccountToken);
|
|
pCEPWizardInfo->hAccountToken=NULL;
|
|
}
|
|
}
|
|
|
|
//network logon to obtain the token
|
|
if(!LogonUserW(
|
|
wszUser,
|
|
wszDomain,
|
|
pCEPWizardInfo->pwszPassword,
|
|
LOGON32_LOGON_NETWORK,
|
|
LOGON32_PROVIDER_DEFAULT,
|
|
&(pCEPWizardInfo->hAccountToken)))
|
|
{
|
|
idsHrErr=IDS_FAIL_LOGON_USER;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//build the account name for IIS_WPG group.
|
|
//for a non-DC, it will be localhost\IIS_WPG
|
|
//for a DC, it will be domain\IIS_WPG
|
|
|
|
//get the domain or localhost name
|
|
pwszAccount=GetAccountDomainName(pCEPWizardInfo->fDC);
|
|
|
|
if(NULL==pwszAccount)
|
|
{
|
|
idsHrErr=IDS_FAIL_FIND_DOMAIN;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//build the IIS_WPG account
|
|
pwszIIS=(LPWSTR)malloc((wcslen(pwszAccount) + 1 + wcslen(IIS_WPG) + 1)*sizeof(WCHAR));
|
|
if(NULL==pwszIIS)
|
|
goto Account_Done;
|
|
|
|
wcscpy(pwszIIS, pwszAccount);
|
|
wcscat(pwszIIS, L"\\");
|
|
wcscat(pwszIIS, IIS_WPG);
|
|
|
|
|
|
//Obtain the SID for the IIS_WPG group
|
|
dwChar=0;
|
|
dwDomainChar=0;
|
|
|
|
LookupAccountNameW(
|
|
NULL, //local system
|
|
pwszIIS,
|
|
NULL,
|
|
&dwChar,
|
|
NULL,
|
|
&dwDomainChar,
|
|
&SidName);
|
|
|
|
pSidIIS=(PSID)malloc(dwChar);
|
|
if(NULL==pSidIIS)
|
|
goto Account_Done;
|
|
|
|
pwszDomain=(LPWSTR)malloc(dwDomainChar * sizeof(WCHAR));
|
|
if(NULL==pwszDomain)
|
|
goto Account_Done;
|
|
|
|
if(!LookupAccountNameW(
|
|
NULL, //local system
|
|
pwszIIS,
|
|
pSidIIS,
|
|
&dwChar,
|
|
pwszDomain,
|
|
&dwDomainChar,
|
|
&SidName))
|
|
{
|
|
idsHrErr=IDS_FAIL_LOOK_UP;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//Verify the account is part of the local IIS_WPG group
|
|
if(!CheckTokenMembership(
|
|
pCEPWizardInfo->hAccountToken,
|
|
pSidIIS,
|
|
&fMember))
|
|
{
|
|
idsHrErr=IDS_FAIL_CHECK_MEMBER;
|
|
goto Account_Done;
|
|
}
|
|
|
|
if(FALSE == fMember)
|
|
{
|
|
idsErr=IDS_NOT_IIS_MEMBER;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//on an enterprise CA, verify the account as READ access to the template
|
|
if(pCEPWizardInfo->fEnterpriseCA)
|
|
{
|
|
//make sure that this is an domain account:
|
|
//DOMAIN_GROUP_RID_USERS
|
|
if(0 != wcslen(wszDomain))
|
|
{
|
|
dwSize=0;
|
|
|
|
GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
NULL,
|
|
&dwSize);
|
|
|
|
pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
|
|
|
|
if(NULL==pwszComputerName)
|
|
goto Account_Done;
|
|
|
|
if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
pwszComputerName,
|
|
&dwSize))
|
|
{
|
|
idsHrErr=IDS_FAIL_GET_COMPUTER_NAME;
|
|
goto Account_Done;
|
|
}
|
|
|
|
|
|
if(0 == _wcsicmp(wszDomain, pwszComputerName))
|
|
{
|
|
idsErr=IDS_NO_LOCAL_ACCOUNT;
|
|
goto Account_Done;
|
|
}
|
|
}
|
|
|
|
hr=CAFindCertTypeByName(wszCERTTYPE_IPSEC_INTERMEDIATE_OFFLINE, NULL, CT_ENUM_MACHINE_TYPES, &hCertType);
|
|
|
|
if(S_OK != hr)
|
|
{
|
|
idsHrErr=IDS_FAIL_FIND_CERT_TYPE;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//get the SD for the template
|
|
hr=CACertTypeGetSecurity(hCertType, &pCertTypeSD);
|
|
|
|
if(S_OK != hr)
|
|
{
|
|
idsHrErr=IDS_FAIL_FIND_SD_CERT_TYPE;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//check the DS_READ Access
|
|
dwPSSize=sizeof(ps);
|
|
|
|
if(!AccessCheck(
|
|
pCertTypeSD,
|
|
pCEPWizardInfo->hAccountToken,
|
|
ACTRL_DS_LIST | ACTRL_DS_READ_PROP,
|
|
&GenericMapping,
|
|
&ps,
|
|
&dwPSSize,
|
|
&grantAccess,
|
|
&fAccessAllowed))
|
|
{
|
|
idsHrErr=IDS_FAIL_DETECT_READ_ACCESS;
|
|
goto Account_Done;
|
|
}
|
|
|
|
//make sure the account has read access to the template
|
|
if(FALSE == fAccessAllowed)
|
|
{
|
|
idsErr=IDS_NO_READ_ACCESS_TO_TEMPLATE;
|
|
goto Account_Done;
|
|
}
|
|
}
|
|
|
|
//everything looks good
|
|
idsErr=0;
|
|
idsHrErr=0;
|
|
|
|
Account_Done:
|
|
|
|
if(pwszComputerName)
|
|
{
|
|
free(pwszComputerName);
|
|
}
|
|
|
|
if(pwszConfirm)
|
|
{
|
|
free(pwszConfirm);
|
|
}
|
|
|
|
if(pwszAccount)
|
|
{
|
|
NetApiBufferFree(pwszAccount);
|
|
}
|
|
|
|
if(pwszIIS)
|
|
{
|
|
free(pwszIIS);
|
|
}
|
|
|
|
if(pwszDomain)
|
|
{
|
|
free(pwszDomain);
|
|
}
|
|
|
|
if(pSidIIS)
|
|
{
|
|
free(pSidIIS);
|
|
}
|
|
|
|
if(pCertTypeSD)
|
|
{
|
|
LocalFree(pCertTypeSD);
|
|
}
|
|
|
|
if(hCertType)
|
|
{
|
|
CACloseCertType(hCertType);
|
|
}
|
|
|
|
if(0 != idsErr)
|
|
{
|
|
CEPMessageBox(hwndDlg, idsErr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
}
|
|
else
|
|
{
|
|
if(0 != idsHrErr)
|
|
{
|
|
if(S_OK == hr)
|
|
{
|
|
hr=HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
CEPErrorMessageBoxEx(hwndDlg, idsHrErr, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL, IDS_GEN_ERROR_MSG_HR, IDS_GEN_ERROR_MSG);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Chanllenge
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_Challenge(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
|
|
|
|
//by default, we should use Challenge password
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_CHALLENGE_CHECK), BM_SETCHECK, BST_CHECKED, 0);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(TRUE == (pCEPWizardInfo->fLocalSystem))
|
|
{
|
|
//skip the account page and goes to the application identity page
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_APP_ID);
|
|
}
|
|
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//check for the Challenge password options
|
|
if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_CHALLENGE_CHECK, BM_GETCHECK, 0, 0))
|
|
pCEPWizardInfo->fPassword=TRUE;
|
|
else
|
|
pCEPWizardInfo->fPassword=FALSE;
|
|
|
|
|
|
//warn users about the implication of not using a password
|
|
if(FALSE == pCEPWizardInfo->fPassword)
|
|
{
|
|
if(IDNO==CEPMessageBox(hwndDlg, IDS_NO_CHALLENGE_PASSWORD, MB_ICONWARNING|MB_YESNO|MB_APPLMODAL))
|
|
{
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!EmptyCEPStore())
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_EXISTING_RA, MB_ICONINFORMATION|MB_OK|MB_APPLMODAL);
|
|
|
|
if(IDNO==CEPMessageBox(hwndDlg, IDS_PROCESS_PENDING, MB_ICONQUESTION|MB_YESNO|MB_APPLMODAL))
|
|
{
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Enroll
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_Enroll(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
DWORD dwIndex=0;
|
|
DWORD dwChar=0;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
|
|
|
|
//by default, we do not use the advanced enrollment options
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), BM_SETCHECK, BST_UNCHECKED, 0);
|
|
|
|
//preset the country string since we only allow 2 characters
|
|
SetDlgItemTextU(hwndDlg, IDC_ENROLL_COUNTRY, L"US");
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//if the adv selection is made, it has to stay selected
|
|
if(pCEPWizardInfo->fEnrollAdv)
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), FALSE);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//gather RA subject informaton
|
|
for(dwIndex=0; dwIndex < RA_INFO_COUNT; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgpwszName[dwIndex])
|
|
{
|
|
free(pCEPWizardInfo->rgpwszName[dwIndex]);
|
|
pCEPWizardInfo->rgpwszName[dwIndex]=NULL;
|
|
|
|
}
|
|
|
|
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
|
|
g_rgRAEnrollInfo[dwIndex].dwIDC,
|
|
WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
pCEPWizardInfo->rgpwszName[dwIndex]=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL!=(pCEPWizardInfo->rgpwszName[dwIndex]))
|
|
{
|
|
GetDlgItemTextU(hwndDlg, g_rgRAEnrollInfo[dwIndex].dwIDC,
|
|
pCEPWizardInfo->rgpwszName[dwIndex],
|
|
dwChar+1);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//we require name and company
|
|
if((NULL==(pCEPWizardInfo->rgpwszName[0])) ||
|
|
(NULL==(pCEPWizardInfo->rgpwszName[2]))
|
|
)
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_ENROLL_REQUIRE_NAME, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
|
|
|
|
//we only allow 2 characeters for the country
|
|
if(NULL !=(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1]))
|
|
{
|
|
if(2 < wcslen(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1]))
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_ENROLL_COUNTRY_TOO_LARGE, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//check for the advanced options
|
|
if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_ENORLL_ADV_CHECK, BM_GETCHECK, 0, 0))
|
|
pCEPWizardInfo->fEnrollAdv=TRUE;
|
|
else
|
|
pCEPWizardInfo->fEnrollAdv=FALSE;
|
|
|
|
|
|
//If the advanced is selected, skip the CSP Page
|
|
if(FALSE== pCEPWizardInfo->fEnrollAdv)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPLETION);
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// CSP
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_CSP(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
NM_LISTVIEW FAR * pnmv=NULL;
|
|
BOOL fSign=FALSE;
|
|
int idCombo=0;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
|
|
|
|
//populate the CSP list and key length combo box
|
|
InitCSPList(hwndDlg, IDC_CSP_SIGN_LIST, TRUE,
|
|
pCEPWizardInfo);
|
|
|
|
InitCSPList(hwndDlg, IDC_CSP_ENCRYPT_LIST, FALSE,
|
|
pCEPWizardInfo);
|
|
|
|
RefreshKeyLengthCombo(hwndDlg,
|
|
IDC_CSP_SIGN_LIST,
|
|
IDC_CSP_SIGN_COMBO,
|
|
TRUE,
|
|
pCEPWizardInfo);
|
|
|
|
RefreshKeyLengthCombo(hwndDlg,
|
|
IDC_CSP_ENCRYPT_LIST,
|
|
IDC_CSP_ENCRYPT_COMBO,
|
|
FALSE,
|
|
pCEPWizardInfo);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case LVN_ITEMCHANGED:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
pnmv = (LPNMLISTVIEW) lParam;
|
|
|
|
if(NULL==pnmv)
|
|
break;
|
|
|
|
if (pnmv->uNewState & LVIS_SELECTED)
|
|
{
|
|
|
|
if(IDC_CSP_SIGN_LIST == (pnmv->hdr).idFrom)
|
|
{
|
|
fSign=TRUE;
|
|
idCombo=IDC_CSP_SIGN_COMBO;
|
|
}
|
|
else
|
|
{
|
|
if(IDC_CSP_ENCRYPT_LIST != (pnmv->hdr).idFrom)
|
|
break;
|
|
|
|
fSign=FALSE;
|
|
idCombo=IDC_CSP_ENCRYPT_COMBO;
|
|
}
|
|
|
|
RefreshKeyLengthCombo(
|
|
hwndDlg,
|
|
(int)((pnmv->hdr).idFrom),
|
|
idCombo,
|
|
fSign,
|
|
pCEPWizardInfo);
|
|
}
|
|
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//get the select CSP and key length
|
|
if(!GetSelectedCSP(hwndDlg,
|
|
IDC_CSP_SIGN_LIST,
|
|
&(pCEPWizardInfo->dwSignProvIndex)))
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
|
|
if(!GetSelectedCSP(hwndDlg,
|
|
IDC_CSP_ENCRYPT_LIST,
|
|
&(pCEPWizardInfo->dwEncryptProvIndex)))
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
|
|
if(!GetSelectedKeyLength(hwndDlg,
|
|
IDC_CSP_SIGN_COMBO,
|
|
&(pCEPWizardInfo->dwSignKeyLength)))
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
|
|
if(!GetSelectedKeyLength(hwndDlg,
|
|
IDC_CSP_ENCRYPT_COMBO,
|
|
&(pCEPWizardInfo->dwEncryptKeyLength)))
|
|
{
|
|
CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Completion
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY CEP_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
HWND hwndControl=NULL;
|
|
LV_COLUMNW lvC;
|
|
HCURSOR hPreCursor=NULL;
|
|
HCURSOR hWinPreCursor=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCEPWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
|
|
|
|
SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE);
|
|
|
|
//insert two columns
|
|
hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST);
|
|
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
//2nd column is the content
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem= 1;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
|
|
break;
|
|
|
|
|
|
break;
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST))
|
|
DisplayConfirmation(hwndControl, pCEPWizardInfo);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//skip CSP page if adv is not selected
|
|
if(FALSE == pCEPWizardInfo->fEnrollAdv)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ENROLL);
|
|
|
|
break;
|
|
|
|
case PSN_WIZFINISH:
|
|
|
|
if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//do the real setup work
|
|
I_DoSetupWork(hwndDlg, pCEPWizardInfo);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// Helper Functions for the wizard pages
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// CEPGetAccountNameFromPicker
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL CEPGetAccountNameFromPicker(HWND hwndParent,
|
|
IDsObjectPicker *pIDsObjectPicker,
|
|
LPWSTR *ppwszSelectedUserSAM)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
BOOL fGotStgMedium = FALSE;
|
|
LPWSTR pwszPath=NULL;
|
|
DWORD dwIndex =0 ;
|
|
DWORD dwCount=0;
|
|
WCHAR wszWinNT[]=L"WinNT://";
|
|
DWORD dwSize=0;
|
|
LPWSTR pwsz=NULL;
|
|
DWORD cCount=0;
|
|
|
|
IDataObject *pdo = NULL;
|
|
PDS_SELECTION_LIST pDsSelList=NULL;
|
|
LPWSTR pwszComputerName=NULL;
|
|
|
|
STGMEDIUM stgmedium =
|
|
{
|
|
TYMED_HGLOBAL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
FORMATETC formatetc =
|
|
{
|
|
(CLIPFORMAT)g_cfDsObjectPicker,
|
|
NULL,
|
|
DVASPECT_CONTENT,
|
|
-1,
|
|
TYMED_HGLOBAL
|
|
};
|
|
|
|
//input check
|
|
if((NULL == pIDsObjectPicker) || (NULL == ppwszSelectedUserSAM))
|
|
goto CLEANUP;
|
|
|
|
*ppwszSelectedUserSAM = NULL;
|
|
|
|
|
|
if(S_OK != pIDsObjectPicker->InvokeDialog(hwndParent, &pdo))
|
|
goto CLEANUP;
|
|
|
|
if(S_OK != pdo->GetData(&formatetc, &stgmedium))
|
|
goto CLEANUP;
|
|
|
|
fGotStgMedium = TRUE;
|
|
|
|
pDsSelList = (PDS_SELECTION_LIST)GlobalLock(stgmedium.hGlobal);
|
|
|
|
if(!pDsSelList)
|
|
goto CLEANUP;
|
|
|
|
//detect if this is a domain account
|
|
//local account will be in the format of Winnt://workgroup/machine/foo
|
|
|
|
//Get the SAM name
|
|
if((pDsSelList->aDsSelection[0]).pwzADsPath == NULL)
|
|
goto CLEANUP;
|
|
|
|
//the ADsPath is in the form of "WinNT://"
|
|
if(wcslen((pDsSelList->aDsSelection[0]).pwzADsPath) <= wcslen(wszWinNT))
|
|
goto CLEANUP;
|
|
|
|
if( 0 != _wcsnicmp((pDsSelList->aDsSelection[0]).pwzADsPath, wszWinNT, wcslen(wszWinNT)))
|
|
goto CLEANUP;
|
|
|
|
pwsz = ((pDsSelList->aDsSelection[0]).pwzADsPath) + wcslen(wszWinNT);
|
|
|
|
while(L'\0' != (*pwsz))
|
|
{
|
|
if(L'/' == (*pwsz))
|
|
{
|
|
cCount++;
|
|
}
|
|
|
|
pwsz++;
|
|
}
|
|
|
|
if(1 == cCount)
|
|
{
|
|
//domain\administrator have no UPN
|
|
//if((pDsSelList->aDsSelection[0]).pwzUPN != NULL)
|
|
//if(0 != _wcsicmp(L"",(pDsSelList->aDsSelection[0]).pwzUPN))
|
|
pwszPath = ((pDsSelList->aDsSelection[0]).pwzADsPath) + wcslen(wszWinNT);
|
|
|
|
*ppwszSelectedUserSAM=(LPWSTR)malloc((wcslen(pwszPath) + 1) * sizeof(WCHAR));
|
|
|
|
if(NULL == (*ppwszSelectedUserSAM))
|
|
goto CLEANUP;
|
|
|
|
wcscpy(*ppwszSelectedUserSAM, pwszPath);
|
|
|
|
//search for the "/" and make it "\". Since the ADsPath is in the form
|
|
//of "WinNT://domain/name". We need the SAM name in the form of
|
|
//domain\name
|
|
dwCount = wcslen(*ppwszSelectedUserSAM);
|
|
|
|
for(dwIndex = 0; dwIndex < dwCount; dwIndex++)
|
|
{
|
|
if((*ppwszSelectedUserSAM)[dwIndex] == L'/')
|
|
{
|
|
(*ppwszSelectedUserSAM)[dwIndex] = L'\\';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//use the format of localMachine\\account for local account
|
|
if(NULL == (*ppwszSelectedUserSAM))
|
|
{
|
|
if(NULL == (pDsSelList->aDsSelection[0]).pwzName)
|
|
goto CLEANUP;
|
|
|
|
//Get the computer name
|
|
dwSize=0;
|
|
|
|
GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
NULL,
|
|
&dwSize);
|
|
|
|
pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
|
|
|
|
if(NULL==pwszComputerName)
|
|
goto CLEANUP;
|
|
|
|
|
|
if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
pwszComputerName,
|
|
&dwSize))
|
|
goto CLEANUP;
|
|
|
|
|
|
*ppwszSelectedUserSAM=(LPWSTR)malloc((wcslen(pwszComputerName) + wcslen((pDsSelList->aDsSelection[0]).pwzName) + wcslen(L"\\") + 1) * sizeof(WCHAR));
|
|
|
|
if(NULL == (*ppwszSelectedUserSAM))
|
|
goto CLEANUP;
|
|
|
|
wcscpy(*ppwszSelectedUserSAM, pwszComputerName);
|
|
wcscat(*ppwszSelectedUserSAM, L"\\");
|
|
wcscat(*ppwszSelectedUserSAM, (pDsSelList->aDsSelection[0]).pwzName);
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
if(pwszComputerName)
|
|
free(pwszComputerName);
|
|
|
|
if(pDsSelList)
|
|
GlobalUnlock(stgmedium.hGlobal);
|
|
|
|
if (TRUE == fGotStgMedium)
|
|
ReleaseStgMedium(&stgmedium);
|
|
|
|
if(pdo)
|
|
pdo->Release();
|
|
|
|
return fResult;
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// RefreshKeyLengthCombo
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI RefreshKeyLengthCombo(HWND hwndDlg,
|
|
int idsList,
|
|
int idsCombo,
|
|
BOOL fSign,
|
|
CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwDefaultKeyLength=0;
|
|
DWORD *pdwList=NULL;
|
|
DWORD dwListCount=0;
|
|
DWORD dwMax=0;
|
|
DWORD dwMin=0;
|
|
DWORD dwIndex=0;
|
|
DWORD dwCSPIndex=0;
|
|
CEP_CSP_INFO *pCSPInfo=NULL;
|
|
int iInsertedIndex=0;
|
|
WCHAR wszKeyLength[CEP_KEY_LENGTH_STRING];
|
|
BOOL fSelected=FALSE;
|
|
|
|
//get the selected list view item
|
|
if(!GetSelectedCSP(hwndDlg,idsList,&dwCSPIndex))
|
|
goto CLEANUP;
|
|
|
|
pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwCSPIndex]);
|
|
|
|
if(fSign)
|
|
{
|
|
dwDefaultKeyLength=pCSPInfo->dwDefaultSign;
|
|
pdwList=pCSPInfo->pdwSignList;
|
|
dwListCount= pCSPInfo->dwSignCount;
|
|
dwMax=pCSPInfo->dwMaxSign;
|
|
dwMin=pCSPInfo->dwMinSign;
|
|
}
|
|
else
|
|
{
|
|
dwDefaultKeyLength=pCSPInfo->dwDefaultEncrypt;
|
|
pdwList=pCSPInfo->pdwEncryptList;
|
|
dwListCount=pCSPInfo->dwEncryptCount;
|
|
dwMax=pCSPInfo->dwMaxEncrypt;
|
|
dwMin=pCSPInfo->dwMinEncrypt;
|
|
}
|
|
|
|
//clear out the combo box
|
|
SendDlgItemMessageU(hwndDlg, idsCombo, CB_RESETCONTENT, 0, 0);
|
|
|
|
|
|
for(dwIndex=0; dwIndex < dwListCount; dwIndex++)
|
|
{
|
|
if((pdwList[dwIndex] >= dwMin) && (pdwList[dwIndex] <= dwMax))
|
|
{
|
|
_ltow(pdwList[dwIndex], wszKeyLength, 10);
|
|
|
|
// 64 bit- will never insert more than 1B entries, so INT is fine
|
|
iInsertedIndex=(int)SendDlgItemMessageU(hwndDlg, idsCombo, CB_ADDSTRING,
|
|
0, (LPARAM)wszKeyLength);
|
|
|
|
if((iInsertedIndex != CB_ERR) && (iInsertedIndex != CB_ERRSPACE))
|
|
{
|
|
SendDlgItemMessage(hwndDlg, idsCombo, CB_SETITEMDATA,
|
|
(WPARAM)iInsertedIndex, (LPARAM)pdwList[dwIndex]);
|
|
|
|
if(dwDefaultKeyLength==pdwList[dwIndex])
|
|
{
|
|
SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, iInsertedIndex, 0);
|
|
fSelected=TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(fSelected==FALSE)
|
|
SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, 0, 0);
|
|
|
|
fResult=TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// InitCSPList
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI InitCSPList(HWND hwndDlg,
|
|
int idControl,
|
|
BOOL fSign,
|
|
CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwIndex=0;
|
|
CEP_CSP_INFO *pCSPInfo=NULL;
|
|
int iInsertedIndex=0;
|
|
HWND hwndList=NULL;
|
|
LV_ITEMW lvItem;
|
|
LV_COLUMNW lvC;
|
|
BOOL fSelected=FALSE;
|
|
|
|
if(NULL==(hwndList=GetDlgItem(hwndDlg, idControl)))
|
|
goto CLEANUP;
|
|
|
|
//insert a column into the list view
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (-1 == ListView_InsertColumnU(hwndList, 0, &lvC))
|
|
goto CLEANUP;
|
|
|
|
// set up the fields in the list view item struct that don't change from item to item
|
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
|
lvItem.mask = LVIF_TEXT | LVIF_STATE |LVIF_PARAM ;
|
|
|
|
for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
|
|
{
|
|
fSelected=FALSE;
|
|
|
|
pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwIndex]);
|
|
|
|
if(fSign)
|
|
{
|
|
if(!(pCSPInfo->fSignature))
|
|
continue;
|
|
|
|
if(dwIndex==pCEPWizardInfo->dwSignProvIndex)
|
|
fSelected=TRUE;
|
|
}
|
|
else
|
|
{
|
|
if(!(pCSPInfo->fEncryption))
|
|
continue;
|
|
|
|
if(dwIndex==pCEPWizardInfo->dwEncryptProvIndex)
|
|
fSelected=TRUE;
|
|
}
|
|
|
|
lvItem.iItem=dwIndex;
|
|
lvItem.lParam = (LPARAM)dwIndex;
|
|
lvItem.pszText=pCSPInfo->pwszCSPName;
|
|
|
|
iInsertedIndex=ListView_InsertItemU(hwndList, &lvItem);
|
|
|
|
if(fSelected)
|
|
{
|
|
ListView_SetItemState(
|
|
hwndList,
|
|
iInsertedIndex,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
}
|
|
|
|
}
|
|
|
|
//make the column autosize
|
|
ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
|
|
|
|
fResult=TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// GetSelectedCSP
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI GetSelectedCSP(HWND hwndDlg,
|
|
int idControl,
|
|
DWORD *pdwCSPIndex)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
HWND hwndControl=NULL;
|
|
LV_ITEM lvItem;
|
|
int iIndex=0;
|
|
|
|
//get the window handle of the list view
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, idControl)))
|
|
goto CLEANUP;
|
|
|
|
//now, mark the one that is selected
|
|
if(-1 == (iIndex= ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
goto CLEANUP;
|
|
|
|
|
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
|
lvItem.mask=LVIF_PARAM;
|
|
lvItem.iItem=iIndex;
|
|
|
|
if(!ListView_GetItem(hwndControl, &lvItem))
|
|
goto CLEANUP;
|
|
|
|
// will never have more than 1B CSPs, so this is fine
|
|
*pdwCSPIndex=(DWORD)(lvItem.lParam);
|
|
|
|
fResult=TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
return fResult;
|
|
|
|
}
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// GetSelectedKeyLength
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI GetSelectedKeyLength(HWND hwndDlg,
|
|
int idControl,
|
|
DWORD *pdwKeyLength)
|
|
{
|
|
|
|
int iIndex=0;
|
|
BOOL fResult=FALSE;
|
|
|
|
iIndex=(int)SendDlgItemMessage(hwndDlg, idControl, CB_GETCURSEL, 0, 0);
|
|
|
|
if(CB_ERR==iIndex)
|
|
goto CLEANUP;
|
|
|
|
// will never be > 1B bits long, so this is ok
|
|
*pdwKeyLength=(DWORD)SendDlgItemMessage(hwndDlg, idControl, CB_GETITEMDATA, iIndex, 0);
|
|
|
|
fResult=TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
return fResult;
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// FormatMessageStr
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
int ListView_InsertItemU_IDS(HWND hwndList,
|
|
LV_ITEMW *plvItem,
|
|
UINT idsString,
|
|
LPWSTR pwszText)
|
|
{
|
|
WCHAR wszText[MAX_STRING_SIZE];
|
|
|
|
|
|
if(pwszText)
|
|
plvItem->pszText=pwszText;
|
|
else
|
|
{
|
|
if(!LoadStringU(g_hModule, idsString, wszText, MAX_STRING_SIZE))
|
|
return -1;
|
|
|
|
plvItem->pszText=wszText;
|
|
}
|
|
|
|
return ListView_InsertItemU(hwndList, plvItem);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
// populate the wizards's confirmation page in the order of Challenge,
|
|
// RA informaton, and CSPs
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
void WINAPI DisplayConfirmation(HWND hwndControl,
|
|
CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
WCHAR wszYes[MAX_TITLE_LENGTH];
|
|
DWORD dwIndex=0;
|
|
UINT ids=0;
|
|
BOOL fNewItem=FALSE;
|
|
WCHAR wszLength[CEP_KEY_LENGTH_STRING];
|
|
|
|
LV_COLUMNW lvC;
|
|
LV_ITEMW lvItem;
|
|
|
|
//delete all the old items in the listView
|
|
ListView_DeleteAllItems(hwndControl);
|
|
|
|
//insert row by row
|
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
|
|
|
// set up the fields in the list view item struct that don't change from item to item
|
|
lvItem.mask = LVIF_TEXT | LVIF_STATE ;
|
|
lvItem.state = 0;
|
|
lvItem.stateMask = 0;
|
|
|
|
//*******************************************************************
|
|
//account information
|
|
lvItem.iItem=0;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ACCOUNT_INFORMATION, NULL);
|
|
|
|
//content
|
|
(lvItem.iSubItem)++;
|
|
|
|
if(FALSE == (pCEPWizardInfo->fLocalSystem))
|
|
{
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->pwszUserName);
|
|
}
|
|
else
|
|
{
|
|
if(LoadStringU(g_hModule, IDS_LOCAL_SYSTEM, wszYes, MAX_TITLE_LENGTH))
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszYes);
|
|
}
|
|
|
|
|
|
//*******************************************************************
|
|
//challenge
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CHALLENGE_PHRASE, NULL);
|
|
|
|
//content
|
|
(lvItem.iSubItem)++;
|
|
|
|
if(pCEPWizardInfo->fPassword)
|
|
ids=IDS_YES;
|
|
else
|
|
ids=IDS_NO;
|
|
|
|
if(LoadStringU(g_hModule, ids, wszYes, MAX_TITLE_LENGTH))
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszYes);
|
|
|
|
//***************************************************************************
|
|
// RA credentials
|
|
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_RA_CREDENTIAL, NULL);
|
|
|
|
//content
|
|
for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgpwszName[dwIndex])
|
|
{
|
|
if(TRUE==fNewItem)
|
|
{
|
|
//increase the row
|
|
lvItem.iItem++;
|
|
lvItem.pszText=L"";
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU(hwndControl, &lvItem);
|
|
}
|
|
else
|
|
fNewItem=TRUE;
|
|
|
|
lvItem.iSubItem++;
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->rgpwszName[dwIndex]);
|
|
}
|
|
}
|
|
|
|
//***************************************************************************
|
|
//CSPInfo
|
|
if(pCEPWizardInfo->fEnrollAdv)
|
|
{
|
|
//signature CSP Name
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_CSP, NULL);
|
|
|
|
lvItem.iSubItem++;
|
|
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
|
pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].pwszCSPName);
|
|
|
|
|
|
//signaure key length
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_KEY_LENGTH, NULL);
|
|
|
|
lvItem.iSubItem++;
|
|
|
|
_ltow(pCEPWizardInfo->dwSignKeyLength, wszLength, 10);
|
|
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength);
|
|
|
|
//encryption CSP name
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_CSP, NULL);
|
|
|
|
lvItem.iSubItem++;
|
|
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
|
pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName);
|
|
|
|
//encryption key length
|
|
lvItem.iItem++;
|
|
lvItem.iSubItem=0;
|
|
|
|
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_KEY_LENGTH, NULL);
|
|
|
|
lvItem.iSubItem++;
|
|
|
|
_ltow(pCEPWizardInfo->dwEncryptKeyLength, wszLength, 10);
|
|
|
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength);
|
|
}
|
|
|
|
//autosize the columns
|
|
ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
|
|
ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// GetServiceWaitPeriod
|
|
//
|
|
// Obtain the value from the registry
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void GetServiceWaitPeriod(DWORD *pdwServiceWait)
|
|
{
|
|
DWORD cbData=0;
|
|
DWORD dwData=0;
|
|
DWORD dwType=0;
|
|
|
|
HKEY hKeyCEP=NULL;
|
|
|
|
//set the default value
|
|
*pdwServiceWait=SCEP_SERVICE_WAIT_PERIOD;
|
|
|
|
//get the CA's type from the registry
|
|
cbData=sizeof(dwData);
|
|
|
|
//we have to have the knowledge of the ca type
|
|
if(ERROR_SUCCESS == RegOpenKeyExU(
|
|
HKEY_LOCAL_MACHINE,
|
|
MSCEP_LOCATION,
|
|
0,
|
|
KEY_READ,
|
|
&hKeyCEP))
|
|
{
|
|
if(ERROR_SUCCESS == RegQueryValueExU(
|
|
hKeyCEP,
|
|
MSCEP_KEY_SERVICE_WAIT,
|
|
NULL,
|
|
&dwType,
|
|
(BYTE *)&dwData,
|
|
&cbData))
|
|
{
|
|
if ((dwType == REG_DWORD) || (dwType == REG_BINARY))
|
|
{
|
|
*pdwServiceWait=dwData;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(hKeyCEP)
|
|
RegCloseKey(hKeyCEP);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// Main Function
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" int _cdecl wmain(int nArgs, WCHAR ** rgwszArgs)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
UINT idsMsg=IDS_FAIL_INIT_WIZARD;
|
|
HRESULT hr=E_FAIL;
|
|
PROPSHEETPAGEW rgCEPSheet[CEP_PROP_SHEET];
|
|
PROPSHEETHEADERW cepHeader;
|
|
CEP_PAGE_INFO rgCEPPageInfo[CEP_PROP_SHEET]=
|
|
{(LPCWSTR)MAKEINTRESOURCE(IDD_WELCOME), CEP_Welcome,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_APP_ID), CEP_App_ID,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_ACCOUNT), CEP_Account,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_CHALLENGE), CEP_Challenge,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_ENROLL), CEP_Enroll,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_CSP), CEP_CSP,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_COMPLETION), CEP_Completion,
|
|
};
|
|
DWORD dwIndex=0;
|
|
WCHAR wszTitle[MAX_TITLE_LENGTH];
|
|
INT_PTR iReturn=-1;
|
|
ENUM_CATYPES catype;
|
|
DWORD dwWaitCounter=0;
|
|
BOOL fEnterpriseCA=FALSE;
|
|
DSOP_SCOPE_INIT_INFO ScopeInit;
|
|
DSOP_INIT_INFO InitInfo;
|
|
DWORD dwServiceWait=SCEP_SERVICE_WAIT_PERIOD;
|
|
OSVERSIONINFOEXW versionInfo;
|
|
|
|
|
|
CEP_WIZARD_INFO CEPWizardInfo;
|
|
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDomainInfo=NULL;
|
|
|
|
memset(rgCEPSheet, 0, sizeof(PROPSHEETPAGEW)*CEP_PROP_SHEET);
|
|
memset(&cepHeader, 0, sizeof(PROPSHEETHEADERW));
|
|
memset(&CEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO));
|
|
|
|
if(FAILED(CoInitialize(NULL)))
|
|
return FALSE;
|
|
|
|
if(NULL==(g_hModule=GetModuleHandle(NULL)))
|
|
goto CommonReturn;
|
|
|
|
if(!IsValidInstallation(&idsMsg))
|
|
goto ErrorReturn;
|
|
|
|
//get the wait period for start/stop service account
|
|
GetServiceWaitPeriod(&dwServiceWait);
|
|
|
|
if(!IsCaRunning())
|
|
{
|
|
if(S_OK != (hr=CepStartService(CERTSVC_NAME)))
|
|
{
|
|
idsMsg=IDS_NO_CA_RUNNING;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
}
|
|
|
|
//make sure the CA is up running
|
|
for (dwWaitCounter=0; dwWaitCounter < dwServiceWait; dwWaitCounter++)
|
|
{
|
|
if (!IsCaRunning())
|
|
Sleep(1000);
|
|
else
|
|
break;
|
|
}
|
|
|
|
|
|
if (dwServiceWait == dwWaitCounter)
|
|
{
|
|
idsMsg=IDS_CAN_NOT_START_CA;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
|
|
//make sure we have the correct admin rights based on the CA type
|
|
if(S_OK != (hr=GetCaType(&catype)))
|
|
{
|
|
idsMsg=IDS_FAIL_GET_CA_TYPE;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//some cisco routers only work with root CA
|
|
if((ENUM_ENTERPRISE_ROOTCA != catype) && (ENUM_STANDALONE_ROOTCA != catype))
|
|
{
|
|
if(IDNO==CEPMessageBox(NULL, IDS_CAN_NOT_ROOT_CA, MB_ICONWARNING|MB_YESNO|MB_APPLMODAL))
|
|
{
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
}
|
|
|
|
//for either Enteprise CA or Standalone CA, the user has to be the local machine admin
|
|
// check for machine admin
|
|
if(!IsUserInAdminGroup(FALSE))
|
|
{
|
|
idsMsg=IDS_NOT_MACHINE_ADMIN;
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
|
|
if (ENUM_ENTERPRISE_ROOTCA==catype || ENUM_ENTERPRISE_SUBCA==catype)
|
|
{
|
|
fEnterpriseCA=TRUE;
|
|
|
|
// check for enterprise admin
|
|
if(!IsUserInAdminGroup(TRUE))
|
|
{
|
|
idsMsg=IDS_NOT_ENT_ADMIN;
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
//everything looks good. We start the wizard page
|
|
if(!CEPWizardInit())
|
|
goto ErrorWithWin32Return;
|
|
|
|
CEPWizardInfo.fEnrollAdv=FALSE;
|
|
CEPWizardInfo.fPassword=FALSE;
|
|
CEPWizardInfo.fEnterpriseCA=fEnterpriseCA;
|
|
CEPWizardInfo.fDC=FALSE;
|
|
CEPWizardInfo.fDomain=TRUE; //defeult to assume the machine is on a domain
|
|
CEPWizardInfo.dwServiceWait=dwServiceWait;
|
|
|
|
//detect if the machine is a DC
|
|
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
|
|
|
if(GetVersionEx(reinterpret_cast<OSVERSIONINFOW *>(&versionInfo)))
|
|
{
|
|
CEPWizardInfo.fDC = (versionInfo.wProductType == VER_NT_DOMAIN_CONTROLLER);
|
|
}
|
|
|
|
|
|
//detect if the machine is on a domain
|
|
if(ERROR_SUCCESS != DsRoleGetPrimaryDomainInformation(
|
|
NULL,
|
|
DsRolePrimaryDomainInfoBasic,
|
|
(PBYTE*)&pDomainInfo))
|
|
{
|
|
idsMsg=IDS_FAIL_DOMAIN_INFO;
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
if((DsRole_RoleStandaloneWorkstation == (pDomainInfo->MachineRole)) ||
|
|
(DsRole_RoleStandaloneServer == (pDomainInfo->MachineRole))
|
|
)
|
|
{
|
|
CEPWizardInfo.fDomain=FALSE;
|
|
}
|
|
|
|
//initialize the object picker object
|
|
//init for the user selection dialogue
|
|
memset(&ScopeInit, 0, sizeof(DSOP_SCOPE_INIT_INFO));
|
|
memset(&InitInfo, 0, sizeof(InitInfo));
|
|
|
|
ScopeInit.cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
|
|
//only domain account for enterprise CA
|
|
if(fEnterpriseCA)
|
|
{
|
|
ScopeInit.flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN|DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
|
|
}
|
|
else
|
|
{
|
|
ScopeInit.flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN|DSOP_SCOPE_TYPE_GLOBAL_CATALOG|DSOP_SCOPE_TYPE_TARGET_COMPUTER;
|
|
}
|
|
|
|
ScopeInit.flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT; //this will give us the SAM name for the user
|
|
ScopeInit.FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
|
|
ScopeInit.FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
|
|
InitInfo.cbSize = sizeof(InitInfo);
|
|
InitInfo.pwzTargetComputer = NULL; // NULL == local machine
|
|
InitInfo.cDsScopeInfos = 1;
|
|
InitInfo.aDsScopeInfos = &ScopeInit;
|
|
InitInfo.flOptions = 0; //we are doing single select
|
|
|
|
//create the COM object
|
|
if(S_OK != (hr=CoCreateInstance
|
|
(CLSID_DsObjectPicker,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDsObjectPicker,
|
|
(void **) &(CEPWizardInfo.pIDsObjectPicker))))
|
|
{
|
|
idsMsg=IDS_FAIL_GET_OBJECT_PICKER;
|
|
goto ErrorWithHResultReturn;
|
|
|
|
}
|
|
|
|
if(S_OK != (hr=CEPWizardInfo.pIDsObjectPicker->Initialize(&InitInfo)))
|
|
{
|
|
idsMsg=IDS_FAIL_GET_OBJECT_PICKER;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//initialize the CSP information
|
|
if(!CEPGetCSPInformation(&CEPWizardInfo))
|
|
{
|
|
idsMsg=IDS_FAIL_GET_CSP_INFO;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
|
|
{
|
|
CEPWizardInfo.rgpwszName[dwIndex]=NULL;
|
|
}
|
|
|
|
if(!SetupFonts(
|
|
g_hModule,
|
|
NULL,
|
|
&(CEPWizardInfo.hBigBold),
|
|
&(CEPWizardInfo.hBold)))
|
|
goto ErrorReturn;
|
|
|
|
|
|
for(dwIndex=0; dwIndex<CEP_PROP_SHEET; dwIndex++)
|
|
{
|
|
rgCEPSheet[dwIndex].dwSize=sizeof(rgCEPSheet[dwIndex]);
|
|
|
|
rgCEPSheet[dwIndex].hInstance=g_hModule;
|
|
|
|
rgCEPSheet[dwIndex].pszTemplate=rgCEPPageInfo[dwIndex].pszTemplate;
|
|
|
|
rgCEPSheet[dwIndex].pfnDlgProc=rgCEPPageInfo[dwIndex].pfnDlgProc;
|
|
|
|
rgCEPSheet[dwIndex].lParam=(LPARAM)&CEPWizardInfo;
|
|
}
|
|
|
|
//set up the header information
|
|
cepHeader.dwSize=sizeof(cepHeader);
|
|
cepHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
|
|
cepHeader.hwndParent=NULL;
|
|
cepHeader.hInstance=g_hModule;
|
|
|
|
if(LoadStringU(g_hModule, IDS_WIZARD_CAPTION, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
|
|
cepHeader.pszCaption=wszTitle;
|
|
|
|
cepHeader.nPages=CEP_PROP_SHEET;
|
|
cepHeader.nStartPage=0;
|
|
cepHeader.ppsp=rgCEPSheet;
|
|
|
|
//create the wizard
|
|
iReturn = PropertySheetU(&cepHeader);
|
|
|
|
if(-1 == iReturn)
|
|
goto ErrorWithWin32Return;
|
|
|
|
if(0 == iReturn)
|
|
{
|
|
//cancel button is pushed. We return FALSE so that
|
|
//the reboot will not happen.
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
if(pDomainInfo)
|
|
{
|
|
DsRoleFreeMemory(pDomainInfo);
|
|
}
|
|
|
|
FreeCEPWizardInfo(&CEPWizardInfo);
|
|
|
|
CoUninitialize();
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
|
|
CEPMessageBox(NULL, idsMsg, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorWithHResultReturn:
|
|
|
|
fResult=FALSE;
|
|
|
|
CEPErrorMessageBox(NULL, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorWithWin32Return:
|
|
|
|
fResult=FALSE;
|
|
|
|
hr=HRESULT_FROM_WIN32(GetLastError());
|
|
|
|
CEPErrorMessageBox(NULL, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//**********************************************************************
|
|
//
|
|
// Helper functions
|
|
//
|
|
//**********************************************************************
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// I_DoSetupWork
|
|
//
|
|
// we are ready to do the real work
|
|
//-----------------------------------------------------------------------
|
|
BOOL WINAPI I_DoSetupWork(HWND hWnd, CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
UINT idsMsg=IDS_FAIL_INIT_WIZARD;
|
|
HRESULT hr=E_FAIL;
|
|
DWORD dwWaitCounter=0;
|
|
DWORD dwIndex=0;
|
|
BOOL bStart=FALSE;
|
|
DWORD dwSize=0;
|
|
WCHAR wszTitle[MAX_TITLE_LENGTH];
|
|
DWORD cbUserInfo = 0;
|
|
|
|
PTOKEN_USER pUserInfo = NULL;
|
|
LPWSTR pwszRADN=NULL;
|
|
LPWSTR pwszComputerName=NULL;
|
|
LPWSTR pwszText=NULL;
|
|
|
|
//************************************************************************************
|
|
//delete all existing CEP certificates
|
|
if(!RemoveRACertificates())
|
|
{
|
|
idsMsg=IDS_FAIL_DELETE_RA;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
//************************************************************************************
|
|
//CEP policy registry
|
|
if(!UpdateCEPRegistry(pCEPWizardInfo->fPassword,
|
|
pCEPWizardInfo->fEnterpriseCA))
|
|
{
|
|
idsMsg=IDS_FAIL_UPDATE_REGISTRY;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
//************************************************************************************
|
|
// Add the virtual root
|
|
if(S_OK != (hr=AddVDir(pCEPWizardInfo->fDC, CEP_DIR_NAME, SCEP_APPLICATION_POOL, pCEPWizardInfo->fLocalSystem, pCEPWizardInfo->pwszUserName, pCEPWizardInfo->pwszPassword)))
|
|
{
|
|
idsMsg=IDS_FAIL_ADD_VROOT;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//************************************************************************************
|
|
// Stop and Start W3SVC service for the change to take effect
|
|
CepStopService(pCEPWizardInfo->dwServiceWait,IIS_NAME, &bStart);
|
|
|
|
if(S_OK != (hr=CepStartService(IIS_NAME)))
|
|
{
|
|
idsMsg=IDS_FAIL_START_IIS;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//make sure the w3svc is up running
|
|
for (dwWaitCounter=0; dwWaitCounter < pCEPWizardInfo->dwServiceWait; dwWaitCounter++)
|
|
{
|
|
if (!IsServiceRunning(IIS_NAME))
|
|
Sleep(1000);
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (pCEPWizardInfo->dwServiceWait == dwWaitCounter)
|
|
{
|
|
idsMsg=IDS_FAIL_START_IIS;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//************************************************************************************
|
|
//Get the security ID for the account
|
|
//get the account's SID
|
|
if(FALSE == (pCEPWizardInfo->fLocalSystem))
|
|
{
|
|
if(NULL == pCEPWizardInfo->hAccountToken)
|
|
{
|
|
idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
|
|
hr=E_INVALIDARG;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
GetTokenInformation(pCEPWizardInfo->hAccountToken, TokenUser, NULL, 0, &cbUserInfo);
|
|
if(cbUserInfo == 0)
|
|
{
|
|
idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
pUserInfo = (PTOKEN_USER)LocalAlloc(LPTR, cbUserInfo);
|
|
if(pUserInfo == NULL)
|
|
{
|
|
idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
|
|
hr=E_OUTOFMEMORY;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
if(!GetTokenInformation(pCEPWizardInfo->hAccountToken, TokenUser, pUserInfo, cbUserInfo, &cbUserInfo))
|
|
{
|
|
idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
}
|
|
|
|
//************************************************************************************
|
|
//Update the certificate template and its ACLs for enterprise CA
|
|
if (pCEPWizardInfo->fEnterpriseCA)
|
|
{
|
|
// get the templates and permisisons right
|
|
if(S_OK != (hr=DoCertSrvEnterpriseChanges(pCEPWizardInfo->fLocalSystem ? NULL : (SID *)((pUserInfo->User).Sid))))
|
|
{
|
|
idsMsg=IDS_FAIL_ADD_TEMPLATE;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
}
|
|
|
|
|
|
//************************************************************************************
|
|
//Enroll for the RA certificate
|
|
|
|
//build the name in the form of L"C=US;S=Washington;CN=TestSetupUtil"
|
|
pwszRADN=(LPWSTR)malloc(sizeof(WCHAR));
|
|
if(NULL==pwszRADN)
|
|
{
|
|
idsMsg=IDS_NO_MEMORY;
|
|
goto ErrorReturn;
|
|
}
|
|
*pwszRADN=L'\0';
|
|
|
|
for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
|
|
{
|
|
if((pCEPWizardInfo->rgpwszName)[dwIndex])
|
|
{
|
|
if(0 != wcslen(pwszRADN))
|
|
wcscat(pwszRADN, L";");
|
|
|
|
pwszRADN=(LPWSTR)realloc(pwszRADN,
|
|
sizeof(WCHAR) * (wcslen(pwszRADN) +
|
|
wcslen((pCEPWizardInfo->rgpwszName)[dwIndex]) +
|
|
wcslen(L";") +
|
|
wcslen(g_rgRAEnrollInfo[dwIndex].pwszPreFix) +
|
|
1));
|
|
|
|
if(NULL==pwszRADN)
|
|
{
|
|
idsMsg=IDS_NO_MEMORY;
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
wcscat(pwszRADN,g_rgRAEnrollInfo[dwIndex].pwszPreFix);
|
|
wcscat(pwszRADN,(pCEPWizardInfo->rgpwszName)[dwIndex]);
|
|
}
|
|
}
|
|
|
|
if(S_OK != (hr=EnrollForRACertificates(
|
|
pwszRADN,
|
|
(pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].pwszCSPName,
|
|
(pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].dwCSPType,
|
|
pCEPWizardInfo->dwSignKeyLength,
|
|
(pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName,
|
|
(pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].dwCSPType,
|
|
pCEPWizardInfo->dwEncryptKeyLength,
|
|
pCEPWizardInfo->fLocalSystem ? NULL : (SID *)((pUserInfo->User).Sid))))
|
|
{
|
|
idsMsg=IDS_FAIL_ENROLL_RA_CERT;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//************************************************************************************
|
|
//CA policy registry
|
|
|
|
CepStopService(pCEPWizardInfo->dwServiceWait, CERTSVC_NAME, &bStart);
|
|
|
|
if(S_OK != (hr=DoCertSrvRegChanges(FALSE)))
|
|
{
|
|
idsMsg=IDS_FAIL_UPDATE_CERTSVC;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
if(S_OK != (hr=CepStartService(CERTSVC_NAME)))
|
|
{
|
|
idsMsg=IDS_FAIL_START_CERTSVC;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//make sure the CA is up running
|
|
for (dwWaitCounter=0; dwWaitCounter < pCEPWizardInfo->dwServiceWait; dwWaitCounter++)
|
|
{
|
|
if (!IsCaRunning())
|
|
Sleep(1000);
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (pCEPWizardInfo->dwServiceWait == dwWaitCounter)
|
|
{
|
|
idsMsg=IDS_CAN_NOT_START_CA;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
//************************************************************************************
|
|
//Add the EventLog Source
|
|
if(S_OK != AddLogSourceToRegistry(L"%SystemRoot%\\System32\\Certsrv\\Mscep\\mscep.dll"))
|
|
{
|
|
idsMsg=IDS_FAIL_REG_EVENT_LOG;
|
|
goto ErrorWithHResultReturn;
|
|
}
|
|
|
|
|
|
//************************************************************************************
|
|
//success
|
|
//inform the user of the password location and URL
|
|
dwSize=0;
|
|
|
|
GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
NULL,
|
|
&dwSize);
|
|
|
|
pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
|
|
|
|
if(NULL==pwszComputerName)
|
|
{
|
|
idsMsg=IDS_NO_MEMORY;
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
|
|
if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
|
|
pwszComputerName,
|
|
&dwSize))
|
|
{
|
|
idsMsg=IDS_FAIL_GET_COMPUTER_NAME;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
if(!FormatMessageUnicode(&pwszText, IDS_CEP_SUCCESS_INFO, pwszComputerName, CEP_DIR_NAME, CEP_DLL_NAME))
|
|
{
|
|
idsMsg=IDS_NO_MEMORY;
|
|
goto ErrorWithWin32Return;
|
|
}
|
|
|
|
wszTitle[0]=L'\0';
|
|
|
|
LoadStringU(g_hModule, IDS_WIZARD_CAPTION, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0]));
|
|
|
|
MessageBoxU(hWnd, pwszText, wszTitle, MB_OK | MB_APPLMODAL);
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
if(pUserInfo)
|
|
{
|
|
LocalFree(pUserInfo);
|
|
}
|
|
|
|
if(pwszText)
|
|
LocalFree((HLOCAL)pwszText);
|
|
|
|
if(pwszComputerName)
|
|
free(pwszComputerName);
|
|
|
|
if(pwszRADN)
|
|
free(pwszRADN);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
|
|
CEPMessageBox(hWnd, idsMsg, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorWithHResultReturn:
|
|
|
|
fResult=FALSE;
|
|
|
|
CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorWithWin32Return:
|
|
|
|
fResult=FALSE;
|
|
|
|
hr=HRESULT_FROM_WIN32(GetLastError());
|
|
|
|
CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CEPGetCSPInformation
|
|
//
|
|
// We initialize the following members of CEP_WIZARD_INFO:
|
|
//
|
|
// CEP_CSP_INFO *rgCSPInfo;
|
|
// DWORD dwCSPCount;
|
|
// DWORD dwSignProvIndex;
|
|
// DWORD dwSignKeySize;
|
|
// DWORD dwEncryptProvIndex;
|
|
// DWORD dwEncryptKeySize;
|
|
//
|
|
//
|
|
// typedef struct _CEP_CSP_INFO
|
|
//{
|
|
// LPWSTR pwszCSPName;
|
|
// DWORD dwCSPType;
|
|
// BOOL fSignature;
|
|
// BOOL fExchange;
|
|
// DWORD dwMaxSign; //Max key length of signature
|
|
// DWORD dwMinSign; //Min key length of signature
|
|
// DWORD dwDefaultSign; //default key length of signature
|
|
// DWORD dwMaxEncrypt;
|
|
// DWORD dwMinEncrypt;
|
|
// DWORD dwDefaultEncrypt;
|
|
// DWORD *pdwSignList; //the table of possible signing key length
|
|
// DWORD dwSignCount; //the count of entries in the table
|
|
// DWORD *pdwEncryptList;
|
|
// DWORD dwEncryptCount;
|
|
//}CEP_CSP_INFO;
|
|
//
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI CEPGetCSPInformation(CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwCSPIndex=0;
|
|
DWORD dwProviderType=0;
|
|
DWORD cbSize=0;
|
|
DWORD dwFlags=0;
|
|
DWORD dwIndex=0;
|
|
int iDefaultSignature=-1;
|
|
int iDefaultEncryption=-1;
|
|
PROV_ENUMALGS_EX paramData;
|
|
|
|
CEP_CSP_INFO *pCSPInfo=NULL;
|
|
HCRYPTPROV hProv = NULL;
|
|
|
|
//enum all the providers on the system
|
|
while(CryptEnumProvidersU(
|
|
dwCSPIndex,
|
|
NULL,
|
|
0,
|
|
&dwProviderType,
|
|
NULL,
|
|
&cbSize))
|
|
{
|
|
|
|
pCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO));
|
|
|
|
if(NULL == pCSPInfo)
|
|
goto MemoryErr;
|
|
|
|
memset(pCSPInfo, 0, sizeof(CEP_CSP_INFO));
|
|
|
|
pCSPInfo->pwszCSPName=(LPWSTR)malloc(cbSize);
|
|
|
|
if(NULL==(pCSPInfo->pwszCSPName))
|
|
goto MemoryErr;
|
|
|
|
//get the CSP name and the type
|
|
if(!CryptEnumProvidersU(
|
|
dwCSPIndex,
|
|
NULL,
|
|
0,
|
|
&(pCSPInfo->dwCSPType),
|
|
pCSPInfo->pwszCSPName,
|
|
&cbSize))
|
|
goto TryNext;
|
|
|
|
if(!CryptAcquireContextU(&hProv,
|
|
NULL,
|
|
pCSPInfo->pwszCSPName,
|
|
pCSPInfo->dwCSPType,
|
|
CRYPT_VERIFYCONTEXT))
|
|
goto TryNext;
|
|
|
|
//get the max/min of key length for both signature and encryption
|
|
dwFlags=CRYPT_FIRST;
|
|
cbSize=sizeof(paramData);
|
|
memset(¶mData, 0, sizeof(PROV_ENUMALGS_EX));
|
|
|
|
while(CryptGetProvParam(
|
|
hProv,
|
|
PP_ENUMALGS_EX,
|
|
(BYTE *) ¶mData,
|
|
&cbSize,
|
|
dwFlags))
|
|
{
|
|
if (ALG_CLASS_SIGNATURE == GET_ALG_CLASS(paramData.aiAlgid))
|
|
{
|
|
pCSPInfo->fSignature=TRUE;
|
|
pCSPInfo->dwMaxSign = paramData.dwMaxLen;
|
|
pCSPInfo->dwMinSign = paramData.dwMinLen;
|
|
}
|
|
|
|
if (ALG_CLASS_KEY_EXCHANGE == GET_ALG_CLASS(paramData.aiAlgid))
|
|
{
|
|
pCSPInfo->fEncryption=TRUE;
|
|
pCSPInfo->dwMaxEncrypt = paramData.dwMaxLen;
|
|
pCSPInfo->dwMinEncrypt = paramData.dwMinLen;
|
|
}
|
|
|
|
dwFlags=0;
|
|
cbSize=sizeof(paramData);
|
|
memset(¶mData, 0, sizeof(PROV_ENUMALGS_EX));
|
|
}
|
|
|
|
//the min/max has to within the limit
|
|
if(pCSPInfo->fSignature)
|
|
{
|
|
if(pCSPInfo->dwMaxSign < g_rgdwSmallKeyLength[0])
|
|
pCSPInfo->fSignature=FALSE;
|
|
|
|
if(pCSPInfo->dwMinSign > g_rgdwKeyLength[g_dwKeyLengthCount-1])
|
|
pCSPInfo->fSignature=FALSE;
|
|
|
|
}
|
|
|
|
if(pCSPInfo->fEncryption)
|
|
{
|
|
if(pCSPInfo->dwMaxEncrypt < g_rgdwSmallKeyLength[0])
|
|
pCSPInfo->fEncryption=FALSE;
|
|
|
|
if(pCSPInfo->dwMinEncrypt > g_rgdwKeyLength[g_dwKeyLengthCount-1])
|
|
pCSPInfo->fEncryption=FALSE;
|
|
}
|
|
|
|
if((FALSE == pCSPInfo->fEncryption) && (FALSE==pCSPInfo->fSignature))
|
|
goto TryNext;
|
|
|
|
//decide the default key length
|
|
for(dwIndex=0; dwIndex<g_dwDefaultKeyCount; dwIndex++)
|
|
{
|
|
if((pCSPInfo->fSignature) && (0==pCSPInfo->dwDefaultSign))
|
|
{
|
|
if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinSign) &&
|
|
(g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxSign)
|
|
)
|
|
pCSPInfo->dwDefaultSign=g_rgdwDefaultKey[dwIndex];
|
|
}
|
|
|
|
if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt))
|
|
{
|
|
if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinEncrypt) &&
|
|
(g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxEncrypt)
|
|
)
|
|
pCSPInfo->dwDefaultEncrypt=g_rgdwDefaultKey[dwIndex];
|
|
}
|
|
}
|
|
|
|
//make sure that we have find a default
|
|
if((pCSPInfo->fSignature) && (0==pCSPInfo->dwDefaultSign))
|
|
goto TryNext;
|
|
|
|
if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt))
|
|
goto TryNext;
|
|
|
|
//decide the display list
|
|
if(pCSPInfo->fSignature)
|
|
{
|
|
if(pCSPInfo->dwMaxSign <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1])
|
|
{
|
|
pCSPInfo->pdwSignList=g_rgdwSmallKeyLength;
|
|
pCSPInfo->dwSignCount=g_dwSmallKeyLengthCount;
|
|
}
|
|
else
|
|
{
|
|
pCSPInfo->pdwSignList=g_rgdwKeyLength;
|
|
pCSPInfo->dwSignCount=g_dwKeyLengthCount;
|
|
}
|
|
}
|
|
|
|
|
|
if(pCSPInfo->fEncryption)
|
|
{
|
|
if(pCSPInfo->dwMaxEncrypt <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1])
|
|
{
|
|
pCSPInfo->pdwEncryptList=g_rgdwSmallKeyLength;
|
|
pCSPInfo->dwEncryptCount=g_dwSmallKeyLengthCount;
|
|
}
|
|
else
|
|
{
|
|
pCSPInfo->pdwEncryptList=g_rgdwKeyLength;
|
|
pCSPInfo->dwEncryptCount=g_dwKeyLengthCount;
|
|
}
|
|
}
|
|
|
|
|
|
//the CSP looks good
|
|
(pCEPWizardInfo->dwCSPCount)++;
|
|
|
|
//realloc to mapped to LocalRealloc which does not take NULL
|
|
if(1 == pCEPWizardInfo->dwCSPCount)
|
|
pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO));
|
|
else
|
|
pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)realloc(pCEPWizardInfo->rgCSPInfo,
|
|
(pCEPWizardInfo->dwCSPCount) * sizeof(CEP_CSP_INFO));
|
|
|
|
if(NULL==pCEPWizardInfo->rgCSPInfo)
|
|
{
|
|
pCEPWizardInfo->dwCSPCount=0;
|
|
goto MemoryErr;
|
|
}
|
|
|
|
memcpy(&(pCEPWizardInfo->rgCSPInfo[(pCEPWizardInfo->dwCSPCount)-1]),
|
|
pCSPInfo, sizeof(CEP_CSP_INFO));
|
|
|
|
free(pCSPInfo);
|
|
|
|
pCSPInfo=NULL;
|
|
|
|
//we default to use RSA_FULL
|
|
if(0 == _wcsicmp(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].pwszCSPName,
|
|
MS_DEF_PROV_W))
|
|
{
|
|
if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fSignature)
|
|
{
|
|
iDefaultSignature=pCEPWizardInfo->dwCSPCount-1;
|
|
}
|
|
|
|
if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fEncryption)
|
|
{
|
|
iDefaultEncryption=pCEPWizardInfo->dwCSPCount-1;
|
|
}
|
|
}
|
|
|
|
|
|
TryNext:
|
|
cbSize=0;
|
|
|
|
dwCSPIndex++;
|
|
|
|
if(pCSPInfo)
|
|
{
|
|
if(pCSPInfo->pwszCSPName)
|
|
free(pCSPInfo->pwszCSPName);
|
|
|
|
free(pCSPInfo);
|
|
}
|
|
|
|
pCSPInfo=NULL;
|
|
|
|
if(hProv)
|
|
CryptReleaseContext(hProv, 0);
|
|
|
|
hProv=NULL;
|
|
}
|
|
|
|
|
|
//we need to have some valid data
|
|
if((0==pCEPWizardInfo->dwCSPCount) || (NULL==pCEPWizardInfo->rgCSPInfo))
|
|
goto InvalidArgErr;
|
|
|
|
//get the default CSP selection
|
|
if(-1 != iDefaultSignature)
|
|
pCEPWizardInfo->dwSignProvIndex=iDefaultSignature;
|
|
else
|
|
{
|
|
//find the 1st signature CSP
|
|
for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgCSPInfo[dwIndex].fSignature)
|
|
{
|
|
pCEPWizardInfo->dwSignProvIndex=dwIndex;
|
|
break;
|
|
}
|
|
|
|
//we do no have signature CSPs
|
|
if(dwIndex == pCEPWizardInfo->dwCSPCount)
|
|
goto InvalidArgErr;
|
|
|
|
}
|
|
}
|
|
|
|
pCEPWizardInfo->dwSignKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].dwDefaultSign;
|
|
|
|
if(-1 != iDefaultEncryption)
|
|
pCEPWizardInfo->dwEncryptProvIndex=iDefaultEncryption;
|
|
else
|
|
{
|
|
//find the 1st exchange CSP
|
|
for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgCSPInfo[dwIndex].fEncryption)
|
|
{
|
|
pCEPWizardInfo->dwEncryptProvIndex=dwIndex;
|
|
break;
|
|
}
|
|
|
|
//we do no have encryption CSPs
|
|
if(dwIndex == pCEPWizardInfo->dwCSPCount)
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
pCEPWizardInfo->dwEncryptKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].dwDefaultEncrypt;
|
|
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
if(pCSPInfo)
|
|
{
|
|
if(pCSPInfo->pwszCSPName)
|
|
free(pCSPInfo->pwszCSPName);
|
|
|
|
free(pCSPInfo);
|
|
}
|
|
|
|
if(hProv)
|
|
CryptReleaseContext(hProv, 0);
|
|
|
|
if(pCEPWizardInfo->rgCSPInfo)
|
|
{
|
|
for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName)
|
|
free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName);
|
|
}
|
|
|
|
free(pCEPWizardInfo->rgCSPInfo);
|
|
}
|
|
|
|
pCEPWizardInfo->dwCSPCount=0;
|
|
|
|
pCEPWizardInfo->rgCSPInfo=NULL;
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// UpdateCEPRegistry
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI UpdateCEPRegistry(BOOL fPassword, BOOL fEnterpriseCA)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwDisposition=0;
|
|
LPWSTR pwszReg[]={MSCEP_REFRESH_LOCATION,
|
|
MSCEP_PASSWORD_LOCATION,
|
|
MSCEP_PASSWORD_MAX_LOCATION,
|
|
MSCEP_PASSWORD_VALIDITY_LOCATION,
|
|
MSCEP_CACHE_REQUEST_LOCATION,
|
|
MSCEP_CATYPE_LOCATION};
|
|
DWORD dwRegCount=0;
|
|
DWORD dwRegIndex=0;
|
|
|
|
|
|
HKEY hKey=NULL;
|
|
|
|
|
|
//we delete all existing CEP related registry keys
|
|
dwRegCount=sizeof(pwszReg)/sizeof(pwszReg[0]);
|
|
|
|
for(dwRegIndex=0; dwRegIndex < dwRegCount; dwRegIndex++)
|
|
{
|
|
RegDeleteKeyU(HKEY_LOCAL_MACHINE, pwszReg[dwRegIndex]);
|
|
}
|
|
|
|
//password
|
|
if (ERROR_SUCCESS != RegCreateKeyExU(
|
|
HKEY_LOCAL_MACHINE,
|
|
MSCEP_PASSWORD_LOCATION,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisposition))
|
|
goto RegErr;
|
|
|
|
if(fPassword)
|
|
dwDisposition=1;
|
|
else
|
|
dwDisposition=0;
|
|
|
|
if(ERROR_SUCCESS != RegSetValueExU(
|
|
hKey,
|
|
MSCEP_KEY_PASSWORD,
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&dwDisposition,
|
|
sizeof(dwDisposition)))
|
|
goto RegErr;
|
|
|
|
if(hKey)
|
|
RegCloseKey(hKey);
|
|
|
|
hKey=NULL;
|
|
|
|
//caType
|
|
dwDisposition=0;
|
|
|
|
if (ERROR_SUCCESS != RegCreateKeyExU(
|
|
HKEY_LOCAL_MACHINE,
|
|
MSCEP_CATYPE_LOCATION,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisposition))
|
|
goto RegErr;
|
|
|
|
if(fEnterpriseCA)
|
|
dwDisposition=1;
|
|
else
|
|
dwDisposition=0;
|
|
|
|
if(ERROR_SUCCESS != RegSetValueExU(
|
|
hKey,
|
|
MSCEP_KEY_CATYPE,
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&dwDisposition,
|
|
sizeof(dwDisposition)))
|
|
goto RegErr;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
if(hKey)
|
|
RegCloseKey(hKey);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(RegErr);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// EmptyCEPStore
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI EmptyCEPStore()
|
|
{
|
|
BOOL fResult=TRUE;
|
|
|
|
HCERTSTORE hCEPStore=NULL;
|
|
PCCERT_CONTEXT pCurCert=NULL;
|
|
|
|
if(NULL == (hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
|
|
ENCODE_TYPE,
|
|
NULL,
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG,
|
|
CEP_STORE_NAME)))
|
|
return TRUE;
|
|
|
|
|
|
if(NULL != (pCurCert=CertEnumCertificatesInStore(hCEPStore, NULL)))
|
|
{
|
|
CertFreeCertificateContext(pCurCert);
|
|
fResult=FALSE;
|
|
}
|
|
|
|
CertCloseStore(hCEPStore, 0);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// RemoveRACertificates
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI RemoveRACertificates()
|
|
{
|
|
PCCERT_CONTEXT pCurCert=NULL;
|
|
PCCERT_CONTEXT pPreCert=NULL;
|
|
PCCERT_CONTEXT pDupCert=NULL;
|
|
BOOL fResult=TRUE;
|
|
|
|
HCERTSTORE hCEPStore=NULL;
|
|
|
|
|
|
if(hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
|
|
ENCODE_TYPE,
|
|
NULL,
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG,
|
|
CEP_STORE_NAME))
|
|
{
|
|
while(pCurCert=CertEnumCertificatesInStore(hCEPStore,
|
|
pPreCert))
|
|
{
|
|
|
|
if(pDupCert=CertDuplicateCertificateContext(pCurCert))
|
|
{
|
|
if(!CertDeleteCertificateFromStore(pDupCert))
|
|
{
|
|
fResult=FALSE;
|
|
}
|
|
|
|
pDupCert=NULL;
|
|
}
|
|
else
|
|
fResult=FALSE;
|
|
|
|
pPreCert=pCurCert;
|
|
}
|
|
|
|
CertCloseStore(hCEPStore, 0);
|
|
}
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// FreeCEPWizardInfo
|
|
//
|
|
//------------------------------------------------------------------------
|
|
void WINAPI FreeCEPWizardInfo(CEP_WIZARD_INFO *pCEPWizardInfo)
|
|
{
|
|
DWORD dwIndex=0;
|
|
|
|
if(pCEPWizardInfo)
|
|
{
|
|
DestroyFonts(pCEPWizardInfo->hBigBold,
|
|
pCEPWizardInfo->hBold);
|
|
|
|
for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgpwszName[dwIndex])
|
|
free(pCEPWizardInfo->rgpwszName[dwIndex]);
|
|
}
|
|
|
|
if(pCEPWizardInfo->rgCSPInfo)
|
|
{
|
|
for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
|
|
{
|
|
if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName)
|
|
free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName);
|
|
}
|
|
|
|
free(pCEPWizardInfo->rgCSPInfo);
|
|
}
|
|
|
|
if(pCEPWizardInfo->pwszUserName)
|
|
{
|
|
free(pCEPWizardInfo->pwszUserName);
|
|
}
|
|
|
|
if(pCEPWizardInfo->pwszPassword)
|
|
{
|
|
SecureZeroMemory(pCEPWizardInfo->pwszPassword, sizeof(WCHAR) * wcslen(pCEPWizardInfo->pwszPassword));
|
|
free(pCEPWizardInfo->pwszPassword);
|
|
}
|
|
|
|
if(pCEPWizardInfo->hAccountToken)
|
|
{
|
|
CloseHandle(pCEPWizardInfo->hAccountToken);
|
|
}
|
|
|
|
if(pCEPWizardInfo->pIDsObjectPicker)
|
|
{
|
|
(pCEPWizardInfo->pIDsObjectPicker)->Release();
|
|
}
|
|
|
|
memset(pCEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO));
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CEPWizardInit
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI CEPWizardInit()
|
|
{
|
|
INITCOMMONCONTROLSEX initcomm = {
|
|
sizeof(initcomm), ICC_NATIVEFNTCTL_CLASS | ICC_LISTVIEW_CLASSES
|
|
};
|
|
|
|
return InitCommonControlsEx(&initcomm);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// IsValidInstallation
|
|
//
|
|
//------------------------------------------------------------------------
|
|
BOOL WINAPI IsValidInstallation(UINT *pidsMsg)
|
|
{
|
|
if(!IsNT5())
|
|
{
|
|
*pidsMsg=IDS_NO_NT5;
|
|
return FALSE;
|
|
}
|
|
|
|
if(!IsIISInstalled())
|
|
{
|
|
*pidsMsg=IDS_NO_IIS;
|
|
return FALSE;
|
|
}
|
|
|
|
if(!IsGoodCaInstalled())
|
|
{
|
|
*pidsMsg=IDS_NO_GOOD_CA;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CEPErrorMessageBox
|
|
//
|
|
//------------------------------------------------------------------------
|
|
int WINAPI CEPErrorMessageBox(
|
|
HWND hWnd,
|
|
UINT idsReason,
|
|
HRESULT hr,
|
|
UINT uType
|
|
)
|
|
{
|
|
return CEPErrorMessageBoxEx(hWnd,
|
|
idsReason,
|
|
hr,
|
|
uType,
|
|
IDS_CEP_ERROR_MSG_HR,
|
|
IDS_CEP_ERROR_MSG);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CEPErrorMessageBoxEx
|
|
//
|
|
//------------------------------------------------------------------------
|
|
int WINAPI CEPErrorMessageBoxEx(
|
|
HWND hWnd,
|
|
UINT idsReason,
|
|
HRESULT hr,
|
|
UINT uType,
|
|
UINT idsFormat1,
|
|
UINT idsFormat2
|
|
)
|
|
{
|
|
|
|
WCHAR wszReason[MAX_STRING_SIZE];
|
|
WCHAR wszCaption[MAX_STRING_SIZE];
|
|
UINT intReturn=0;
|
|
|
|
LPWSTR pwszText=NULL;
|
|
LPWSTR pwszErrorMsg=NULL;
|
|
|
|
if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption)/sizeof(WCHAR)))
|
|
goto CLEANUP;
|
|
|
|
if(!LoadStringU(g_hModule, idsReason, wszReason, sizeof(wszReason)/sizeof(WCHAR)))
|
|
goto CLEANUP;
|
|
|
|
if(!FAILED(hr))
|
|
hr=E_FAIL;
|
|
|
|
//using W version because this is a NT5 only function call
|
|
if(FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
hr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPWSTR) &pwszErrorMsg,
|
|
0,
|
|
NULL))
|
|
{
|
|
|
|
if(!FormatMessageUnicode(&pwszText, idsFormat1, wszReason, pwszErrorMsg))
|
|
goto CLEANUP;
|
|
|
|
}
|
|
else
|
|
{
|
|
if(!FormatMessageUnicode(&pwszText, idsFormat2, wszReason))
|
|
goto CLEANUP;
|
|
}
|
|
|
|
intReturn=MessageBoxU(hWnd, pwszText, wszCaption, uType);
|
|
|
|
|
|
CLEANUP:
|
|
|
|
if(pwszText)
|
|
LocalFree((HLOCAL)pwszText);
|
|
|
|
if(pwszErrorMsg)
|
|
LocalFree((HLOCAL)pwszErrorMsg);
|
|
|
|
return intReturn;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CEPMessageBox
|
|
//
|
|
//------------------------------------------------------------------------
|
|
int WINAPI CEPMessageBox(
|
|
HWND hWnd,
|
|
UINT idsText,
|
|
UINT uType
|
|
)
|
|
{
|
|
|
|
WCHAR wszText[MAX_STRING_SIZE];
|
|
WCHAR wszCaption[MAX_STRING_SIZE];
|
|
UINT intReturn=0;
|
|
|
|
if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption)/sizeof(WCHAR)))
|
|
return 0;
|
|
|
|
if(!LoadStringU(g_hModule, idsText, wszText, sizeof(wszText)/sizeof(WCHAR)))
|
|
return 0;
|
|
|
|
intReturn=MessageBoxU(hWnd, wszText, wszCaption, uType);
|
|
|
|
return intReturn;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// SetControlFont
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void WINAPI SetControlFont(
|
|
IN HFONT hFont,
|
|
IN HWND hwnd,
|
|
IN INT nId
|
|
)
|
|
{
|
|
if( hFont )
|
|
{
|
|
HWND hwndControl = GetDlgItem(hwnd, nId);
|
|
|
|
if( hwndControl )
|
|
{
|
|
SetWindowFont(hwndControl, hFont, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// SetupFonts
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI SetupFonts(
|
|
IN HINSTANCE hInstance,
|
|
IN HWND hwnd,
|
|
IN HFONT *pBigBoldFont,
|
|
IN HFONT *pBoldFont
|
|
)
|
|
{
|
|
//
|
|
// Create the fonts we need based on the dialog font
|
|
//
|
|
NONCLIENTMETRICS ncm = {0};
|
|
ncm.cbSize = sizeof(ncm);
|
|
|
|
if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0))
|
|
return FALSE;
|
|
|
|
LOGFONT BigBoldLogFont = ncm.lfMessageFont;
|
|
LOGFONT BoldLogFont = ncm.lfMessageFont;
|
|
|
|
//
|
|
// Create Big Bold Font and Bold Font
|
|
//
|
|
BigBoldLogFont.lfWeight = FW_BOLD;
|
|
BoldLogFont.lfWeight = FW_BOLD;
|
|
|
|
INT BigBoldFontSize = 12;
|
|
|
|
HDC hdc = GetDC( hwnd );
|
|
|
|
if( hdc )
|
|
{
|
|
BigBoldLogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * BigBoldFontSize / 72);
|
|
|
|
*pBigBoldFont = CreateFontIndirect(&BigBoldLogFont);
|
|
*pBoldFont = CreateFontIndirect(&BoldLogFont);
|
|
|
|
ReleaseDC(hwnd,hdc);
|
|
|
|
if(*pBigBoldFont && *pBoldFont)
|
|
return TRUE;
|
|
else
|
|
{
|
|
if( *pBigBoldFont )
|
|
{
|
|
DeleteObject(*pBigBoldFont);
|
|
*pBigBoldFont=NULL;
|
|
}
|
|
|
|
if( *pBoldFont )
|
|
{
|
|
DeleteObject(*pBoldFont);
|
|
*pBoldFont=NULL;
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// DestroyFonts
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void WINAPI DestroyFonts(
|
|
IN HFONT hBigBoldFont,
|
|
IN HFONT hBoldFont
|
|
)
|
|
{
|
|
if( hBigBoldFont )
|
|
{
|
|
DeleteObject( hBigBoldFont );
|
|
}
|
|
|
|
if( hBoldFont )
|
|
{
|
|
DeleteObject( hBoldFont );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// FormatMessageUnicode
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI FormatMessageUnicode(LPWSTR *ppwszFormat,UINT ids,...)
|
|
{
|
|
// get format string from resources
|
|
WCHAR wszFormat[1000];
|
|
va_list argList;
|
|
DWORD cbMsg=0;
|
|
BOOL fResult=FALSE;
|
|
HRESULT hr=S_OK;
|
|
|
|
if(NULL == ppwszFormat)
|
|
goto InvalidArgErr;
|
|
|
|
if(!LoadStringU(g_hModule, ids, wszFormat, sizeof(wszFormat)/sizeof(WCHAR)))
|
|
goto LoadStringError;
|
|
|
|
// format message into requested buffer
|
|
va_start(argList, ids);
|
|
|
|
cbMsg = FormatMessageU(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
|
|
wszFormat,
|
|
0, // dwMessageId
|
|
0, // dwLanguageId
|
|
(LPWSTR) (ppwszFormat),
|
|
0, // minimum size to allocate
|
|
&argList);
|
|
|
|
va_end(argList);
|
|
|
|
if(!cbMsg)
|
|
goto FormatMessageError;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult=FALSE;
|
|
|
|
goto CommonReturn;
|
|
|
|
|
|
TRACE_ERROR(LoadStringError);
|
|
TRACE_ERROR(FormatMessageError);
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// AddLogSourceToRegistry
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT WINAPI AddLogSourceToRegistry(LPWSTR pwszMsgDLL)
|
|
{
|
|
DWORD dwError=ERROR_SUCCESS;
|
|
DWORD dwData=0;
|
|
WCHAR const *pwszRegPath = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
|
|
WCHAR NameBuf[MAX_STRING_SIZE];
|
|
|
|
HKEY hkey = NULL;
|
|
|
|
|
|
wcscpy(NameBuf, pwszRegPath);
|
|
wcscat(NameBuf, MSCEP_EVENT_LOG);
|
|
|
|
// Create a new key for our application
|
|
if(ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, NameBuf, &hkey))
|
|
{
|
|
if(ERROR_SUCCESS != (dwError = RegCreateKey(HKEY_LOCAL_MACHINE, NameBuf, &hkey)))
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Add the Event-ID message-file name to the subkey
|
|
|
|
dwError = RegSetValueEx(
|
|
hkey,
|
|
L"EventMessageFile",
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(const BYTE *) pwszMsgDLL,
|
|
(wcslen(pwszMsgDLL) + 1) * sizeof(WCHAR));
|
|
|
|
if(ERROR_SUCCESS != dwError)
|
|
goto CLEANUP;
|
|
|
|
// Set the supported types flags and add it to the subkey
|
|
|
|
dwData = EVENTLOG_ERROR_TYPE |
|
|
EVENTLOG_WARNING_TYPE |
|
|
EVENTLOG_INFORMATION_TYPE;
|
|
|
|
dwError = RegSetValueEx(
|
|
hkey,
|
|
L"TypesSupported",
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &dwData,
|
|
sizeof(DWORD));
|
|
if(ERROR_SUCCESS != dwError)
|
|
goto CLEANUP;
|
|
|
|
dwError=ERROR_SUCCESS;
|
|
|
|
CLEANUP:
|
|
|
|
if (NULL != hkey)
|
|
{
|
|
RegCloseKey(hkey);
|
|
}
|
|
return(HRESULT_FROM_WIN32(dwError));
|
|
}
|
|
|
|
|
|
LPWSTR
|
|
GetAccountDomainName(BOOL fDC)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the name of the account domain for this machine.
|
|
|
|
For workstatations, the account domain is the netbios computer name.
|
|
For DCs, the account domain is the netbios domain name.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
Returns a pointer to the name. The name should be free using NetApiBufferFree.
|
|
|
|
NULL - on error.
|
|
|
|
--*/
|
|
{
|
|
DWORD WinStatus;
|
|
|
|
LPWSTR AllocatedName = NULL;
|
|
|
|
|
|
//
|
|
// If this machine is a domain controller,
|
|
// get the domain name.
|
|
//
|
|
|
|
if ( fDC )
|
|
{
|
|
|
|
WinStatus = NetpGetDomainName( &AllocatedName );
|
|
|
|
if ( WinStatus != NO_ERROR )
|
|
{
|
|
SetLastError(WinStatus);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Otherwise, the 'account domain' is the computername
|
|
//
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
WinStatus = NetpGetComputerName( &AllocatedName );
|
|
|
|
if ( WinStatus != NO_ERROR )
|
|
{
|
|
SetLastError(WinStatus);
|
|
return NULL;
|
|
}
|
|
|
|
}
|
|
|
|
return AllocatedName;
|
|
}
|