blob: 2c5a5fc48a0bf05a99d737d1ac35928e4bf91b1f [file] [log] [blame]
[email protected]03ef4b2a2012-03-06 15:04:201// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4237dd52012-06-05 00:00:325#include "chrome/browser/ui/website_settings/website_settings.h"
[email protected]03ef4b2a2012-03-06 15:04:206
7#include <string>
8#include <vector>
9
[email protected]15b092542012-05-16 13:08:1410#include "base/bind.h"
11#include "base/bind_helpers.h"
[email protected]eb2140c2013-07-29 12:37:3412#include "base/command_line.h"
[email protected]15b092542012-05-16 13:08:1413#include "base/i18n/time_formatting.h"
[email protected]3ea1b182013-02-08 22:38:4114#include "base/metrics/histogram.h"
15#include "base/strings/string_number_conversions.h"
[email protected]774cc3c2013-06-07 20:26:4516#include "base/strings/utf_string_conversions.h"
[email protected]0b9fdd72012-04-04 10:00:3317#include "base/values.h"
[email protected]b0cb5e82012-07-19 19:22:4718#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
19#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
20#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
21#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
22#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
23#include "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h"
[email protected]0b9fdd72012-04-04 10:00:3324#include "chrome/browser/content_settings/content_settings_utils.h"
25#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]df818272012-04-20 13:10:5026#include "chrome/browser/content_settings/local_shared_objects_container.h"
[email protected]77a91c72012-08-13 16:19:3427#include "chrome/browser/history/history_service_factory.h"
[email protected]03ef4b2a2012-03-06 15:04:2028#include "chrome/browser/profiles/profile.h"
[email protected]03ef4b2a2012-03-06 15:04:2029#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]66f157312012-08-01 13:50:2630#include "chrome/browser/ui/website_settings/website_settings_infobar_delegate.h"
[email protected]4237dd52012-06-05 00:00:3231#include "chrome/browser/ui/website_settings/website_settings_ui.h"
[email protected]0b9fdd72012-04-04 10:00:3332#include "chrome/common/content_settings_pattern.h"
33#include "content/public/browser/browser_thread.h"
[email protected]b59c6cf02012-03-12 20:51:4234#include "content/public/browser/cert_store.h"
[email protected]e22d64f2012-09-10 09:03:2335#include "content/public/browser/user_metrics.h"
[email protected]eb2140c2013-07-29 12:37:3436#include "content/public/common/content_switches.h"
[email protected]94c74b42013-12-02 15:19:4937#include "content/public/common/signed_certificate_timestamp_id_and_status.h"
[email protected]03ef4b2a2012-03-06 15:04:2038#include "content/public/common/ssl_status.h"
39#include "content/public/common/url_constants.h"
40#include "grit/chromium_strings.h"
41#include "grit/generated_resources.h"
[email protected]be28b5f42012-07-20 11:31:2542#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
[email protected]6e7845ae2013-03-29 21:48:1143#include "net/cert/cert_status_flags.h"
44#include "net/cert/x509_certificate.h"
[email protected]536fd0b2013-03-14 17:41:5745#include "net/ssl/ssl_cipher_suite_names.h"
46#include "net/ssl/ssl_connection_status_flags.h"
[email protected]03ef4b2a2012-03-06 15:04:2047#include "ui/base/l10n/l10n_util.h"
48#include "ui/base/resource/resource_bundle.h"
49
[email protected]24a9f1c92013-11-13 12:33:3750#if defined(OS_CHROMEOS)
51#include "chrome/browser/chromeos/policy/policy_cert_service.h"
52#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
53#endif
54
[email protected]0b9fdd72012-04-04 10:00:3355using content::BrowserThread;
56
57namespace {
58
[email protected]b1d113d2012-06-27 21:27:3459// The list of content settings types to display on the Website Settings UI.
[email protected]0b9fdd72012-04-04 10:00:3360ContentSettingsType kPermissionType[] = {
[email protected]b1d113d2012-06-27 21:27:3461 CONTENT_SETTINGS_TYPE_IMAGES,
62 CONTENT_SETTINGS_TYPE_JAVASCRIPT,
[email protected]0b9fdd72012-04-04 10:00:3363 CONTENT_SETTINGS_TYPE_PLUGINS,
[email protected]b1d113d2012-06-27 21:27:3464 CONTENT_SETTINGS_TYPE_POPUPS,
[email protected]0b9fdd72012-04-04 10:00:3365 CONTENT_SETTINGS_TYPE_GEOLOCATION,
[email protected]b1d113d2012-06-27 21:27:3466 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
67 CONTENT_SETTINGS_TYPE_FULLSCREEN,
68 CONTENT_SETTINGS_TYPE_MOUSELOCK,
69 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
[email protected]62167c12013-07-10 23:02:0870 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
[email protected]eb2140c2013-07-29 12:37:3471 CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
[email protected]0b9fdd72012-04-04 10:00:3372};
73
[email protected]94c74b42013-12-02 15:19:4974bool CertificateTransparencyStatusMatch(
75 const content::SignedCertificateTimestampIDStatusList& scts,
76 net::ct::SCTVerifyStatus status) {
77 for (content::SignedCertificateTimestampIDStatusList::const_iterator it =
78 scts.begin();
79 it != scts.end();
80 ++it) {
81 if (it->status == status)
82 return true;
83 }
84
85 return false;
86}
87
88int GetSiteIdentityDetailsMessageByCTInfo(
89 const content::SignedCertificateTimestampIDStatusList& scts,
90 bool is_ev) {
91 // No SCTs - no CT information.
92 if (scts.empty())
93 return (is_ev ? IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_NO_CT
94 : IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_NO_CT);
95
96 if (CertificateTransparencyStatusMatch(scts, net::ct::SCT_STATUS_OK))
97 return (is_ev ? IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_CT_VERIFIED
98 : IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_CT_VERIFIED);
99
100 if (CertificateTransparencyStatusMatch(scts, net::ct::SCT_STATUS_INVALID))
101 return (is_ev ? IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_CT_INVALID
102 : IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_CT_INVALID);
103
104 // status is SCT_STATUS_LOG_UNKNOWN
105 return (is_ev ? IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_CT_UNVERIFIED
106 : IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_CT_UNVERIFIED);
107}
108
109// This function will return SITE_IDENTITY_STATUS_CERT or
110// SITE_IDENTITY_STATUS_EV_CERT depending on |is_ev| unless there are SCTs
111// which failed verification, in which case it will return
112// SITE_IDENTITY_STATUS_ERROR.
113WebsiteSettings::SiteIdentityStatus GetSiteIdentityStatusByCTInfo(
114 const content::SignedCertificateTimestampIDStatusList& scts,
115 bool is_ev) {
116 if (CertificateTransparencyStatusMatch(scts, net::ct::SCT_STATUS_INVALID))
117 return WebsiteSettings::SITE_IDENTITY_STATUS_ERROR;
118
119 return is_ev ? WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT
120 : WebsiteSettings::SITE_IDENTITY_STATUS_CERT;
121}
122
[email protected]0b9fdd72012-04-04 10:00:33123} // namespace
124
125WebsiteSettings::WebsiteSettings(
126 WebsiteSettingsUI* ui,
127 Profile* profile,
[email protected]df818272012-04-20 13:10:50128 TabSpecificContentSettings* tab_specific_content_settings,
[email protected]4f822f022012-12-20 19:11:42129 InfoBarService* infobar_service,
[email protected]0b9fdd72012-04-04 10:00:33130 const GURL& url,
131 const content::SSLStatus& ssl,
132 content::CertStore* cert_store)
[email protected]df818272012-04-20 13:10:50133 : TabSpecificContentSettings::SiteDataObserver(
134 tab_specific_content_settings),
135 ui_(ui),
[email protected]4f822f022012-12-20 19:11:42136 infobar_service_(infobar_service),
[email protected]66f157312012-08-01 13:50:26137 show_info_bar_(false),
[email protected]0b9fdd72012-04-04 10:00:33138 site_url_(url),
139 site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN),
[email protected]f61c1ce2012-05-09 13:55:11140 cert_id_(0),
[email protected]03ef4b2a2012-03-06 15:04:20141 site_connection_status_(SITE_CONNECTION_STATUS_UNKNOWN),
[email protected]0b9fdd72012-04-04 10:00:33142 cert_store_(cert_store),
143 content_settings_(profile->GetHostContentSettingsMap()) {
[email protected]03ef4b2a2012-03-06 15:04:20144 Init(profile, url, ssl);
[email protected]0b9fdd72012-04-04 10:00:33145
[email protected]78a1fd90a2012-07-19 08:11:25146 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
147 profile, Profile::EXPLICIT_ACCESS);
[email protected]15b092542012-05-16 13:08:14148 if (history_service) {
149 history_service->GetVisibleVisitCountToHost(
150 site_url_,
151 &visit_count_request_consumer_,
152 base::Bind(&WebsiteSettings::OnGotVisitCountToHost,
153 base::Unretained(this)));
154 }
155
[email protected]0b9fdd72012-04-04 10:00:33156 PresentSitePermissions();
[email protected]df818272012-04-20 13:10:50157 PresentSiteData();
[email protected]24c8818c2012-04-25 09:57:41158 PresentSiteIdentity();
[email protected]15b092542012-05-16 13:08:14159 PresentHistoryInfo(base::Time());
[email protected]e22d64f2012-09-10 09:03:23160
161 // Every time the Website Settings UI is opened a |WebsiteSettings| object is
162 // created. So this counts how ofter the Website Settings UI is opened.
163 content::RecordAction(content::UserMetricsAction("WebsiteSettings_Opened"));
[email protected]03ef4b2a2012-03-06 15:04:20164}
165
[email protected]0b9fdd72012-04-04 10:00:33166WebsiteSettings::~WebsiteSettings() {
[email protected]03ef4b2a2012-03-06 15:04:20167}
168
[email protected]df818272012-04-20 13:10:50169void WebsiteSettings::OnSitePermissionChanged(ContentSettingsType type,
170 ContentSetting setting) {
[email protected]e22d64f2012-09-10 09:03:23171 // Count how often a permission for a specific content type is changed using
172 // the Website Settings UI.
173 UMA_HISTOGRAM_COUNTS("WebsiteSettings.PermissionChanged", type);
174
[email protected]df818272012-04-20 13:10:50175 ContentSettingsPattern primary_pattern;
176 ContentSettingsPattern secondary_pattern;
177 switch (type) {
178 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
[email protected]eb2140c2013-07-29 12:37:34179 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
[email protected]df818272012-04-20 13:10:50180 // TODO(markusheintz): The rule we create here should also change the
181 // location permission for iframed content.
182 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_);
183 secondary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_);
184 break;
185 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
186 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_);
187 secondary_pattern = ContentSettingsPattern::Wildcard();
188 break;
[email protected]b1d113d2012-06-27 21:27:34189 case CONTENT_SETTINGS_TYPE_IMAGES:
190 case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
[email protected]df818272012-04-20 13:10:50191 case CONTENT_SETTINGS_TYPE_PLUGINS:
192 case CONTENT_SETTINGS_TYPE_POPUPS:
[email protected]b1d113d2012-06-27 21:27:34193 case CONTENT_SETTINGS_TYPE_FULLSCREEN:
194 case CONTENT_SETTINGS_TYPE_MOUSELOCK:
[email protected]ad635b12013-07-22 21:53:27195 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
[email protected]df818272012-04-20 13:10:50196 primary_pattern = ContentSettingsPattern::FromURL(site_url_);
197 secondary_pattern = ContentSettingsPattern::Wildcard();
198 break;
[email protected]0bacc1912012-12-11 11:05:34199 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: {
200 // We need to use the same same patterns as other places like infobar code
201 // to override the existing rule instead of creating the new one.
202 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_);
203 secondary_pattern = ContentSettingsPattern::Wildcard();
204 // Set permission for both microphone and camera.
205 content_settings_->SetContentSetting(
[email protected]007b3f82013-04-09 08:46:45206 primary_pattern,
207 secondary_pattern,
208 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
209 std::string(),
210 setting);
[email protected]0bacc1912012-12-11 11:05:34211
212 content_settings_->SetContentSetting(
[email protected]007b3f82013-04-09 08:46:45213 primary_pattern,
214 secondary_pattern,
215 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
216 std::string(),
217 setting);
[email protected]0bacc1912012-12-11 11:05:34218 break;
219 }
[email protected]df818272012-04-20 13:10:50220 default:
221 NOTREACHED() << "ContentSettingsType " << type << "is not supported.";
222 break;
[email protected]0b9fdd72012-04-04 10:00:33223 }
224
[email protected]0bacc1912012-12-11 11:05:34225 if (type != CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
226 // Permission settings are specified via rules. There exists always at least
227 // one rule for the default setting. Get the rule that currently defines
228 // the permission for the given permission |type|. Then test whether the
229 // existing rule is more specific than the rule we are about to create. If
230 // the existing rule is more specific, than change the existing rule instead
231 // of creating a new rule that would be hidden behind the existing rule.
232 // This is not a concern for CONTENT_SETTINGS_TYPE_MEDIASTREAM since users
233 // can not create media settings exceptions by hand.
234 content_settings::SettingInfo info;
235 scoped_ptr<Value> v(content_settings_->GetWebsiteSetting(
[email protected]007b3f82013-04-09 08:46:45236 site_url_, site_url_, type, std::string(), &info));
[email protected]0bacc1912012-12-11 11:05:34237 DCHECK(info.source == content_settings::SETTING_SOURCE_USER);
238 ContentSettingsPattern::Relation r1 =
239 info.primary_pattern.Compare(primary_pattern);
240 DCHECK(r1 != ContentSettingsPattern::DISJOINT_ORDER_POST &&
241 r1 != ContentSettingsPattern::DISJOINT_ORDER_PRE);
242 if (r1 == ContentSettingsPattern::PREDECESSOR) {
243 primary_pattern = info.primary_pattern;
244 } else if (r1 == ContentSettingsPattern::IDENTITY) {
245 ContentSettingsPattern::Relation r2 =
246 info.secondary_pattern.Compare(secondary_pattern);
247 DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST &&
248 r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE);
249 if (r2 == ContentSettingsPattern::PREDECESSOR)
250 secondary_pattern = info.secondary_pattern;
251 }
252
253 Value* value = NULL;
254 if (setting != CONTENT_SETTING_DEFAULT)
255 value = Value::CreateIntegerValue(setting);
256 content_settings_->SetWebsiteSetting(
[email protected]007b3f82013-04-09 08:46:45257 primary_pattern, secondary_pattern, type, std::string(), value);
[email protected]df818272012-04-20 13:10:50258 }
259
[email protected]66f157312012-08-01 13:50:26260 show_info_bar_ = true;
[email protected]2f45d542012-08-22 08:47:24261
[email protected]76955932012-12-06 11:01:10262// TODO(markusheintz): This is a temporary hack to fix issue:
263// http://crbug.com/144203.
[email protected]e379ba42012-08-22 22:40:25264#if defined(OS_MACOSX)
[email protected]2f45d542012-08-22 08:47:24265 // Refresh the UI to reflect the new setting.
266 PresentSitePermissions();
[email protected]e379ba42012-08-22 22:40:25267#endif
[email protected]df818272012-04-20 13:10:50268}
269
[email protected]15b092542012-05-16 13:08:14270void WebsiteSettings::OnGotVisitCountToHost(HistoryService::Handle handle,
271 bool found_visits,
272 int visit_count,
273 base::Time first_visit) {
274 if (!found_visits) {
275 // This indicates an error, such as the page's URL scheme wasn't
276 // http/https.
277 first_visit = base::Time();
278 } else if (visit_count == 0) {
279 first_visit = base::Time::Now();
280 }
281 PresentHistoryInfo(first_visit);
282}
283
[email protected]df818272012-04-20 13:10:50284void WebsiteSettings::OnSiteDataAccessed() {
285 PresentSiteData();
[email protected]0b9fdd72012-04-04 10:00:33286}
287
[email protected]66f157312012-08-01 13:50:26288void WebsiteSettings::OnUIClosing() {
[email protected]0be09932013-01-08 02:03:50289 if (show_info_bar_)
[email protected]ed9bc652013-07-11 17:17:36290 WebsiteSettingsInfoBarDelegate::Create(infobar_service_);
[email protected]66f157312012-08-01 13:50:26291}
292
[email protected]0b9fdd72012-04-04 10:00:33293void WebsiteSettings::Init(Profile* profile,
294 const GURL& url,
295 const content::SSLStatus& ssl) {
[email protected]03ef4b2a2012-03-06 15:04:20296 if (url.SchemeIs(chrome::kChromeUIScheme)) {
297 site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE;
298 site_identity_details_ =
299 l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE);
300 site_connection_status_ = SITE_CONNECTION_STATUS_INTERNAL_PAGE;
301 return;
302 }
303
304 scoped_refptr<net::X509Certificate> cert;
305
306 // Identity section.
[email protected]a04db822013-12-11 19:14:40307 base::string16 subject_name(UTF8ToUTF16(url.host()));
[email protected]03ef4b2a2012-03-06 15:04:20308 if (subject_name.empty()) {
309 subject_name.assign(
310 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
[email protected]03ef4b2a2012-03-06 15:04:20311 }
312
[email protected]f61c1ce2012-05-09 13:55:11313 cert_id_ = ssl.cert_id;
314
[email protected]03ef4b2a2012-03-06 15:04:20315 if (ssl.cert_id &&
316 cert_store_->RetrieveCert(ssl.cert_id, &cert) &&
317 (!net::IsCertStatusError(ssl.cert_status) ||
318 net::IsCertStatusMinorError(ssl.cert_status))) {
319 // There are no major errors. Check for minor errors.
[email protected]24a9f1c92013-11-13 12:33:37320#if defined(OS_CHROMEOS)
321 policy::PolicyCertService* service =
322 policy::PolicyCertServiceFactory::GetForProfile(profile);
323 const bool used_policy_certs = service && service->UsedPolicyCertificates();
324#else
325 const bool used_policy_certs = false;
326#endif
327 if (used_policy_certs) {
[email protected]eaf3f322013-04-25 21:53:59328 site_identity_status_ = SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT;
[email protected]24a9f1c92013-11-13 12:33:37329 site_identity_details_ = l10n_util::GetStringFUTF16(
330 IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE, UTF8ToUTF16(url.host()));
[email protected]eaf3f322013-04-25 21:53:59331 } else if (net::IsCertStatusMinorError(ssl.cert_status)) {
[email protected]03ef4b2a2012-03-06 15:04:20332 site_identity_status_ = SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN;
[email protected]a04db822013-12-11 19:14:40333 base::string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName()));
[email protected]03ef4b2a2012-03-06 15:04:20334 if (issuer_name.empty()) {
335 issuer_name.assign(l10n_util::GetStringUTF16(
336 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
337 }
[email protected]94c74b42013-12-02 15:19:49338
[email protected]03ef4b2a2012-03-06 15:04:20339 site_identity_details_.assign(l10n_util::GetStringFUTF16(
[email protected]94c74b42013-12-02 15:19:49340 GetSiteIdentityDetailsMessageByCTInfo(
341 ssl.signed_certificate_timestamp_ids, false /* not EV */),
342 issuer_name));
[email protected]03ef4b2a2012-03-06 15:04:20343
344 site_identity_details_ += ASCIIToUTF16("\n\n");
345 if (ssl.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) {
346 site_identity_details_ += l10n_util::GetStringUTF16(
347 IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION);
348 } else if (ssl.cert_status & net::CERT_STATUS_NO_REVOCATION_MECHANISM) {
349 site_identity_details_ += l10n_util::GetStringUTF16(
350 IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM);
351 } else {
352 NOTREACHED() << "Need to specify string for this warning";
353 }
354 } else if (ssl.cert_status & net::CERT_STATUS_IS_EV) {
355 // EV HTTPS page.
[email protected]94c74b42013-12-02 15:19:49356 site_identity_status_ = GetSiteIdentityStatusByCTInfo(
357 ssl.signed_certificate_timestamp_ids, true);
[email protected]03ef4b2a2012-03-06 15:04:20358 DCHECK(!cert->subject().organization_names.empty());
359 organization_name_ = UTF8ToUTF16(cert->subject().organization_names[0]);
360 // An EV Cert is required to have a city (localityName) and country but
361 // state is "if any".
362 DCHECK(!cert->subject().locality_name.empty());
363 DCHECK(!cert->subject().country_name.empty());
[email protected]a04db822013-12-11 19:14:40364 base::string16 locality;
[email protected]03ef4b2a2012-03-06 15:04:20365 if (!cert->subject().state_or_province_name.empty()) {
366 locality = l10n_util::GetStringFUTF16(
367 IDS_PAGEINFO_ADDRESS,
368 UTF8ToUTF16(cert->subject().locality_name),
369 UTF8ToUTF16(cert->subject().state_or_province_name),
370 UTF8ToUTF16(cert->subject().country_name));
371 } else {
372 locality = l10n_util::GetStringFUTF16(
373 IDS_PAGEINFO_PARTIAL_ADDRESS,
374 UTF8ToUTF16(cert->subject().locality_name),
375 UTF8ToUTF16(cert->subject().country_name));
376 }
377 DCHECK(!cert->subject().organization_names.empty());
378 site_identity_details_.assign(l10n_util::GetStringFUTF16(
[email protected]94c74b42013-12-02 15:19:49379 GetSiteIdentityDetailsMessageByCTInfo(
380 ssl.signed_certificate_timestamp_ids, true /* is EV */),
[email protected]03ef4b2a2012-03-06 15:04:20381 UTF8ToUTF16(cert->subject().organization_names[0]),
382 locality,
383 UTF8ToUTF16(cert->issuer().GetDisplayName())));
[email protected]03ef4b2a2012-03-06 15:04:20384 } else {
385 // Non-EV OK HTTPS page.
[email protected]94c74b42013-12-02 15:19:49386 site_identity_status_ = GetSiteIdentityStatusByCTInfo(
387 ssl.signed_certificate_timestamp_ids, false);
[email protected]a04db822013-12-11 19:14:40388 base::string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName()));
[email protected]03ef4b2a2012-03-06 15:04:20389 if (issuer_name.empty()) {
390 issuer_name.assign(l10n_util::GetStringUTF16(
391 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
392 }
[email protected]94c74b42013-12-02 15:19:49393
[email protected]03ef4b2a2012-03-06 15:04:20394 site_identity_details_.assign(l10n_util::GetStringFUTF16(
[email protected]94c74b42013-12-02 15:19:49395 GetSiteIdentityDetailsMessageByCTInfo(
396 ssl.signed_certificate_timestamp_ids, false /* not EV */),
397 issuer_name));
[email protected]03ef4b2a2012-03-06 15:04:20398 }
399 } else {
400 // HTTP or HTTPS with errors (not warnings).
401 site_identity_details_.assign(l10n_util::GetStringUTF16(
402 IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY));
403 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED)
404 site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT;
405 else
406 site_identity_status_ = SITE_IDENTITY_STATUS_ERROR;
407
[email protected]a04db822013-12-11 19:14:40408 const base::string16 bullet = UTF8ToUTF16("\n • ");
[email protected]03ef4b2a2012-03-06 15:04:20409 std::vector<SSLErrorInfo> errors;
410 SSLErrorInfo::GetErrorsForCertStatus(ssl.cert_id, ssl.cert_status,
411 url, &errors);
412 for (size_t i = 0; i < errors.size(); ++i) {
413 site_identity_details_ += bullet;
414 site_identity_details_ += errors[i].short_description();
415 }
416
417 if (ssl.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) {
418 site_identity_details_ += ASCIIToUTF16("\n\n");
419 site_identity_details_ += l10n_util::GetStringUTF16(
420 IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME);
421 }
422 }
423
424 // Site Connection
425 // We consider anything less than 80 bits encryption to be weak encryption.
426 // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and
427 // weakly encrypted connections.
428 site_connection_status_ = SITE_CONNECTION_STATUS_UNKNOWN;
429
430 if (!ssl.cert_id) {
431 // Not HTTPS.
432 DCHECK_EQ(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED);
433 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED)
434 site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED;
435 else
436 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR;
437
438 site_connection_details_.assign(l10n_util::GetStringFUTF16(
439 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
440 subject_name));
441 } else if (ssl.security_bits < 0) {
442 // Security strength is unknown. Say nothing.
443 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR;
444 } else if (ssl.security_bits == 0) {
445 DCHECK_NE(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED);
446 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR;
447 site_connection_details_.assign(l10n_util::GetStringFUTF16(
448 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
449 subject_name));
450 } else if (ssl.security_bits < 80) {
451 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR;
452 site_connection_details_.assign(l10n_util::GetStringFUTF16(
453 IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT,
454 subject_name));
455 } else {
456 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED;
457 site_connection_details_.assign(l10n_util::GetStringFUTF16(
458 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT,
459 subject_name,
460 base::IntToString16(ssl.security_bits)));
461 if (ssl.content_status) {
462 bool ran_insecure_content =
463 !!(ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT);
464 site_connection_status_ = ran_insecure_content ?
465 SITE_CONNECTION_STATUS_ENCRYPTED_ERROR
466 : SITE_CONNECTION_STATUS_MIXED_CONTENT;
467 site_connection_details_.assign(l10n_util::GetStringFUTF16(
468 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK,
469 site_connection_details_,
470 l10n_util::GetStringUTF16(ran_insecure_content ?
471 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR :
472 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING)));
473 }
474 }
475
476 uint16 cipher_suite =
477 net::SSLConnectionStatusToCipherSuite(ssl.connection_status);
478 if (ssl.security_bits > 0 && cipher_suite) {
479 int ssl_version =
480 net::SSLConnectionStatusToVersion(ssl.connection_status);
481 const char* ssl_version_str;
482 net::SSLVersionToString(&ssl_version_str, ssl_version);
483 site_connection_details_ += ASCIIToUTF16("\n\n");
484 site_connection_details_ += l10n_util::GetStringFUTF16(
485 IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION,
486 ASCIIToUTF16(ssl_version_str));
487
488 bool did_fallback = (ssl.connection_status &
[email protected]80c75f682012-05-26 16:22:17489 net::SSL_CONNECTION_VERSION_FALLBACK) != 0;
[email protected]03ef4b2a2012-03-06 15:04:20490 bool no_renegotiation =
491 (ssl.connection_status &
492 net::SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION) != 0;
493 const char *key_exchange, *cipher, *mac;
[email protected]b6c1d9e82013-06-12 17:26:57494 bool is_aead;
495 net::SSLCipherSuiteToStrings(
496 &key_exchange, &cipher, &mac, &is_aead, cipher_suite);
[email protected]03ef4b2a2012-03-06 15:04:20497
498 site_connection_details_ += ASCIIToUTF16("\n\n");
[email protected]b6c1d9e82013-06-12 17:26:57499 if (is_aead) {
500 site_connection_details_ += l10n_util::GetStringFUTF16(
501 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD,
502 ASCIIToUTF16(cipher), ASCIIToUTF16(key_exchange));
503 } else {
504 site_connection_details_ += l10n_util::GetStringFUTF16(
505 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS,
506 ASCIIToUTF16(cipher), ASCIIToUTF16(mac), ASCIIToUTF16(key_exchange));
507 }
[email protected]03ef4b2a2012-03-06 15:04:20508
[email protected]03ef4b2a2012-03-06 15:04:20509 if (did_fallback) {
510 // For now, only SSLv3 fallback will trigger a warning icon.
511 if (site_connection_status_ < SITE_CONNECTION_STATUS_MIXED_CONTENT)
512 site_connection_status_ = SITE_CONNECTION_STATUS_MIXED_CONTENT;
513 site_connection_details_ += ASCIIToUTF16("\n\n");
514 site_connection_details_ += l10n_util::GetStringUTF16(
515 IDS_PAGE_INFO_SECURITY_TAB_FALLBACK_MESSAGE);
516 }
517 if (no_renegotiation) {
518 site_connection_details_ += ASCIIToUTF16("\n\n");
519 site_connection_details_ += l10n_util::GetStringUTF16(
520 IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE);
521 }
522 }
[email protected]e583f752012-08-30 13:26:21523
524 // By default select the permissions tab that displays all the site
525 // permissions. In case of a connection error or an issue with the
526 // certificate presented by the website, select the connection tab to draw
527 // the user's attention to the issue. If the site does not provide a
528 // certificate because it was loaded over an unencrypted connection, don't
529 // select the connection tab.
530 WebsiteSettingsUI::TabId tab_id = WebsiteSettingsUI::TAB_ID_PERMISSIONS;
531 if (site_connection_status_ == SITE_CONNECTION_STATUS_ENCRYPTED_ERROR ||
532 site_connection_status_ == SITE_CONNECTION_STATUS_MIXED_CONTENT ||
533 site_identity_status_ == SITE_IDENTITY_STATUS_ERROR ||
[email protected]eaf3f322013-04-25 21:53:59534 site_identity_status_ == SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN ||
535 site_identity_status_ == SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT)
[email protected]e583f752012-08-30 13:26:21536 tab_id = WebsiteSettingsUI::TAB_ID_CONNECTION;
537 ui_->SetSelectedTab(tab_id);
[email protected]03ef4b2a2012-03-06 15:04:20538}
[email protected]0b9fdd72012-04-04 10:00:33539
[email protected]df818272012-04-20 13:10:50540void WebsiteSettings::PresentSitePermissions() {
541 PermissionInfoList permission_info_list;
542
543 WebsiteSettingsUI::PermissionInfo permission_info;
544 for (size_t i = 0; i < arraysize(kPermissionType); ++i) {
545 permission_info.type = kPermissionType[i];
[email protected]eb2140c2013-07-29 12:37:34546 if (permission_info.type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
547 const CommandLine* command_line = CommandLine::ForCurrentProcess();
548 if (!command_line->HasSwitch(switches::kEnableWebMIDI))
549 continue;
550 }
[email protected]df818272012-04-20 13:10:50551
552 content_settings::SettingInfo info;
[email protected]0bacc1912012-12-11 11:05:34553 if (permission_info.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
554 scoped_ptr<base::Value> mic_value(content_settings_->GetWebsiteSetting(
[email protected]007b3f82013-04-09 08:46:45555 site_url_,
556 site_url_,
557 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
558 std::string(),
559 &info));
[email protected]0bacc1912012-12-11 11:05:34560 ContentSetting mic_setting =
561 content_settings::ValueToContentSetting(mic_value.get());
562
563 scoped_ptr<base::Value> camera_value(content_settings_->GetWebsiteSetting(
[email protected]007b3f82013-04-09 08:46:45564 site_url_,
565 site_url_,
566 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
567 std::string(),
568 &info));
[email protected]0bacc1912012-12-11 11:05:34569 ContentSetting camera_setting =
570 content_settings::ValueToContentSetting(camera_value.get());
571
572 if (mic_setting != camera_setting || mic_setting == CONTENT_SETTING_ASK)
573 permission_info.setting = CONTENT_SETTING_DEFAULT;
574 else
575 permission_info.setting = mic_setting;
[email protected]fe4686a2012-10-19 15:38:26576 } else {
[email protected]0bacc1912012-12-11 11:05:34577 scoped_ptr<Value> value(content_settings_->GetWebsiteSetting(
[email protected]007b3f82013-04-09 08:46:45578 site_url_, site_url_, permission_info.type, std::string(), &info));
[email protected]0bacc1912012-12-11 11:05:34579 DCHECK(value.get());
580 if (value->GetType() == Value::TYPE_INTEGER) {
581 permission_info.setting =
582 content_settings::ValueToContentSetting(value.get());
583 } else {
584 NOTREACHED();
585 }
[email protected]fe4686a2012-10-19 15:38:26586 }
587
[email protected]8bdf45c32012-08-04 00:12:55588 permission_info.source = info.source;
[email protected]df818272012-04-20 13:10:50589
[email protected]b1d113d2012-06-27 21:27:34590 if (info.primary_pattern == ContentSettingsPattern::Wildcard() &&
[email protected]0bacc1912012-12-11 11:05:34591 info.secondary_pattern == ContentSettingsPattern::Wildcard() &&
592 permission_info.type != CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
[email protected]b1d113d2012-06-27 21:27:34593 permission_info.default_setting = permission_info.setting;
594 permission_info.setting = CONTENT_SETTING_DEFAULT;
595 } else {
596 permission_info.default_setting =
597 content_settings_->GetDefaultContentSetting(permission_info.type,
598 NULL);
[email protected]df818272012-04-20 13:10:50599 }
[email protected]b1d113d2012-06-27 21:27:34600 permission_info_list.push_back(permission_info);
[email protected]df818272012-04-20 13:10:50601 }
602
603 ui_->SetPermissionInfo(permission_info_list);
[email protected]0b9fdd72012-04-04 10:00:33604}
605
[email protected]df818272012-04-20 13:10:50606void WebsiteSettings::PresentSiteData() {
607 CookieInfoList cookie_info_list;
[email protected]e0ac35892012-05-15 12:53:34608 const LocalSharedObjectsContainer& allowed_objects =
609 tab_specific_content_settings()->allowed_local_shared_objects();
610 const LocalSharedObjectsContainer& blocked_objects =
611 tab_specific_content_settings()->blocked_local_shared_objects();
612
613 // Add first party cookie and site data counts.
[email protected]df818272012-04-20 13:10:50614 WebsiteSettingsUI::CookieInfo cookie_info;
[email protected]e0ac35892012-05-15 12:53:34615 std::string cookie_source =
[email protected]ed32c212013-05-14 20:49:29616 net::registry_controlled_domains::GetDomainAndRegistry(
617 site_url_,
618 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
[email protected]e0ac35892012-05-15 12:53:34619 if (cookie_source.empty())
620 cookie_source = site_url_.host();
621 cookie_info.cookie_source = cookie_source;
622 cookie_info.allowed = allowed_objects.GetObjectCountForDomain(site_url_);
623 cookie_info.blocked = blocked_objects.GetObjectCountForDomain(site_url_);
624 cookie_info_list.push_back(cookie_info);
625
626 // Add third party cookie counts.
627 cookie_info.cookie_source = l10n_util::GetStringUTF8(
628 IDS_WEBSITE_SETTINGS_THIRD_PARTY_SITE_DATA);
629 cookie_info.allowed = allowed_objects.GetObjectCount() - cookie_info.allowed;
630 cookie_info.blocked = blocked_objects.GetObjectCount() - cookie_info.blocked;
[email protected]df818272012-04-20 13:10:50631 cookie_info_list.push_back(cookie_info);
[email protected]0b9fdd72012-04-04 10:00:33632
[email protected]df818272012-04-20 13:10:50633 ui_->SetCookieInfo(cookie_info_list);
[email protected]0b9fdd72012-04-04 10:00:33634}
[email protected]16de6de2012-04-04 12:24:14635
[email protected]24c8818c2012-04-25 09:57:41636void WebsiteSettings::PresentSiteIdentity() {
637 // After initialization the status about the site's connection
638 // and it's identity must be available.
639 DCHECK_NE(site_identity_status_, SITE_IDENTITY_STATUS_UNKNOWN);
640 DCHECK_NE(site_connection_status_, SITE_CONNECTION_STATUS_UNKNOWN);
641 WebsiteSettingsUI::IdentityInfo info;
642 if (site_identity_status_ == SITE_IDENTITY_STATUS_EV_CERT)
643 info.site_identity = UTF16ToUTF8(organization_name());
644 else
645 info.site_identity = site_url_.host();
646
647 info.connection_status = site_connection_status_;
648 info.connection_status_description =
649 UTF16ToUTF8(site_connection_details_);
650 info.identity_status = site_identity_status_;
651 info.identity_status_description =
652 UTF16ToUTF8(site_identity_details_);
[email protected]f61c1ce2012-05-09 13:55:11653 info.cert_id = cert_id_;
[email protected]24c8818c2012-04-25 09:57:41654 ui_->SetIdentityInfo(info);
655}
656
[email protected]15b092542012-05-16 13:08:14657void WebsiteSettings::PresentHistoryInfo(base::Time first_visit) {
658 if (first_visit == base::Time()) {
[email protected]b959d7d42013-12-13 17:26:37659 ui_->SetFirstVisit(base::string16());
[email protected]15b092542012-05-16 13:08:14660 return;
661 }
662
663 bool visited_before_today = false;
664 base::Time today = base::Time::Now().LocalMidnight();
665 base::Time first_visit_midnight = first_visit.LocalMidnight();
666 visited_before_today = (first_visit_midnight < today);
667
[email protected]a04db822013-12-11 19:14:40668 base::string16 first_visit_text;
[email protected]15b092542012-05-16 13:08:14669 if (visited_before_today) {
670 first_visit_text = l10n_util::GetStringFUTF16(
671 IDS_PAGE_INFO_SECURITY_TAB_VISITED_BEFORE_TODAY,
672 base::TimeFormatShortDate(first_visit));
673 } else {
674 first_visit_text = l10n_util::GetStringUTF16(
675 IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY);
676
677 }
678 ui_->SetFirstVisit(first_visit_text);
679}