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