1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/base/winfirewall.h"
12 
13 #include "webrtc/base/win32.h"
14 
15 #include <comdef.h>
16 #include <netfw.h>
17 
18 #define RELEASE(lpUnk) do { \
19   if ((lpUnk) != NULL) { \
20     (lpUnk)->Release(); \
21     (lpUnk) = NULL; \
22   } \
23 } while (0)
24 
25 namespace rtc {
26 
27 //////////////////////////////////////////////////////////////////////
28 // WinFirewall
29 //////////////////////////////////////////////////////////////////////
30 
WinFirewall()31 WinFirewall::WinFirewall() : mgr_(NULL), policy_(NULL), profile_(NULL) {
32 }
33 
~WinFirewall()34 WinFirewall::~WinFirewall() {
35   Shutdown();
36 }
37 
Initialize(HRESULT * result)38 bool WinFirewall::Initialize(HRESULT* result) {
39   if (mgr_) {
40     if (result) {
41       *result = S_OK;
42     }
43     return true;
44   }
45 
46   HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr),
47                                 0, CLSCTX_INPROC_SERVER,
48                                 __uuidof(INetFwMgr),
49                                 reinterpret_cast<void **>(&mgr_));
50   if (SUCCEEDED(hr) && (mgr_ != NULL))
51     hr = mgr_->get_LocalPolicy(&policy_);
52   if (SUCCEEDED(hr) && (policy_ != NULL))
53     hr = policy_->get_CurrentProfile(&profile_);
54 
55   if (result)
56     *result = hr;
57   return SUCCEEDED(hr) && (profile_ != NULL);
58 }
59 
Shutdown()60 void WinFirewall::Shutdown() {
61   RELEASE(profile_);
62   RELEASE(policy_);
63   RELEASE(mgr_);
64 }
65 
Enabled() const66 bool WinFirewall::Enabled() const {
67   if (!profile_)
68     return false;
69 
70   VARIANT_BOOL fwEnabled = VARIANT_FALSE;
71   profile_->get_FirewallEnabled(&fwEnabled);
72   return (fwEnabled != VARIANT_FALSE);
73 }
74 
QueryAuthorized(const char * filename,bool * authorized) const75 bool WinFirewall::QueryAuthorized(const char* filename, bool* authorized)
76     const {
77   return QueryAuthorizedW(ToUtf16(filename).c_str(), authorized);
78 }
79 
QueryAuthorizedW(const wchar_t * filename,bool * authorized) const80 bool WinFirewall::QueryAuthorizedW(const wchar_t* filename, bool* authorized)
81     const {
82   *authorized = false;
83   bool success = false;
84 
85   if (!profile_)
86     return false;
87 
88   _bstr_t bfilename = filename;
89 
90   INetFwAuthorizedApplications* apps = NULL;
91   HRESULT hr = profile_->get_AuthorizedApplications(&apps);
92   if (SUCCEEDED(hr) && (apps != NULL)) {
93     INetFwAuthorizedApplication* app = NULL;
94     hr = apps->Item(bfilename, &app);
95     if (SUCCEEDED(hr) && (app != NULL)) {
96       VARIANT_BOOL fwEnabled = VARIANT_FALSE;
97       hr = app->get_Enabled(&fwEnabled);
98       app->Release();
99 
100       if (SUCCEEDED(hr)) {
101         success = true;
102         *authorized = (fwEnabled != VARIANT_FALSE);
103       }
104     } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
105       // No entry in list of authorized apps
106       success = true;
107     } else {
108       // Unexpected error
109     }
110     apps->Release();
111   }
112 
113   return success;
114 }
115 
AddApplication(const char * filename,const char * friendly_name,bool authorized,HRESULT * result)116 bool WinFirewall::AddApplication(const char* filename,
117                                  const char* friendly_name,
118                                  bool authorized,
119                                  HRESULT* result) {
120   return AddApplicationW(ToUtf16(filename).c_str(),
121       ToUtf16(friendly_name).c_str(), authorized, result);
122 }
123 
AddApplicationW(const wchar_t * filename,const wchar_t * friendly_name,bool authorized,HRESULT * result)124 bool WinFirewall::AddApplicationW(const wchar_t* filename,
125                                   const wchar_t* friendly_name,
126                                   bool authorized,
127                                   HRESULT* result) {
128   INetFwAuthorizedApplications* apps = NULL;
129   HRESULT hr = profile_->get_AuthorizedApplications(&apps);
130   if (SUCCEEDED(hr) && (apps != NULL)) {
131     INetFwAuthorizedApplication* app = NULL;
132     hr = CoCreateInstance(__uuidof(NetFwAuthorizedApplication),
133                           0, CLSCTX_INPROC_SERVER,
134                           __uuidof(INetFwAuthorizedApplication),
135                           reinterpret_cast<void **>(&app));
136     if (SUCCEEDED(hr) && (app != NULL)) {
137       _bstr_t bstr = filename;
138       hr = app->put_ProcessImageFileName(bstr);
139       bstr = friendly_name;
140       if (SUCCEEDED(hr))
141         hr = app->put_Name(bstr);
142       if (SUCCEEDED(hr))
143         hr = app->put_Enabled(authorized ? VARIANT_TRUE : VARIANT_FALSE);
144       if (SUCCEEDED(hr))
145         hr = apps->Add(app);
146       app->Release();
147     }
148     apps->Release();
149   }
150   if (result)
151     *result = hr;
152   return SUCCEEDED(hr);
153 }
154 
155 }  // namespace rtc
156