OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/policy/core/browser/browser_policy_connector.h" | 5 #include "components/policy/core/browser/browser_policy_connector.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/metrics/histogram.h" | |
15 #include "base/metrics/sparse_histogram.h" | |
14 #include "base/prefs/pref_registry_simple.h" | 16 #include "base/prefs/pref_registry_simple.h" |
15 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
16 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
17 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" | 19 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" |
18 #include "components/policy/core/common/cloud/device_management_service.h" | 20 #include "components/policy/core/common/cloud/device_management_service.h" |
19 #include "components/policy/core/common/configuration_policy_provider.h" | 21 #include "components/policy/core/common/configuration_policy_provider.h" |
20 #include "components/policy/core/common/policy_namespace.h" | 22 #include "components/policy/core/common/policy_namespace.h" |
21 #include "components/policy/core/common/policy_pref_names.h" | 23 #include "components/policy/core/common/policy_pref_names.h" |
22 #include "components/policy/core/common/policy_service_impl.h" | 24 #include "components/policy/core/common/policy_service_impl.h" |
23 #include "components/policy/core/common/policy_statistics_collector.h" | 25 #include "components/policy/core/common/policy_statistics_collector.h" |
24 #include "components/policy/core/common/policy_switches.h" | 26 #include "components/policy/core/common/policy_switches.h" |
25 #include "google_apis/gaia/gaia_auth_util.h" | 27 #include "google_apis/gaia/gaia_auth_util.h" |
26 #include "net/url_request/url_request_context_getter.h" | 28 #include "net/url_request/url_request_context_getter.h" |
27 #include "policy/policy_constants.h" | 29 #include "policy/policy_constants.h" |
28 #include "third_party/icu/source/i18n/unicode/regex.h" | 30 #include "third_party/icu/source/i18n/unicode/regex.h" |
29 | 31 |
30 namespace policy { | 32 namespace policy { |
31 | 33 |
32 namespace { | 34 namespace { |
33 | 35 |
34 // The URL for the device management server. | 36 // The URL for the device management server. |
35 const char kDefaultDeviceManagementServerUrl[] = | 37 const char kDefaultDeviceManagementServerUrl[] = |
36 "https://m.google.com/devicemanagement/data/api"; | 38 "https://m.google.com/devicemanagement/data/api"; |
37 | 39 |
38 // Used in BrowserPolicyConnector::SetPolicyProviderForTesting. | 40 // Used in BrowserPolicyConnector::SetPolicyProviderForTesting. |
39 bool g_created_policy_service = false; | 41 bool g_created_policy_service = false; |
40 ConfigurationPolicyProvider* g_testing_provider = NULL; | 42 ConfigurationPolicyProvider* g_testing_provider = NULL; |
41 | 43 |
44 void ReportRegexSuccessMetric(bool success) { | |
45 UMA_HISTOGRAM_BOOLEAN("Enterprise.DomainWhitelistRegexSuccess", success); | |
46 } | |
47 | |
48 | |
Ilya Sherman
2014/07/24 17:29:32
nit: Spurious newline
Andrew T Wilson (Slow)
2014/07/25 07:39:01
Done.
| |
49 // Regexes that match many of the larger public email providers as we know | |
50 // these users are not from hosted enterprise domains. Keep this list in sync | |
51 // with the EnterpriseDomainRegex enum in histograms.xml. | |
52 const wchar_t* kNonManagedDomainPatterns[] = { | |
Ilya Sherman
2014/07/24 17:29:33
nit: Can this be more const?
Andrew T Wilson (Slow)
2014/07/25 07:39:01
Done.
| |
53 L"aol\\.com", | |
54 L"googlemail\\.com", | |
55 L"gmail\\.com", | |
56 L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk | |
Ilya Sherman
2014/07/24 17:29:33
Hmm, this is a slightly strange regex -- why speci
Andrew T Wilson (Slow)
2014/07/24 19:49:53
Agreed, I can fix this in a separate CL (this isn'
| |
57 L"live\\.com", | |
58 L"mail\\.ru", | |
59 L"msn\\.com", | |
60 L"qq\\.com", | |
61 L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw | |
62 L"yandex\\.ru", | |
63 }; | |
64 | |
42 // Returns true if |domain| matches the regex |pattern|. | 65 // Returns true if |domain| matches the regex |pattern|. |
43 bool MatchDomain(const base::string16& domain, const base::string16& pattern) { | 66 bool MatchDomain(const base::string16& domain, const base::string16& pattern, |
67 size_t index) { | |
44 UErrorCode status = U_ZERO_ERROR; | 68 UErrorCode status = U_ZERO_ERROR; |
45 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length()); | 69 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length()); |
46 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); | 70 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); |
47 if (!U_SUCCESS(status)) { | 71 if (!U_SUCCESS(status)) { |
48 // http://crbug.com/365351 - if for some reason the matcher creation fails | 72 // http://crbug.com/365351 - if for some reason the matcher creation fails |
49 // just return that the pattern doesn't match the domain. This is safe | 73 // just return that the pattern doesn't match the domain. This is safe |
50 // because the calling method (IsNonEnterpriseUser()) is just used to enable | 74 // because the calling method (IsNonEnterpriseUser()) is just used to enable |
51 // an optimization for non-enterprise users - better to skip the | 75 // an optimization for non-enterprise users - better to skip the |
52 // optimization than crash. | 76 // optimization than crash. |
53 DLOG(ERROR) << "Possible invalid domain pattern: " << pattern | 77 DLOG(ERROR) << "Possible invalid domain pattern: " << pattern |
54 << " - Error: " << status; | 78 << " - Error: " << status; |
79 ReportRegexSuccessMetric(false); | |
80 UMA_HISTOGRAM_ENUMERATION("Enterprise.DomainWhitelistRegexFailureIndex", | |
81 index, arraysize(kNonManagedDomainPatterns)); | |
Ilya Sherman
2014/07/24 17:29:33
Note that as you have this set up, the only valid
Andrew T Wilson (Slow)
2014/07/24 19:49:53
Yes. My goal isn't to have this be a long-term UMA
| |
82 UMA_HISTOGRAM_SPARSE_SLOWLY("Enterprise.DomainWhitelistRegexFailureStatus", | |
83 status); | |
55 return false; | 84 return false; |
56 } | 85 } |
86 ReportRegexSuccessMetric(true); | |
57 icu::UnicodeString icu_input(domain.data(), domain.length()); | 87 icu::UnicodeString icu_input(domain.data(), domain.length()); |
58 matcher.reset(icu_input); | 88 matcher.reset(icu_input); |
59 status = U_ZERO_ERROR; | 89 status = U_ZERO_ERROR; |
60 UBool match = matcher.matches(status); | 90 UBool match = matcher.matches(status); |
61 DCHECK(U_SUCCESS(status)); | 91 DCHECK(U_SUCCESS(status)); |
62 return !!match; // !! == convert from UBool to bool. | 92 return !!match; // !! == convert from UBool to bool. |
63 } | 93 } |
64 | 94 |
65 } // namespace | 95 } // namespace |
66 | 96 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 | 215 |
186 // static | 216 // static |
187 bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) { | 217 bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) { |
188 if (username.empty() || username.find('@') == std::string::npos) { | 218 if (username.empty() || username.find('@') == std::string::npos) { |
189 // An empty username means incognito user in case of ChromiumOS and | 219 // An empty username means incognito user in case of ChromiumOS and |
190 // no logged-in user in case of Chromium (SigninService). Many tests use | 220 // no logged-in user in case of Chromium (SigninService). Many tests use |
191 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise | 221 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise |
192 // users. | 222 // users. |
193 return true; | 223 return true; |
194 } | 224 } |
195 | |
196 // Exclude many of the larger public email providers as we know these users | |
197 // are not from hosted enterprise domains. | |
198 static const wchar_t* kNonManagedDomainPatterns[] = { | |
199 L"aol\\.com", | |
200 L"googlemail\\.com", | |
201 L"gmail\\.com", | |
202 L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk | |
203 L"live\\.com", | |
204 L"mail\\.ru", | |
205 L"msn\\.com", | |
206 L"qq\\.com", | |
207 L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw | |
208 L"yandex\\.ru", | |
209 }; | |
210 const base::string16 domain = base::UTF8ToUTF16( | 225 const base::string16 domain = base::UTF8ToUTF16( |
211 gaia::ExtractDomainName(gaia::CanonicalizeEmail(username))); | 226 gaia::ExtractDomainName(gaia::CanonicalizeEmail(username))); |
212 for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) { | 227 for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) { |
213 base::string16 pattern = base::WideToUTF16(kNonManagedDomainPatterns[i]); | 228 base::string16 pattern = base::WideToUTF16(kNonManagedDomainPatterns[i]); |
214 if (MatchDomain(domain, pattern)) | 229 if (MatchDomain(domain, pattern, i)) |
215 return true; | 230 return true; |
216 } | 231 } |
217 return false; | 232 return false; |
218 } | 233 } |
219 | 234 |
220 // static | 235 // static |
221 std::string BrowserPolicyConnector::GetDeviceManagementUrl() { | 236 std::string BrowserPolicyConnector::GetDeviceManagementUrl() { |
222 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 237 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
223 if (command_line->HasSwitch(switches::kDeviceManagementUrl)) | 238 if (command_line->HasSwitch(switches::kDeviceManagementUrl)) |
224 return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl); | 239 return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl); |
(...skipping 14 matching lines...) Expand all Loading... | |
239 } | 254 } |
240 | 255 |
241 void BrowserPolicyConnector::SetPlatformPolicyProvider( | 256 void BrowserPolicyConnector::SetPlatformPolicyProvider( |
242 scoped_ptr<ConfigurationPolicyProvider> provider) { | 257 scoped_ptr<ConfigurationPolicyProvider> provider) { |
243 CHECK(!platform_policy_provider_); | 258 CHECK(!platform_policy_provider_); |
244 platform_policy_provider_ = provider.get(); | 259 platform_policy_provider_ = provider.get(); |
245 AddPolicyProvider(provider.Pass()); | 260 AddPolicyProvider(provider.Pass()); |
246 } | 261 } |
247 | 262 |
248 } // namespace policy | 263 } // namespace policy |
OLD | NEW |