diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /dom/ipc/LoginDetectionService.cpp | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/ipc/LoginDetectionService.cpp')
-rw-r--r-- | dom/ipc/LoginDetectionService.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/dom/ipc/LoginDetectionService.cpp b/dom/ipc/LoginDetectionService.cpp new file mode 100644 index 0000000000..28342e430c --- /dev/null +++ b/dom/ipc/LoginDetectionService.cpp @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "LoginDetectionService.h" + +#include "nsILoginInfo.h" +#include "nsILoginManager.h" +#include "nsIObserver.h" +#include "nsIXULRuntime.h" +#include "nsServiceManagerUtils.h" +#include "nsXULAppAPI.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPrefs_fission.h" +#include "mozilla/dom/ProcessIsolation.h" + +namespace mozilla::dom { + +static StaticRefPtr<LoginDetectionService> gLoginDetectionService; + +namespace { + +void OnFissionPrefsChange(const char* aPrefName, void* aData) { + MOZ_ASSERT(gLoginDetectionService); + + gLoginDetectionService->MaybeStartMonitoring(); +} + +} // namespace + +NS_IMPL_ISUPPORTS(LoginDetectionService, nsILoginDetectionService, + nsILoginSearchCallback, nsIObserver, nsISupportsWeakReference) + +// static +already_AddRefed<LoginDetectionService> LoginDetectionService::GetSingleton() { + if (gLoginDetectionService) { + return do_AddRef(gLoginDetectionService); + } + + gLoginDetectionService = new LoginDetectionService(); + ClearOnShutdown(&gLoginDetectionService); + + return do_AddRef(gLoginDetectionService); +} + +LoginDetectionService::LoginDetectionService() : mIsLoginsLoaded(false) {} +LoginDetectionService::~LoginDetectionService() { UnregisterObserver(); } + +void LoginDetectionService::MaybeStartMonitoring() { + if (IsIsolateHighValueSiteEnabled()) { + // We want to isolate sites with a saved password, so fetch saved logins + // from the password manager, and then add the 'HighValue' permission. + + // Note that we don't monitor whether a login is added or removed after + // logins are fetched. For adding logins, this will be covered by form + // submission detection heuristic. As for removing logins, it doesn't + // provide security benefit just to NOT isolate the removed site. The site + // will not be isolated when its permission expired. + FetchLogins(); + } + + if (IsIsolateHighValueSiteEnabled() || + StaticPrefs::fission_highValue_login_monitor()) { + // When the pref is on, we monitor users' login attempt event when we + // are not isolating high value sites. This is because We can't detect the + // case where a user is already logged in to a site, and don't save a + // password for it. So we want to start monitoring login attempts prior + // to releasing the feature. + if (!mObs) { + mObs = mozilla::services::GetObserverService(); + mObs->AddObserver(this, "passwordmgr-form-submission-detected", false); + } + } else { + UnregisterObserver(); + } +} + +void LoginDetectionService::FetchLogins() { + nsresult rv; + nsCOMPtr<nsILoginManager> loginManager = + do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv); + if (NS_WARN_IF(!loginManager)) { + return; + } + + Unused << loginManager->GetAllLoginsWithCallbackAsync(this); +} + +void LoginDetectionService::UnregisterObserver() { + if (mObs) { + mObs->RemoveObserver(this, "passwordmgr-form-submission-detected"); + mObs = nullptr; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// nsILoginDetectionService implementation +NS_IMETHODIMP LoginDetectionService::Init() { + if (XRE_IsContentProcess()) { + return NS_OK; + } + + Preferences::RegisterCallback(OnFissionPrefsChange, "fission.autostart"); + Preferences::RegisterCallback(OnFissionPrefsChange, + "fission.webContentIsolationStrategy"); + + MaybeStartMonitoring(); + + return NS_OK; +} + +NS_IMETHODIMP LoginDetectionService::IsLoginsLoaded(bool* aResult) { + if (IsIsolateHighValueSiteEnabled()) { + *aResult = mIsLoginsLoaded; + } else { + // When the feature is disabled, just returns true so testcases don't + // block on waiting for us to load logins. + *aResult = true; + } + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsILoginSearchObserver implementation +NS_IMETHODIMP +LoginDetectionService::OnSearchComplete( + const nsTArray<RefPtr<nsILoginInfo>>& aLogins) { + // Add all origins with saved passwords to the permission manager. + for (const auto& login : aLogins) { + nsString origin; + login->GetOrigin(origin); + + AddHighValuePermission(NS_ConvertUTF16toUTF8(origin), + mozilla::dom::kHighValueHasSavedLoginPermission); + } + + mIsLoginsLoaded = true; + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIObserver implementation +NS_IMETHODIMP +LoginDetectionService::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if ("passwordmgr-form-submission-detected"_ns.Equals(aTopic)) { + nsDependentString origin(aData); + AddHighValuePermission(NS_ConvertUTF16toUTF8(origin), + mozilla::dom::kHighValueIsLoggedInPermission); + } + + return NS_OK; +} + +} // namespace mozilla::dom |