Index: chrome/installer/util/advanced_security_firewall_manager_win.cc |
diff --git a/chrome/installer/util/advanced_security_firewall_manager_win.cc b/chrome/installer/util/advanced_security_firewall_manager_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b0e4eb35b1ec2760702142d148787e49e9ce43b6 |
--- /dev/null |
+++ b/chrome/installer/util/advanced_security_firewall_manager_win.cc |
@@ -0,0 +1,158 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/installer/util/advanced_security_firewall_manager_win.h" |
+ |
+#include "base/logging.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/win/scoped_bstr.h" |
+#include "chrome/installer/util/browser_distribution.h" |
+#include "chrome/installer/util/install_util.h" |
+#include "chrome/installer/util/l10n_string_util.h" |
+ |
+#include "installer_util_strings.h" // NOLINT |
+ |
+namespace installer { |
+ |
+AdvancedSecurityFirewallManager::AdvancedSecurityFirewallManager() {} |
+ |
+AdvancedSecurityFirewallManager::~AdvancedSecurityFirewallManager() {} |
+ |
+bool AdvancedSecurityFirewallManager::Init(BrowserDistribution* dist, |
+ const base::FilePath& chrome_path) { |
+ HRESULT hr = firewall_policy_.CreateInstance(CLSID_NetFwPolicy2); |
+ if (FAILED(hr)) { |
+ DLOG(ERROR) << base::StringPrintf("0x%X", hr); |
+ return false; |
+ } |
+ distribution_ = dist; |
+ chrome_path_ = chrome_path; |
+ return true; |
+} |
+ |
+bool AdvancedSecurityFirewallManager::AddUDPFirewallRuleIfAbsent() { |
+ base::win::ScopedComPtr<INetFwRules> rules; |
+ HRESULT hr = firewall_policy_->get_Rules(rules.Receive()); |
+ if (FAILED(hr)) { |
+ DLOG(ERROR) << base::StringPrintf("0x%X", hr); |
+ return false; |
+ } |
+ |
+ // First, check if the rule is already present. If so, there is no work to do. |
+ base::win::ScopedComPtr<INetFwRule> udp_rule; |
+ hr = rules->Item(base::win::ScopedBstr(GetUDPRuleName().c_str()), |
+ udp_rule.Receive()); |
+ if (SUCCEEDED(hr)) |
+ return true; |
+ |
+ // Create the rule and add it to the rule set (only succeeds if elevated). |
+ udp_rule = CreateUDPRule(); |
+ if (udp_rule.get()) |
+ hr = rules->Add(udp_rule); |
+ |
+ return SUCCEEDED(hr); |
+} |
+ |
+void AdvancedSecurityFirewallManager::DeleteUDPFirewallRule() { |
+ base::win::ScopedComPtr<INetFwRules> rules; |
+ HRESULT hr = firewall_policy_->get_Rules(rules.Receive()); |
+ if (FAILED(hr)) { |
+ DLOG(ERROR) << base::StringPrintf("0x%X", hr); |
+ return; |
+ } |
+ |
+ hr = rules->Remove(base::win::ScopedBstr(GetUDPRuleName().c_str())); |
+ DLOG_IF(ERROR, FAILED(hr)) << base::StringPrintf("0x%X", hr); |
+} |
+ |
+bool AdvancedSecurityFirewallManager::CanUseLocalUDPPort() { |
+ // Determine if the firewall is enabled for the currently active profiles. If |
+ // it isn't, it is safe to use a local UDP port without user annoyance. |
+ long current_profile_types = 0; |
+ HRESULT hr = firewall_policy_->get_CurrentProfileTypes( |
+ ¤t_profile_types); |
+ if (SUCCEEDED(hr)) { |
+ // The most-restrictive active profile takes precedence. |
+ const NET_FW_PROFILE_TYPE2 kProfileTypes[] = { |
+ NET_FW_PROFILE2_PUBLIC, |
+ NET_FW_PROFILE2_PRIVATE, |
+ NET_FW_PROFILE2_DOMAIN |
+ }; |
+ bool has_enabled_profile = false; |
+ for (size_t i = 0; !has_enabled_profile && i < arraysize(kProfileTypes); |
+ ++i) { |
+ if ((current_profile_types & kProfileTypes[i]) != 0) { |
+ VARIANT_BOOL enabled = VARIANT_TRUE; |
+ hr = firewall_policy_->get_FirewallEnabled(kProfileTypes[i], &enabled); |
+ // Assume the firewall is enabled if we can't determine. |
+ if (FAILED(hr) || enabled != VARIANT_FALSE) |
+ has_enabled_profile = true; |
+ } |
+ } |
+ if (!has_enabled_profile) |
+ return true; |
+ } |
+ |
+ // See if the rule is in place for Chrome. |
+ base::win::ScopedComPtr<INetFwRules> rules; |
+ hr = firewall_policy_->get_Rules(rules.Receive()); |
+ if (FAILED(hr)) { |
+ DLOG(ERROR) << base::StringPrintf("0x%X", hr); |
+ return false; |
+ } |
+ |
+ base::win::ScopedComPtr<INetFwRule> udp_rule; |
+ hr = rules->Item(base::win::ScopedBstr(GetUDPRuleName().c_str()), |
+ udp_rule.Receive()); |
+ if (SUCCEEDED(hr)) |
+ return true; |
+ |
+ return false; |
+} |
+ |
+base::string16 AdvancedSecurityFirewallManager::GetUDPRuleName() { |
+#if defined(GOOGLE_CHROME_BUILD) |
+ if (InstallUtil::IsChromeSxSProcess()) |
+ return GetLocalizedString(IDS_INBOUND_UDP_RULE_NAME_SXS_BASE); |
+#endif |
+ return GetLocalizedString(IDS_INBOUND_UDP_RULE_NAME_BASE); |
+} |
+ |
+base::string16 AdvancedSecurityFirewallManager::GetUDPRuleDescription() { |
+#if defined(GOOGLE_CHROME_BUILD) |
+ if (InstallUtil::IsChromeSxSProcess()) |
+ return GetLocalizedString(IDS_INBOUND_UDP_RULE_DESCRIPTION_SXS_BASE); |
+#endif |
+ return GetLocalizedString(IDS_INBOUND_UDP_RULE_DESCRIPTION_BASE); |
+} |
+ |
+base::win::ScopedComPtr<INetFwRule> |
+AdvancedSecurityFirewallManager::CreateUDPRule() { |
+ base::win::ScopedComPtr<INetFwRule> udp_rule; |
+ |
+ HRESULT hr = udp_rule.CreateInstance(CLSID_NetFwRule); |
+ if (FAILED(hr)) { |
+ DLOG(ERROR) << base::StringPrintf("0x%X", hr); |
+ return base::win::ScopedComPtr<INetFwRule>(); |
+ } |
+ |
+ const base::string16 display_name(distribution_->GetDisplayName()); |
+ |
+ // TODO(grt): http://crbug.com/75152 Use references to localized resources. |
+ udp_rule->put_Name(base::win::ScopedBstr(GetUDPRuleName().c_str())); |
+ udp_rule->put_Description(base::win::ScopedBstr( |
+ GetUDPRuleDescription().c_str())); |
+ udp_rule->put_ApplicationName(base::win::ScopedBstr( |
+ chrome_path_.value().c_str())); |
+ udp_rule->put_Protocol(NET_FW_IP_PROTOCOL_UDP); |
+ udp_rule->put_Direction(NET_FW_RULE_DIR_IN); |
+ udp_rule->put_Enabled(VARIANT_TRUE); |
+ udp_rule->put_Grouping(base::win::ScopedBstr(display_name.c_str())); |
+ udp_rule->put_Profiles(NET_FW_PROFILE2_ALL); |
+ udp_rule->put_Action(NET_FW_ACTION_BLOCK); |
+ |
+ return udp_rule; |
+} |
+ |
+} // namespace installer |