596 lines
16 KiB
C
596 lines
16 KiB
C
// Copyright (c) 2000, Microsoft Corporation, all rights reserved
|
|
//
|
|
// IPSecPolicy.c
|
|
// Remote Access Common Dialog APIs
|
|
// IPSecPolicy dialogs
|
|
//
|
|
// 10/04/2000 Gang Zhao
|
|
//
|
|
|
|
|
|
#include "rasdlgp.h"
|
|
#include <rasauth.h>
|
|
#include <rrascfg.h>
|
|
#include <ras.h>
|
|
#include <mprapi.h>
|
|
#include <mprerror.h>
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Help maps
|
|
//----------------------------------------------------------------------------
|
|
|
|
static DWORD g_adwCiHelp[] =
|
|
{
|
|
CID_CI_CB_PresharedKey, HID_CI_CB_PresharedKey,
|
|
CID_CI_ST_Key, HID_CI_EB_PSK,
|
|
CID_CI_EB_PSK, HID_CI_EB_PSK,
|
|
0, 0
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Local datatypes
|
|
//----------------------------------------------------------------------------
|
|
typedef struct
|
|
_CIARGS
|
|
{
|
|
EINFO * pEinfo;
|
|
|
|
}
|
|
CIARGS;
|
|
|
|
typedef struct
|
|
_CIINFO
|
|
{
|
|
//Caller's arguments to the dialog
|
|
//
|
|
CIARGS * pArgs;
|
|
|
|
//Handles of this dialog and some of its controls
|
|
//for PSK
|
|
HWND hwndDlg;
|
|
HWND hwndCbPresharedKey;
|
|
HWND hwndStKey;
|
|
HWND hwndEbPSK;
|
|
|
|
//for User certs
|
|
//
|
|
HWND hwndCbUserCerts;
|
|
|
|
//for specific certs
|
|
//
|
|
HWND hwndCbSpecificCerts;
|
|
HWND hwndPbSelect;
|
|
HWND hwndLbCertsList;
|
|
|
|
}
|
|
CIINFO;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Local prototypes (alphabetically)
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
CiCommand(
|
|
IN CIINFO* pInfo,
|
|
IN WORD wNotification,
|
|
IN WORD wId,
|
|
IN HWND hwndCtrl );
|
|
|
|
INT_PTR CALLBACK
|
|
CiDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam );
|
|
|
|
BOOL
|
|
CiInit(
|
|
IN HWND hwndDlg,
|
|
IN CIARGS* pArgs );
|
|
|
|
VOID
|
|
CiTerm(
|
|
IN HWND hwndDlg );
|
|
|
|
BOOL
|
|
CiSave(
|
|
IN CIINFO* pInfo );
|
|
|
|
//
|
|
// Add new features for whistler bug 193987
|
|
// Pop Up a Dialog box for IPSec Policy
|
|
// currently just Pre-shared key/L2TP, and will have Certificates/L2TP in the future
|
|
//
|
|
|
|
BOOL
|
|
IPSecPolicyDlg(
|
|
IN HWND hwndOwner,
|
|
IN OUT EINFO* pArgs )
|
|
{
|
|
INT_PTR nStatus;
|
|
CIARGS args;
|
|
|
|
TRACE( "IPSecPolicyDlg" );
|
|
|
|
args.pEinfo = pArgs;
|
|
|
|
nStatus =
|
|
DialogBoxParam(
|
|
g_hinstDll,
|
|
MAKEINTRESOURCE( DID_CI_CustomIPSec ),
|
|
hwndOwner,
|
|
CiDlgProc,
|
|
(LPARAM )&args );
|
|
|
|
if (nStatus == -1)
|
|
{
|
|
ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
|
|
nStatus = FALSE;
|
|
}
|
|
|
|
return (nStatus) ? TRUE : FALSE;
|
|
}//end of IPSecPolicyDlg()
|
|
|
|
|
|
INT_PTR CALLBACK
|
|
CiDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam )
|
|
|
|
// DialogProc callback for the Custom IPSecPolicy dialog. Parameters
|
|
// and return value are as described for standard windows 'DialogProc's.
|
|
//
|
|
{
|
|
#if 0
|
|
TRACE4( "CiDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
|
|
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
|
|
#endif
|
|
|
|
switch (unMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
return CiInit( hwnd, (CIARGS* )lparam );
|
|
}
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
ContextHelp( g_adwCiHelp, hwnd, unMsg, wparam, lparam );
|
|
break;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
CIINFO* pInfo = (CIINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
|
|
ASSERT( pInfo );
|
|
|
|
return CiCommand(
|
|
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
|
|
}
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
CiTerm( hwnd );
|
|
break;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}//end of CiDlgProc()
|
|
|
|
|
|
BOOL
|
|
CiInit(
|
|
IN HWND hwndDlg,
|
|
IN CIARGS* pArgs )
|
|
|
|
// Called on WM_INITDIALOG. 'HwndDlg' is the handle of the phonebook
|
|
// dialog window. 'PArgs' is caller's arguments as passed to the stub
|
|
// API.
|
|
//
|
|
// Return false if focus was set, true otherwise, i.e. as defined for
|
|
// WM_INITDIALOG.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
DWORD dwAr;
|
|
CIINFO* pInfo;
|
|
|
|
TRACE( "CiInit" );
|
|
|
|
// Allocate the dialog context block. Initialize minimally for proper
|
|
// cleanup, then attach to the dialog window.
|
|
//
|
|
{
|
|
pInfo = Malloc( sizeof(*pInfo) );
|
|
if (!pInfo)
|
|
{
|
|
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
|
|
EndDialog( hwndDlg, FALSE );
|
|
return TRUE;
|
|
}
|
|
|
|
ZeroMemory( pInfo, sizeof(*pInfo) );
|
|
pInfo->pArgs = pArgs;
|
|
pInfo->hwndDlg = hwndDlg;
|
|
|
|
SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
|
|
TRACE( "Context set" );
|
|
}
|
|
|
|
pInfo->hwndCbPresharedKey = GetDlgItem( hwndDlg, CID_CI_CB_PresharedKey );
|
|
ASSERT(pInfo->hwndCbPresharedKey);
|
|
pInfo->hwndStKey = GetDlgItem( hwndDlg, CID_CI_ST_Key );
|
|
ASSERT(pInfo->hwndStKey);
|
|
pInfo->hwndEbPSK = GetDlgItem( hwndDlg, CID_CI_EB_PSK );
|
|
ASSERT(pInfo->hwndEbPSK);
|
|
pInfo->hwndCbUserCerts = GetDlgItem( hwndDlg, CID_CI_CB_UserCerts );
|
|
ASSERT(pInfo->hwndCbUserCerts);
|
|
pInfo->hwndCbSpecificCerts = GetDlgItem( hwndDlg, CID_CI_CB_SpecificCerts );
|
|
ASSERT(pInfo->hwndCbSpecificCerts);
|
|
pInfo->hwndPbSelect = GetDlgItem( hwndDlg, CID_CI_PB_Select );
|
|
ASSERT(pInfo->hwndPbSelect);
|
|
pInfo->hwndLbCertsList = GetDlgItem( hwndDlg, CID_CI_LB_CertsList );
|
|
ASSERT(pInfo->hwndLbCertsList);
|
|
|
|
//Hide the User certs and Specific certs until the whistler server
|
|
ShowWindow( pInfo->hwndCbUserCerts, SW_HIDE );
|
|
ShowWindow( pInfo->hwndCbSpecificCerts, SW_HIDE );
|
|
ShowWindow( pInfo->hwndPbSelect, SW_HIDE );
|
|
ShowWindow( pInfo->hwndLbCertsList, SW_HIDE );
|
|
|
|
// Fill the EAP packages listbox and select the previously identified
|
|
// selection. The Properties button is disabled by default, but may
|
|
// be enabled when the EAP list selection is set.
|
|
//
|
|
{
|
|
BOOL fEnabled;
|
|
|
|
fEnabled = !!((pArgs->pEinfo->pEntry->dwIpSecFlags)& AR_F_IpSecPSK) ;
|
|
|
|
Button_SetCheck( pInfo->hwndCbPresharedKey, fEnabled );
|
|
|
|
EnableWindow( pInfo->hwndStKey, fEnabled );
|
|
EnableWindow( pInfo->hwndEbPSK, fEnabled );
|
|
Edit_LimitText( pInfo->hwndEbPSK, PWLEN ); //Limit the length of PSK
|
|
}
|
|
|
|
//
|
|
//Fill the Preshared Key in "*"s or just leave it bland if none
|
|
//is saved previously
|
|
//
|
|
//for Demand Dial, use MprAdmin.... router functions
|
|
//
|
|
if (pArgs->pEinfo->fRouter)
|
|
{
|
|
if( !(pArgs->pEinfo->fPSKCached) )
|
|
{
|
|
// Initialize the interface-information structure.
|
|
//
|
|
DWORD dwErr;
|
|
HANDLE hServer = NULL;
|
|
HANDLE hInterface = NULL;
|
|
WCHAR* pwszInterface = NULL;
|
|
WCHAR pszComputer[512];
|
|
MPR_INTERFACE_0 mi0;
|
|
MPR_CREDENTIALSEX_1 * pMc1 = NULL;
|
|
|
|
dwErr = NO_ERROR;
|
|
do {
|
|
dwErr = g_pMprAdminServerConnect(pArgs->pEinfo->pszRouter, &hServer);
|
|
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
TRACE("CiInit: MprAdminServerConnect failed!");
|
|
break;
|
|
}
|
|
|
|
ZeroMemory( &mi0, sizeof(mi0) );
|
|
|
|
mi0.dwIfType = ROUTER_IF_TYPE_FULL_ROUTER;
|
|
mi0.fEnabled = TRUE;
|
|
|
|
pwszInterface = StrDupWFromT( pArgs->pEinfo->pEntry->pszEntryName );
|
|
if (!pwszInterface)
|
|
{
|
|
TRACE("CiInit:pwszInterface conversion failed!");
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
lstrcpynW(
|
|
mi0.wszInterfaceName,
|
|
pwszInterface,
|
|
MAX_INTERFACE_NAME_LEN+1 );
|
|
|
|
// Get the interface handle
|
|
//
|
|
ASSERT( g_pMprAdminInterfaceGetHandle );
|
|
dwErr = g_pMprAdminInterfaceGetHandle(
|
|
hServer,
|
|
pwszInterface,
|
|
&hInterface,
|
|
FALSE);
|
|
|
|
if (dwErr)
|
|
{
|
|
TRACE1( "CiInit: MprAdminInterfaceGetHandle error %d", dwErr);
|
|
break;
|
|
}
|
|
|
|
//Get the IPSec Policy keys(PSK for Whislter)
|
|
//
|
|
ASSERT( g_pMprAdminInterfaceGetCredentialsEx );
|
|
dwErr = g_pMprAdminInterfaceGetCredentialsEx(
|
|
hServer,
|
|
hInterface,
|
|
1,
|
|
(LPBYTE *)&pMc1 );
|
|
if(dwErr)
|
|
{
|
|
TRACE1(
|
|
"CiInit: MprAdminInterfaceGetCredentialsEx error %d", dwErr);
|
|
break;
|
|
}
|
|
|
|
if ( !pMc1 )
|
|
{
|
|
TRACE(
|
|
"CiInit: MprAdminInterfaceGetCredentialsEx returns invalid credential pointer!");
|
|
|
|
dwErr = ERROR_CAN_NOT_COMPLETE;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if ( lstrlenA( pMc1->lpbCredentialsInfo ) >0 )
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );
|
|
|
|
// Whistler bug 254385 encode password when not being used
|
|
// Whistler bug 275526 NetVBL BVT Break: Routing BVT broken
|
|
//
|
|
ZeroMemory(
|
|
pMc1->lpbCredentialsInfo,
|
|
lstrlenA(pMc1->lpbCredentialsInfo) + 1 );
|
|
}
|
|
else
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK,TEXT("") );
|
|
}
|
|
|
|
ASSERT( g_pMprAdminBufferFree );
|
|
g_pMprAdminBufferFree( pMc1 );
|
|
}
|
|
|
|
}
|
|
while (FALSE) ;
|
|
|
|
// Cleanup
|
|
{
|
|
// If some operation failed, restore the router to the
|
|
// state it was previously in.
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK, TEXT("") );
|
|
}
|
|
|
|
// Close all handles, free all strings.
|
|
if ( pwszInterface )
|
|
{
|
|
Free0( pwszInterface );
|
|
}
|
|
|
|
if (hServer)
|
|
{
|
|
g_pMprAdminServerDisconnect( hServer );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
|
|
}
|
|
|
|
}
|
|
else //retrieve the credentials with Ras functions
|
|
{
|
|
// Look up cached PSK, from RASMAN or EINFO
|
|
//
|
|
if( !(pArgs->pEinfo->fPSKCached) )
|
|
{
|
|
DWORD dwErrRc;
|
|
RASCREDENTIALS rc;
|
|
|
|
ZeroMemory( &rc, sizeof(rc) );
|
|
rc.dwSize = sizeof(rc);
|
|
rc.dwMask = RASCM_PreSharedKey;
|
|
ASSERT( g_pRasGetCredentials );
|
|
TRACE( "RasGetCredentials" );
|
|
dwErrRc = g_pRasGetCredentials(
|
|
pInfo->pArgs->pEinfo->pFile->pszPath,
|
|
pInfo->pArgs->pEinfo->pEntry->pszEntryName,
|
|
&rc );
|
|
|
|
TRACE2( "RasGetCredentials=%d,m=%d", dwErrRc, rc.dwMask );
|
|
|
|
if (dwErrRc == 0 && (rc.dwMask & RASCM_PreSharedKey) && ( lstrlen(rc.szPassword) > 0 ) )
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK, TEXT("****************") );
|
|
}
|
|
else
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK,TEXT("") );
|
|
}
|
|
|
|
// Whistler bug 254385 encode password when not being used
|
|
//
|
|
ZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
|
|
}
|
|
else
|
|
{
|
|
SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
|
|
}
|
|
|
|
}
|
|
// Center dialog on the owner window.
|
|
//
|
|
CenterWindow( hwndDlg, GetParent( hwndDlg ) );
|
|
|
|
// Add context help button to title bar.
|
|
//
|
|
AddContextHelpButton( hwndDlg );
|
|
|
|
SetFocus( pInfo->hwndEbPSK );
|
|
|
|
return TRUE;
|
|
} //end of CiInit()
|
|
|
|
|
|
BOOL
|
|
CiCommand(
|
|
IN CIINFO* pInfo,
|
|
IN WORD wNotification,
|
|
IN WORD wId,
|
|
IN HWND hwndCtrl )
|
|
|
|
// Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
|
|
// is the notification code of the command. 'wId' is the control/menu
|
|
// identifier of the command. 'HwndCtrl' is the control window handle of
|
|
// the command.
|
|
//
|
|
// Returns true if processed message, false otherwise.
|
|
//
|
|
{
|
|
TRACE3( "CiCommand(n=%d,i=%d,c=$%x)",
|
|
(DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
|
|
|
|
switch (wId)
|
|
{
|
|
case CID_CI_EB_PSK:
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
case CID_CI_CB_PresharedKey:
|
|
{
|
|
BOOL fEnabled;
|
|
|
|
fEnabled = Button_GetCheck( pInfo->hwndCbPresharedKey );
|
|
EnableWindow( pInfo->hwndStKey, fEnabled );
|
|
EnableWindow( pInfo->hwndEbPSK, fEnabled );
|
|
}
|
|
break;
|
|
|
|
case IDOK:
|
|
{
|
|
if (CiSave( pInfo ))
|
|
{
|
|
EndDialog( pInfo->hwndDlg, TRUE );
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
case IDCANCEL:
|
|
{
|
|
TRACE( "Cancel pressed" );
|
|
EndDialog( pInfo->hwndDlg, FALSE );
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}//end of CiCommand()
|
|
|
|
BOOL
|
|
CiSave(
|
|
IN CIINFO* pInfo )
|
|
|
|
// Saves control contents to caller's PBENTRY argument. 'PInfo' is the
|
|
// dialog context.
|
|
//
|
|
// Returns TRUE if successful or false if invalid combination of
|
|
// selections was detected and reported.
|
|
//
|
|
{
|
|
TCHAR szPSK[PWLEN + 1];
|
|
BOOL fPskChecked = FALSE;
|
|
|
|
fPskChecked = Button_GetCheck( pInfo->hwndCbPresharedKey );
|
|
|
|
if ( fPskChecked )
|
|
{
|
|
GetWindowText( pInfo->hwndEbPSK, szPSK, PWLEN+1 );
|
|
|
|
if ( lstrlen( szPSK ) == 0 )
|
|
{
|
|
MsgDlgUtil( pInfo->hwndDlg, SID_HavetoEnterPSK, NULL, g_hinstDll, SID_PopupTitle );
|
|
return FALSE;
|
|
}
|
|
else if (!lstrcmp( szPSK, TEXT("****************")) ) //16 "*" means no change
|
|
{
|
|
;
|
|
}
|
|
else //save PSK to EINFO and mark the fPSKCached
|
|
{
|
|
// Whistler bug 224074 use only lstrcpyn's to prevent
|
|
// maliciousness
|
|
//
|
|
// Whistler bug 254385 encode password when not being used
|
|
// Assumed password was not encoded by GetWindowText()
|
|
//
|
|
lstrcpyn(
|
|
pInfo->pArgs->pEinfo->szPSK,
|
|
szPSK,
|
|
sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
|
|
EncodePassword( pInfo->pArgs->pEinfo->szPSK );
|
|
pInfo->pArgs->pEinfo->fPSKCached = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Whistler bug 224074 use only lstrcpyn's to prevent
|
|
// maliciousness
|
|
//
|
|
lstrcpyn(
|
|
pInfo->pArgs->pEinfo->szPSK,
|
|
TEXT(""),
|
|
sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
|
|
pInfo->pArgs->pEinfo->fPSKCached = FALSE;
|
|
}
|
|
|
|
// Whistler bug 254385 encode password when not being used
|
|
//
|
|
ZeroMemory( szPSK, sizeof(szPSK) );
|
|
|
|
//Change the value of dwIpSecFlags only along with a valid operation
|
|
//
|
|
pInfo->pArgs->pEinfo->pEntry->dwIpSecFlags = fPskChecked?AR_F_IpSecPSK : 0;
|
|
|
|
return TRUE;
|
|
}//end of CiSave()
|
|
|
|
|
|
VOID
|
|
CiTerm(
|
|
IN HWND hwndDlg )
|
|
|
|
// Dialog termination. Releases the context block. 'HwndDlg' is the
|
|
// handle of a dialog.
|
|
//
|
|
{
|
|
CIINFO* pInfo;
|
|
|
|
TRACE( "CiTerm" );
|
|
|
|
pInfo = (CIINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
|
|
if (pInfo)
|
|
{
|
|
Free( pInfo );
|
|
TRACE( "Context freed" );
|
|
}
|
|
}//end of CiTerm()
|