diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/parentalcontrols | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/parentalcontrols')
7 files changed, 594 insertions, 0 deletions
diff --git a/toolkit/components/parentalcontrols/moz.build b/toolkit/components/parentalcontrols/moz.build new file mode 100644 index 0000000000..b616574bc1 --- /dev/null +++ b/toolkit/components/parentalcontrols/moz.build @@ -0,0 +1,34 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Toolkit", "General") + +XPIDL_SOURCES += [ + "nsIParentalControlsService.idl", +] + +XPIDL_MODULE = "parentalcontrols" + +if not CONFIG["MOZ_DISABLE_PARENTAL_CONTROLS"]: + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": + SOURCES += [ + "nsParentalControlsServiceWin.cpp", + ] + elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": + UNIFIED_SOURCES += [ + "nsParentalControlsServiceCocoa.mm", + ] + elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": + UNIFIED_SOURCES += [ + "nsParentalControlsServiceAndroid.cpp", + ] + else: + SOURCES += [ + "nsParentalControlsServiceDefault.cpp", + ] + +FINAL_LIBRARY = "xul" diff --git a/toolkit/components/parentalcontrols/nsIParentalControlsService.idl b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl new file mode 100644 index 0000000000..d6e2900e74 --- /dev/null +++ b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsISupports.idl" + +interface nsIURI; +interface nsIFile; +interface nsIInterfaceRequestor; +interface nsIArray; + +[scriptable, uuid(2e97e5dd-467b-4aea-a1bb-6773c0f2beb0)] +interface nsIParentalControlsService : nsISupports +{ + /** + * Action types that can be blocked for users. + */ + const short DOWNLOAD = 1; // Downloading files + const short INSTALL_EXTENSION = 2; // Installing extensions + const short INSTALL_APP = 3; // Installing webapps + const short BROWSE = 4; // Opening specific urls + const short SHARE = 5; // Sharing + const short BOOKMARK = 6; // Creating bookmarks + const short ADD_CONTACT = 7; // Add contacts to the system database + const short SET_IMAGE = 8; // Setting images as wall paper + const short MODIFY_ACCOUNTS = 9; // Modifying system accounts + const short REMOTE_DEBUGGING = 10; // Remote debugging + const short IMPORT_SETTINGS = 11; // Importing settings from other apps + const short PRIVATE_BROWSING = 12; // Disallow usage of private browsing + const short DATA_CHOICES = 13; // Choose whether or not to send usage information + const short CLEAR_HISTORY = 14; // Clear browsing history + const short MASTER_PASSWORD = 15; // Setting master password for logins + const short GUEST_BROWSING = 16; // Disallow usage of guest browsing + const short ADVANCED_SETTINGS = 17; // Advanced settings + const short CAMERA_MICROPHONE = 18; // Camera and microphone (WebRTC) + const short BLOCK_LIST = 19; // Block websites that include sensitive content + const short TELEMETRY = 20; // Submit telemetry data + const short HEALTH_REPORT = 21; // Submit FHR data + const short DEFAULT_THEME = 22; // Use default theme or a special parental controls theme + + /** + * @returns true if the current user account has parental controls + * restrictions enabled. + */ + readonly attribute boolean parentalControlsEnabled; + + /** + * @returns true if the current user account parental controls + * restrictions include the blocking of all file downloads. + */ + readonly attribute boolean blockFileDownloadsEnabled; + + /** + * Check if the user can do the prescibed action for this uri. + * + * @param aAction Action being performed + * @param aUri The uri requesting this action + * @param aWindow The window generating this event. + */ + boolean isAllowed(in short aAction, [optional] in nsIURI aUri); + + /** + * @returns true if the current user account has parental controls + * logging enabled. If true, applications should log relevent events + * using 'log'. + */ + readonly attribute boolean loggingEnabled; + + /** + * Log entry types. Additional types can be defined and implemented + * as needed. Other possible event types might include email events, + * media related events, and IM events. + */ + const short ePCLog_URIVisit = 1; /* Web content */ + const short ePCLog_FileDownload = 2; /* File downloads */ + + /** + * Log an application specific parental controls + * event. + * + * @param aEntryType Constant defining the type of event. + * @param aFlag A flag indicating if the subject content + * was blocked. + * @param aSource The URI source of the subject content. + * @param aTarget The location the content was saved to if + * no blocking occurred. + */ + void log(in short aEntryType, in boolean aFlag, in nsIURI aSource, [optional] in nsIFile aTarget); +}; diff --git a/toolkit/components/parentalcontrols/nsParentalControlsService.h b/toolkit/components/parentalcontrols/nsParentalControlsService.h new file mode 100644 index 0000000000..4645253ff6 --- /dev/null +++ b/toolkit/components/parentalcontrols/nsParentalControlsService.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef nsParentalControlsService_h__ +#define nsParentalControlsService_h__ + +#include "nsIParentalControlsService.h" +#include "nsCOMPtr.h" +#include "nsIURI.h" + +#if defined(XP_WIN) +# include <wpcapi.h> +# include <wpcevent.h> +#endif + +class nsParentalControlsService : public nsIParentalControlsService { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPARENTALCONTROLSSERVICE + + nsParentalControlsService(); + + protected: + virtual ~nsParentalControlsService(); + + private: + bool mEnabled; +#if defined(XP_WIN) + REGHANDLE mProvider; + IWindowsParentalControls* mPC; + void LogFileDownload(bool blocked, nsIURI* aSource, nsIFile* aTarget); +#endif +}; + +#endif /* nsParentalControlsService_h__ */ diff --git a/toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp b/toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp new file mode 100644 index 0000000000..cdcb7edb32 --- /dev/null +++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ +/* 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 "nsParentalControlsService.h" +#include "nsString.h" +#include "nsIFile.h" + +NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService) + +nsParentalControlsService::nsParentalControlsService() : mEnabled(false) {} + +nsParentalControlsService::~nsParentalControlsService() {} + +NS_IMETHODIMP +nsParentalControlsService::GetParentalControlsEnabled(bool* aResult) { + *aResult = mEnabled; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetBlockFileDownloadsEnabled(bool* aResult) { + // NOTE: isAllowed returns the opposite intention, so we need to flip it + bool res; + IsAllowed(nsIParentalControlsService::DOWNLOAD, NULL, &res); + *aResult = !res; + + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetLoggingEnabled(bool* aResult) { + // Android doesn't currently have any method of logging restricted actions. + *aResult = false; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::Log(int16_t aEntryType, bool aBlocked, + nsIURI* aSource, nsIFile* aTarget) { + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri, + bool* _retval) { + nsresult rv = NS_OK; + *_retval = true; + + if (!mEnabled) { + return rv; + } + + return NS_ERROR_NOT_AVAILABLE; +} diff --git a/toolkit/components/parentalcontrols/nsParentalControlsServiceCocoa.mm b/toolkit/components/parentalcontrols/nsParentalControlsServiceCocoa.mm new file mode 100644 index 0000000000..a2ddb258ff --- /dev/null +++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceCocoa.mm @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ +/* 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 "nsParentalControlsService.h" +#include "nsString.h" +#include "nsIFile.h" + +#import <Cocoa/Cocoa.h> + +NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService) + +nsParentalControlsService::nsParentalControlsService() : mEnabled(false) { + mEnabled = CFPreferencesAppValueIsForced(CFSTR("restrictWeb"), + CFSTR("com.apple.familycontrols.contentfilter")); +} + +nsParentalControlsService::~nsParentalControlsService() {} + +NS_IMETHODIMP +nsParentalControlsService::GetParentalControlsEnabled(bool* aResult) { + *aResult = mEnabled; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetBlockFileDownloadsEnabled(bool* aResult) { + *aResult = false; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetLoggingEnabled(bool* aResult) { + *aResult = false; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::Log(int16_t aEntryType, bool blocked, nsIURI* aSource, + nsIFile* aTarget) { + // silently drop on the floor + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri, bool* _retval) { + return NS_ERROR_NOT_AVAILABLE; +} diff --git a/toolkit/components/parentalcontrols/nsParentalControlsServiceDefault.cpp b/toolkit/components/parentalcontrols/nsParentalControlsServiceDefault.cpp new file mode 100644 index 0000000000..2b5f0c8e32 --- /dev/null +++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceDefault.cpp @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ +/* 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 "nsParentalControlsService.h" +#include "nsIFile.h" +#include "mozilla/Unused.h" + +NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService) + +nsParentalControlsService::nsParentalControlsService() : mEnabled(false) { + mozilla::Unused << mEnabled; +} + +nsParentalControlsService::~nsParentalControlsService() = default; + +NS_IMETHODIMP +nsParentalControlsService::GetParentalControlsEnabled(bool* aResult) { + *aResult = false; + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetBlockFileDownloadsEnabled(bool* aResult) { + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsParentalControlsService::GetLoggingEnabled(bool* aResult) { + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsParentalControlsService::Log(int16_t aEntryType, bool blocked, + nsIURI* aSource, nsIFile* aTarget) { + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri, + bool* _retval) { + return NS_ERROR_NOT_AVAILABLE; +} diff --git a/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp b/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp new file mode 100644 index 0000000000..a3edd56ca3 --- /dev/null +++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ +/* 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 "nsParentalControlsService.h" +#include "nsComponentManagerUtils.h" +#include "nsString.h" +#include "nsIArray.h" +#include "nsIWidget.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIFile.h" +#include "nsILocalFileWin.h" +#include "nsArrayUtils.h" +#include "nsIXULAppInfo.h" +#include "nsWindowsHelpers.h" +#include "nsIWindowsRegKey.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/WindowsVersion.h" + +#include <sddl.h> + +using namespace mozilla; + +NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService) + +// Get the SID string for the user associated with this process's token. +static nsAutoString GetUserSid() { + nsAutoString ret; + HANDLE rawToken; + BOOL success = + ::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &rawToken); + if (!success) { + return ret; + } + nsAutoHandle token(rawToken); + + DWORD bufLen; + success = ::GetTokenInformation(token, TokenUser, nullptr, 0, &bufLen); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + return ret; + } + + UniquePtr<char[]> buf = MakeUnique<char[]>(bufLen); + success = ::GetTokenInformation(token, TokenUser, buf.get(), bufLen, &bufLen); + MOZ_ASSERT(success); + + if (success) { + TOKEN_USER* tokenUser = (TOKEN_USER*)(buf.get()); + PSID sid = tokenUser->User.Sid; + LPWSTR sidStr; + success = ::ConvertSidToStringSidW(sid, &sidStr); + if (success) { + ret = sidStr; + ::LocalFree(sidStr); + } + } + return ret; +} + +nsParentalControlsService::nsParentalControlsService() + : mEnabled(false), mProvider(0), mPC(nullptr) { + // On at least some builds of Windows 10, the old parental controls API no + // longer exists, so we have to pull the info we need out of the registry. + if (IsWin10OrLater()) { + nsAutoString regKeyName; + regKeyName.AppendLiteral( + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Parental Controls\\" + "Users\\"); + regKeyName.Append(GetUserSid()); + regKeyName.AppendLiteral("\\Web"); + + nsresult rv; + nsCOMPtr<nsIWindowsRegKey> regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + if (NS_FAILED(rv)) { + return; + } + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, regKeyName, + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return; + } + + uint32_t filterOn = 0; + rv = regKey->ReadIntValue(u"Filter On"_ns, &filterOn); + if (NS_FAILED(rv)) { + return; + } + + mEnabled = filterOn != 0; + return; + } + + HRESULT hr; + CoInitialize(nullptr); + hr = CoCreateInstance(__uuidof(WindowsParentalControls), nullptr, + CLSCTX_INPROC, IID_PPV_ARGS(&mPC)); + if (FAILED(hr)) return; + + RefPtr<IWPCSettings> wpcs; + if (FAILED(mPC->GetUserSettings(nullptr, getter_AddRefs(wpcs)))) { + // Not available on this os or not enabled for this user account or we're + // running as admin + mPC->Release(); + mPC = nullptr; + return; + } + + DWORD settings = 0; + wpcs->GetRestrictions(&settings); + + // If we can't determine specifically whether Web Filtering is on/off (i.e. + // we're on Windows < 8), then assume it's on unless no restrictions are set. + bool enable = IsWin8OrLater() ? settings & WPCFLAG_WEB_FILTERED + : settings != WPCFLAG_NO_RESTRICTION; + + if (enable) { + mEnabled = true; + } +} + +nsParentalControlsService::~nsParentalControlsService() { + if (mPC) mPC->Release(); + + if (mProvider) { + EventUnregister(mProvider); + } +} + +//------------------------------------------------------------------------ + +NS_IMETHODIMP +nsParentalControlsService::GetParentalControlsEnabled(bool* aResult) { + *aResult = false; + + if (mEnabled) *aResult = true; + + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetBlockFileDownloadsEnabled(bool* aResult) { + *aResult = false; + + if (!mEnabled) { + return NS_ERROR_NOT_AVAILABLE; + } + + // If we're on Windows 10 and we don't have the whole API available, then + // we can't tell if file downloads are allowed, so assume they are to avoid + // breaking downloads for every single user with parental controls. + if (!mPC) { + return NS_OK; + } + + RefPtr<IWPCWebSettings> wpcws; + if (SUCCEEDED(mPC->GetWebSettings(nullptr, getter_AddRefs(wpcws)))) { + DWORD settings = 0; + wpcws->GetSettings(&settings); + if (settings == WPCFLAG_WEB_SETTING_DOWNLOADSBLOCKED) *aResult = true; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsParentalControlsService::GetLoggingEnabled(bool* aResult) { + *aResult = false; + + if (!mEnabled) { + return NS_ERROR_NOT_AVAILABLE; + } + + // If we're on Windows 10 and we don't have the whole API available, then + // we don't know how logging should be done, so report that it's disabled. + if (!mPC) { + return NS_OK; + } + + // Check the general purpose logging flag + RefPtr<IWPCSettings> wpcs; + if (SUCCEEDED(mPC->GetUserSettings(nullptr, getter_AddRefs(wpcs)))) { + BOOL enabled = FALSE; + wpcs->IsLoggingRequired(&enabled); + if (enabled) *aResult = true; + } + + return NS_OK; +} + +// Post a log event to the system +NS_IMETHODIMP +nsParentalControlsService::Log(int16_t aEntryType, bool blocked, + nsIURI* aSource, nsIFile* aTarget) { + if (!mEnabled) return NS_ERROR_NOT_AVAILABLE; + + NS_ENSURE_ARG_POINTER(aSource); + + // Confirm we should be logging + bool enabled; + GetLoggingEnabled(&enabled); + if (!enabled) return NS_ERROR_NOT_AVAILABLE; + + // Register a Vista log event provider associated with the parental controls + // channel. + if (!mProvider) { + if (EventRegister(&WPCPROV, nullptr, nullptr, &mProvider) != ERROR_SUCCESS) + return NS_ERROR_OUT_OF_MEMORY; + } + + switch (aEntryType) { + case ePCLog_URIVisit: + // Not needed, Vista's web content filter handles this for us + break; + case ePCLog_FileDownload: + LogFileDownload(blocked, aSource, aTarget); + break; + default: + break; + } + + return NS_OK; +} + +//------------------------------------------------------------------------ + +// Sends a file download event to the Vista Event Log +void nsParentalControlsService::LogFileDownload(bool blocked, nsIURI* aSource, + nsIFile* aTarget) { + nsAutoCString curi; + + // Note, EventDataDescCreate is a macro defined in the headers, not a function + + aSource->GetSpec(curi); + nsAutoString uri = NS_ConvertUTF8toUTF16(curi); + + // Get the name of the currently running process + nsCOMPtr<nsIXULAppInfo> appInfo = + do_GetService("@mozilla.org/xre/app-info;1"); + nsAutoCString asciiAppName; + if (appInfo) appInfo->GetName(asciiAppName); + nsAutoString appName = NS_ConvertUTF8toUTF16(asciiAppName); + + static const WCHAR fill[] = L""; + + // See wpcevent.h and msdn for event formats + EVENT_DATA_DESCRIPTOR eventData[WPC_ARGS_FILEDOWNLOADEVENT_CARGS]; + DWORD dwBlocked = blocked; + + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_URL], + (const void*)uri.get(), + ((ULONG)uri.Length() + 1) * sizeof(WCHAR)); + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_APPNAME], + (const void*)appName.get(), + ((ULONG)appName.Length() + 1) * sizeof(WCHAR)); + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_VERSION], + (const void*)fill, sizeof(fill)); + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_BLOCKED], + (const void*)&dwBlocked, sizeof(dwBlocked)); + + if (aTarget) { // May be null + nsAutoString path; + aTarget->GetPath(path); + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_PATH], + (const void*)path.get(), + ((ULONG)path.Length() + 1) * sizeof(WCHAR)); + } else { + EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_PATH], + (const void*)fill, sizeof(fill)); + } + + EventWrite(mProvider, &WPCEVENT_WEB_FILEDOWNLOAD, ARRAYSIZE(eventData), + eventData); +} + +NS_IMETHODIMP +nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri, + bool* _retval) { + return NS_ERROR_NOT_AVAILABLE; +} |