转自:http://technet.microsoft.com/zh-cn/dd339611(v=vs.85)
/********************************************************************++ 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; }