Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This example restricts service using the Windows Firewall with Advanced Security APIs.
/********************************************************************++
Copyright (C) Microsoft. All Rights Reserved.
Abstract:
This C++ file includes sample code that restricts a service using
the Microsoft Windows Firewall APIs.
--********************************************************************/
#include <windows.h>
#include <stdio.h>
#include <netfw.h>
#pragma comment( lib, "ole32.lib" )
#pragma comment( lib, "oleaut32.lib" )
// Forward declarations
HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2);
int __cdecl main()
{
HRESULT hrComInit = S_OK;
HRESULT hr = S_OK;
INetFwRules *pFwRules = NULL;
INetFwRule *pFwRule = NULL;
VARIANT_BOOL isServiceRestricted = FALSE;
INetFwPolicy2 *pNetFwPolicy2 = NULL;
INetFwServiceRestriction *pFwServiceRestriction = NULL;
// The Service and App name to use
BSTR bstrServiceName = SysAllocString(L"SampleService"); // provide a valid service short name here.
BSTR bstrAppName = SysAllocString(L"%systemDrive%\\WINDOWS\\system32\\svchost.exe");
// The rule name, description should be provided as indirect strings '@appfullpath,-resource index' for
// localization purposes.
// Using the strings directly for illustration here.
BSTR bstrRuleName = SysAllocString(L"Allow TCP 12345 to sampleservice");
BSTR bstrRuleDescription = SysAllocString(L"Allow only TCP 12345 traffic to sampleservice service, block everything else");
BSTR bstrRuleLPorts = SysAllocString(L"12345");
// Error checking for BSTR allocations
if (NULL == bstrServiceName) { printf("Failed to allocate bstrServiceName\n"); goto Cleanup; }
if (NULL == bstrAppName) { printf("Failed to allocate bstrAppName\n"); goto Cleanup; }
if (NULL == bstrRuleName) { printf("Failed to allocate bstrRuleName\n"); goto Cleanup; }
if (NULL == bstrRuleDescription) { printf("Failed to allocate bstrRuleDescription\n"); goto Cleanup; }
if (NULL == bstrRuleLPorts) { printf("Failed to allocate bstrRuleLPorts\n"); goto Cleanup; }
// Initialize COM.
hrComInit = CoInitializeEx(
0,
COINIT_APARTMENTTHREADED
);
// Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
// initialized with a different mode. Since we don't care what the mode is,
// we'll just use the existing mode.
if (hrComInit != RPC_E_CHANGED_MODE)
{
if (FAILED(hrComInit))
{
printf("CoInitializeEx failed: 0x%08lx\n", hrComInit);
goto Cleanup;
}
}
// Retrieve INetFwPolicy2
hr = WFCOMInitialize(&pNetFwPolicy2);
if (FAILED(hr))
{
goto Cleanup;
}
// Retrieve INetFwServiceRestriction
hr = pNetFwPolicy2->get_ServiceRestriction(&pFwServiceRestriction);
if (FAILED(hr))
{
printf("get_ServiceRestriction failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Restrict the sampleservice Service.
// This will add two WSH rules -
// - a default block all inbound traffic to the service
// - a default block all outbound traffic from the service
hr = pFwServiceRestriction->RestrictService(bstrServiceName, bstrAppName, TRUE, FALSE);
if (FAILED(hr))
{
printf("RestrictService failed: 0x%08lx\nMake sure you specified a valid service shortname.\n", hr);
goto Cleanup;
}
// If the service does not send/receive any network traffic then you are done. You can skip adding the allow WSH rules below.
// If the service requires sending/receiving certain traffic, then add 'allow' WSH rules as follows
// Get the collections of Windows Service Hardening networking rules first
hr = pFwServiceRestriction->get_Rules(&pFwRules);
if (FAILED(hr))
{
wprintf(L"get_Rules failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Add inbound WSH allow rule for allowing TCP 12345 to the service
// Create a new Rule object.
hr = CoCreateInstance(
__uuidof(NetFwRule),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(INetFwRule),
(void**)&pFwRule);
if (FAILED(hr))
{
printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Rule Name
hr = pFwRule->put_Name(bstrRuleName);
if (FAILED(hr))
{
printf("put_Name failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Rule Description
hr = pFwRule->put_Description(bstrRuleDescription);
if (FAILED(hr))
{
printf("put_Description failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Application Name
hr = pFwRule->put_ApplicationName(bstrAppName);
if (FAILED(hr))
{
printf("put_ApplicationName failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Service Name
hr = pFwRule->put_ServiceName(bstrServiceName);
if (FAILED(hr))
{
printf("put_ServiceName failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Protocol
hr = pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP);
if (FAILED(hr))
{
printf("put_Protocol failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the Local Ports
hr = pFwRule->put_LocalPorts(bstrRuleLPorts);
if (FAILED(hr))
{
printf("put_LocalPorts failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the rule Action
hr = pFwRule->put_Action(NET_FW_ACTION_ALLOW);
if (FAILED(hr))
{
printf("put_Action failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Populate the rule Enabled setting
hr = pFwRule->put_Enabled(VARIANT_TRUE);
if (FAILED(hr))
{
printf("put_Enabled failed: 0x%08lx\n", hr);
goto Cleanup;
}
// Add the Rule to the collection of Windows Service Hardening(WSH) rules
hr = pFwRules->Add(pFwRule);
if (FAILED(hr))
{
printf("Firewall Rule Add failed: 0x%08lx\n", hr);
goto Cleanup;
}
Sleep(3000);
// Check to see if the Service is Restricted
hr = pFwServiceRestriction->ServiceRestricted(bstrServiceName, bstrAppName, &isServiceRestricted);
if (FAILED(hr))
{
printf("ServiceRestricted failed: 0x%08lx\n", hr);
goto Cleanup;
}
if (isServiceRestricted)
{
printf ("Service was successfully restricted in WSH.\nExcept for TCP 12345 inbound traffic and its responses, all other inbound and outbound connections to and from the service will be blocked.\n");
}
else
{
printf ("The Service could not be properly restricted.\n");
}
Cleanup:
// Free BSTR's
SysFreeString(bstrServiceName);
SysFreeString(bstrAppName);
SysFreeString(bstrRuleName);
SysFreeString(bstrRuleDescription);
SysFreeString(bstrRuleLPorts);
// Release the INetFwRule object
if (pFwRule != NULL)
{
pFwRule->Release();
}
// Release the INetFwRules object
if (pFwRules != NULL)
{
pFwRules->Release();
}
// Release INetFwPolicy2
if (pNetFwPolicy2 != NULL)
{
pNetFwPolicy2->Release();
}
// Uninitialize COM.
if (SUCCEEDED(hrComInit))
{
CoUninitialize();
}
return 0;
}
// Instantiate INetFwPolicy2
HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
{
HRESULT hr = S_OK;
hr = CoCreateInstance(
__uuidof(NetFwPolicy2),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(INetFwPolicy2),
(void**)ppNetFwPolicy2);
if (FAILED(hr))
{
printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
goto Cleanup;
}
Cleanup:
return hr;
}