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.
664 lines
17 KiB
664 lines
17 KiB
/*
|
|
|
|
Copyright (c) 1997, Microsoft Corporation, all rights reserved
|
|
|
|
Description:
|
|
|
|
History:
|
|
|
|
*/
|
|
#include <nt.h> // Required by windows.h
|
|
#include <ntrtl.h> // Required by windows.h
|
|
#include <nturtl.h> // Required by windows.h
|
|
#include <windows.h> // Win32 base API's
|
|
|
|
#include <schannel.h>
|
|
#define SECURITY_WIN32
|
|
#include <sspi.h> // For CredHandle
|
|
#include <wincrypt.h> // Required by sclogon.h
|
|
#include <eaptypeid.h>
|
|
#include <rasauth.h> // Required by raseapif.h
|
|
#include <eaptypeid.h>
|
|
#include <raseapif.h>
|
|
#include <rasman.h> // For EAPLOGONINFO
|
|
#include "eaptls.h"
|
|
|
|
#include "ceapcfg.h"
|
|
|
|
|
|
extern "C"
|
|
DWORD
|
|
InvokeServerConfigUI(
|
|
IN HWND hWnd,
|
|
IN WCHAR* pwszMachineName,
|
|
IN BOOL fConfigInRegistry,
|
|
IN const BYTE* pConfigDataIn,
|
|
IN DWORD dwSizeofConfigDataIn,
|
|
OUT PBYTE* ppConfigDataOut,
|
|
OUT DWORD* pdwSizeofConfigDataOut
|
|
);
|
|
|
|
extern "C"
|
|
DWORD
|
|
DwGetGlobalConfig(
|
|
IN DWORD dwEapTypeId,
|
|
OUT PBYTE* ppbData,
|
|
OUT DWORD* pdwData);
|
|
|
|
extern "C"
|
|
DWORD
|
|
WINAPI PeapInvokeServerConfigUI(
|
|
IN HWND hWnd,
|
|
IN WCHAR* pwszMachineName,
|
|
IN BOOL fConfigInRegistry,
|
|
IN const BYTE* pConfigDataIn,
|
|
IN DWORD pdwSizeofConfigDataIn,
|
|
OUT PBYTE* ppConfigDataOut,
|
|
OUT DWORD* pdwConfigDataOut
|
|
|
|
);
|
|
|
|
|
|
extern "C"
|
|
DWORD
|
|
EapTlsInvokeIdentityUI(
|
|
IN BOOL fServer,
|
|
IN BOOL fRouterConfig,
|
|
IN DWORD dwFlags,
|
|
IN WCHAR* pszStoreName,
|
|
IN const WCHAR* pwszPhonebook,
|
|
IN const WCHAR* pwszEntry,
|
|
IN HWND hwndParent,
|
|
IN BYTE* pConnectionDataIn,
|
|
IN DWORD dwSizeOfConnectionDataIn,
|
|
IN BYTE* pUserDataIn,
|
|
IN DWORD dwSizeOfUserDataIn,
|
|
OUT BYTE** ppUserDataOut,
|
|
OUT DWORD* pdwSizeOfUserDataOut,
|
|
OUT WCHAR** ppwszIdentity
|
|
);
|
|
|
|
extern "C"
|
|
DWORD
|
|
RasEapInvokeConfigUI(
|
|
IN DWORD dwEapTypeId,
|
|
IN HWND hwndParent,
|
|
IN DWORD dwFlags,
|
|
IN BYTE* pConnectionDataIn,
|
|
IN DWORD dwSizeOfConnectionDataIn,
|
|
OUT BYTE** ppConnectionDataOut,
|
|
OUT DWORD* pdwSizeOfConnectionDataOut
|
|
);
|
|
|
|
extern "C"
|
|
DWORD
|
|
RasEapFreeMemory(
|
|
IN BYTE* pMemory
|
|
);
|
|
/*
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
Implementation of IEAPProviderConfig::Initialize
|
|
|
|
*/
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::Initialize(
|
|
LPCOLESTR pwszMachineName,
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR* puConnectionParam
|
|
)
|
|
{
|
|
size_t size;
|
|
WCHAR* pwsz = NULL;
|
|
DWORD dwErr = NO_ERROR;
|
|
|
|
*puConnectionParam = NULL;
|
|
|
|
if (dwEapTypeId != PPP_EAP_TLS && dwEapTypeId != PPP_EAP_PEAP)
|
|
{
|
|
dwErr = ERROR_NOT_SUPPORTED;
|
|
goto LDone;
|
|
}
|
|
|
|
size = wcslen(pwszMachineName);
|
|
|
|
pwsz = (WCHAR*) LocalAlloc(LPTR, (size + 1)*sizeof(WCHAR));
|
|
|
|
if (NULL == pwsz)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto LDone;
|
|
}
|
|
|
|
CopyMemory(pwsz, pwszMachineName, (size + 1)*sizeof(WCHAR));
|
|
*puConnectionParam = (ULONG_PTR)pwsz;
|
|
pwsz = NULL;
|
|
|
|
LDone:
|
|
|
|
LocalFree(pwsz);
|
|
|
|
return(HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
/*
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
Implementation of IEAPProviderConfig::Uninitialize
|
|
|
|
*/
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::Uninitialize(
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR uConnectionParam
|
|
)
|
|
{
|
|
LocalFree((VOID*)uConnectionParam);
|
|
return(HRESULT_FROM_WIN32(NO_ERROR));
|
|
}
|
|
|
|
/*
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
Implementation of IEAPProviderConfig::ServerInvokeConfigUI
|
|
hWnd - handle to the parent window
|
|
dwRes1 - reserved parameter (ignore)
|
|
dwRes2 - reserved parameter (ignore)
|
|
|
|
*/
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::ServerInvokeConfigUI(
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR uConnectionParam,
|
|
HWND hWnd,
|
|
DWORD_PTR dwRes1,
|
|
DWORD_PTR dwRes2
|
|
)
|
|
{
|
|
WCHAR* pwszMachineName;
|
|
HRESULT hr;
|
|
DWORD dwErr;
|
|
|
|
if (dwEapTypeId != PPP_EAP_TLS
|
|
#ifdef IMPL_PEAP
|
|
&& dwEapTypeId != PPP_EAP_PEAP
|
|
#endif
|
|
)
|
|
{
|
|
dwErr = ERROR_NOT_SUPPORTED;
|
|
goto LDone;
|
|
}
|
|
|
|
pwszMachineName = (WCHAR*)uConnectionParam;
|
|
|
|
if (NULL == pwszMachineName)
|
|
{
|
|
dwErr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if ( dwEapTypeId == PPP_EAP_TLS )
|
|
{
|
|
dwErr = InvokeServerConfigUI(hWnd, pwszMachineName,
|
|
TRUE, NULL, 0,
|
|
NULL, NULL);
|
|
}
|
|
#ifdef IMPL_PEAP
|
|
else
|
|
{
|
|
|
|
dwErr = PeapInvokeServerConfigUI(hWnd, pwszMachineName,
|
|
TRUE, NULL, 0,
|
|
NULL, NULL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LDone:
|
|
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
/*
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
Implementation of IEAPProviderConfig::RouterInvokeConfigUI
|
|
|
|
*/
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::RouterInvokeConfigUI(
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR uConnectionParam,
|
|
HWND hwndParent,
|
|
DWORD dwFlags,
|
|
BYTE* pConnectionDataIn,
|
|
DWORD dwSizeOfConnectionDataIn,
|
|
BYTE** ppConnectionDataOut,
|
|
DWORD* pdwSizeOfConnectionDataOut
|
|
)
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
BYTE* pConnectionDataOut = NULL;
|
|
DWORD dwSizeOfConnectionDataOut = 0;
|
|
|
|
*ppConnectionDataOut = NULL;
|
|
*pdwSizeOfConnectionDataOut = 0;
|
|
|
|
if (dwEapTypeId != PPP_EAP_TLS )
|
|
{
|
|
dwErr = ERROR_NOT_SUPPORTED;
|
|
goto LDone;
|
|
}
|
|
|
|
dwErr = RasEapInvokeConfigUI(
|
|
dwEapTypeId,
|
|
hwndParent,
|
|
dwFlags,
|
|
pConnectionDataIn,
|
|
dwSizeOfConnectionDataIn,
|
|
&pConnectionDataOut,
|
|
&dwSizeOfConnectionDataOut);
|
|
|
|
if ( (NO_ERROR == dwErr)
|
|
&& (0 != dwSizeOfConnectionDataOut))
|
|
{
|
|
*ppConnectionDataOut = (BYTE*)CoTaskMemAlloc(dwSizeOfConnectionDataOut);
|
|
|
|
if (NULL == *ppConnectionDataOut)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto LDone;
|
|
}
|
|
|
|
CopyMemory(*ppConnectionDataOut, pConnectionDataOut,
|
|
dwSizeOfConnectionDataOut);
|
|
*pdwSizeOfConnectionDataOut = dwSizeOfConnectionDataOut;
|
|
}
|
|
|
|
LDone:
|
|
|
|
RasEapFreeMemory(pConnectionDataOut);
|
|
|
|
return(HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
/*
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
Implementation of IEAPProviderConfig::RouterInvokeCredentialsUI
|
|
|
|
*/
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::RouterInvokeCredentialsUI(
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR uConnectionParam,
|
|
HWND hwndParent,
|
|
DWORD dwFlags,
|
|
BYTE* pConnectionDataIn,
|
|
DWORD dwSizeOfConnectionDataIn,
|
|
BYTE* pUserDataIn,
|
|
DWORD dwSizeOfUserDataIn,
|
|
BYTE** ppUserDataOut,
|
|
DWORD* pdwSizeOfUserDataOut
|
|
)
|
|
{
|
|
#define MAX_STORE_NAME_LENGTH MAX_COMPUTERNAME_LENGTH + 20
|
|
|
|
WCHAR awszStoreName[MAX_STORE_NAME_LENGTH + 1];
|
|
DWORD dwErr;
|
|
DWORD dwSizeOfUserDataOut;
|
|
BYTE* pUserDataOut = NULL;
|
|
WCHAR* pwszIdentityOut = NULL;
|
|
WCHAR* pwszMachineName;
|
|
BOOL fLocal = FALSE;
|
|
|
|
*ppUserDataOut = NULL;
|
|
*pdwSizeOfUserDataOut = 0;
|
|
|
|
if (dwEapTypeId != PPP_EAP_TLS )
|
|
{
|
|
dwErr = ERROR_NOT_SUPPORTED;
|
|
goto LDone;
|
|
}
|
|
|
|
pwszMachineName = (WCHAR*)uConnectionParam;
|
|
|
|
if (0 == *pwszMachineName)
|
|
{
|
|
fLocal = TRUE;
|
|
}
|
|
|
|
wcscpy(awszStoreName, L"\\\\");
|
|
wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH);
|
|
wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY"));
|
|
if ( dwEapTypeId == PPP_EAP_TLS )
|
|
{
|
|
dwErr = EapTlsInvokeIdentityUI(
|
|
FALSE /* fServer */,
|
|
TRUE /* fRouterConfig */,
|
|
dwFlags,
|
|
fLocal ? L"MY" : awszStoreName,
|
|
L"",
|
|
L"",
|
|
hwndParent,
|
|
pConnectionDataIn,
|
|
dwSizeOfConnectionDataIn,
|
|
pUserDataIn,
|
|
dwSizeOfUserDataIn,
|
|
&pUserDataOut,
|
|
&dwSizeOfUserDataOut,
|
|
&pwszIdentityOut);
|
|
|
|
if ( (NO_ERROR == dwErr)
|
|
&& (0 != dwSizeOfUserDataOut))
|
|
{
|
|
*ppUserDataOut = (BYTE*)CoTaskMemAlloc(dwSizeOfUserDataOut);
|
|
|
|
if (NULL == *ppUserDataOut)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto LDone;
|
|
}
|
|
|
|
CopyMemory(*ppUserDataOut, pUserDataOut, dwSizeOfUserDataOut);
|
|
*pdwSizeOfUserDataOut = dwSizeOfUserDataOut;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Show PEAP dialog to get identity for router...
|
|
}
|
|
|
|
LDone:
|
|
|
|
RasEapFreeMemory(pUserDataOut);
|
|
RasEapFreeMemory((BYTE*)pwszIdentityOut);
|
|
|
|
return(HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::ServerInvokeConfigUI2(
|
|
DWORD dwEapTypeId,
|
|
ULONG_PTR uConnectionParam,
|
|
HWND hWnd,
|
|
const BYTE* pConfigDataIn,
|
|
DWORD dwSizeOfConfigDataIn,
|
|
BYTE** ppConfigDataOut,
|
|
DWORD* pdwSizeOfConfigDataOut
|
|
)
|
|
{
|
|
WCHAR *pwszMachineName = (WCHAR *)uConnectionParam;
|
|
DWORD dwErr = NO_ERROR;
|
|
PBYTE pbConfigDataOut = NULL;
|
|
DWORD dwSizeofConfigDataOut;
|
|
|
|
if( ((PPP_EAP_TLS != dwEapTypeId)
|
|
&& (PPP_EAP_PEAP != dwEapTypeId))
|
|
|| (NULL == pwszMachineName)
|
|
|| (NULL == ppConfigDataOut)
|
|
|| (NULL == pdwSizeOfConfigDataOut))
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
*ppConfigDataOut = NULL;
|
|
*pdwSizeOfConfigDataOut = 0;
|
|
|
|
if(PPP_EAP_TLS == dwEapTypeId)
|
|
{
|
|
dwErr = InvokeServerConfigUI(
|
|
hWnd,
|
|
pwszMachineName,
|
|
FALSE,
|
|
pConfigDataIn,
|
|
dwSizeOfConfigDataIn,
|
|
&pbConfigDataOut,
|
|
&dwSizeofConfigDataOut);
|
|
}
|
|
else
|
|
{
|
|
dwErr = PeapInvokeServerConfigUI(
|
|
hWnd,
|
|
pwszMachineName,
|
|
FALSE,
|
|
pConfigDataIn,
|
|
dwSizeOfConfigDataIn,
|
|
&pbConfigDataOut,
|
|
&dwSizeofConfigDataOut);
|
|
}
|
|
|
|
if( (NO_ERROR != dwErr)
|
|
|| (NULL == pbConfigDataOut)
|
|
|| (0 == dwSizeofConfigDataOut))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
*ppConfigDataOut = (BYTE *)CoTaskMemAlloc(dwSizeofConfigDataOut);
|
|
if(NULL == *ppConfigDataOut)
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
CopyMemory(*ppConfigDataOut, pbConfigDataOut, dwSizeofConfigDataOut);
|
|
*pdwSizeOfConfigDataOut = dwSizeofConfigDataOut;
|
|
|
|
done:
|
|
if(NULL != pbConfigDataOut)
|
|
{
|
|
RtlSecureZeroMemory(pbConfigDataOut, dwSizeofConfigDataOut);
|
|
RasEapFreeMemory(pbConfigDataOut);
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CEapCfg::GetGlobalConfig(
|
|
DWORD dwEapTypeId,
|
|
BYTE** ppConfigDataOut,
|
|
DWORD* pdwSizeofConfigDataOut
|
|
)
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
DWORD dwSize = 0;
|
|
PBYTE pbData = NULL;
|
|
|
|
if( ((PPP_EAP_TLS != dwEapTypeId)
|
|
&& (PPP_EAP_PEAP != dwEapTypeId))
|
|
|| (NULL == ppConfigDataOut)
|
|
|| (NULL == pdwSizeofConfigDataOut))
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
*ppConfigDataOut = NULL;
|
|
*pdwSizeofConfigDataOut = 0;
|
|
|
|
dwErr = DwGetGlobalConfig(dwEapTypeId,
|
|
&pbData,
|
|
&dwSize);
|
|
|
|
if(NO_ERROR != dwErr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
*ppConfigDataOut = (BYTE *) CoTaskMemAlloc(dwSize);
|
|
if(NULL == *ppConfigDataOut)
|
|
{
|
|
dwErr = E_OUTOFMEMORY;
|
|
goto done;
|
|
}
|
|
|
|
CopyMemory(*ppConfigDataOut, pbData, dwSize);
|
|
*pdwSizeofConfigDataOut = dwSize;
|
|
|
|
done:
|
|
if(NULL != pbData)
|
|
{
|
|
RtlSecureZeroMemory(pbData, dwSize);
|
|
LocalFree(pbData);
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|
|
|
|
extern "C"
|
|
{
|
|
//utility function kept here so that we dont have to get the COM junk in other files
|
|
|
|
DWORD PeapEapInfoInvokeServerConfigUI (
|
|
HWND hWndParent,
|
|
LPWSTR lpwszMachineName,
|
|
PPEAP_EAP_INFO pEapInfo,
|
|
const BYTE* pbConfigDataIn,
|
|
DWORD dwSizeOfConfigDataIn,
|
|
PBYTE* ppbConfigDataOut,
|
|
DWORD* pdwSizeOfConfigDataOut
|
|
)
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
GUID guid;
|
|
HRESULT hr = S_OK;
|
|
ULONG_PTR uConnection = 0;
|
|
CComPtr<IEAPProviderConfig> spEAPConfig;
|
|
CComPtr<IEAPProviderConfig2> spEAPConfig2;
|
|
|
|
if ( NULL == ppbConfigDataOut ||
|
|
NULL == pdwSizeOfConfigDataOut
|
|
)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto L_ERR;
|
|
}
|
|
hr = CLSIDFromString(pEapInfo->lpwszConfigClsId, &guid);
|
|
|
|
if (FAILED(hr)) goto L_ERR;
|
|
|
|
//
|
|
// First try and see if the eap supports IEAPProviderConfig2
|
|
// interface. If this fails, try IEAPProviderConfig interface.
|
|
//
|
|
hr = CoCreateInstance(
|
|
guid,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IEAPProviderConfig2),
|
|
(LPVOID *)&spEAPConfig2);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
|
|
// Create the EAP provider object
|
|
// ----------------------------------------------------------------
|
|
hr = CoCreateInstance( guid,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IEAPProviderConfig),
|
|
(LPVOID *) &spEAPConfig);
|
|
if (FAILED(hr )) goto L_ERR;
|
|
|
|
// Configure this EAP provider
|
|
// ----------------------------------------------------------------
|
|
// EAP configure displays its own error message, so no hr is kept
|
|
|
|
if ( !FAILED(spEAPConfig->Initialize(lpwszMachineName,
|
|
pEapInfo->dwTypeId, &uConnection)))
|
|
{
|
|
spEAPConfig->ServerInvokeConfigUI(pEapInfo->dwTypeId,
|
|
uConnection, hWndParent, 0, 0);
|
|
|
|
spEAPConfig->Uninitialize(pEapInfo->dwTypeId,
|
|
uConnection);
|
|
}
|
|
|
|
if ( hr == E_NOTIMPL )
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
if(!FAILED(spEAPConfig2->Initialize(lpwszMachineName,
|
|
pEapInfo->dwTypeId,
|
|
&uConnection)))
|
|
{
|
|
PBYTE pbConfigDataOut = NULL;
|
|
DWORD dwSizeOfConfigDataOut = 0;
|
|
|
|
if(!FAILED(spEAPConfig2->ServerInvokeConfigUI2(
|
|
pEapInfo->dwTypeId,
|
|
uConnection,
|
|
hWndParent,
|
|
pbConfigDataIn,
|
|
dwSizeOfConfigDataIn,
|
|
&pbConfigDataOut,
|
|
&dwSizeOfConfigDataOut)))
|
|
{
|
|
|
|
if( (NULL == pbConfigDataOut)
|
|
|| (0 == dwSizeOfConfigDataOut))
|
|
{
|
|
//
|
|
// we are done
|
|
//
|
|
goto L_ERR;
|
|
}
|
|
|
|
//
|
|
// Copy over the data
|
|
//
|
|
*ppbConfigDataOut = (BYTE *) LocalAlloc(LPTR, dwSizeOfConfigDataOut);
|
|
if(NULL == *ppbConfigDataOut)
|
|
{
|
|
CoTaskMemFree(pbConfigDataOut);
|
|
dwRetCode = E_OUTOFMEMORY;
|
|
}
|
|
|
|
CopyMemory(*ppbConfigDataOut,
|
|
pbConfigDataOut,
|
|
dwSizeOfConfigDataOut);
|
|
|
|
*pdwSizeOfConfigDataOut = dwSizeOfConfigDataOut;
|
|
CoTaskMemFree(pbConfigDataOut);
|
|
}
|
|
|
|
spEAPConfig2->Uninitialize(pEapInfo->dwTypeId,
|
|
uConnection);
|
|
|
|
}
|
|
}
|
|
|
|
L_ERR:
|
|
if ( FAILED(hr) )
|
|
{
|
|
dwRetCode = hr;
|
|
}
|
|
|
|
|
|
return dwRetCode;
|
|
}
|
|
|
|
}
|
|
|