Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004--2005, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "talk/base/winfirewall.h"
     29 
     30 #include "talk/base/win32.h"
     31 
     32 #include <comdef.h>
     33 #include <netfw.h>
     34 
     35 #define RELEASE(lpUnk) do { \
     36   if ((lpUnk) != NULL) { \
     37     (lpUnk)->Release(); \
     38     (lpUnk) = NULL; \
     39   } \
     40 } while (0)
     41 
     42 namespace talk_base {
     43 
     44 //////////////////////////////////////////////////////////////////////
     45 // WinFirewall
     46 //////////////////////////////////////////////////////////////////////
     47 
     48 WinFirewall::WinFirewall() : mgr_(NULL), policy_(NULL), profile_(NULL) {
     49 }
     50 
     51 WinFirewall::~WinFirewall() {
     52   Shutdown();
     53 }
     54 
     55 bool WinFirewall::Initialize(HRESULT* result) {
     56   if (mgr_) {
     57     if (result) {
     58       *result = S_OK;
     59     }
     60     return true;
     61   }
     62 
     63   HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr),
     64                                 0, CLSCTX_INPROC_SERVER,
     65                                 __uuidof(INetFwMgr),
     66                                 reinterpret_cast<void **>(&mgr_));
     67   if (SUCCEEDED(hr) && (mgr_ != NULL))
     68     hr = mgr_->get_LocalPolicy(&policy_);
     69   if (SUCCEEDED(hr) && (policy_ != NULL))
     70     hr = policy_->get_CurrentProfile(&profile_);
     71 
     72   if (result)
     73     *result = hr;
     74   return SUCCEEDED(hr) && (profile_ != NULL);
     75 }
     76 
     77 void WinFirewall::Shutdown() {
     78   RELEASE(profile_);
     79   RELEASE(policy_);
     80   RELEASE(mgr_);
     81 }
     82 
     83 bool WinFirewall::Enabled() const {
     84   if (!profile_)
     85     return false;
     86 
     87   VARIANT_BOOL fwEnabled = VARIANT_FALSE;
     88   profile_->get_FirewallEnabled(&fwEnabled);
     89   return (fwEnabled != VARIANT_FALSE);
     90 }
     91 
     92 bool WinFirewall::QueryAuthorized(const char* filename, bool* authorized)
     93     const {
     94   return QueryAuthorizedW(ToUtf16(filename).c_str(), authorized);
     95 }
     96 
     97 bool WinFirewall::QueryAuthorizedW(const wchar_t* filename, bool* authorized)
     98     const {
     99   *authorized = false;
    100   bool success = false;
    101 
    102   if (!profile_)
    103     return false;
    104 
    105   _bstr_t bfilename = filename;
    106 
    107   INetFwAuthorizedApplications* apps = NULL;
    108   HRESULT hr = profile_->get_AuthorizedApplications(&apps);
    109   if (SUCCEEDED(hr) && (apps != NULL)) {
    110     INetFwAuthorizedApplication* app = NULL;
    111     hr = apps->Item(bfilename, &app);
    112     if (SUCCEEDED(hr) && (app != NULL)) {
    113       VARIANT_BOOL fwEnabled = VARIANT_FALSE;
    114       hr = app->get_Enabled(&fwEnabled);
    115       app->Release();
    116 
    117       if (SUCCEEDED(hr)) {
    118         success = true;
    119         *authorized = (fwEnabled != VARIANT_FALSE);
    120       }
    121     } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
    122       // No entry in list of authorized apps
    123       success = true;
    124     } else {
    125       // Unexpected error
    126     }
    127     apps->Release();
    128   }
    129 
    130   return success;
    131 }
    132 
    133 bool WinFirewall::AddApplication(const char* filename,
    134                                  const char* friendly_name,
    135                                  bool authorized,
    136                                  HRESULT* result) {
    137   return AddApplicationW(ToUtf16(filename).c_str(),
    138       ToUtf16(friendly_name).c_str(), authorized, result);
    139 }
    140 
    141 bool WinFirewall::AddApplicationW(const wchar_t* filename,
    142                                   const wchar_t* friendly_name,
    143                                   bool authorized,
    144                                   HRESULT* result) {
    145   INetFwAuthorizedApplications* apps = NULL;
    146   HRESULT hr = profile_->get_AuthorizedApplications(&apps);
    147   if (SUCCEEDED(hr) && (apps != NULL)) {
    148     INetFwAuthorizedApplication* app = NULL;
    149     hr = CoCreateInstance(__uuidof(NetFwAuthorizedApplication),
    150                           0, CLSCTX_INPROC_SERVER,
    151                           __uuidof(INetFwAuthorizedApplication),
    152                           reinterpret_cast<void **>(&app));
    153     if (SUCCEEDED(hr) && (app != NULL)) {
    154       _bstr_t bstr = filename;
    155       hr = app->put_ProcessImageFileName(bstr);
    156       bstr = friendly_name;
    157       if (SUCCEEDED(hr))
    158         hr = app->put_Name(bstr);
    159       if (SUCCEEDED(hr))
    160         hr = app->put_Enabled(authorized ? VARIANT_TRUE : VARIANT_FALSE);
    161       if (SUCCEEDED(hr))
    162         hr = apps->Add(app);
    163       app->Release();
    164     }
    165     apps->Release();
    166   }
    167   if (result)
    168     *result = hr;
    169   return SUCCEEDED(hr);
    170 }
    171 
    172 }  // namespace talk_base
    173