2025-11-28 00:35:46 +09:00

854 lines
30 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Utils.h"
#include <ipsectypes.h>
#include <objbase.h>
#include "InterfaceConfiguration.h"
//********************************************************************************************
// Function: SetCustomIpsecConfigurationOnInterface
//
// Description: Creates a demand dial interface and configures custom IPSec policies on it.
//
//********************************************************************************************
VOID SetCustomIpsecConfigurationOnInterface(
_In_opt_ LPWSTR serverName
)
{
DWORD status = ERROR_SUCCESS;
MPR_SERVER_HANDLE serverHandleAdmin = NULL;
HANDLE serverHandleConfig = NULL;
HANDLE interfaceHandleAdmin = NULL;
HANDLE interfaceHandleConfig = NULL;
wprintf(L"---------------------------------------------------------\n\n");
wprintf(L"Executing SetCustomIpsecConfigurationOnInterface on '%s'\n", \
(serverName == NULL) ? L"Current machine" : serverName);
// Try connecting to remoteAccess (RRAS) server for both administration and and configuration to
// get the handles serverHandleAdmin and serverHandleConfig. We cannot create/modify/retrieve
// interfaces configurations, if it fails to get either of these handles.
//
status = RemoteAccessServerConenct(serverName, &serverHandleAdmin, &serverHandleConfig);
// Both serverHandleAdmin and serverHandleConfig has to be valid.
//
if ((ERROR_SUCCESS != status) ||
(NULL == serverHandleAdmin) ||
(NULL == serverHandleConfig))
{
wprintf(L"RemoteAccessServerConenct failed. \
The RemoteAccess service might be stopped - Try after starting the RemoteAccess service.\n");
DisplayError(status);
goto Done;
}
// Create a new interface
//
status = CreateNewDoDInterface(serverHandleAdmin, serverHandleConfig, &interfaceHandleAdmin, &interfaceHandleConfig);
if (ERROR_SUCCESS != status)
{
wprintf(L"CreateNewDoDInterface failed.\n");
DisplayError(status);
goto Done;
}
// Set custom IPSec policies on interface
//
status = ConfigureCustomIPSecPolicyOnDoDInterface(serverHandleAdmin, serverHandleConfig, interfaceHandleAdmin, interfaceHandleConfig);
if (ERROR_SUCCESS != status)
{
wprintf(L"ConfigureCustomIPSecPolicyOnDoDInterface failed.\n");
DisplayError(status);
goto Done;
}
// Retrieve and display the interface configuration
//
status = DisplayDoDInterfaceConfiguration(serverHandleAdmin, interfaceHandleAdmin);
if (ERROR_SUCCESS != status)
{
wprintf(L"DisplayDoDInterfaceConfiguration failed.\n");
DisplayError(status);
goto Done;
}
Done:
RemoteAccessServerDisconenct(serverHandleAdmin, serverHandleConfig);
if (status != ERROR_SUCCESS)
{
wprintf(L"SetCustomIpsecConfigurationOnInterface failed\n");
DisplayError(status);
}
wprintf(L"---------------------------------------------------------\n\n");
}
//********************************************************************************************
// Function: RemoveCustomIpsecConfigurationFromInterface
//
// Description: Removes custom IPSec configuration from a demand dial interface.
//
//********************************************************************************************
VOID RemoveCustomIpsecConfigurationFromInterface(
_In_opt_ LPWSTR serverName
)
{
DWORD status = ERROR_SUCCESS;
MPR_SERVER_HANDLE serverHandleAdmin = NULL;
HANDLE serverHandleConfig = NULL;
HANDLE interfaceHandleAdmin = NULL;
HANDLE interfaceHandleConfig = NULL;
WCHAR interfaceName[256] = {0};
MPR_IF_CUSTOMINFOEX interfaceCustomConfigCurrent;
MPR_IF_CUSTOMINFOEX interfaceCustomConfigToBeUpdated;
ZeroMemory(&interfaceCustomConfigCurrent, sizeof(MPR_IF_CUSTOMINFOEX));
ZeroMemory(&interfaceCustomConfigToBeUpdated, sizeof(MPR_IF_CUSTOMINFOEX));
wprintf(L"---------------------------------------------------------\n\n");
wprintf(L"Executing RemoveCustomIpsecConfigurationFromInterface on '%s'\n", \
(serverName == NULL) ? L"Current machine" : serverName);
wprintf(L"\nEnter the interface name: ");
wscanf_s(L"%s", interfaceName, 256);
FlushCurrentLine();
// Try connecting to remoteAccess (RRAS) server for both administration and and configuration to
// get the handles serverHandleAdmin and serverHandleConfig. We cannot create/modify/retrieve
// interfaces configurations, if it fails to get either of these handles.
//
status = RemoteAccessServerConenct(serverName, &serverHandleAdmin, &serverHandleConfig);
// Both serverHandleAdmin and serverHandleConfig has to be valid.
//
if ((ERROR_SUCCESS != status) ||
(NULL == serverHandleAdmin) ||
(NULL == serverHandleConfig))
{
wprintf(L"RemoteAccessServerConenct failed. \
The RemoteAccess service might be stopped - Try after starting the RemoteAccess service.\n");
DisplayError(status);
goto Done;
}
status = g_pMprAdminInterfaceGetHandle(
serverHandleAdmin,
interfaceName,
&interfaceHandleAdmin,
FALSE
);
if (ERROR_SUCCESS != status)
{
if (ERROR_NO_SUCH_INTERFACE == status)
{
// Interface does not exist
//
wprintf(L"Interface '%s' does not exists.\n", interfaceName);
}
else
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceGetHandle failed.\n");
DisplayError(status);
}
goto Done;
}
status = g_pMprConfigInterfaceGetHandle(
serverHandleConfig,
interfaceName,
&interfaceHandleConfig
);
if (ERROR_SUCCESS != status)
{
if (ERROR_NO_SUCH_INTERFACE == status)
{
// Interface does not exist
//
wprintf(L"Interface '%s' does not exists.\n", interfaceName);
}
else
{
// some genuine error, we should return
//
wprintf(L"MprConfigInterfaceGetHandle failed.\n");
DisplayError(status);
}
goto Done;
}
// Retrieve and display the custom IPSec configuration on the interface (before removing the custom configuration);
//
status = DisplayDoDInterfaceConfiguration(serverHandleAdmin, interfaceHandleAdmin);
if (ERROR_SUCCESS != status)
{
wprintf(L"DisplayDoDInterfaceConfiguration failed.\n");
DisplayError(status);
goto Done;
}
// Retrieve the current custom configuration interface
//
interfaceCustomConfigCurrent.Header.revision = MPRAPI_MPR_IF_CUSTOM_CONFIG_OBJECT_REVISION_2;
interfaceCustomConfigCurrent.Header.type = MPRAPI_OBJECT_TYPE_IF_CUSTOM_CONFIG_OBJECT;
interfaceCustomConfigCurrent.Header.size = sizeof(MPR_IF_CUSTOMINFOEX);
status = g_pMprAdminInterfaceGetCustomInfoEx(
serverHandleAdmin, // hMprServer
interfaceHandleAdmin, // interfaceHandleAdmin
&interfaceCustomConfigCurrent // pCustomInfo
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceGetCustomInfoEx failed.\n");
DisplayError(status);
goto Done;
}
// Check whether custom configuration is available on the specified interface
//
if (!(interfaceCustomConfigCurrent.dwFlags & MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2))
{
wprintf(L"No custom configuration available on interface '%s'.\n", interfaceName);
goto Done;
}
wprintf(L"Removing custom configuration from interface '%s'.\n", interfaceName);
// Copy the current custom configuration object to the to be updated custom configuration
// object.
//
memcpy(&interfaceCustomConfigToBeUpdated, &interfaceCustomConfigCurrent, sizeof(MPR_IF_CUSTOMINFOEX));
// Remove the IPSec certificate configuration (if available)
//
if (interfaceCustomConfigCurrent.customIkev2Config.certificateName.cbData != 0 ||
interfaceCustomConfigCurrent.customIkev2Config.certificateHash.cbData != 0 )
{
wprintf(L"Removing the certificate configuration from interface '%s'.\n", interfaceName);
// In order to remove machine certificate configuration,
// set the cbData of certificateName (CERT_NAME_BLOB) to 0 and
// set the pbData of certificateName (CERT_NAME_BLOB) to NULL.
//set the cbData of certificateHash (CRYPT_HASH_BLOB) to 0 and
// set the pbData of certificateHash (CRYPT_HASH_BLOB) to NULL.
interfaceCustomConfigToBeUpdated.customIkev2Config.certificateName.cbData = 0;
interfaceCustomConfigToBeUpdated.customIkev2Config.certificateName.pbData = NULL;
interfaceCustomConfigToBeUpdated.customIkev2Config.certificateHash.cbData = 0;
interfaceCustomConfigToBeUpdated.customIkev2Config.certificateHash.pbData = NULL;
// Update the custom configuration on the interface
//
status = UpdateInterfaceCustomConfiguration(
serverHandleAdmin,
serverHandleConfig,
interfaceHandleAdmin,
interfaceHandleConfig,
&interfaceCustomConfigToBeUpdated
);
if (ERROR_SUCCESS != status)
{
wprintf(L"UpdateInterfaceCustomConfiguration failed.\n");
DisplayError(status);
goto Done;
}
// Retrieve and display the updated interface configuration
//
status = DisplayDoDInterfaceConfiguration(serverHandleAdmin, interfaceHandleAdmin);
if (ERROR_SUCCESS != status)
{
wprintf(L"DisplayDoDInterfaceConfiguration failed.\n");
DisplayError(status);
goto Done;
}
}
// Remove the IPSec custom policy configuration (if available)
//
if (interfaceCustomConfigCurrent.customIkev2Config.customPolicy != NULL)
{
wprintf(L"Removing the custom IPSec policy configuration from interface '%s'.\n", interfaceName);
// In order to remove custom IPsec policy set interfaceCustomConfigToBeUpdated.customPolicy to NULL
//
interfaceCustomConfigToBeUpdated.customIkev2Config.customPolicy = NULL;
// Update the custom configuration on the interface
//
status = UpdateInterfaceCustomConfiguration(
serverHandleAdmin,
serverHandleConfig,
interfaceHandleAdmin,
interfaceHandleConfig,
&interfaceCustomConfigToBeUpdated
);
if (ERROR_SUCCESS != status)
{
wprintf(L"UpdateInterfaceCustomConfiguration failed.\n");
DisplayError(status);
goto Done;
}
// Retrieve and display the updated interface configuration
//
status = DisplayDoDInterfaceConfiguration(serverHandleAdmin, interfaceHandleAdmin);
if (ERROR_SUCCESS != status)
{
wprintf(L"DisplayDoDInterfaceConfiguration failed.\n");
DisplayError(status);
goto Done;
}
}
// Remove the IPSec custom policy configuration
//
wprintf(L"Removing all the custom configuration from interface '%s'.\n", interfaceName);
// In order to remove custom IPsec configuration clear the MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2
// flag from interfaceCustomConfigToBeUpdated.dwFlags
//
interfaceCustomConfigToBeUpdated.dwFlags &= ~(MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2);
// Update the custom configuration on the interface
//
status = UpdateInterfaceCustomConfiguration(
serverHandleAdmin,
serverHandleConfig,
interfaceHandleAdmin,
interfaceHandleConfig,
&interfaceCustomConfigToBeUpdated
);
if (ERROR_SUCCESS != status)
{
wprintf(L"UpdateInterfaceCustomConfiguration failed.\n");
DisplayError(status);
goto Done;
}
// Retrieve and display the updated interface configuration
//
status = DisplayDoDInterfaceConfiguration(serverHandleAdmin, interfaceHandleAdmin);
if (ERROR_SUCCESS != status)
{
wprintf(L"DisplayDoDInterfaceConfiguration failed.\n");
DisplayError(status);
goto Done;
}
Done:
// Free the interfaceCustomConfigCurrent object
//
FreeInterfaceCustomConfigObject(&interfaceCustomConfigCurrent);
RemoteAccessServerDisconenct(serverHandleAdmin, serverHandleConfig);
if (status != ERROR_SUCCESS)
{
wprintf(L"SetCustomIpsecConfigurationOnInterface failed\n");
DisplayError(status);
}
wprintf(L"---------------------------------------------------------\n\n");
}
//********************************************************************************************
// Function: CreateNewDoDInterface
//
// Description: Creates a new demand dial interface on the specified remote access server and
// returns the handle to the newly created interface.
//
//********************************************************************************************
DWORD CreateNewDoDInterface(
_In_ MPR_SERVER_HANDLE serverHandleAdmin,
_In_ HANDLE serverHandleConfig,
_Out_ HANDLE* interfaceHandleAdmin,
_Out_ HANDLE* interfaceHandleConfig
)
{
DWORD status = ERROR_SUCCESS;
MPR_INTERFACE_3 ifInfo;
BOOL interfaceAlreadyExists = TRUE;
int index = 0;
HANDLE tempInterfaceHandle = NULL;
*interfaceHandleAdmin = NULL;
*interfaceHandleConfig = NULL;
ZeroMemory(&ifInfo, sizeof(MPR_INTERFACE_3));
// Create an interface with a name that does not exists
//
do
{
StringCchPrintf(ifInfo.wszInterfaceName, ARRAYSIZE(ifInfo.wszInterfaceName), L"DoD-%d", index++);
status = g_pMprAdminInterfaceGetHandle(
serverHandleAdmin,
ifInfo.wszInterfaceName,
&tempInterfaceHandle,
FALSE
);
if (ERROR_SUCCESS != status)
{
if (ERROR_NO_SUCH_INTERFACE == status)
{
// Interface does not exists, we can use the current interface name stored in "ifInfo.wszInterfaceName"
// Ignore the error.
//
interfaceAlreadyExists = FALSE;
status = ERROR_SUCCESS;
}
else
{
// some genuine error, we should return
wprintf(L"MprAdminInterfaceGetHandle failed.\n");
DisplayError(status);
goto Done;
}
}
}
while (interfaceAlreadyExists);
// set the other interface properties
//
ifInfo.fEnabled = TRUE;
ifInfo.dwIfType = ROUTER_IF_TYPE_FULL_ROUTER;
StringCchCopy(ifInfo.szLocalPhoneNumber, ARRAYSIZE(ifInfo.szLocalPhoneNumber), L"131.107.0.2");
ifInfo.dwfOptions =
MPRIO_RequireDataEncryption |
MPRIO_RequireMachineCertificates;
ifInfo.dwfNetProtocols = MPRNP_Ip | MPRNP_Ipv6;
StringCchCopy(ifInfo.szDeviceType, ARRAYSIZE(ifInfo.szDeviceType), MPRDT_Vpn);
StringCchCopy(ifInfo.szDeviceName, ARRAYSIZE(ifInfo.szDeviceName), L"Fabrikam Inc 28800 External");
ifInfo.dwIdleDisconnectSeconds = 300;
ifInfo.dwType = MPRET_Vpn;
ifInfo.dwEncryptionType = MPR_ET_Require;
HRESULT hr = CoCreateGuid(&ifInfo.guidId);
if(S_OK != hr)
{
status = HRESULT_CODE(hr);
wprintf(L"CoCreateGuid failed.\n");
DisplayError(status);
}
ifInfo.dwVpnStrategy = MPR_VS_Ikev2Only;
// create an interface
//
status = g_pMprAdminInterfaceCreate(
serverHandleAdmin, // hMprServer
3, // dwLevel
(LPBYTE ) &ifInfo, // lpBuffer
interfaceHandleAdmin // phInterface
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceCreate failed.\n");
DisplayError(status);
goto Done;
}
// Persists the interface configuration
//
status = g_pMprConfigInterfaceCreate(
serverHandleConfig, // hMprConfig
0, // dwLevel
(LPBYTE ) ((MPR_INTERFACE_0 *)&ifInfo), // lpBuffer
interfaceHandleConfig // phInterface
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprConfigInterfaceCreate failed.\n");
DisplayError(status);
goto Done;
}
Done:
if (ERROR_SUCCESS != status)
{
wprintf(L"SetCustomIpsecConfigurationOnInterface failed: %u\n", status);
}
return status;
}
//********************************************************************************************
// Function: ConfigureCustomIPSecPolicyOnDoDInterface
//
// Description: Configures custom IPSec policies on the specified interface.
//
//********************************************************************************************
DWORD ConfigureCustomIPSecPolicyOnDoDInterface(
_In_ MPR_SERVER_HANDLE serverHandleAdmin,
_In_ HANDLE serverHandleConfig,
_In_ HANDLE interfaceHandleAdmin,
_In_ HANDLE interfaceHandleConfig
)
{
DWORD status = ERROR_SUCCESS;
MPR_IF_CUSTOMINFOEX mprInterfaceCustomInfo;
PROUTER_CUSTOM_IKEv2_POLICY0 customIkev2Policy = NULL;
CERT_NAME_BLOB machineCertificate;
CRYPT_HASH_BLOB machineCertificateHash;
ZeroMemory(&machineCertificate, sizeof(CERT_NAME_BLOB));
ZeroMemory(&machineCertificateHash, sizeof(CRYPT_HASH_BLOB));
// Create a custom IKEv2 policy object
//
customIkev2Policy = (ROUTER_CUSTOM_IKEv2_POLICY0*) MPRAPI_SAMPLE_MALLOC(sizeof(ROUTER_CUSTOM_IKEv2_POLICY0));
if (NULL == customIkev2Policy)
{
status = ERROR_OUTOFMEMORY;
wprintf(L"Error:Failed to allocate memory.\n");
DisplayError(status);
goto Done;
}
customIkev2Policy->dwIntegrityMethod = IKEEXT_INTEGRITY_SHA_256;
customIkev2Policy->dwEncryptionMethod = IKEEXT_CIPHER_AES_256;
customIkev2Policy->dwCipherTransformConstant = IKEEXT_CIPHER_AES_256;
customIkev2Policy->dwAuthTransformConstant = IPSEC_AUTH_SHA_256;
customIkev2Policy->dwPfsGroup = IPSEC_PFS_2048;
customIkev2Policy->dwDhGroup = IKEEXT_DH_GROUP_2;
// Populate the interface custom info object
//
ZeroMemory(&mprInterfaceCustomInfo, sizeof(MPR_IF_CUSTOMINFOEX));
// Set the Header info
//
mprInterfaceCustomInfo.Header.revision = MPRAPI_MPR_IF_CUSTOM_CONFIG_OBJECT_REVISION_2;
mprInterfaceCustomInfo.Header.type = MPRAPI_OBJECT_TYPE_IF_CUSTOM_CONFIG_OBJECT;
mprInterfaceCustomInfo.Header.size = sizeof(MPR_IF_CUSTOMINFOEX);
mprInterfaceCustomInfo.dwFlags = MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2;
// Get the machine certificate to be configured
// Certificate Hash is supported as multiple certificates with same name can exist on a machine
//
if (ERROR_SUCCESS != (status = GetCertificateNameAndHashBlob(&machineCertificate, &machineCertificateHash)))
{
// The method can return an error even if valid machineCertificate info is retrieved and machineCertificateHash is not.
// Either of them is sufficient to configure the certificate on the interface
if(machineCertificate.cbData == 0)
{
wprintf(L"GetCertificateNameAndHashBlob failed\n");
DisplayError(status);
// we are not configuring the certficate on the interface
}
// ignore the error.
}
mprInterfaceCustomInfo.customIkev2Config.dwSaLifeTime = 3600; // 60 minutes
mprInterfaceCustomInfo.customIkev2Config.dwSaDataSize = 10 * 1024 * 1024; // 10 Megabyte
mprInterfaceCustomInfo.customIkev2Config.certificateName.cbData = machineCertificate.cbData;
mprInterfaceCustomInfo.customIkev2Config.certificateName.pbData = machineCertificate.pbData;
mprInterfaceCustomInfo.customIkev2Config.certificateHash.cbData = machineCertificateHash.cbData;
mprInterfaceCustomInfo.customIkev2Config.certificateHash.pbData = machineCertificateHash.pbData;
mprInterfaceCustomInfo.customIkev2Config.customPolicy = customIkev2Policy;
// Update the custom configuration on the interface
//
status = UpdateInterfaceCustomConfiguration(
serverHandleAdmin,
serverHandleConfig,
interfaceHandleAdmin,
interfaceHandleConfig,
&mprInterfaceCustomInfo
);
if (ERROR_SUCCESS != status)
{
wprintf(L"UpdateInterfaceCustomConfiguration failed.\n");
DisplayError(status);
goto Done;
}
Done:
MPRAPI_SAMPLE_FREE(customIkev2Policy);
if ((machineCertificate.cbData > 0) &&
(NULL != machineCertificate.pbData))
{
MPRAPI_SAMPLE_FREE(machineCertificate.pbData);
}
if ((machineCertificateHash.cbData > 0) &&
(NULL != machineCertificateHash.pbData))
{
MPRAPI_SAMPLE_FREE(machineCertificateHash.pbData);
}
return status;
}
//********************************************************************************************
// Function: DisplayDoDInterfaceConfiguration
//
// Description: Retrieves and displays the custom IPSec policies configured on the specified interface
//
//********************************************************************************************
DWORD DisplayDoDInterfaceConfiguration(
_In_ MPR_SERVER_HANDLE serverHandleAdmin,
_In_ HANDLE interfaceHandleAdmin
)
{
DWORD status = ERROR_SUCCESS;
MPR_INTERFACE_3* ifInfo =
NULL;
MPR_IF_CUSTOMINFOEX interfaceCustomConfig;
ZeroMemory(&interfaceCustomConfig, sizeof(MPR_IF_CUSTOMINFOEX));
// Retrieve the interface info
//
status = g_pMprAdminInterfaceGetInfo(
serverHandleAdmin, // hMprServer
interfaceHandleAdmin, // interfaceHandleAdmin
3, // dwLevel
(LPBYTE*)&ifInfo // lplpbBuffer
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceGetInfo failed.\n");
DisplayError(status);
goto Done;
}
wprintf(L"Interface Info:\n");
PrintInterfaceInfo(ifInfo);
// Retrieve the interface custom configuration
//
interfaceCustomConfig.Header.revision = MPRAPI_MPR_IF_CUSTOM_CONFIG_OBJECT_REVISION_2;
interfaceCustomConfig.Header.type = MPRAPI_OBJECT_TYPE_IF_CUSTOM_CONFIG_OBJECT;
interfaceCustomConfig.Header.size = sizeof(MPR_IF_CUSTOMINFOEX);
status = g_pMprAdminInterfaceGetCustomInfoEx(
serverHandleAdmin, // hMprServer
interfaceHandleAdmin, // interfaceHandleAdmin
&interfaceCustomConfig // pCustomInfo
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceGetCustomInfoEx failed.\n");
DisplayError(status);
goto Done;
}
wprintf(L"\t Custom configuration:\n");
if (interfaceCustomConfig.dwFlags & MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2)
{
PrintInterfaceCustomConfiguration(&interfaceCustomConfig.customIkev2Config);
}
else
{
wprintf(L"\t No custom configuration available for interface '%s'\n", ifInfo->wszInterfaceName);
}
Done:
if (NULL != ifInfo)
{
g_pMprAdminBufferFree(ifInfo);
}
FreeInterfaceCustomConfigObject(&interfaceCustomConfig);
return status;
}
//********************************************************************************************
// Function: UpdateInterfaceCustomConfiguration
//
// Description: Update the custom configuration of the speficied interface with
// the supplied custom configuration information 'mprInterfaceCustomInfo'.
//
//********************************************************************************************
DWORD UpdateInterfaceCustomConfiguration(
_In_ MPR_SERVER_HANDLE serverHandleAdmin,
_In_ HANDLE serverHandleConfig,
_In_ HANDLE interfaceHandleAdmin,
_In_ HANDLE interfaceHandleConfig,
_In_ MPR_IF_CUSTOMINFOEX* mprInterfaceCustomInfo
)
{
DWORD status = ERROR_SUCCESS;
// Call the MprAdminInterfaceSetCustomInfoEx API to update the custom IPSec policies
// on the interface
//
status = g_pMprAdminInterfaceSetCustomInfoEx(
serverHandleAdmin, // hMprServer
interfaceHandleAdmin, // interfaceHandleAdmin
mprInterfaceCustomInfo // pCustomInfo
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprAdminInterfaceSetCustomInfoEx failed.\n");
DisplayError(status);
goto Done;
}
// Call the MprAdminInterfaceSetCustomInfoEx API to persist the updated custom configuration on the
// the interface
//
status = g_pMprConfigInterfaceSetCustomInfoEx(
serverHandleConfig, // hMprConfig
interfaceHandleConfig, // hRouterInterface
mprInterfaceCustomInfo // pCustomInfo
);
if (ERROR_SUCCESS != status)
{
// some genuine error, we should return
//
wprintf(L"MprConfigInterfaceSetCustomInfoEx failed.\n");
DisplayError(status);
goto Done;
}
Done:
return status;
}
//********************************************************************************************
// Function: PrintInterfaceCustomConfiguration
//
// Description: Prints various fields of the ROUTER_IKEv2_IF_CUSTOM_CONFIG0 structure in string format
//
//********************************************************************************************
VOID PrintInterfaceCustomConfiguration(
_In_ ROUTER_IKEv2_IF_CUSTOM_CONFIG* customIkev2Config
)
{
if (customIkev2Config == NULL)
{
wprintf(L"\t\t NULL custom configuration\n");
return;
}
wprintf(L"\t\t dwSaLifeTime: %u\n", customIkev2Config->dwSaLifeTime);
wprintf(L"\t\t dwSaDataSize: %u\n", customIkev2Config->dwSaDataSize);
wprintf(L"\t\t CertificateName configured: %s\n", (0 == customIkev2Config->certificateName.cbData) ? L"No" : L"Yes");
wprintf(L"\t\t CertificateHash configured: %s\n", (0 == customIkev2Config->certificateHash.cbData) ? L"No" : L"Yes");
if (customIkev2Config->customPolicy == NULL)
{
wprintf(L"\t\t IPsec custom policy not configured.\n");
}
else
{
PrintCustomIkev2Policy(L"\t\t", customIkev2Config->customPolicy);
}
}
//********************************************************************************************
// Function: PrintInterfaceInfo
//
// Description: Prints various fields of the speficied MPR_INTERFACE_3 structure in string format
//
//********************************************************************************************
VOID PrintInterfaceInfo(
_In_ MPR_INTERFACE_3* ifInfo
)
{
WCHAR strGUID[256] = {0};
StringFromGUID2(ifInfo->guidId, strGUID, ARRAYSIZE(strGUID));
wprintf(L"\t Interface name: %s\n", ifInfo->wszInterfaceName);
wprintf(L"\t Interface GUID: %s\n", strGUID);
wprintf(L"\t Destination: %s\n", ifInfo->szLocalPhoneNumber);
wprintf(L"\t Interface status: %s\n", (ifInfo->fEnabled) ? L"ENABLED" : L"DISABLED");
wprintf(L"\t Interface type: ");
PrintInterfaceType(ifInfo->dwIfType);
wprintf(L"\n");
wprintf(L"\t Connection State: ");
PrintConnectionState(ifInfo->dwConnectionState);
wprintf(L"\n");
wprintf(L"\t Encryption Type: ");
PrintEncryptionType(ifInfo->dwEncryptionType);
wprintf(L"\n");
wprintf(L"\t Entry Type: ");
PrintEntryType(ifInfo->dwType);
wprintf(L"\n");
wprintf(L"\t Vpn Strategy: ");
PrintVpnStrategy(ifInfo->dwVpnStrategy);
wprintf(L"\n");
wprintf(L"\t UnReachabilityReasons: %u\n", ifInfo->fUnReachabilityReasons);
wprintf(L"\t Last Error: %u\n", ifInfo->dwLastError);
wprintf(L"\t dwfOptions: %u\n", ifInfo->dwfOptions);
wprintf(L"\t dwfNetProtocols: %u\n", ifInfo->dwfNetProtocols);
wprintf(L"\t DeviceType: %s\n", ifInfo->szDeviceType);
wprintf(L"\t DeviceName: %s\n", ifInfo->szDeviceName);
wprintf(L"\t IdleDisconnectSeconds: %u\n", ifInfo->dwIdleDisconnectSeconds);
}
//********************************************************************************************
// Function: FreeInterfaceCustomConfigObject
//
// Description: Releases the various fields of the MPR_IF_CUSTOMINFOEX
// structure, those are allocated by the remote access server.
//
//********************************************************************************************
VOID FreeInterfaceCustomConfigObject(
_In_ MPR_IF_CUSTOMINFOEX* customConfig
)
{
if (customConfig == NULL)
return;
if (customConfig->dwFlags & MPRAPI_IF_CUSTOM_CONFIG_FOR_IKEV2)
{
if (customConfig->customIkev2Config.certificateName.cbData != 0)
{
g_pMprAdminBufferFree(customConfig->customIkev2Config.certificateName.pbData);
customConfig->customIkev2Config.certificateName.cbData = 0;
customConfig->customIkev2Config.certificateName.pbData = NULL;
}
if(customConfig->Header.revision == MPRAPI_MPR_IF_CUSTOM_CONFIG_OBJECT_REVISION_2
&& customConfig->customIkev2Config.certificateHash.cbData != 0)
{
g_pMprAdminBufferFree(customConfig->customIkev2Config.certificateHash.pbData);
customConfig->customIkev2Config.certificateHash.cbData = 0;
customConfig->customIkev2Config.certificateHash.pbData = NULL;
}
if (customConfig->customIkev2Config.customPolicy != NULL)
{
g_pMprAdminBufferFree(customConfig->customIkev2Config.customPolicy);
customConfig->customIkev2Config.customPolicy = NULL;
}
}
}