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 #ifndef COMPONENTS_PAGE_INFO_PAGE_INFO_H_
6 #define COMPONENTS_PAGE_INFO_PAGE_INFO_H_
7 
8 #include <vector>
9 
10 #include "base/macros.h"
11 #include "base/strings/string16.h"
12 #include "build/build_config.h"
13 #include "components/browsing_data/content/local_shared_objects_container.h"
14 #include "components/content_settings/core/common/content_settings.h"
15 #include "components/content_settings/core/common/content_settings_types.h"
16 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
17 #include "components/safe_browsing/buildflags.h"
18 #include "components/security_state/core/security_state.h"
19 #include "content/public/browser/web_contents_observer.h"
20 #include "ui/gfx/vector_icon_types.h"
21 #include "url/gurl.h"
22 
23 namespace content {
24 class WebContents;
25 }
26 
27 namespace content_settings {
28 class PageSpecificContentSettings;
29 }
30 
31 namespace net {
32 class X509Certificate;
33 }
34 
35 namespace permissions {
36 class ChooserContextBase;
37 }
38 
39 class HostContentSettingsMap;
40 class PageInfoDelegate;
41 class PageInfoUI;
42 class PageInfoBubbleViewBrowserTest;
43 
44 using password_manager::metrics_util::PasswordType;
45 
46 // The |PageInfo| provides information about a website's permissions,
47 // connection state and its identity. It owns a UI that displays the
48 // information and allows users to change the permissions. |PageInfo|
49 // objects must be created on the heap. They destroy themselves after the UI is
50 // closed.
51 class PageInfo : public content::WebContentsObserver {
52  public:
53   // TODO(palmer): Figure out if it is possible to unify SiteConnectionStatus
54   // and SiteIdentityStatus.
55   //
56   // Status of a connection to a website.
57   enum SiteConnectionStatus {
58     SITE_CONNECTION_STATUS_UNKNOWN = 0,  // No status available.
59     SITE_CONNECTION_STATUS_ENCRYPTED,    // Connection is encrypted.
60     SITE_CONNECTION_STATUS_INSECURE_PASSIVE_SUBRESOURCE,  // Non-secure passive
61                                                           // content.
62     SITE_CONNECTION_STATUS_INSECURE_FORM_ACTION,          // Non-secure form
63                                                           // target.
64     SITE_CONNECTION_STATUS_INSECURE_ACTIVE_SUBRESOURCE,   // Non-secure active
65                                                           // content.
66     SITE_CONNECTION_STATUS_UNENCRYPTED,      // Connection is not encrypted.
67     SITE_CONNECTION_STATUS_ENCRYPTED_ERROR,  // Connection error occurred.
68     SITE_CONNECTION_STATUS_INTERNAL_PAGE,    // Internal site.
69     SITE_CONNECTION_STATUS_LEGACY_TLS,  // Connection used a legacy TLS version.
70   };
71 
72   // Validation status of a website's identity.
73   enum SiteIdentityStatus {
74     // No status about the website's identity available.
75     SITE_IDENTITY_STATUS_UNKNOWN = 0,
76     // The website provided a valid certificate.
77     SITE_IDENTITY_STATUS_CERT,
78     // The website provided a valid EV certificate.
79     SITE_IDENTITY_STATUS_EV_CERT,
80     // Site identity could not be verified because the site did not provide a
81     // certificate. This is the expected state for HTTP connections.
82     SITE_IDENTITY_STATUS_NO_CERT,
83     // An error occured while verifying the site identity.
84     SITE_IDENTITY_STATUS_ERROR,
85     // The site is a trusted internal chrome page.
86     SITE_IDENTITY_STATUS_INTERNAL_PAGE,
87     // The profile has accessed data using an administrator-provided
88     // certificate, so the administrator might be able to intercept data.
89     SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT,
90     // The website provided a valid certificate, but the certificate or chain
91     // is using a deprecated signature algorithm.
92     SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM,
93   };
94 
95   // Safe Browsing status of a website.
96   enum SafeBrowsingStatus {
97     SAFE_BROWSING_STATUS_NONE = 0,
98     // The website has been flagged by Safe Browsing as dangerous for
99     // containing malware, social engineering, unwanted software, or password
100     // reuse on a low reputation site.
101     SAFE_BROWSING_STATUS_MALWARE,
102     SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING,
103     SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE,
104     SAFE_BROWSING_STATUS_SAVED_PASSWORD_REUSE,
105     SAFE_BROWSING_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE,
106     SAFE_BROWSING_STATUS_SIGNED_IN_NON_SYNC_PASSWORD_REUSE,
107     SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE,
108     SAFE_BROWSING_STATUS_BILLING,
109   };
110 
111   // Events for UMA. Do not reorder or change! Exposed in header so enum is
112   // accessible from test.
113   enum SSLCertificateDecisionsDidRevoke {
114     USER_CERT_DECISIONS_NOT_REVOKED = 0,
115     USER_CERT_DECISIONS_REVOKED = 1,
116     END_OF_SSL_CERTIFICATE_DECISIONS_DID_REVOKE_ENUM
117   };
118 
119   // UMA statistics for PageInfo. Do not reorder or remove existing
120   // fields. A Java counterpart will be generated for this enum.
121   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.page_info
122   enum PageInfoAction {
123     PAGE_INFO_OPENED = 0,
124     // No longer used; indicated actions for the old version of Page Info that
125     // had a "Permissions" tab and a "Connection" tab.
126     // PAGE_INFO_PERMISSIONS_TAB_SELECTED = 1,
127     // PAGE_INFO_CONNECTION_TAB_SELECTED = 2,
128     // PAGE_INFO_CONNECTION_TAB_SHOWN_IMMEDIATELY = 3,
129     PAGE_INFO_COOKIES_DIALOG_OPENED = 4,
130     PAGE_INFO_CHANGED_PERMISSION = 5,
131     PAGE_INFO_CERTIFICATE_DIALOG_OPENED = 6,
132     // No longer used; indicated a UI viewer for SCTs.
133     // PAGE_INFO_TRANSPARENCY_VIEWER_OPENED = 7,
134     PAGE_INFO_CONNECTION_HELP_OPENED = 8,
135     PAGE_INFO_SITE_SETTINGS_OPENED = 9,
136     PAGE_INFO_SECURITY_DETAILS_OPENED = 10,
137     PAGE_INFO_COOKIES_ALLOWED_FOR_SITE = 11,
138     PAGE_INFO_COOKIES_BLOCKED_FOR_SITE = 12,
139     PAGE_INFO_COOKIES_CLEARED = 13,
140     PAGE_INFO_PERMISSION_DIALOG_OPENED = 14,
141     PAGE_INFO_PERMISSIONS_CLEARED = 15,
142     PAGE_INFO_PERMISSIONS_CHANGED = 16,
143     PAGE_INFO_COUNT
144   };
145 
146   struct ChooserUIInfo {
147     ContentSettingsType content_settings_type;
148     int description_string_id;
149     int allowed_by_policy_description_string_id;
150     int delete_tooltip_string_id;
151   };
152 
153   // |PermissionInfo| contains information about a single permission |type| for
154   // the current website.
155   struct PermissionInfo {
156     PermissionInfo() = default;
157     // Site permission |type|.
158     ContentSettingsType type = ContentSettingsType::DEFAULT;
159     // The current value for the permission |type| (e.g. ALLOW or BLOCK).
160     ContentSetting setting = CONTENT_SETTING_DEFAULT;
161     // The global default settings for this permission |type|.
162     ContentSetting default_setting = CONTENT_SETTING_DEFAULT;
163     // The settings source e.g. user, extensions, policy, ... .
164     content_settings::SettingSource source =
165         content_settings::SETTING_SOURCE_NONE;
166     // Whether we're in incognito mode.
167     bool is_incognito = false;
168     bool is_one_time = false;
169   };
170 
171   // Creates a PageInfo for the passed |url| using the given |ssl| status
172   // object to determine the status of the site's connection.
173   PageInfo(std::unique_ptr<PageInfoDelegate> delegate,
174            content::WebContents* web_contents,
175            const GURL& url);
176   ~PageInfo() override;
177 
178   // Checks whether this permission is currently the factory default, as set by
179   // Chrome. Specifically, that the following three conditions are true:
180   //   - The current active setting comes from the default or pref provider.
181   //   - The setting is the factory default setting (as opposed to a global
182   //     default setting set by the user).
183   //   - The setting is a wildcard setting applying to all origins (which can
184   //     only be set from the default provider).
185   static bool IsPermissionFactoryDefault(const PermissionInfo& info);
186 
187   // Returns whether this page info is for an internal page.
188   static bool IsFileOrInternalPage(const GURL& url);
189 
190   // Initializes UI state that is dependent on having access to the PageInfoUI
191   // object associated with this object. This explicit post-construction
192   // initialization step is necessary as PageInfoUI subclasses create this
193   // object and also may invoke it as part of the initialization flow that
194   // occurs in this method. If this initialization flow was done as part of
195   // PageInfo's constructor, those subclasses would not have their PageInfo
196   // member set and crashes would ensue.
197   void InitializeUiState(PageInfoUI* ui);
198 
199   // This method is called to update the presenter's security state and forwards
200   // that change on to the UI to be redrawn.
201   void UpdateSecurityState();
202 
203   void RecordPageInfoAction(PageInfoAction action);
204 
205   void UpdatePermissions();
206 
207   // This method is called when ever a permission setting is changed.
208   void OnSitePermissionChanged(ContentSettingsType type,
209                                ContentSetting value,
210                                bool is_one_time);
211 
212   // This method is called whenever access to an object is revoked.
213   void OnSiteChosenObjectDeleted(const ChooserUIInfo& ui_info,
214                                  const base::Value& object);
215 
216   // This method is called by the UI when the UI is closing.
217   // If specified, |reload_prompt| is set to whether closing the UI resulted in
218   // a prompt to the user to reload the page.
219   void OnUIClosing(bool* reload_prompt);
220 
221   // This method is called when the revoke SSL error bypass button is pressed.
222   void OnRevokeSSLErrorBypassButtonPressed();
223 
224   // Handles opening the link to show more site settings and records the event.
225   void OpenSiteSettingsView();
226 
227   // This method is called when the user pressed "Change password" button.
228   void OnChangePasswordButtonPressed(content::WebContents* web_contents);
229 
230   // This method is called when the user pressed "Mark as legitimate" button.
231   void OnWhitelistPasswordReuseButtonPressed(
232       content::WebContents* web_contents);
233 
234   // Return a pointer to the ChooserContextBase corresponding to the
235   // content settings type, |type|. Returns nullptr for content settings
236   // for which there's no ChooserContextBase.
237   permissions::ChooserContextBase* GetChooserContextFromUIInfo(
238       const ChooserUIInfo& ui_info) const;
239 
240   // Accessors.
site_connection_status()241   const SiteConnectionStatus& site_connection_status() const {
242     return site_connection_status_;
243   }
244 
site_url()245   const GURL& site_url() const { return site_url_; }
246 
site_identity_status()247   const SiteIdentityStatus& site_identity_status() const {
248     return site_identity_status_;
249   }
250 
safe_browsing_status()251   const SafeBrowsingStatus& safe_browsing_status() const {
252     return safe_browsing_status_;
253   }
254 
255  private:
256   FRIEND_TEST_ALL_PREFIXES(PageInfoTest,
257                            NonFactoryDefaultAndRecentlyChangedPermissionsShown);
258   FRIEND_TEST_ALL_PREFIXES(PageInfoTest, IncognitoPermissionsEmptyByDefault);
259   FRIEND_TEST_ALL_PREFIXES(PageInfoTest, IncognitoPermissionsDontShowAsk);
260   friend class PageInfoBubbleViewBrowserTest;
261 
262   // Populates this object's UI state with provided security context. This
263   // function does not update visible UI-- that's part of Present*().
264   void ComputeUIInputs(const GURL& url);
265 
266   // Sets (presents) the information about the site's permissions in the |ui_|.
267   void PresentSitePermissions();
268 
269   // Sets (presents) the information about the site's data in the |ui_|.
270   void PresentSiteData();
271 
272   // Sets (presents) the information about the site's identity and connection
273   // in the |ui_|.
274   void PresentSiteIdentity();
275 
276   // Presents feature related info in the |ui_|; like, if VR content is being
277   // presented in a headset.
278   void PresentPageFeatureInfo();
279 
280 #if BUILDFLAG(FULL_SAFE_BROWSING)
281   // Records a password reuse event. If FULL_SAFE_BROWSING is defined, this
282   // function WILL record an event. Callers should check conditions beforehand.
283   void RecordPasswordReuseEvent();
284 #endif
285 
286   // Helper function to get the |HostContentSettingsMap| associated with
287   // |PageInfo|.
288   HostContentSettingsMap* GetContentSettings() const;
289 
290   // Helper function to get the Safe Browsing status and details by malicious
291   // content status.
292   // TODO(jdeblasio): Eliminate this and just use MaliciousContentStatus?
293   void GetSafeBrowsingStatusByMaliciousContentStatus(
294       security_state::MaliciousContentStatus malicious_content_status,
295       PageInfo::SafeBrowsingStatus* status,
296       base::string16* details);
297 
298   // Retrieves all the permissions that are shown in Page Info.
299   // Exposed for testing.
300   static std::vector<ContentSettingsType> GetAllPermissionsForTesting();
301 
302   // Returns PageSpecificContentSettings for the observed WebContents if
303   // present, nullptr otherwise.
304   content_settings::PageSpecificContentSettings*
305   GetPageSpecificContentSettings() const;
306 
307   // Whether the content setting of type |type| has changed via Page Info UI.
308   bool HasContentSettingChangedViaPageInfo(ContentSettingsType type);
309 
310   // Notifies the delegate that the content setting of type |type| has changed
311   // via Page Info UI.
312   void ContentSettingChangedViaPageInfo(ContentSettingsType type);
313 
314   // Get counts of allowed and blocked cookies.
315   int GetFirstPartyAllowedCookiesCount(const GURL& site_url);
316   int GetFirstPartyBlockedCookiesCount(const GURL& site_url);
317   int GetThirdPartyAllowedCookiesCount(const GURL& site_url);
318   int GetThirdPartyBlockedCookiesCount(const GURL& site_url);
319 
320   // The page info UI displays information and controls for site-
321   // specific data (local stored objects like cookies), site-specific
322   // permissions (location, pop-up, plugin, etc. permissions) and site-specific
323   // information (identity, connection status, etc.).
324   PageInfoUI* ui_;
325 
326   // The delegate allows the embedder to customize |PageInfo|'s behavior.
327   std::unique_ptr<PageInfoDelegate> delegate_;
328 
329   // The flag that controls whether an infobar is displayed after the website
330   // settings UI is closed or not.
331   bool show_info_bar_;
332 
333   // The Omnibox URL of the website for which to display site permissions and
334   // site information.
335   GURL site_url_;
336 
337   // Status of the website's identity verification check.
338   SiteIdentityStatus site_identity_status_;
339 
340   // Safe Browsing status of the website.
341   SafeBrowsingStatus safe_browsing_status_;
342 
343   // Safety tip info of the website. Set regardless of whether the feature is
344   // enabled to show the UI.
345   security_state::SafetyTipInfo safety_tip_info_;
346 
347   // For secure connection |certificate_| is set to the server certificate.
348   scoped_refptr<net::X509Certificate> certificate_;
349 
350   // Status of the connection to the website.
351   SiteConnectionStatus site_connection_status_;
352 
353   // TODO(markusheintz): Move the creation of all the base::string16 typed UI
354   // strings below to the corresponding UI code, in order to prevent
355   // unnecessary UTF-8 string conversions.
356 
357 #if defined(OS_ANDROID)
358   // Details about the website's identity. If the website's identity has been
359   // verified then |identity_status_description_android_| contains who verified
360   // the identity. This string will be displayed in the UI.
361   base::string16 identity_status_description_android_;
362 #endif
363 
364   // Set when the user has explicitly bypassed an SSL error for this host or
365   // explicitly denied it (the latter of which is not currently possible in the
366   // Chrome UI). When |show_ssl_decision_revoke_button| is true, the connection
367   // area of the page info will include an option for the user to revoke their
368   // decision to bypass the SSL error for this host.
369   bool show_ssl_decision_revoke_button_;
370 
371   // Details about the connection to the website. In case of an encrypted
372   // connection |site_connection_details_| contains encryption details, like
373   // encryption strength and ssl protocol version. This string will be
374   // displayed in the UI.
375   base::string16 site_connection_details_;
376 
377   // For websites that provided an EV certificate |orgainization_name_|
378   // contains the organization name of the certificate. In all other cases
379   // |organization_name| is an empty string. This string will be displayed in
380   // the UI.
381   base::string16 organization_name_;
382 
383   bool did_revoke_user_ssl_decisions_;
384 
385   security_state::SecurityLevel security_level_;
386 
387   security_state::VisibleSecurityState visible_security_state_for_metrics_;
388 
389   // Set when the user ignored the password reuse modal warning dialog. When
390   // |show_change_password_buttons_| is true, the page identity area of the page
391   // info will include buttons to change corresponding password, and to
392   // whitelist current site.
393   bool show_change_password_buttons_;
394 
395   // The time the Page Info UI is opened, for measuring total time open.
396   base::TimeTicks start_time_;
397 
398   // Records whether the user interacted with the bubble beyond opening it.
399   bool did_perform_action_;
400 
401   DISALLOW_COPY_AND_ASSIGN(PageInfo);
402 };
403 
404 #endif  // COMPONENTS_PAGE_INFO_PAGE_INFO_H_
405