int __cdecl main() { HRESULT hrComInit = S_OK; HRESULT hr = S_OK; variant_t vtInterfaceName("Local Area Connection"), vtInterface; long index = 0; SAFEARRAY *pSa = NULL; INetFwPolicy2 *pNetFwPolicy2 = NULL; INetFwRules *pFwRules = NULL; INetFwRule *pFwRule = NULL; long CurrentProfilesBitMask = 0; // The rule name, description, and group are provided as indirect strings for // localization purposes. These resource strings can be found in the rc file BSTR bstrRuleName = SysAllocString(L"@Add_PerInterface_Rule.exe,-128"); BSTR bstrRuleDescription = SysAllocString(L"@Add_PerInterface_Rule.exe,-129"); BSTR bstrRuleGroup = SysAllocString(L"@Add_PerInterface_Rule.exe,-127"); BSTR bstrRuleLPorts = SysAllocString(L"2300"); // Error checking for BSTR allocations if (NULL == bstrRuleName) { printf("Failed to allocate bstrRuleName\n"); goto Cleanup; } if (NULL == bstrRuleDescription) { printf("Failed to allocate bstrRuleDescription\n"); goto Cleanup; } if (NULL == bstrRuleGroup) { printf("Failed to allocate bstrRuleGroup\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 INetFwRules hr = pNetFwPolicy2->get_Rules(&pFwRules); if (FAILED(hr)) { printf("get_Rules failed: 0x%08lx\n", hr); goto Cleanup; } // Retrieve Current Profiles bitmask hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask); if (FAILED(hr)) { printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr); goto Cleanup; } // When possible we avoid adding firewall rules to the Public profile. // If Public is currently active and it is not the only active profile, we remove it from the bitmask if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) && (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC)) { CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC; } // Retrieve Local Interface pSa = SafeArrayCreateVector(VT_VARIANT, 0, 1); if (!pSa) _com_issue_error(E_OUTOFMEMORY); else { hr = SafeArrayPutElement(pSa, &index, &vtInterfaceName); if FAILED(hr) _com_issue_error(hr); vtInterface.vt = VT_ARRAY | VT_VARIANT; vtInterface.parray = pSa; } // Create a new Firewall 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 Firewall Rule Name hr = pFwRule->put_Name(bstrRuleName); if (FAILED(hr)) { printf("put_Name failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall Rule Description hr = pFwRule->put_Description(bstrRuleDescription); if (FAILED(hr)) { printf("put_Description failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall Rule 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 Firewall Rule Local Ports hr = pFwRule->put_LocalPorts(bstrRuleLPorts); if (FAILED(hr)) { printf("put_LocalPorts failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall Rule Group hr = pFwRule->put_Grouping(bstrRuleGroup); if (FAILED(hr)) { printf("put_Grouping failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall Rule Profiles hr = pFwRule->put_Profiles(CurrentProfilesBitMask); if (FAILED(hr)) { printf("put_Profiles failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall Rule Interfaces hr = pFwRule->put_Interfaces(vtInterface); if (FAILED(hr)) { printf("put_Interfaces failed: 0x%08lx\n", hr); goto Cleanup; } // Populate the Firewall 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 Firewall Rule Enabled hr = pFwRule->put_Enabled(VARIANT_TRUE); if (FAILED(hr)) { printf("put_Enabled failed: 0x%08lx\n", hr); goto Cleanup; } // Add the Firewall Rule hr = pFwRules->Add(pFwRule); if (FAILED(hr)) { printf("Firewall Rule Add failed: 0x%08lx\n", hr); goto Cleanup; } Cleanup: // Free BSTR's SysFreeString(bstrRuleName); SysFreeString(bstrRuleDescription); SysFreeString(bstrRuleGroup); SysFreeString(bstrRuleLPorts); // Release the INetFwRule object if (pFwRule != NULL) { pFwRule->Release(); } // Release the INetFwRules object if (pFwRules != NULL) { pFwRules->Release(); } // Release the INetFwPolicy2 object if (pNetFwPolicy2 != NULL) { pNetFwPolicy2->Release(); } // Uninitialize COM. if (SUCCEEDED(hrComInit)) { CoUninitialize(); } return 0; }
/****************************************************************** CreateFwRuleObject - CoCreate a firewall rule, and set the common set of properties which are shared between port and application firewall rules ********************************************************************/ static HRESULT CreateFwRuleObject( __in BSTR bstrName, __in int iProfile, __in_opt LPCWSTR wzRemoteAddresses, __in LPCWSTR wzPort, __in int iProtocol, __in LPCWSTR wzDescription, __out INetFwRule** ppNetFwRule ) { HRESULT hr = S_OK; BSTR bstrRemoteAddresses = NULL; BSTR bstrPort = NULL; BSTR bstrDescription = NULL; INetFwRule* pNetFwRule = NULL; *ppNetFwRule = NULL; // convert to BSTRs to make COM happy bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses); ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses"); bstrPort = ::SysAllocString(wzPort); ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port"); bstrDescription = ::SysAllocString(wzDescription); ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description"); hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (void**)&pNetFwRule); ExitOnFailure(hr, "failed to create NetFwRule object"); hr = pNetFwRule->put_Name(bstrName); ExitOnFailure(hr, "failed to set exception name"); hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2>(iProfile)); ExitOnFailure(hr, "failed to set exception profile"); if (MSI_NULL_INTEGER != iProtocol) { hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(iProtocol)); ExitOnFailure(hr, "failed to set exception protocol"); } if (bstrPort && *bstrPort) { hr = pNetFwRule->put_LocalPorts(bstrPort); ExitOnFailure(hr, "failed to set exception port"); } if (bstrRemoteAddresses && *bstrRemoteAddresses) { hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses); ExitOnFailure1(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses); } if (bstrDescription && *bstrDescription) { hr = pNetFwRule->put_Description(bstrDescription); ExitOnFailure1(hr, "failed to set exception description '%ls'", bstrDescription); } *ppNetFwRule = pNetFwRule; pNetFwRule = NULL; LExit: ReleaseBSTR(bstrRemoteAddresses); ReleaseBSTR(bstrPort); ReleaseBSTR(bstrDescription); ReleaseObject(pNetFwRule); return hr; }
HRESULT FirewallSecurityProvider::AddRule( INetFwRules* pFwRules, wstring const & policyName, wstring const & ruleDescription, LONG currentProfilesBitMask, LONG protocol, LONG port, bool outgoing) { #if defined(PLATFORM_UNIX) string policyNameA = StringUtility::Utf16ToUtf8(policyName); HRESULT hr = AddIptablesEntry(policyNameA, protocol, port, outgoing); if (FAILED(hr)) { WriteWarning(TraceFirewallSecurityProvider, Root.TraceId, "Failed to add firewall rule (ipv4), hresult {0}", hr); } else { hr = AddIp6tablesEntry(policyNameA, protocol, port, outgoing); if (FAILED(hr)) { WriteWarning(TraceFirewallSecurityProvider, Root.TraceId, "Failed to add firewall rule (ipv6), hresult {0}", hr); } } return hr; #else HRESULT hr = S_OK; INetFwRule *pFwRule = NULL; hr = CoCreateInstance( __uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule); if (SUCCEEDED(hr)) { // Populate the Firewall Rule object pFwRule->put_Name((BSTR)policyName.c_str()); pFwRule->put_Description((BSTR)ruleDescription.c_str()); pFwRule->put_ApplicationName(nullptr); pFwRule->put_Protocol(protocol); pFwRule->put_LocalPorts((BSTR)StringUtility::ToWString<UINT>(port).c_str()); if (outgoing) { pFwRule->put_Direction(NET_FW_RULE_DIR_OUT); } else { pFwRule->put_Direction(NET_FW_RULE_DIR_IN); } pFwRule->put_Grouping((BSTR)FirewallSecurityProvider::firewallGroup_.c_str()); pFwRule->put_Profiles(currentProfilesBitMask); pFwRule->put_Action(NET_FW_ACTION_ALLOW); pFwRule->put_Enabled(VARIANT_TRUE); // Add the Firewall Rule hr = pFwRules->Add(pFwRule); if (FAILED(hr)) { WriteWarning( TraceFirewallSecurityProvider, Root.TraceId, "Failed to add firewall rule, hresult {0}", hr); } if (pFwRule != NULL) { pFwRule->Release(); } } else { WriteWarning( TraceFirewallSecurityProvider, Root.TraceId, "Failed to create firewall rule instance, hresult {0}", hr); } return hr; #endif }