ファイアウォール有効無効を取得するには


巡茶  2009-11-18 20:10:25  No: 71108

題通りなのですが、
ファイアウォール有効無効を取得する方法が分からず
困っています。

また、ファイアウォールが有効な場合
「例外を許可しない」のチェックがなしで、
例外に自作のソフトが登録されているかのチェックもしたいのですが
これも分かりません。

ご存知の方いましたら、よろしくお願いします。

環境
VC++6 MFC XP以降


オショウ  2009-11-18 20:50:19  No: 71109

ええ〜と・・・

OSは何でしょう・・・
当然、VISTA以降なら管理者権限必要です。

C++なんで・・・
#include <netfw.h>

以下も必要だったかは未確認・・・
#include <objbase.h>
#include <oleauto.h>

例えば・・・(C++ CLIで書いてます)

  static  HRESULT WindowsFirewallInitialize(OUT INetFwProfile** fwProfile){

    HRESULT hr = S_OK;
    INetFwMgr* fwMgr = NULL;
    INetFwPolicy* fwPolicy = NULL;

    _ASSERT(fwProfile != NULL);

    *fwProfile = NULL;

    // Create an instance of the firewall settings manager.
    hr = CoCreateInstance(__uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&fwMgr);
    if (FAILED(hr)){
      printf("CoCreateInstance failed: 0x%08lx\n", hr);
      goto error;
    }

    // Retrieve the local firewall policy.
    hr = fwMgr->get_LocalPolicy(&fwPolicy);
    if (FAILED(hr)){
      printf("get_LocalPolicy failed: 0x%08lx\n", hr);
      goto error;
    }

    // Retrieve the firewall profile currently in effect.
    hr = fwPolicy->get_CurrentProfile(fwProfile);
    if (FAILED(hr)){
      printf("get_CurrentProfile failed: 0x%08lx\n", hr);
      goto error;
    }

  error:
    // Release the local firewall policy.
    if (fwPolicy != NULL){
      fwPolicy->Release();
    }

    // Release the firewall settings manager.
    if (fwMgr != NULL){
      fwMgr->Release();
    }

    return hr;
  }

    で、まず使えるように初期化して・・・

  System::Boolean  AdminUtil::AddFireWallRule(String^ ExecName, String^ RuleName){

    System::Boolean  bRet;
    HRESULT      hr;
    HRESULT      comInit;
    INetFwProfile*  fwProfile = NULL;
    wchar_t      wExecName[MAX_PATH];
    wchar_t      wRuleName[MAX_PATH];

    bRet = false;

    RtlZeroMemory(wExecName, MAX_PATH * 2);
    RtlZeroMemory(wRuleName, MAX_PATH * 2);

    MarshalString(ExecName, wExecName, ExecName->Length * 2 );
    MarshalString(RuleName, wRuleName, RuleName->Length * 2 );

    comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE );

    __try {
      if (comInit != RPC_E_CHANGED_MODE){
        hr = comInit;
        if (FAILED(hr)){
          printf("CoInitializeEx failed: 0x%08lx\n", hr);
          __leave;
        }
      }

      hr = WindowsFirewallInitialize(&fwProfile);
      if (FAILED(hr)){
        printf("WindowsFirewallInitialize failed: 0x%08lx\n", hr);
          __leave;
      }

      hr = WindowsFirewallAppAdd(fwProfile, wExecName , wRuleName );
      if (FAILED(hr)){
        printf("WindowsFirewallAddApp failed: 0x%08lx\n", hr);
          __leave;
      }

      bRet = true;
    } __finally{
      WindowsFirewallCleanup(fwProfile);

      if (SUCCEEDED(comInit)){
        CoUninitialize();
      }
    }

    return bRet;

  }

    で、ルールを追加する・・・

    細かいところは、ヘッダーの中身読むなり、検索して
    もらえれば、ヒットしますヨ!

※  ファイアウォールの有効無効も当然取得・設定できます。

以上。参考まで


オショウ  2009-11-18 20:53:05  No: 71110

追伸・・・

有効無効の取得・設定も作っていたので参考に!

  static  HRESULT WindowsFirewallIsOn(IN INetFwProfile* fwProfile, OUT BOOL* fwOn){

    HRESULT hr = S_OK;
    VARIANT_BOOL fwEnabled;

    _ASSERT(fwProfile != NULL);
    _ASSERT(fwOn != NULL);

    *fwOn = FALSE;

    // Get the current state of the firewall.
    hr = fwProfile->get_FirewallEnabled(&fwEnabled);
    if (FAILED(hr)){
      printf("get_FirewallEnabled failed: 0x%08lx\n", hr);
      goto error;
    }

    // Check to see if the firewall is on.
    if (fwEnabled != VARIANT_FALSE){
      *fwOn = TRUE;
      printf("The firewall is on.\n");
    } else {
      printf("The firewall is off.\n");
    }

  error:
    return hr;

  }

ほかにも・・・

  static  HRESULT WindowsFirewallTurnOn(IN INetFwProfile* fwProfile){

    HRESULT hr = S_OK;
    BOOL fwOn;

    _ASSERT(fwProfile != NULL);

    // Check to see if the firewall is off.
    hr = WindowsFirewallIsOn(fwProfile, &fwOn);
    if (FAILED(hr)){
      printf("WindowsFirewallIsOn failed: 0x%08lx\n", hr);
      goto error;
    }

    // If it is, turn it on.
    if (!fwOn){
      // Turn the firewall on.
      hr = fwProfile->put_FirewallEnabled(VARIANT_TRUE);
      if (FAILED(hr)){
        printf("put_FirewallEnabled failed: 0x%08lx\n", hr);
        goto error;
      }
      printf("The firewall is now on.\n");
    }

  error:
    return hr;

  }

  static  HRESULT WindowsFirewallTurnOff(IN INetFwProfile* fwProfile){

    HRESULT hr = S_OK;
    BOOL fwOn;

    _ASSERT(fwProfile != NULL);

    // Check to see if the firewall is on.
    hr = WindowsFirewallIsOn(fwProfile, &fwOn);
    if (FAILED(hr)){
      printf("WindowsFirewallIsOn failed: 0x%08lx\n", hr);
      goto error;
    }

    // If it is, turn it off.
    if (fwOn){
      // Turn the firewall off.
      hr = fwProfile->put_FirewallEnabled(VARIANT_FALSE);
      if (FAILED(hr)){
        printf("put_FirewallEnabled failed: 0x%08lx\n", hr);
        goto error;
      }
      printf("The firewall is now off.\n");
    }

  error:
    return hr;

  }

  static  HRESULT WindowsFirewallPortIsEnabled(IN INetFwProfile* fwProfile, IN LONG portNumber, IN NET_FW_IP_PROTOCOL ipProtocol, OUT BOOL* fwPortEnabled ){

    HRESULT hr = S_OK;
    VARIANT_BOOL fwEnabled;
    INetFwOpenPort* fwOpenPort = NULL;
    INetFwOpenPorts* fwOpenPorts = NULL;

    _ASSERT(fwProfile != NULL);
    _ASSERT(fwPortEnabled != NULL);

    *fwPortEnabled = FALSE;

    // Retrieve the globally open ports collection.
    hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts);
    if (FAILED(hr)){
      printf("get_GloballyOpenPorts failed: 0x%08lx\n", hr);
      goto error;
    }

    // Attempt to retrieve the globally open port.
    hr = fwOpenPorts->Item(portNumber, ipProtocol, &fwOpenPort);
    if (SUCCEEDED(hr)){
      // Find out if the globally open port is enabled.
      hr = fwOpenPort->get_Enabled(&fwEnabled);
      if (FAILED(hr)){
        printf("get_Enabled failed: 0x%08lx\n", hr);
        goto error;
      }
      if (fwEnabled != VARIANT_FALSE){
        // The globally open port is enabled.
        *fwPortEnabled = TRUE;

        printf("Port %ld is open in the firewall.\n", portNumber);
      } else {
        printf("Port %ld is not open in the firewall.\n", portNumber);
      }
    } else {
      // The globally open port was not in the collection.
      hr = S_OK;

      printf("Port %ld is not open in the firewall.\n", portNumber);
    }

  error:
    // Release the globally open port.
    if (fwOpenPort != NULL){
      fwOpenPort->Release();
    }

    // Release the globally open ports collection.
    if (fwOpenPorts != NULL){
      fwOpenPorts->Release();
    }

    return hr;

  }

  static  HRESULT WindowsFirewallPortAdd( IN INetFwProfile* fwProfile, IN LONG portNumber, IN NET_FW_IP_PROTOCOL ipProtocol, IN const wchar_t* name ){

    HRESULT hr = S_OK;
    BOOL fwPortEnabled;
    BSTR fwBstrName = NULL;

    INetFwOpenPort* fwOpenPort = NULL;
    INetFwOpenPorts* fwOpenPorts = NULL;

    _ASSERT(fwProfile != NULL);
    _ASSERT(name != NULL);

    // First check to see if the port is already added.
    hr = WindowsFirewallPortIsEnabled( fwProfile, portNumber, ipProtocol, &fwPortEnabled );
    if (FAILED(hr)){
      printf("WindowsFirewallPortIsEnabled failed: 0x%08lx\n", hr);
      goto error;
    }

    // Only add the port if it isn't already added.
    if (!fwPortEnabled){
      // Retrieve the collection of globally open ports.
      hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts);
      if (FAILED(hr)){
        printf("get_GloballyOpenPorts failed: 0x%08lx\n", hr);
        goto error;
      }

      // Create an instance of an open port.
      hr = CoCreateInstance( __uuidof(NetFwOpenPort), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwOpenPort), (void**)&fwOpenPort );
      if (FAILED(hr)){
        printf("CoCreateInstance failed: 0x%08lx\n", hr);
        goto error;
      }

      // Set the port number.
      hr = fwOpenPort->put_Port(portNumber);
      if (FAILED(hr)){
        printf("put_Port failed: 0x%08lx\n", hr);
        goto error;
      }

      // Set the IP protocol.
      hr = fwOpenPort->put_Protocol(ipProtocol);
      if (FAILED(hr)){
        printf("put_Protocol failed: 0x%08lx\n", hr);
        goto error;
      }

      // Allocate a BSTR for the friendly name of the port.
      fwBstrName = SysAllocString(name);
      if (SysStringLen(fwBstrName) == 0){
        hr = E_OUTOFMEMORY;
        printf("SysAllocString failed: 0x%08lx\n", hr);
        goto error;
      }

      // Set the friendly name of the port.
      hr = fwOpenPort->put_Name(fwBstrName);
      if (FAILED(hr)){
        printf("put_Name failed: 0x%08lx\n", hr);
        goto error;
      }

      // Opens the port and adds it to the collection.
      hr = fwOpenPorts->Add(fwOpenPort);
      if (FAILED(hr)){
        printf("Add failed: 0x%08lx\n", hr);
        goto error;
      }

      printf("Port %ld is now open in the firewall.\n", portNumber);

    }

  error:
    // Free the BSTR.
    SysFreeString(fwBstrName);
    
    // Release the open port instance.
    if (fwOpenPort != NULL){
      fwOpenPort->Release();
    }

    // Release the globally open ports collection.
    if (fwOpenPorts != NULL){
      fwOpenPorts->Release();
    }

    return hr;

  }

以上。


オショウ  2009-11-18 20:54:08  No: 71111

追伸2・・・(抜けた)

  static  void WindowsFirewallCleanup(IN INetFwProfile* fwProfile){

    // Release the firewall profile.
    if (fwProfile != NULL){
      fwProfile->Release();
    }

  }

以上。


tetrapod  2009-11-18 22:23:55  No: 71112

まあ本来 Firewall っつのは安全のためにあるものなので
たかだか1アプリケーションが FW の有無をチェックしてどーのこーの、ってのは
セキュリティ的にお勧めできないなー、むしろ絶対するなと言っておく。

FW への穴あけは本来ユーザーの責任でするべきであって、自動ですべきぢゃない。
自動で穴あけせざるを得ないとしたら、インストーラーがすべき。
少なくとも俺ならアプリケーション本体に FW を触るコードは組み込まない。

まあ案件にもよるが Windows Firewall だけ穴あけても意味なくて、
家庭用ルータの NAT 設定までしなきゃ片手落ちだと思う・・・
UPnP とか・・


オショウ  2009-11-18 23:27:01  No: 71113

アプリ製作者の立場からだと、インストーラを含めて
提供するケースがおおいにあり・・・

で、インストーラでは、自身が既に管理者権限を有する
ので、その段階でやってしまった方が、逆に安全と言う
か楽と言うか・・・

まぁ〜インストーラ作らない人やそういう要望を受けない
人なら、そういう意見もありだとは思う。

※  私は、VISTA/Win7/Server2003/Server2008での
    小規模・大規模的システム製作やっているので
    そういうことは必要不可欠な技術範疇なもので

※  敢えて言うと、VISTA以降のUAC回避も裏技的な
    方法使わずに一般的に公開されているSDKだけ
    の情報で回避できる。(マイクロソフトの!)
    まぁ〜情報を提供する側が、ストレートに解る
    ように情報提供していない為、解りにくいんだ
    が・・・(敢えて解らないようにしているとし
    か思えないフシがある(と思う))

※  さらに・・・
    インターネット上でいろいろな検索サイトを探せば
    ほぼ入手できないコードはない・・・
    大概は海外圏だが・・・
    そこまで調べる根気と時間があれば、こういうサイ
    トにカキコミはされない・・・

板汚しでした・・・

以上。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加