1 // Copyright 2020 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 "weblayer/browser/password_manager_driver_factory.h"
6 
7 #include "components/password_manager/content/browser/bad_message.h"
8 #include "components/site_isolation/site_isolation_policy.h"
9 #include "content/public/browser/browser_context.h"
10 #include "content/public/browser/render_frame_host.h"
11 #include "content/public/browser/web_contents.h"
12 #include "mojo/public/cpp/bindings/associated_receiver.h"
13 
14 namespace weblayer {
15 
16 // A minimal implementation of autofill::mojom::PasswordManagerDriver which just
17 // listens for the user to type into a password field.
18 class PasswordManagerDriverFactory::PasswordManagerDriver
19     : public autofill::mojom::PasswordManagerDriver {
20  public:
PasswordManagerDriver(content::RenderFrameHost * render_frame_host)21   explicit PasswordManagerDriver(content::RenderFrameHost* render_frame_host)
22       : render_frame_host_(render_frame_host) {}
23 
BindPendingReceiver(mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver> pending_receiver)24   void BindPendingReceiver(
25       mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver>
26           pending_receiver) {
27     password_manager_receiver_.Bind(std::move(pending_receiver));
28   }
29 
30  private:
31   // autofill::mojom::PasswordManagerDriver:
32   // Note that these messages received from a potentially compromised renderer.
33   // For that reason, any access to form data should be validated via
34   // bad_message::CheckChildProcessSecurityPolicy.
PasswordFormsParsed(const std::vector<autofill::FormData> & forms_data)35   void PasswordFormsParsed(
36       const std::vector<autofill::FormData>& forms_data) override {}
PasswordFormsRendered(const std::vector<autofill::FormData> & visible_forms_data,bool did_stop_loading)37   void PasswordFormsRendered(
38       const std::vector<autofill::FormData>& visible_forms_data,
39       bool did_stop_loading) override {}
PasswordFormSubmitted(const autofill::FormData & form_data)40   void PasswordFormSubmitted(const autofill::FormData& form_data) override {}
InformAboutUserInput(const autofill::FormData & form_data)41   void InformAboutUserInput(const autofill::FormData& form_data) override {
42     if (!password_manager::bad_message::CheckChildProcessSecurityPolicyForURL(
43             render_frame_host_, form_data.url,
44             password_manager::BadMessageReason::
45                 CPMD_BAD_ORIGIN_UPON_USER_INPUT_CHANGE)) {
46       return;
47     }
48 
49     if (FormHasNonEmptyPasswordField(form_data) &&
50         site_isolation::SiteIsolationPolicy::
51             IsIsolationForPasswordSitesEnabled()) {
52       // This function signals that a password field has been filled (whether by
53       // the user, JS, autofill, or some other means) or a password form has
54       // been submitted. Use this as a heuristic to start site-isolating the
55       // form's site. This is intended to be used primarily when full site
56       // isolation is not used, such as on Android.
57       content::SiteInstance::StartIsolatingSite(
58           render_frame_host_->GetSiteInstance()->GetBrowserContext(),
59           form_data.url);
60     }
61   }
SameDocumentNavigation(autofill::mojom::SubmissionIndicatorEvent submission_indication_event)62   void SameDocumentNavigation(autofill::mojom::SubmissionIndicatorEvent
63                                   submission_indication_event) override {}
PasswordFormCleared(const autofill::FormData & form_data)64   void PasswordFormCleared(const autofill::FormData& form_data) override {}
RecordSavePasswordProgress(const std::string & log)65   void RecordSavePasswordProgress(const std::string& log) override {}
UserModifiedPasswordField()66   void UserModifiedPasswordField() override {}
UserModifiedNonPasswordField(autofill::FieldRendererId renderer_id,const base::string16 & value)67   void UserModifiedNonPasswordField(autofill::FieldRendererId renderer_id,
68                                     const base::string16& value) override {}
ShowPasswordSuggestions(base::i18n::TextDirection text_direction,const base::string16 & typed_username,int options,const gfx::RectF & bounds)69   void ShowPasswordSuggestions(base::i18n::TextDirection text_direction,
70                                const base::string16& typed_username,
71                                int options,
72                                const gfx::RectF& bounds) override {}
ShowTouchToFill()73   void ShowTouchToFill() override {}
CheckSafeBrowsingReputation(const GURL & form_action,const GURL & frame_url)74   void CheckSafeBrowsingReputation(const GURL& form_action,
75                                    const GURL& frame_url) override {}
FocusedInputChanged(autofill::mojom::FocusedFieldType focused_field_type)76   void FocusedInputChanged(
77       autofill::mojom::FocusedFieldType focused_field_type) override {}
LogFirstFillingResult(autofill::FormRendererId form_renderer_id,int32_t result)78   void LogFirstFillingResult(autofill::FormRendererId form_renderer_id,
79                              int32_t result) override {}
80 
81   mojo::AssociatedReceiver<autofill::mojom::PasswordManagerDriver>
82       password_manager_receiver_{this};
83   content::RenderFrameHost* render_frame_host_;
84 };
85 
PasswordManagerDriverFactory(content::WebContents * web_contents)86 PasswordManagerDriverFactory::PasswordManagerDriverFactory(
87     content::WebContents* web_contents)
88     : content::WebContentsObserver(web_contents) {}
89 
90 PasswordManagerDriverFactory::~PasswordManagerDriverFactory() = default;
91 
92 // static
BindPasswordManagerDriver(mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver> pending_receiver,content::RenderFrameHost * render_frame_host)93 void PasswordManagerDriverFactory::BindPasswordManagerDriver(
94     mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver>
95         pending_receiver,
96     content::RenderFrameHost* render_frame_host) {
97   content::WebContents* web_contents =
98       content::WebContents::FromRenderFrameHost(render_frame_host);
99   if (!web_contents)
100     return;
101 
102   PasswordManagerDriverFactory* factory =
103       PasswordManagerDriverFactory::FromWebContents(web_contents);
104   if (!factory)
105     return;
106 
107   factory->GetDriverForFrame(render_frame_host)
108       ->BindPendingReceiver(std::move(pending_receiver));
109 }
110 
111 PasswordManagerDriverFactory::PasswordManagerDriver*
GetDriverForFrame(content::RenderFrameHost * render_frame_host)112 PasswordManagerDriverFactory::GetDriverForFrame(
113     content::RenderFrameHost* render_frame_host) {
114   DCHECK_EQ(web_contents(),
115             content::WebContents::FromRenderFrameHost(render_frame_host));
116   DCHECK(render_frame_host->IsRenderFrameCreated());
117 
118   // TryEmplace() will return an iterator to the driver corresponding to
119   // `render_frame_host`. It creates a new one if required.
120   return &base::TryEmplace(frame_driver_map_, render_frame_host,
121                            render_frame_host)
122               .first->second;
123 }
124 
RenderFrameDeleted(content::RenderFrameHost * render_frame_host)125 void PasswordManagerDriverFactory::RenderFrameDeleted(
126     content::RenderFrameHost* render_frame_host) {
127   frame_driver_map_.erase(render_frame_host);
128 }
129 
130 WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordManagerDriverFactory)
131 
132 }  // namespace weblayer
133