netwerk/url-classifier/UrlClassifierFeatureFingerprintingAnnotation.cpp
author Andrea Marchesini <amarchesini@mozilla.com>
Thu, 14 Mar 2019 17:48:20 +0000
changeset 521916 83534ac4c0eb43b8cfa1c6f93431978fe11ba120
parent 521846 38470d2dd98c7c7528c2756b006205f9c454ac0f
child 526724 a247a37c1e9b6d2277bb6f6466321b26734f6714
permissions -rw-r--r--
Bug 1533074 - Implement Fingerprinting and Cryptomining annotation features - Part 2 - Fingerprinting-annotation, r=dimi Differential Revision: https://phabricator.services.mozilla.com/D22342

/* -*- 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 "UrlClassifierFeatureFingerprintingAnnotation.h"

#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"

namespace mozilla {
namespace net {

namespace {

#define FINGERPRINTING_ANNOTATION_FEATURE_NAME "fingerprinting-annotation"

#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST \
  "urlclassifier.features.fingerprinting.annotate.blacklistTables"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST_TEST_ENTRIES \
  "urlclassifier.features.fingerprinting.annotate.blacklistHosts"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST \
  "urlclassifier.features.fingerprinting.annotate.whitelistTables"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST_TEST_ENTRIES \
  "urlclassifier.features.fingerprinting.annotate.whitelistHosts"
#define TABLE_FINGERPRINTING_ANNOTATION_BLACKLIST_PREF \
  "fingerprinting-annotate-blacklist-pref"
#define TABLE_FINGERPRINTING_ANNOTATION_WHITELIST_PREF \
  "fingerprinting-annotate-whitelist-pref"

StaticRefPtr<UrlClassifierFeatureFingerprintingAnnotation>
    gFeatureFingerprintingAnnotation;

}  // namespace

UrlClassifierFeatureFingerprintingAnnotation::
    UrlClassifierFeatureFingerprintingAnnotation()
    : UrlClassifierFeatureBase(
          NS_LITERAL_CSTRING(FINGERPRINTING_ANNOTATION_FEATURE_NAME),
          NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST),
          NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST),
          NS_LITERAL_CSTRING(
              URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST_TEST_ENTRIES),
          NS_LITERAL_CSTRING(
              URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST_TEST_ENTRIES),
          NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_ANNOTATION_BLACKLIST_PREF),
          NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_ANNOTATION_WHITELIST_PREF),
          EmptyCString()) {}

/* static */ const char* UrlClassifierFeatureFingerprintingAnnotation::Name() {
  return FINGERPRINTING_ANNOTATION_FEATURE_NAME;
}

/* static */
void UrlClassifierFeatureFingerprintingAnnotation::MaybeInitialize() {
  UC_LOG(("UrlClassifierFeatureFingerprintingAnnotation: MaybeInitialize"));

  if (!gFeatureFingerprintingAnnotation) {
    gFeatureFingerprintingAnnotation =
        new UrlClassifierFeatureFingerprintingAnnotation();
    gFeatureFingerprintingAnnotation->InitializePreferences();
  }
}

/* static */
void UrlClassifierFeatureFingerprintingAnnotation::MaybeShutdown() {
  UC_LOG(("UrlClassifierFeatureFingerprintingAnnotation: MaybeShutdown"));

  if (gFeatureFingerprintingAnnotation) {
    gFeatureFingerprintingAnnotation->ShutdownPreferences();
    gFeatureFingerprintingAnnotation = nullptr;
  }
}

/* static */
already_AddRefed<UrlClassifierFeatureFingerprintingAnnotation>
UrlClassifierFeatureFingerprintingAnnotation::MaybeCreate(
    nsIChannel* aChannel) {
  MOZ_ASSERT(aChannel);

  UC_LOG(
      ("UrlClassifierFeatureFingerprintingAnnotation: MaybeCreate for channel "
       "%p",
       aChannel));

  if (!StaticPrefs::
          privacy_trackingprotection_fingerprinting_annotate_enabled()) {
    return nullptr;
  }

  if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) {
    return nullptr;
  }

  MaybeInitialize();
  MOZ_ASSERT(gFeatureFingerprintingAnnotation);

  RefPtr<UrlClassifierFeatureFingerprintingAnnotation> self =
      gFeatureFingerprintingAnnotation;
  return self.forget();
}

/* static */
already_AddRefed<nsIUrlClassifierFeature>
UrlClassifierFeatureFingerprintingAnnotation::GetIfNameMatches(
    const nsACString& aName) {
  if (!aName.EqualsLiteral(FINGERPRINTING_ANNOTATION_FEATURE_NAME)) {
    return nullptr;
  }

  MaybeInitialize();
  MOZ_ASSERT(gFeatureFingerprintingAnnotation);

  RefPtr<UrlClassifierFeatureFingerprintingAnnotation> self =
      gFeatureFingerprintingAnnotation;
  return self.forget();
}

NS_IMETHODIMP
UrlClassifierFeatureFingerprintingAnnotation::ProcessChannel(
    nsIChannel* aChannel, const nsACString& aList, bool* aShouldContinue) {
  NS_ENSURE_ARG_POINTER(aChannel);
  NS_ENSURE_ARG_POINTER(aShouldContinue);

  // This is not a blocking feature.
  *aShouldContinue = true;

  UC_LOG(
      ("UrlClassifierFeatureFingerprintingAnnotation::ProcessChannel, "
       "annotating channel[%p]",
       aChannel));

  UrlClassifierCommon::AnnotateChannel(
      aChannel, AntiTrackingCommon::eFingerprinting,
      nsIHttpChannel::ClassificationFlags::CLASSIFIED_FINGERPRINTING,
      nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT);
  return NS_OK;
}

NS_IMETHODIMP
UrlClassifierFeatureFingerprintingAnnotation::GetURIByListType(
    nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
    nsIURI** aURI) {
  NS_ENSURE_ARG_POINTER(aChannel);
  NS_ENSURE_ARG_POINTER(aURI);

  if (aListType == nsIUrlClassifierFeature::blacklist) {
    return aChannel->GetURI(aURI);
  }

  MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
  return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}

}  // namespace net
}  // namespace mozilla