int __cdecl main() { HRESULT hrComInit = S_OK; HRESULT hr = S_OK; 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_GRE_Rule.exe,-128"); BSTR bstrRuleDescription = SysAllocString(L"@Add_GRE_Rule.exe,-129"); BSTR bstrRuleGroup = SysAllocString(L"@Add_GRE_Rule.exe,-127"); // 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; } // 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; } // 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(47); if (FAILED(hr)) { printf("put_Protocol 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 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); // 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; }
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 }