1

When I run my c# console app the windows firewall pops up requesting access for vshost32 (my app listens for incomming messages over port 1234 using TCP and UDP). I accept the offered suggestion (private network). The console app then works fine.

I dont want the user to deal with this, so I have added the code below. However when I investigate what this has done in Control Panel > Firewall, it seems to have enabled it for the 'public network' rather than the private network. This is no use as far as allowing my app to work.

Is there an adjustment in the code below to force it to the private network?

INetFwOpenPorts ports3;
INetFwOpenPort port3 = (INetFwOpenPort)Activator.CreateInstance(
    Type.GetTypeFromProgID("HNetCfg.FWOpenPort"));
port3.Port = 1234; 
port3.Name = "vshost32.exe"; 
port3.Enabled = true;

//**UPDATE** added for suggestion in answer below - still doesnt change anything though
port3.Scope = NetFwTypeLib.NET_FW_SCOPE_.NET_FW_SCOPE_LOCAL_SUBNET;

Type NetFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);
INetFwMgr mgr3 = (INetFwMgr)Activator.CreateInstance(NetFwMgrType);
ports3 = (INetFwOpenPorts)mgr3.LocalPolicy.CurrentProfile.GloballyOpenPorts;
ports3.Add(port3);
spiderplant0
  • 3,872
  • 12
  • 52
  • 91

2 Answers2

2
    INetFwRule firewallRule = (INetFwRule)Activator.CreateInstance(
        Type.GetTypeFromProgID("HNetCfg.FWRule"));

    INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(
        Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));

    firewallRule.ApplicationName = "<path to your app>";

    firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
    firewallRule.Description = " My Windows Firewall Rule";
    firewallRule.Enabled = true;
    firewallRule.InterfaceTypes = "All";
    firewallRule.Name = "<your rule name>";

    // Should really check that rule is not already present before add in
    firewallPolicy.Rules.Add(firewallRule);        
spiderplant0
  • 3,872
  • 12
  • 52
  • 91
1

Refer to my answer to your previous question.

Have a look at the following lines:

private static int Main (string [] args)
{
    var application = new NetFwAuthorizedApplication()
    {
        Name = "MyService",
        Enabled = true,
        RemoteAddresses = "*",
        Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL,
        IpVersion = NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY,
        ProcessImageFileName = "ServiceAssemblyName.dll",
    };

    return (FirewallUtilities.AddApplication(application, out exception) ? 0 : -1);
}

The NET_FW_SCOPE_ enumeration has the following values:

  • NET_FW_SCOPE_ALL = 0,
  • NET_FW_SCOPE_LOCAL_SUBNET = 1,
  • NET_FW_SCOPE_CUSTOM = 2,
  • NET_FW_SCOPE_MAX = 3,

You can further limit the ports, protocol as well as remote addresses to the rule.

UPDATE:

Here is the missing ReleaseComObject function. Place it whatever namespace and remove the reference to ComUtilities.

    public static void ReleaseComObject (object o)
    {
        try
        {
            if (o != null)
            {
                if (Marshal.IsComObject(o))
                {
                    Marshal.ReleaseComObject(o);
                }
            }
        }
        finally
        {
            o = null;
        }
    }

Here is the NetFwAuthorizedApplication class:

namespace MySolution.Configurator.Firewall { using System; using System.Linq; using NetFwTypeLib;

public sealed class NetFwAuthorizedApplication:
    INetFwAuthorizedApplication
{
    public string Name { get; set; }
    public bool Enabled { get; set; }
    public NET_FW_SCOPE_ Scope { get; set; }
    public string RemoteAddresses { get; set; }
    public string ProcessImageFileName { get; set; }
    public NET_FW_IP_VERSION_ IpVersion { get; set; }

    public NetFwAuthorizedApplication ()
    {
        this.Name = "";
        this.Enabled = false;
        this.RemoteAddresses = "";
        this.ProcessImageFileName = "";
        this.Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL;
        this.IpVersion = NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY;
    }

    public NetFwAuthorizedApplication (string name, bool enabled, string remoteAddresses, NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipVersion, string processImageFileName)
    {
        this.Name = name;
        this.Scope = scope;
        this.Enabled = enabled;
        this.IpVersion = ipVersion;
        this.RemoteAddresses = remoteAddresses;
        this.ProcessImageFileName = processImageFileName;
    }

    public static NetFwAuthorizedApplication FromINetFwAuthorizedApplication (INetFwAuthorizedApplication application)
    {
        return (new NetFwAuthorizedApplication(application.Name, application.Enabled, application.RemoteAddresses, application.Scope, application.IpVersion, application.ProcessImageFileName));
    }
}

}

Community
  • 1
  • 1
Raheel Khan
  • 14,205
  • 13
  • 80
  • 168
  • thanks, I guess NET_FW_SCOPE_LOCAL_SUBNET is the equivalent of 'private'. – spiderplant0 Jul 19 '14 at 19:14
  • Thats strange, I added it in (see added line in question) `port3.Scope = NetFwTypeLib.NET_FW_SCOPE_.NET_FW_SCOPE_LOCAL_SUBNET;` but didnt seem to do anything. ALso tried `NET_FW_SCOPE_ALL`. – spiderplant0 Jul 19 '14 at 19:22
  • Seems like you are manipulating the globally open ports collection. I am not sure if that will allow access to a specific app if your windows firewall settings are configured with common defaults. Have a look at the AddApplication method in that answer. It adds to the authorized applications collection. You can use those two classes 'as is' by the way. Just paste the `Main` method contents to your console app and you should be good to go. – Raheel Khan Jul 19 '14 at 19:42
  • I did try your solution but I couldnt figure out what how to resolve `ComUtilities` and `NetFwAuthorizedApplication`. I tried to find a package on nuget. To be honest I was a bit overwhelmed by the amount of code there and wasnt confident about adjusting it. Any hints how to get running gratefully received. – spiderplant0 Jul 19 '14 at 19:48
  • My bad. The `NetFwAuthorizedApplication` is simply a custom class that implements `INetFwAuthorizedApplication`. It is present in that answer but I must have replaced namespaces. Also including `ComUtilities` in the answer above. Don't worry about the amount of code. The two classes are completely self-contained. Check back in a few minutes for an update to the answer. – Raheel Khan Jul 19 '14 at 19:54
  • Thanks, I have it compiling - just need to get it to enable the firewall rule. I have: `Name = "vshost32"` and `ProcessImageFileName = "vshost32.exe"`. Does that sound correct? Or should I use the name of my service app? – spiderplant0 Jul 19 '14 at 20:42
  • The `Name` property can be anything you want. The `ProcessImageFileName` needs to be the full path of the executable or dll that you want to target. Note that `FullPath\AssmeblyExecutable.exe` will show up as `FullPath\AssemblyExecutable.vshost.exe` for Console and WinForm apps in debug mode. Not sure about services. – Raheel Khan Jul 19 '14 at 20:48
  • Great, nearly working - but still it is adding a tick to the public network and not the private one. – spiderplant0 Jul 19 '14 at 21:06
  • Have a look at [this answer](http://stackoverflow.com/a/15416581/938668). It uses the `HNetCfg.FWRule` object instead. – Raheel Khan Jul 20 '14 at 08:55
  • Thanks, yes I saw something similar last night. It seems for Windows 7 (& vista?) you need to use this a new scheme for full control of the firewall. Anyway its all working now - thanks very much for your help. – spiderplant0 Jul 20 '14 at 13:26