Web 2.0 Bubble
WeakReference: GC knows the Best

Controlling Windows Firewall using C# via COM Interop

Firewall Windows firewall is the built in firewall that ships with Windows XP and Windows Vista. This firewall can be controlled from any .NET language via COM interop. The windows firewall UI is a little clumsy to work with so anyone can make his own frontend using any .NET based language.

Setting up

Start by adding a reference to the COM dll that provides the functionality to control the windows firewall. The filename is hnetcfg.dll which can be found at the system32 folder inside windows. So add the file to your C# project.

File location: \Windows\System32\hnetcfg.dll
Then add these using statements to import the COM Objects

using NATUPNPLib;
using NETCONLib;
using NetFwTypeLib;

Obtaining a reference to the firewall manager

The first step toward controlling the windows firewall is to obtain a reference to the firewall manager class. For this we will use the CLSID of the class which is

   {304CE942-6E39-40D8-943A-B913C40C9CD4}

So our code looks like this

private const string CLSID_FIREWALL_MANAGER = 
      "{304CE942-6E39-40D8-943A-B913C40C9CD4}";
private static NetFwTypeLib.INetFwMgr GetFirewallManager()
{
    Type objectType = Type.GetTypeFromCLSID(
          new Guid(CLSID_FIREWALL_MANAGER));
    return Activator.CreateInstance(objectType)
          as NetFwTypeLib.INetFwMgr;
}

The above code shows how to get a reference to the firewall manager

Check if the firewall is turned on

If the firewall is not turned we should look into the current profile and find out then turn it on.

INetFwMgr manager = GetFirewallManager();
bool isFirewallEnabled =
    manager.LocalPolicy.CurrentProfile.FirewallEnabled;
if (isFirewallEnabled==false)
    manager.LocalPolicy.CurrentProfile.FirewallEnabled=true;

Give full trust to your executable

If we want to authorize some application with full trust then we need to create a FirewallAuthorizedApplication (INetFwAuthorizedApplication) object and add it to the authorized application list.

// ProgID for the AuthorizedApplication object
private const string PROGID_AUTHORIZED_APPLICATION =
    "HNetCfg.FwAuthorizedApplication";

public bool AuthorizeApplication(string title, string applicationPath,
    NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipVersion )
{   
  // Create the type from prog id
  Type type = Type.GetTypeFromProgID(PROGID_AUTHORIZED_APPLICATION);
  INetFwAuthorizedApplication auth = Activator.CreateInstance(type)
      as INetFwAuthorizedApplication;
  auth.Name  = title;
  auth.ProcessImageFileName = applicationPath;
  auth.Scope = scope;
  auth.IpVersion = ipVersion;
  auth.Enabled = true;

  INetFwMgr manager = GetFirewallManager();
  try
  {
    manager.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(auth);
  }
  catch (Exception ex)
  {
    return false;
  }
  return true;
}

The above code is for a function that adds an authorized application. Let see the use by authorizing notepad full internet access!

AuthorizeApplication ("Notepad", @"C:\Windows\Notepad.exe", 
                NET_FW_SCOPE_.NET_FW_SCOPE_ALL,
                NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY)

Walla! Now notepad has internet access.

Opening a Port Globally

Sometimes we may want to open a port for any application no matter what. Windows Firewall can be instructed to open a port globally for all applications by adding a port to the globally open ports list. Let try to write a function that opens up a port globally ...

private const string PROGID_OPEN_PORT = "HNetCfg.FWOpenPort";
public bool GloballyOpenPort(string title, int portNo,
    NET_FW_SCOPE_ scope, NET_FW_IP_PROTOCOL_ protocol,
    NET_FW_IP_VERSION_ ipVersion)
{
  Type type = Type.GetTypeFromProgID(PROGID_OPEN_PORT);
  INetFwOpenPort port = Activator.CreateInstance(type)
      as INetFwOpenPort;
  port.Name = title;
  port.Port = portNo;
  port.Scope = scope;
  port.Protocol = protocol;
  port.IpVersion = ipVersion;

  INetFwMgr manager = GetFirewallManagerCached();
  try
  {
    manager.LocalPolicy.CurrentProfile.GloballyOpenPorts.Add(port);
  }
  catch (Exception ex)
  {
    return false;
  }
  return true }

Going further

Since we have demonstrated how to access the windows firewall manager and control its various aspects, now anyone can explore the Windows Fireall API and do a lot more that presented in this post. I would like to point to several MSDN references for further read.

MSDN Windows Firewall Reference
Loads of VBScript samples to do various things, you can translate the code to C#

Since windows firewall can be controlled via COM, any application running in your system can enable/disable or modify the firewall settings. I would suggest to use a third party firewall. For real security geek I would recommend Outpost Firewall ( I use the Outpost Security Suite) as the paid firewall and Comodo Personal Firewall as the best free firewall. Both these firewalls are way superior to other available firewalls.

kick it on DotNetKicks.com

Comments

mad_dog

Ah... it seems that though some people around the web have stated these methods work with Windows 7, they in fact do not.
The code below works for me but only changes for the current profile type (eg: Home/Private, but not Public Network as I am not connected to one).

So just run one of these two method calls, which will do the rest for you:

setFirewallStatus(getCurrPolicy(), false);
getFirewallStatus();
____________________________________________

using NetFwTypeLib;
(in Solution Explorer, right click References, Add Reference, COM tab, select NetFWTypeLib. This is FirewallAPI.dll)

private static INetFwPolicy2 getCurrPolicy()
{
INetFwPolicy2 fwPolicy2;
Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
return fwPolicy2;
}

public bool getFirewallStatus()
{
INetFwPolicy2 fwPolicy2 = getCurrPolicy();
NET_FW_PROFILE_TYPE2_ fwCurrentProfileTypes;
//read Current Profile Types (only to increase Performace)
//avoids access on CurrentProfileTypes from each Property
fwCurrentProfileTypes = (NET_FW_PROFILE_TYPE2_)fwPolicy2.CurrentProfileTypes;
return (fwPolicy2.get_FirewallEnabled(fwCurrentProfileTypes));
}

public void setFirewallStatus(INetFwPolicy2 currPolicy, bool newStatus)
{
NET_FW_PROFILE_TYPE2_ fwCurrentProfileTypes;
//read Current Profile Types (only to increase Performace)
//avoids access on CurrentProfileTypes from each Property
fwCurrentProfileTypes = (NET_FW_PROFILE_TYPE2_)currPolicy.CurrentProfileTypes;
currPolicy.set_FirewallEnabled(fwCurrentProfileTypes, newStatus);
}

___________________________
And thanks to the post on that other site from "user383659" that got me headed in the right direction. :-)

The comments to this entry are closed.