Bug 1584613 - Fix detecting web filtering parental control state on Windows 10. r=aklotz

The Windows parental controls API (e.g. IWindowsParentalControls) appears to
have been removed entirely from at least more recent builds of Windows 10. The
interfaces are still defined, but at runtime creating instances of them fails.
This patch enables us to tell if web filtering is enabled for the current user
on Windows 10 without going through that API by directly reading the relevant
registry value.

All methods of nsIParentalControlsService other than parentalControlsEnabled
have been left unimplemented because it isn't obvious how to implement them
in this environment, since no replacement for the old API seems to have been
provided. For example, it appears that loggingEnabled could be implemented
using the same registry key, but the logging mechanism is unlikely to be
compatible with the old one, so reporting that it is enabled may be unsafe.

Differential Revision: https://phabricator.services.mozilla.com/D47508

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Howell 2019-09-27 22:30:31 +00:00
Родитель 956a5992ad
Коммит 201a156b44
1 изменённых файлов: 83 добавлений и 4 удалений

Просмотреть файл

@ -13,15 +13,86 @@
#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(NS_LITERAL_STRING("Filter On"), &filterOn);
if (NS_FAILED(rv)) {
return;
}
mEnabled = filterOn != 0;
return;
}
HRESULT hr;
CoInitialize(nullptr);
hr = CoCreateInstance(__uuidof(WindowsParentalControls), nullptr,
@ -73,7 +144,9 @@ NS_IMETHODIMP
nsParentalControlsService::GetBlockFileDownloadsEnabled(bool* aResult) {
*aResult = false;
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
if (!mEnabled || !mPC) {
return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<IWPCWebSettings> wpcws;
if (SUCCEEDED(mPC->GetWebSettings(nullptr, getter_AddRefs(wpcws)))) {
@ -89,7 +162,9 @@ NS_IMETHODIMP
nsParentalControlsService::GetLoggingEnabled(bool* aResult) {
*aResult = false;
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
if (!mEnabled || !mPC) {
return NS_ERROR_NOT_AVAILABLE;
}
// Check the general purpose logging flag
RefPtr<IWPCSettings> wpcs;
@ -142,7 +217,9 @@ nsParentalControlsService::RequestURIOverride(
nsIURI* aTarget, nsIInterfaceRequestor* aWindowContext, bool* _retval) {
*_retval = false;
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
if (!mEnabled || !mPC) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ENSURE_ARG_POINTER(aTarget);
@ -173,7 +250,9 @@ nsParentalControlsService::RequestURIOverrides(
nsIArray* aTargets, nsIInterfaceRequestor* aWindowContext, bool* _retval) {
*_retval = false;
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
if (!mEnabled || !mPC) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ENSURE_ARG_POINTER(aTargets);