1 // 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 5 #include "chrome/browser/ui/website_settings/website_settings.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/command_line.h" 13 #include "base/i18n/time_formatting.h" 14 #include "base/metrics/histogram.h" 15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "base/values.h" 18 #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" 24 #include "chrome/browser/content_settings/content_settings_utils.h" 25 #include "chrome/browser/content_settings/host_content_settings_map.h" 26 #include "chrome/browser/content_settings/local_shared_objects_container.h" 27 #include "chrome/browser/history/history_service_factory.h" 28 #include "chrome/browser/policy/profile_policy_connector.h" 29 #include "chrome/browser/policy/profile_policy_connector_factory.h" 30 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/ssl/ssl_error_info.h" 32 #include "chrome/browser/ui/website_settings/website_settings_infobar_delegate.h" 33 #include "chrome/browser/ui/website_settings/website_settings_ui.h" 34 #include "chrome/common/content_settings_pattern.h" 35 #include "content/public/browser/browser_thread.h" 36 #include "content/public/browser/cert_store.h" 37 #include "content/public/browser/user_metrics.h" 38 #include "content/public/common/content_switches.h" 39 #include "content/public/common/ssl_status.h" 40 #include "content/public/common/url_constants.h" 41 #include "grit/chromium_strings.h" 42 #include "grit/generated_resources.h" 43 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 44 #include "net/cert/cert_status_flags.h" 45 #include "net/cert/x509_certificate.h" 46 #include "net/ssl/ssl_cipher_suite_names.h" 47 #include "net/ssl/ssl_connection_status_flags.h" 48 #include "ui/base/l10n/l10n_util.h" 49 #include "ui/base/resource/resource_bundle.h" 50 51 using content::BrowserThread; 52 53 namespace { 54 55 // The list of content settings types to display on the Website Settings UI. 56 ContentSettingsType kPermissionType[] = { 57 CONTENT_SETTINGS_TYPE_IMAGES, 58 CONTENT_SETTINGS_TYPE_JAVASCRIPT, 59 CONTENT_SETTINGS_TYPE_PLUGINS, 60 CONTENT_SETTINGS_TYPE_POPUPS, 61 CONTENT_SETTINGS_TYPE_GEOLOCATION, 62 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 63 CONTENT_SETTINGS_TYPE_FULLSCREEN, 64 CONTENT_SETTINGS_TYPE_MOUSELOCK, 65 CONTENT_SETTINGS_TYPE_MEDIASTREAM, 66 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, 67 CONTENT_SETTINGS_TYPE_MIDI_SYSEX, 68 }; 69 70 } // namespace 71 72 WebsiteSettings::WebsiteSettings( 73 WebsiteSettingsUI* ui, 74 Profile* profile, 75 TabSpecificContentSettings* tab_specific_content_settings, 76 InfoBarService* infobar_service, 77 const GURL& url, 78 const content::SSLStatus& ssl, 79 content::CertStore* cert_store) 80 : TabSpecificContentSettings::SiteDataObserver( 81 tab_specific_content_settings), 82 ui_(ui), 83 infobar_service_(infobar_service), 84 show_info_bar_(false), 85 site_url_(url), 86 site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN), 87 cert_id_(0), 88 site_connection_status_(SITE_CONNECTION_STATUS_UNKNOWN), 89 cert_store_(cert_store), 90 content_settings_(profile->GetHostContentSettingsMap()) { 91 Init(profile, url, ssl); 92 93 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 94 profile, Profile::EXPLICIT_ACCESS); 95 if (history_service) { 96 history_service->GetVisibleVisitCountToHost( 97 site_url_, 98 &visit_count_request_consumer_, 99 base::Bind(&WebsiteSettings::OnGotVisitCountToHost, 100 base::Unretained(this))); 101 } 102 103 PresentSitePermissions(); 104 PresentSiteData(); 105 PresentSiteIdentity(); 106 PresentHistoryInfo(base::Time()); 107 108 // Every time the Website Settings UI is opened a |WebsiteSettings| object is 109 // created. So this counts how ofter the Website Settings UI is opened. 110 content::RecordAction(content::UserMetricsAction("WebsiteSettings_Opened")); 111 } 112 113 WebsiteSettings::~WebsiteSettings() { 114 } 115 116 void WebsiteSettings::OnSitePermissionChanged(ContentSettingsType type, 117 ContentSetting setting) { 118 // Count how often a permission for a specific content type is changed using 119 // the Website Settings UI. 120 UMA_HISTOGRAM_COUNTS("WebsiteSettings.PermissionChanged", type); 121 122 ContentSettingsPattern primary_pattern; 123 ContentSettingsPattern secondary_pattern; 124 switch (type) { 125 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 126 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: 127 // TODO(markusheintz): The rule we create here should also change the 128 // location permission for iframed content. 129 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); 130 secondary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); 131 break; 132 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 133 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); 134 secondary_pattern = ContentSettingsPattern::Wildcard(); 135 break; 136 case CONTENT_SETTINGS_TYPE_IMAGES: 137 case CONTENT_SETTINGS_TYPE_JAVASCRIPT: 138 case CONTENT_SETTINGS_TYPE_PLUGINS: 139 case CONTENT_SETTINGS_TYPE_POPUPS: 140 case CONTENT_SETTINGS_TYPE_FULLSCREEN: 141 case CONTENT_SETTINGS_TYPE_MOUSELOCK: 142 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: 143 primary_pattern = ContentSettingsPattern::FromURL(site_url_); 144 secondary_pattern = ContentSettingsPattern::Wildcard(); 145 break; 146 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: { 147 // We need to use the same same patterns as other places like infobar code 148 // to override the existing rule instead of creating the new one. 149 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); 150 secondary_pattern = ContentSettingsPattern::Wildcard(); 151 // Set permission for both microphone and camera. 152 content_settings_->SetContentSetting( 153 primary_pattern, 154 secondary_pattern, 155 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 156 std::string(), 157 setting); 158 159 content_settings_->SetContentSetting( 160 primary_pattern, 161 secondary_pattern, 162 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 163 std::string(), 164 setting); 165 break; 166 } 167 default: 168 NOTREACHED() << "ContentSettingsType " << type << "is not supported."; 169 break; 170 } 171 172 if (type != CONTENT_SETTINGS_TYPE_MEDIASTREAM) { 173 // Permission settings are specified via rules. There exists always at least 174 // one rule for the default setting. Get the rule that currently defines 175 // the permission for the given permission |type|. Then test whether the 176 // existing rule is more specific than the rule we are about to create. If 177 // the existing rule is more specific, than change the existing rule instead 178 // of creating a new rule that would be hidden behind the existing rule. 179 // This is not a concern for CONTENT_SETTINGS_TYPE_MEDIASTREAM since users 180 // can not create media settings exceptions by hand. 181 content_settings::SettingInfo info; 182 scoped_ptr<Value> v(content_settings_->GetWebsiteSetting( 183 site_url_, site_url_, type, std::string(), &info)); 184 DCHECK(info.source == content_settings::SETTING_SOURCE_USER); 185 ContentSettingsPattern::Relation r1 = 186 info.primary_pattern.Compare(primary_pattern); 187 DCHECK(r1 != ContentSettingsPattern::DISJOINT_ORDER_POST && 188 r1 != ContentSettingsPattern::DISJOINT_ORDER_PRE); 189 if (r1 == ContentSettingsPattern::PREDECESSOR) { 190 primary_pattern = info.primary_pattern; 191 } else if (r1 == ContentSettingsPattern::IDENTITY) { 192 ContentSettingsPattern::Relation r2 = 193 info.secondary_pattern.Compare(secondary_pattern); 194 DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST && 195 r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE); 196 if (r2 == ContentSettingsPattern::PREDECESSOR) 197 secondary_pattern = info.secondary_pattern; 198 } 199 200 Value* value = NULL; 201 if (setting != CONTENT_SETTING_DEFAULT) 202 value = Value::CreateIntegerValue(setting); 203 content_settings_->SetWebsiteSetting( 204 primary_pattern, secondary_pattern, type, std::string(), value); 205 } 206 207 show_info_bar_ = true; 208 209 // TODO(markusheintz): This is a temporary hack to fix issue: 210 // http://crbug.com/144203. 211 #if defined(OS_MACOSX) 212 // Refresh the UI to reflect the new setting. 213 PresentSitePermissions(); 214 #endif 215 } 216 217 void WebsiteSettings::OnGotVisitCountToHost(HistoryService::Handle handle, 218 bool found_visits, 219 int visit_count, 220 base::Time first_visit) { 221 if (!found_visits) { 222 // This indicates an error, such as the page's URL scheme wasn't 223 // http/https. 224 first_visit = base::Time(); 225 } else if (visit_count == 0) { 226 first_visit = base::Time::Now(); 227 } 228 PresentHistoryInfo(first_visit); 229 } 230 231 void WebsiteSettings::OnSiteDataAccessed() { 232 PresentSiteData(); 233 } 234 235 void WebsiteSettings::OnUIClosing() { 236 if (show_info_bar_) 237 WebsiteSettingsInfoBarDelegate::Create(infobar_service_); 238 } 239 240 void WebsiteSettings::Init(Profile* profile, 241 const GURL& url, 242 const content::SSLStatus& ssl) { 243 if (url.SchemeIs(chrome::kChromeUIScheme)) { 244 site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE; 245 site_identity_details_ = 246 l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE); 247 site_connection_status_ = SITE_CONNECTION_STATUS_INTERNAL_PAGE; 248 return; 249 } 250 251 scoped_refptr<net::X509Certificate> cert; 252 253 // Identity section. 254 string16 subject_name(UTF8ToUTF16(url.host())); 255 if (subject_name.empty()) { 256 subject_name.assign( 257 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); 258 } 259 260 cert_id_ = ssl.cert_id; 261 262 if (ssl.cert_id && 263 cert_store_->RetrieveCert(ssl.cert_id, &cert) && 264 (!net::IsCertStatusError(ssl.cert_status) || 265 net::IsCertStatusMinorError(ssl.cert_status))) { 266 // There are no major errors. Check for minor errors. 267 if (policy::ProfilePolicyConnectorFactory::GetForProfile(profile)-> 268 UsedPolicyCertificates()) { 269 site_identity_status_ = SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT; 270 site_identity_details_ = 271 l10n_util::GetStringFUTF16(IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE, 272 UTF8ToUTF16(url.host())); 273 } else if (net::IsCertStatusMinorError(ssl.cert_status)) { 274 site_identity_status_ = SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN; 275 string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName())); 276 if (issuer_name.empty()) { 277 issuer_name.assign(l10n_util::GetStringUTF16( 278 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); 279 } 280 site_identity_details_.assign(l10n_util::GetStringFUTF16( 281 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); 282 283 site_identity_details_ += ASCIIToUTF16("\n\n"); 284 if (ssl.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) { 285 site_identity_details_ += l10n_util::GetStringUTF16( 286 IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION); 287 } else if (ssl.cert_status & net::CERT_STATUS_NO_REVOCATION_MECHANISM) { 288 site_identity_details_ += l10n_util::GetStringUTF16( 289 IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM); 290 } else { 291 NOTREACHED() << "Need to specify string for this warning"; 292 } 293 } else if (ssl.cert_status & net::CERT_STATUS_IS_EV) { 294 // EV HTTPS page. 295 site_identity_status_ = SITE_IDENTITY_STATUS_EV_CERT; 296 DCHECK(!cert->subject().organization_names.empty()); 297 organization_name_ = UTF8ToUTF16(cert->subject().organization_names[0]); 298 // An EV Cert is required to have a city (localityName) and country but 299 // state is "if any". 300 DCHECK(!cert->subject().locality_name.empty()); 301 DCHECK(!cert->subject().country_name.empty()); 302 string16 locality; 303 if (!cert->subject().state_or_province_name.empty()) { 304 locality = l10n_util::GetStringFUTF16( 305 IDS_PAGEINFO_ADDRESS, 306 UTF8ToUTF16(cert->subject().locality_name), 307 UTF8ToUTF16(cert->subject().state_or_province_name), 308 UTF8ToUTF16(cert->subject().country_name)); 309 } else { 310 locality = l10n_util::GetStringFUTF16( 311 IDS_PAGEINFO_PARTIAL_ADDRESS, 312 UTF8ToUTF16(cert->subject().locality_name), 313 UTF8ToUTF16(cert->subject().country_name)); 314 } 315 DCHECK(!cert->subject().organization_names.empty()); 316 site_identity_details_.assign(l10n_util::GetStringFUTF16( 317 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV, 318 UTF8ToUTF16(cert->subject().organization_names[0]), 319 locality, 320 UTF8ToUTF16(cert->issuer().GetDisplayName()))); 321 } else { 322 // Non-EV OK HTTPS page. 323 site_identity_status_ = SITE_IDENTITY_STATUS_CERT; 324 string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName())); 325 if (issuer_name.empty()) { 326 issuer_name.assign(l10n_util::GetStringUTF16( 327 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); 328 } 329 site_identity_details_.assign(l10n_util::GetStringFUTF16( 330 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); 331 } 332 } else { 333 // HTTP or HTTPS with errors (not warnings). 334 site_identity_details_.assign(l10n_util::GetStringUTF16( 335 IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); 336 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED) 337 site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT; 338 else 339 site_identity_status_ = SITE_IDENTITY_STATUS_ERROR; 340 341 const string16 bullet = UTF8ToUTF16("\n "); 342 std::vector<SSLErrorInfo> errors; 343 SSLErrorInfo::GetErrorsForCertStatus(ssl.cert_id, ssl.cert_status, 344 url, &errors); 345 for (size_t i = 0; i < errors.size(); ++i) { 346 site_identity_details_ += bullet; 347 site_identity_details_ += errors[i].short_description(); 348 } 349 350 if (ssl.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) { 351 site_identity_details_ += ASCIIToUTF16("\n\n"); 352 site_identity_details_ += l10n_util::GetStringUTF16( 353 IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME); 354 } 355 } 356 357 // Site Connection 358 // We consider anything less than 80 bits encryption to be weak encryption. 359 // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and 360 // weakly encrypted connections. 361 site_connection_status_ = SITE_CONNECTION_STATUS_UNKNOWN; 362 363 if (!ssl.cert_id) { 364 // Not HTTPS. 365 DCHECK_EQ(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED); 366 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED) 367 site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED; 368 else 369 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; 370 371 site_connection_details_.assign(l10n_util::GetStringFUTF16( 372 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, 373 subject_name)); 374 } else if (ssl.security_bits < 0) { 375 // Security strength is unknown. Say nothing. 376 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; 377 } else if (ssl.security_bits == 0) { 378 DCHECK_NE(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED); 379 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; 380 site_connection_details_.assign(l10n_util::GetStringFUTF16( 381 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, 382 subject_name)); 383 } else if (ssl.security_bits < 80) { 384 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; 385 site_connection_details_.assign(l10n_util::GetStringFUTF16( 386 IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, 387 subject_name)); 388 } else { 389 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED; 390 site_connection_details_.assign(l10n_util::GetStringFUTF16( 391 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, 392 subject_name, 393 base::IntToString16(ssl.security_bits))); 394 if (ssl.content_status) { 395 bool ran_insecure_content = 396 !!(ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT); 397 site_connection_status_ = ran_insecure_content ? 398 SITE_CONNECTION_STATUS_ENCRYPTED_ERROR 399 : SITE_CONNECTION_STATUS_MIXED_CONTENT; 400 site_connection_details_.assign(l10n_util::GetStringFUTF16( 401 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, 402 site_connection_details_, 403 l10n_util::GetStringUTF16(ran_insecure_content ? 404 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR : 405 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING))); 406 } 407 } 408 409 uint16 cipher_suite = 410 net::SSLConnectionStatusToCipherSuite(ssl.connection_status); 411 if (ssl.security_bits > 0 && cipher_suite) { 412 int ssl_version = 413 net::SSLConnectionStatusToVersion(ssl.connection_status); 414 const char* ssl_version_str; 415 net::SSLVersionToString(&ssl_version_str, ssl_version); 416 site_connection_details_ += ASCIIToUTF16("\n\n"); 417 site_connection_details_ += l10n_util::GetStringFUTF16( 418 IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION, 419 ASCIIToUTF16(ssl_version_str)); 420 421 bool did_fallback = (ssl.connection_status & 422 net::SSL_CONNECTION_VERSION_FALLBACK) != 0; 423 bool no_renegotiation = 424 (ssl.connection_status & 425 net::SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION) != 0; 426 const char *key_exchange, *cipher, *mac; 427 bool is_aead; 428 net::SSLCipherSuiteToStrings( 429 &key_exchange, &cipher, &mac, &is_aead, cipher_suite); 430 431 site_connection_details_ += ASCIIToUTF16("\n\n"); 432 if (is_aead) { 433 site_connection_details_ += l10n_util::GetStringFUTF16( 434 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD, 435 ASCIIToUTF16(cipher), ASCIIToUTF16(key_exchange)); 436 } else { 437 site_connection_details_ += l10n_util::GetStringFUTF16( 438 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS, 439 ASCIIToUTF16(cipher), ASCIIToUTF16(mac), ASCIIToUTF16(key_exchange)); 440 } 441 442 if (did_fallback) { 443 // For now, only SSLv3 fallback will trigger a warning icon. 444 if (site_connection_status_ < SITE_CONNECTION_STATUS_MIXED_CONTENT) 445 site_connection_status_ = SITE_CONNECTION_STATUS_MIXED_CONTENT; 446 site_connection_details_ += ASCIIToUTF16("\n\n"); 447 site_connection_details_ += l10n_util::GetStringUTF16( 448 IDS_PAGE_INFO_SECURITY_TAB_FALLBACK_MESSAGE); 449 } 450 if (no_renegotiation) { 451 site_connection_details_ += ASCIIToUTF16("\n\n"); 452 site_connection_details_ += l10n_util::GetStringUTF16( 453 IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE); 454 } 455 } 456 457 // By default select the permissions tab that displays all the site 458 // permissions. In case of a connection error or an issue with the 459 // certificate presented by the website, select the connection tab to draw 460 // the user's attention to the issue. If the site does not provide a 461 // certificate because it was loaded over an unencrypted connection, don't 462 // select the connection tab. 463 WebsiteSettingsUI::TabId tab_id = WebsiteSettingsUI::TAB_ID_PERMISSIONS; 464 if (site_connection_status_ == SITE_CONNECTION_STATUS_ENCRYPTED_ERROR || 465 site_connection_status_ == SITE_CONNECTION_STATUS_MIXED_CONTENT || 466 site_identity_status_ == SITE_IDENTITY_STATUS_ERROR || 467 site_identity_status_ == SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN || 468 site_identity_status_ == SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT) 469 tab_id = WebsiteSettingsUI::TAB_ID_CONNECTION; 470 ui_->SetSelectedTab(tab_id); 471 } 472 473 void WebsiteSettings::PresentSitePermissions() { 474 PermissionInfoList permission_info_list; 475 476 WebsiteSettingsUI::PermissionInfo permission_info; 477 for (size_t i = 0; i < arraysize(kPermissionType); ++i) { 478 permission_info.type = kPermissionType[i]; 479 if (permission_info.type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 480 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 481 if (!command_line->HasSwitch(switches::kEnableWebMIDI)) 482 continue; 483 } 484 485 content_settings::SettingInfo info; 486 if (permission_info.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) { 487 scoped_ptr<base::Value> mic_value(content_settings_->GetWebsiteSetting( 488 site_url_, 489 site_url_, 490 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 491 std::string(), 492 &info)); 493 ContentSetting mic_setting = 494 content_settings::ValueToContentSetting(mic_value.get()); 495 496 scoped_ptr<base::Value> camera_value(content_settings_->GetWebsiteSetting( 497 site_url_, 498 site_url_, 499 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 500 std::string(), 501 &info)); 502 ContentSetting camera_setting = 503 content_settings::ValueToContentSetting(camera_value.get()); 504 505 if (mic_setting != camera_setting || mic_setting == CONTENT_SETTING_ASK) 506 permission_info.setting = CONTENT_SETTING_DEFAULT; 507 else 508 permission_info.setting = mic_setting; 509 } else { 510 scoped_ptr<Value> value(content_settings_->GetWebsiteSetting( 511 site_url_, site_url_, permission_info.type, std::string(), &info)); 512 DCHECK(value.get()); 513 if (value->GetType() == Value::TYPE_INTEGER) { 514 permission_info.setting = 515 content_settings::ValueToContentSetting(value.get()); 516 } else { 517 NOTREACHED(); 518 } 519 } 520 521 permission_info.source = info.source; 522 523 if (info.primary_pattern == ContentSettingsPattern::Wildcard() && 524 info.secondary_pattern == ContentSettingsPattern::Wildcard() && 525 permission_info.type != CONTENT_SETTINGS_TYPE_MEDIASTREAM) { 526 permission_info.default_setting = permission_info.setting; 527 permission_info.setting = CONTENT_SETTING_DEFAULT; 528 } else { 529 permission_info.default_setting = 530 content_settings_->GetDefaultContentSetting(permission_info.type, 531 NULL); 532 } 533 permission_info_list.push_back(permission_info); 534 } 535 536 ui_->SetPermissionInfo(permission_info_list); 537 } 538 539 void WebsiteSettings::PresentSiteData() { 540 CookieInfoList cookie_info_list; 541 const LocalSharedObjectsContainer& allowed_objects = 542 tab_specific_content_settings()->allowed_local_shared_objects(); 543 const LocalSharedObjectsContainer& blocked_objects = 544 tab_specific_content_settings()->blocked_local_shared_objects(); 545 546 // Add first party cookie and site data counts. 547 WebsiteSettingsUI::CookieInfo cookie_info; 548 std::string cookie_source = 549 net::registry_controlled_domains::GetDomainAndRegistry( 550 site_url_, 551 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); 552 if (cookie_source.empty()) 553 cookie_source = site_url_.host(); 554 cookie_info.cookie_source = cookie_source; 555 cookie_info.allowed = allowed_objects.GetObjectCountForDomain(site_url_); 556 cookie_info.blocked = blocked_objects.GetObjectCountForDomain(site_url_); 557 cookie_info_list.push_back(cookie_info); 558 559 // Add third party cookie counts. 560 cookie_info.cookie_source = l10n_util::GetStringUTF8( 561 IDS_WEBSITE_SETTINGS_THIRD_PARTY_SITE_DATA); 562 cookie_info.allowed = allowed_objects.GetObjectCount() - cookie_info.allowed; 563 cookie_info.blocked = blocked_objects.GetObjectCount() - cookie_info.blocked; 564 cookie_info_list.push_back(cookie_info); 565 566 ui_->SetCookieInfo(cookie_info_list); 567 } 568 569 void WebsiteSettings::PresentSiteIdentity() { 570 // After initialization the status about the site's connection 571 // and it's identity must be available. 572 DCHECK_NE(site_identity_status_, SITE_IDENTITY_STATUS_UNKNOWN); 573 DCHECK_NE(site_connection_status_, SITE_CONNECTION_STATUS_UNKNOWN); 574 WebsiteSettingsUI::IdentityInfo info; 575 if (site_identity_status_ == SITE_IDENTITY_STATUS_EV_CERT) 576 info.site_identity = UTF16ToUTF8(organization_name()); 577 else 578 info.site_identity = site_url_.host(); 579 580 info.connection_status = site_connection_status_; 581 info.connection_status_description = 582 UTF16ToUTF8(site_connection_details_); 583 info.identity_status = site_identity_status_; 584 info.identity_status_description = 585 UTF16ToUTF8(site_identity_details_); 586 info.cert_id = cert_id_; 587 ui_->SetIdentityInfo(info); 588 } 589 590 void WebsiteSettings::PresentHistoryInfo(base::Time first_visit) { 591 if (first_visit == base::Time()) { 592 ui_->SetFirstVisit(string16()); 593 return; 594 } 595 596 bool visited_before_today = false; 597 base::Time today = base::Time::Now().LocalMidnight(); 598 base::Time first_visit_midnight = first_visit.LocalMidnight(); 599 visited_before_today = (first_visit_midnight < today); 600 601 string16 first_visit_text; 602 if (visited_before_today) { 603 first_visit_text = l10n_util::GetStringFUTF16( 604 IDS_PAGE_INFO_SECURITY_TAB_VISITED_BEFORE_TODAY, 605 base::TimeFormatShortDate(first_visit)); 606 } else { 607 first_visit_text = l10n_util::GetStringUTF16( 608 IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY); 609 610 } 611 ui_->SetFirstVisit(first_visit_text); 612 } 613