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;
}
Esempio n. 2
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    
}