Bug 1407878 - P1. Check URLs against the login reputation service when a password field is focused. r=francois

--HG--
extra : rebase_source : ac7befbe584f008dcf87999edb6f14e24cb30f4e
This commit is contained in:
DimiL 2017-12-14 10:11:45 +08:00
parent 61983e9ada
commit d40b2f8147
8 changed files with 216 additions and 36 deletions

View File

@ -1115,10 +1115,9 @@ BrowserGlue.prototype = {
SafeBrowsing.init();
// Login reputation depends on the Safe Browsing API.
if (Services.prefs.getBoolPref("browser.safebrowsing.passwords.enabled")) {
Cc["@mozilla.org/reputationservice/login-reputation-service;1"]
let reputationService = Cc["@mozilla.org/reputationservice/login-reputation-service;1"]
.getService(Ci.ILoginReputationService);
}
reputationService.init();
}, 5000);
if (AppConstants.MOZ_CRASHREPORTER) {

View File

@ -1,17 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "nsISupports.idl"
[scriptable, uuid(b527be1e-8fbb-41d9-bee4-267a71236368)]
interface ILoginReputationQueryCallback : nsISupports {
void onQueryComplete();
};
[scriptable, uuid(1b3f1dfe-ce3a-486b-953e-ce5ac863eff9)]
interface ILoginReputationService : nsISupports {
// XXX : Add QueryReputation interface
};

View File

@ -4,16 +4,56 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LoginReputation.h"
#include "nsIDOMHTMLInputElement.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
using namespace mozilla::dom;
#define PREF_PP_ENABLED "browser.safebrowsing.passwords.enabled"
static bool sPasswordProtectionEnabled = false;
// MOZ_LOG=LoginReputation:5
LazyLogModule LoginReputationService::prlog("LoginReputation");
#define LR_LOG(args) MOZ_LOG(LoginReputationService::prlog, mozilla::LogLevel::Debug, args)
#define LR_LOG_ENABLED() MOZ_LOG_TEST(LoginReputationService::prlog, mozilla::LogLevel::Debug)
LazyLogModule gLoginReputationLogModule("LoginReputation");
#define LR_LOG(args) MOZ_LOG(gLoginReputationLogModule, mozilla::LogLevel::Debug, args)
#define LR_LOG_ENABLED() MOZ_LOG_TEST(gLoginReputationLogModule, mozilla::LogLevel::Debug)
// -------------------------------------------------------------------------
// ReputationQueryParam
//
// Concrete class for nsILoginReputationQuery to hold query parameters
//
class ReputationQueryParam final : public nsILoginReputationQuery
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSILOGINREPUTATIONQUERY
explicit ReputationQueryParam(nsIURI* aURI)
: mURI(aURI)
{
};
private:
~ReputationQueryParam() = default;
nsCOMPtr<nsIURI> mURI;
};
NS_IMPL_ISUPPORTS(ReputationQueryParam, nsILoginReputationQuery)
NS_IMETHODIMP
ReputationQueryParam::GetFormURI(nsIURI** aURI)
{
NS_IF_ADDREF(*aURI = mURI);
return NS_OK;
}
// -------------------------------------------------------------------------
// LoginReputationService
//
NS_IMPL_ISUPPORTS(LoginReputationService,
ILoginReputationService)
nsILoginReputationService)
LoginReputationService*
LoginReputationService::gLoginReputationService = nullptr;
@ -36,3 +76,83 @@ LoginReputationService::~LoginReputationService()
{
LR_LOG(("Login reputation service shutting down"));
}
NS_IMETHODIMP
LoginReputationService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
switch (XRE_GetProcessType()) {
case GeckoProcessType_Default:
LR_LOG(("Init login reputation service in parent"));
break;
case GeckoProcessType_Content:
LR_LOG(("Init login reputation service in child"));
break;
default:
// No other process type is supported!
return NS_ERROR_NOT_AVAILABLE;
}
Preferences::AddBoolVarCache(&sPasswordProtectionEnabled, PREF_PP_ENABLED, true);
return NS_OK;
}
// static
already_AddRefed<nsILoginReputationQuery>
LoginReputationService::ConstructQueryParam(nsIURI* aURI)
{
RefPtr<ReputationQueryParam> param = new ReputationQueryParam(aURI);
return param.forget();
}
NS_IMETHODIMP
LoginReputationService::QueryReputationAsync(nsIDOMHTMLInputElement* aInput,
nsILoginReputationQueryCallback* aCallback)
{
NS_ENSURE_ARG_POINTER(aInput);
LR_LOG(("QueryReputationAsync() [this=%p]", this));
if (!sPasswordProtectionEnabled) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
NS_ENSURE_STATE(node);
nsIURI* documentURI = node->OwnerDoc()->GetDocumentURI();
NS_ENSURE_STATE(documentURI);
if (XRE_IsContentProcess()) {
} else {
nsCOMPtr<nsILoginReputationQuery> query =
LoginReputationService::ConstructQueryParam(documentURI);
nsresult rv = QueryReputation(query, aCallback);
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
LoginReputationService::QueryReputation(nsILoginReputationQuery* aQuery,
nsILoginReputationQueryCallback* aCallback)
{
NS_ENSURE_ARG_POINTER(aQuery);
LR_LOG(("QueryReputation() [this=%p]", this));
if (!sPasswordProtectionEnabled) {
return NS_ERROR_FAILURE;
}
// Return SAFE until we add support for the remote service (bug 1413732).
if (aCallback) {
aCallback->OnQueryComplete(nsILoginReputationResult::SAFE);
}
return NS_OK;
}

View File

@ -6,17 +6,21 @@
#ifndef LoginReputation_h__
#define LoginReputation_h__
#include "ILoginReputation.h"
#include "nsILoginReputation.h"
#include "mozilla/Logging.h"
class LoginReputationService final : public ILoginReputationService
class LoginReputationService final : public nsILoginReputationService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_ILOGINREPUTATIONSERVICE
NS_DECL_NSILOGINREPUTATIONSERVICE
public:
static already_AddRefed<LoginReputationService> GetSingleton();
static
already_AddRefed<LoginReputationService> GetSingleton();
static
already_AddRefed<nsILoginReputationQuery> ConstructQueryParam(nsIURI* aURI);
private:
/**
@ -24,11 +28,6 @@ private:
*/
static LoginReputationService* gLoginReputationService;
/**
* MOZ_LOG=LoginReputation:5
*/
static mozilla::LazyLogModule prlog;
LoginReputationService();
~LoginReputationService();
};

View File

@ -10,8 +10,8 @@ with Files('*'):
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
XPIDL_SOURCES += [
'ILoginReputation.idl',
'nsIApplicationReputation.idl',
'nsILoginReputation.idl',
]
XPIDL_MODULE = 'reputationservice'

View File

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "nsISupports.idl"
interface nsIDOMHTMLInputElement;
interface nsIURI;
[scriptable, uuid(6219f9da-297e-446d-8d47-ccdd8e72a1d5)]
interface nsILoginReputationResult : nsISupports {
// These should sync with 'VerdictType' defined in
// LoginReputationClientResponse in csd.proto.
const uint16_t UNSPECIFIED = 0;
const uint16_t SAFE = 1;
const uint16_t LOW_REPUTATION = 2;
const uint16_t PHISHING = 3;
};
[scriptable, uuid(c21ffe59-595f-46c8-9052-fefb639e196e)]
interface nsILoginReputationQuery : nsISupports {
readonly attribute nsIURI formURI;
};
[scriptable, uuid(b527be1e-8fbb-41d9-bee4-267a71236368)]
interface nsILoginReputationQueryCallback : nsISupports {
// aResult should be one of the const value defined in nsILoginReputationResult
// interface.
void onQueryComplete(in uint16_t aResult);
};
[scriptable, uuid(1b3f1dfe-ce3a-486b-953e-ce5ac863eff9)]
interface nsILoginReputationService : nsISupports {
void init();
// If QueryReputationAsync is called from child, it will make a IPC call
// to parent.
void queryReputationAsync(in nsIDOMHTMLInputElement aInput,
in nsILoginReputationQueryCallback aCallback);
// QueryReputation can only be called from parent
void queryReputation(in nsILoginReputationQuery aQuery,
in nsILoginReputationQueryCallback aCallback);
};

View File

@ -72,8 +72,9 @@ GetFormAutoComplete()
}
NS_IMPL_CYCLE_COLLECTION(nsFormFillController,
mController, mLoginManager, mFocusedPopup, mDocShells,
mPopups, mLastListener, mLastFormAutoComplete)
mController, mLoginManager, mLoginReputationService,
mFocusedPopup, mDocShells, mPopups, mLastListener,
mLastFormAutoComplete)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormFillController)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFormFillController)
@ -897,6 +898,24 @@ nsFormFillController::StopSearch()
return NS_OK;
}
nsresult
nsFormFillController::StartQueryLoginReputation(nsIDOMHTMLInputElement *aInput)
{
if (!mLoginReputationService) {
mLoginReputationService =
do_GetService(NS_LOGIN_REPUTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!mLoginReputationService)) {
return NS_ERROR_FAILURE;
}
mLoginReputationService->Init();
}
mLoginReputationService->QueryReputationAsync(aInput, nullptr);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
//// nsIFormAutoCompleteObserver
@ -1075,6 +1094,15 @@ nsFormFillController::MaybeStartControllingInput(nsIDOMHTMLInputElement* aInput)
if (isAutofillInput || isPwmgrInput || hasList || autocomplete) {
StartControllingInput(aInput);
}
#ifdef NIGHTLY_BUILD
// Trigger an asynchronous login reputation query when user focuses on the
// password field.
if (formControl->ControlType() == NS_FORM_INPUT_PASSWORD) {
StartQueryLoginReputation(aInput);
}
#endif
}
nsresult

View File

@ -21,6 +21,7 @@
#include "nsIMutationObserver.h"
#include "nsTArray.h"
#include "nsCycleCollectionParticipant.h"
#include "nsILoginReputation.h"
// X.h defines KeyPress
#ifdef KeyPress
@ -89,10 +90,13 @@ protected:
bool IsTextControl(nsINode* aNode);
nsresult StartQueryLoginReputation(nsIDOMHTMLInputElement *aInput);
// members //////////////////////////////////////////
nsCOMPtr<nsIAutoCompleteController> mController;
nsCOMPtr<nsILoginManager> mLoginManager;
nsCOMPtr<nsILoginReputationService> mLoginReputationService;
nsIDOMHTMLInputElement* mFocusedInput;
nsINode* mFocusedInputNode;