Bug 1886946: Remove incorrect assertion that buffer is not-pinned. r=sfink
[gecko.git] / dom / ipc / LoginDetectionService.cpp
blobddbe1096fb49ea6bb363ae1b1ee8d222d438a830
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "LoginDetectionService.h"
9 #include "nsILoginInfo.h"
10 #include "nsILoginManager.h"
11 #include "nsIObserver.h"
12 #include "nsIXULRuntime.h"
13 #include "nsServiceManagerUtils.h"
14 #include "nsXULAppAPI.h"
16 #include "mozilla/ClearOnShutdown.h"
17 #include "mozilla/StaticPrefs_fission.h"
18 #include "mozilla/dom/ProcessIsolation.h"
20 namespace mozilla::dom {
22 static StaticRefPtr<LoginDetectionService> gLoginDetectionService;
24 namespace {
26 void OnFissionPrefsChange(const char* aPrefName, void* aData) {
27 MOZ_ASSERT(gLoginDetectionService);
29 gLoginDetectionService->MaybeStartMonitoring();
32 } // namespace
34 NS_IMPL_ISUPPORTS(LoginDetectionService, nsILoginDetectionService,
35 nsILoginSearchCallback, nsIObserver, nsISupportsWeakReference)
37 // static
38 already_AddRefed<LoginDetectionService> LoginDetectionService::GetSingleton() {
39 if (gLoginDetectionService) {
40 return do_AddRef(gLoginDetectionService);
43 gLoginDetectionService = new LoginDetectionService();
44 ClearOnShutdown(&gLoginDetectionService);
46 return do_AddRef(gLoginDetectionService);
49 LoginDetectionService::LoginDetectionService() : mIsLoginsLoaded(false) {}
50 LoginDetectionService::~LoginDetectionService() { UnregisterObserver(); }
52 void LoginDetectionService::MaybeStartMonitoring() {
53 if (IsIsolateHighValueSiteEnabled()) {
54 // We want to isolate sites with a saved password, so fetch saved logins
55 // from the password manager, and then add the 'HighValue' permission.
57 // Note that we don't monitor whether a login is added or removed after
58 // logins are fetched. For adding logins, this will be covered by form
59 // submission detection heuristic. As for removing logins, it doesn't
60 // provide security benefit just to NOT isolate the removed site. The site
61 // will not be isolated when its permission expired.
62 FetchLogins();
65 if (IsIsolateHighValueSiteEnabled() ||
66 StaticPrefs::fission_highValue_login_monitor()) {
67 // When the pref is on, we monitor users' login attempt event when we
68 // are not isolating high value sites. This is because We can't detect the
69 // case where a user is already logged in to a site, and don't save a
70 // password for it. So we want to start monitoring login attempts prior
71 // to releasing the feature.
72 if (!mObs) {
73 mObs = mozilla::services::GetObserverService();
74 mObs->AddObserver(this, "passwordmgr-form-submission-detected", false);
76 } else {
77 UnregisterObserver();
81 void LoginDetectionService::FetchLogins() {
82 nsresult rv;
83 nsCOMPtr<nsILoginManager> loginManager =
84 do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
85 if (NS_WARN_IF(!loginManager)) {
86 return;
89 Unused << loginManager->GetAllLoginsWithCallback(this);
92 void LoginDetectionService::UnregisterObserver() {
93 if (mObs) {
94 mObs->RemoveObserver(this, "passwordmgr-form-submission-detected");
95 mObs = nullptr;
99 ///////////////////////////////////////////////////////////////////////////////
100 // nsILoginDetectionService implementation
101 NS_IMETHODIMP LoginDetectionService::Init() {
102 if (XRE_IsContentProcess()) {
103 return NS_OK;
106 Preferences::RegisterCallback(OnFissionPrefsChange, "fission.autostart");
107 Preferences::RegisterCallback(OnFissionPrefsChange,
108 "fission.webContentIsolationStrategy");
110 MaybeStartMonitoring();
112 return NS_OK;
115 NS_IMETHODIMP LoginDetectionService::IsLoginsLoaded(bool* aResult) {
116 if (IsIsolateHighValueSiteEnabled()) {
117 *aResult = mIsLoginsLoaded;
118 } else {
119 // When the feature is disabled, just returns true so testcases don't
120 // block on waiting for us to load logins.
121 *aResult = true;
123 return NS_OK;
126 ///////////////////////////////////////////////////////////////////////////////
127 // nsILoginSearchObserver implementation
128 NS_IMETHODIMP
129 LoginDetectionService::OnSearchComplete(
130 const nsTArray<RefPtr<nsILoginInfo>>& aLogins) {
131 // Add all origins with saved passwords to the permission manager.
132 for (const auto& login : aLogins) {
133 nsString origin;
134 login->GetOrigin(origin);
136 AddHighValuePermission(NS_ConvertUTF16toUTF8(origin),
137 mozilla::dom::kHighValueHasSavedLoginPermission);
140 mIsLoginsLoaded = true;
141 return NS_OK;
144 ///////////////////////////////////////////////////////////////////////////////
145 // nsIObserver implementation
146 NS_IMETHODIMP
147 LoginDetectionService::Observe(nsISupports* aSubject, const char* aTopic,
148 const char16_t* aData) {
149 if ("passwordmgr-form-submission-detected"_ns.Equals(aTopic)) {
150 nsDependentString origin(aData);
151 AddHighValuePermission(NS_ConvertUTF16toUTF8(origin),
152 mozilla::dom::kHighValueIsLoggedInPermission);
155 return NS_OK;
158 } // namespace mozilla::dom