/* -*- 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 https://mozilla.org/MPL/2.0/. */ #ifndef _nsRFPService_h_ #define _nsRFPService_h_ #include #include #include "ErrorList.h" #include "PLDHashTable.h" #include "mozilla/BasicEvents.h" #include "mozilla/gfx/Types.h" #include "mozilla/TypedEnumBits.h" #include "mozilla/dom/MediaDeviceInfoBinding.h" #include "mozilla/dom/ScreenOrientationBinding.h" #include "js/RealmOptions.h" #include "nsHashtablesFwd.h" #include "nsICookieJarSettings.h" #include "nsIFingerprintingWebCompatService.h" #include "nsIObserver.h" #include "nsISupports.h" #include "nsIRFPService.h" #include "nsStringFwd.h" #include // Defines regarding spoofed values of Navigator object. These spoofed values // are returned when 'privacy.resistFingerprinting' is true. // We decided to give different spoofed values according to the platform. The // reason is that it is easy to detect the real platform. So there is no benefit // for hiding the platform: it only brings breakages, like keyboard shortcuts // won't work in macOS if we spoof it as a Windows platform. // We use this value for Desktop mode in Android. // That's why it is defined here, outside of // the platform-specific definitions. #define SPOOFED_UA_OS_OTHER "X11; Linux x86_64" #ifdef XP_WIN # define SPOOFED_UA_OS "Windows NT 10.0; Win64; x64" # define SPOOFED_APPVERSION "5.0 (Windows)" # define SPOOFED_OSCPU "Windows NT 10.0; Win64; x64" # define SPOOFED_MAX_TOUCH_POINTS 10 #elif defined(XP_MACOSX) # define SPOOFED_UA_OS "Macintosh; Intel Mac OS X 10.15" # define SPOOFED_APPVERSION "5.0 (Macintosh)" # define SPOOFED_OSCPU "Intel Mac OS X 10.15" # define SPOOFED_MAX_TOUCH_POINTS 0 #elif defined(MOZ_WIDGET_ANDROID) # define SPOOFED_UA_OS "Android 10; Mobile" # define SPOOFED_APPVERSION "5.0 (Android 10)" # define SPOOFED_OSCPU "Linux armv81" # define SPOOFED_MAX_TOUCH_POINTS 5 #else // For Linux and other platforms, like BSDs, SunOS and etc, we will use Linux // platform. # define SPOOFED_UA_OS SPOOFED_UA_OS_OTHER # define SPOOFED_APPVERSION "5.0 (X11)" # define SPOOFED_OSCPU "Linux x86_64" # define SPOOFED_MAX_TOUCH_POINTS 5 #endif #define LEGACY_BUILD_ID "20181001000000" #define LEGACY_UA_GECKO_TRAIL "20100101" #define SPOOFED_POINTER_INTERFACE MouseEvent_Binding::MOZ_SOURCE_MOUSE struct JSContext; class nsIChannel; class nsICanvasRenderingContextInternal; namespace mozilla { class WidgetKeyboardEvent; class OriginAttributes; class OriginAttributesPattern; namespace dom { class Document; enum class CanvasContextType : uint8_t; } // namespace dom namespace gfx { class DataSourceSurface; } // namespace gfx enum KeyboardLang { EN = 0x01 }; #define RFP_KEYBOARD_LANG_STRING_EN "en" typedef uint8_t KeyboardLangs; enum KeyboardRegion { US = 0x01 }; #define RFP_KEYBOARD_REGION_STRING_US "US" typedef uint8_t KeyboardRegions; // This struct has the information about how to spoof the keyboardEvent.code, // keyboardEvent.keycode and modifier states. struct SpoofingKeyboardCode { CodeNameIndex mCode; uint8_t mKeyCode; Modifiers mModifierStates; }; struct SpoofingKeyboardInfo { nsString mKey; KeyNameIndex mKeyIdx; SpoofingKeyboardCode mSpoofingCode; }; class KeyboardHashKey : public PLDHashEntryHdr { public: typedef const KeyboardHashKey& KeyType; typedef const KeyboardHashKey* KeyTypePointer; KeyboardHashKey(const KeyboardLangs aLang, const KeyboardRegions aRegion, const KeyNameIndex aKeyIdx, const nsAString& aKey); explicit KeyboardHashKey(KeyTypePointer aOther); KeyboardHashKey(KeyboardHashKey&& aOther) noexcept; ~KeyboardHashKey(); bool KeyEquals(KeyTypePointer aOther) const; static KeyTypePointer KeyToPointer(KeyType aKey); static PLDHashNumber HashKey(KeyTypePointer aKey); enum { ALLOW_MEMMOVE = true }; KeyboardLangs mLang; KeyboardRegions mRegion; KeyNameIndex mKeyIdx; nsString mKey; }; // ============================================================================ // Reduce Timer Precision (RTP) Caller Type enum class RTPCallerType : uint8_t { Normal = 0, SystemPrincipal = (1 << 0), ResistFingerprinting = (1 << 1), CrossOriginIsolated = (1 << 2) }; inline JS::RTPCallerTypeToken RTPCallerTypeToToken(RTPCallerType aType) { return JS::RTPCallerTypeToken{uint8_t(aType)}; } inline RTPCallerType RTPCallerTypeFromToken(JS::RTPCallerTypeToken aToken) { MOZ_RELEASE_ASSERT( aToken.value == uint8_t(RTPCallerType::Normal) || aToken.value == uint8_t(RTPCallerType::SystemPrincipal) || aToken.value == uint8_t(RTPCallerType::ResistFingerprinting) || aToken.value == uint8_t(RTPCallerType::CrossOriginIsolated)); return static_cast(aToken.value); } enum TimerPrecisionType { DangerouslyNone = 1, UnconditionalAKAHighRes = 2, Normal = 3, RFP = 4, }; // ============================================================================ enum class CanvasFeatureUsage : uint64_t { None = 0, KnownText_1 = 1llu << 0, KnownText_2 = 1llu << 1, KnownText_3 = 1llu << 2, KnownText_4 = 1llu << 3, KnownText_5 = 1llu << 4, KnownText_6 = 1llu << 5, KnownText_7 = 1llu << 6, KnownText_8 = 1llu << 7, KnownText_9 = 1llu << 8, KnownText_10 = 1llu << 9, KnownText_11 = 1llu << 10, KnownText_12 = 1llu << 11, KnownText_13 = 1llu << 12, KnownText_14 = 1llu << 13, KnownText_15 = 1llu << 14, KnownText_16 = 1llu << 15, KnownText_17 = 1llu << 16, KnownText_18 = 1llu << 17, KnownText_19 = 1llu << 18, KnownText_20 = 1llu << 19, KnownText_21 = 1llu << 20, KnownText_22 = 1llu << 21, KnownText_23 = 1llu << 22, KnownText_24 = 1llu << 23, KnownText_25 = 1llu << 24, KnownText_26 = 1llu << 25, KnownText_27 = 1llu << 26, KnownText_28 = 1llu << 27, KnownText_29 = 1llu << 28, KnownText_30 = 1llu << 29, KnownText_31 = 1llu << 30, KnownText_32 = 1llu << 31, SetFont = 1llu << 32, FillRect = 1llu << 33, LineTo = 1llu << 34, Stroke = 1llu << 35, }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CanvasFeatureUsage); // We try to classify observed canvas fingerprinting scripts into different // classes, but we don't usually know the source/vendor of those scripts. The // classification is based on a behavioral analysis covering things like the // functions called and size of the canvas. The alias given is a guess and // should not be considered definitive. The entity identified may not be doing // this behavior at all, they may be doing a diferent or additional behaviors. enum CanvasFingerprinterAlias { eNoneIdentified = 0, eFingerprintJS = 1, eAkamai = 2, eOzoki = 3, ePerimeterX = 4, eSignifyd = 5, eClaydar = 6, eForter = 7, // Variants are unknown but distinct types of fingerprinters eVariant1 = 8, eVariant2 = 9, eVariant3 = 10, eVariant4 = 11, eVariant5 = 12, eVariant6 = 13, eVariant7 = 14, eVariant8 = 15, eClientGear = 16, eImperva = 17, eLastAlias = eImperva }; enum CanvasExtractionAPI : uint8_t { ToDataURL = 0, ToBlob = 1, GetImageData = 2, ReadPixels = 3 }; enum CanvasUsageSource : uint64_t { Unknown = 0, Impossible = 1llu << 0, // This represents API calls that I don't believe are possible MainThread_Canvas_ImageBitmap_toDataURL = 1llu << 1, MainThread_Canvas_ImageBitmap_toBlob = 1llu << 2, MainThread_Canvas_ImageBitmap_getImageData = 1llu << 3, MainThread_Canvas_Canvas2D_toDataURL = 1llu << 4, MainThread_Canvas_Canvas2D_toBlob = 1llu << 5, MainThread_Canvas_Canvas2D_getImageData = 1llu << 6, MainThread_Canvas_WebGL_toDataURL = 1llu << 7, MainThread_Canvas_WebGL_toBlob = 1llu << 8, MainThread_Canvas_WebGL_getImageData = 1llu << 9, MainThread_Canvas_WebGL_readPixels = 1llu << 10, MainThread_Canvas_WebGPU_toDataURL = 1llu << 11, MainThread_Canvas_WebGPU_toBlob = 1llu << 12, MainThread_Canvas_WebGPU_getImageData = 1llu << 13, MainThread_OffscreenCanvas_ImageBitmap_toDataURL = 1llu << 14, MainThread_OffscreenCanvas_ImageBitmap_toBlob = 1llu << 15, MainThread_OffscreenCanvas_ImageBitmap_getImageData = 1llu << 16, MainThread_OffscreenCanvas_Canvas2D_toDataURL = 1llu << 17, MainThread_OffscreenCanvas_Canvas2D_toBlob = 1llu << 18, MainThread_OffscreenCanvas_Canvas2D_getImageData = 1llu << 19, MainThread_OffscreenCanvas_WebGL_toDataURL = 1llu << 20, MainThread_OffscreenCanvas_WebGL_toBlob = 1llu << 21, MainThread_OffscreenCanvas_WebGL_getImageData = 1llu << 22, MainThread_OffscreenCanvas_WebGL_readPixels = 1llu << 23, MainThread_OffscreenCanvas_WebGPU_toDataURL = 1llu << 24, MainThread_OffscreenCanvas_WebGPU_toBlob = 1llu << 25, MainThread_OffscreenCanvas_WebGPU_getImageData = 1llu << 26, Worker_OffscreenCanvas_ImageBitmap_toBlob = 1llu << 27, Worker_OffscreenCanvas_ImageBitmap_getImageData = 1llu << 28, Worker_OffscreenCanvas_Canvas2D_toBlob = 1llu << 29, Worker_OffscreenCanvas_Canvas2D_getImageData = 1llu << 30, Worker_OffscreenCanvasCanvas2D_Canvas2D_toBlob = 1llu << 31, Worker_OffscreenCanvasCanvas2D_Canvas2D_getImageData = 1llu << 32, Worker_OffscreenCanvas_WebGL_toBlob = 1llu << 33, Worker_OffscreenCanvas_WebGL_getImageData = 1llu << 34, Worker_OffscreenCanvas_WebGL_readPixels = 1llu << 35, Worker_OffscreenCanvas_WebGPU_toBlob = 1llu << 36, Worker_OffscreenCanvas_WebGPU_getImageData = 1llu << 37, // --- New entires added here to preserve original values (no reordering!) MainThread_Canvas_OffscreenCanvas2D_getImageData = 1llu << 38, MainThread_Canvas_OffscreenCanvas2D_toBlob = 1llu << 39, // After you go past 40 - metrics.yaml will need to be updated }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CanvasUsageSource); nsCString CanvasUsageSourceToString(CanvasUsageSource aSource); class CanvasUsage { public: CSSIntSize mSize; dom::CanvasContextType mType; CanvasUsageSource mUsageSource; CanvasFeatureUsage mFeatureUsage; CanvasUsage(CSSIntSize aSize, dom::CanvasContextType aType, CanvasUsageSource aUsageSource, CanvasFeatureUsage aFeatureUsage) : mSize(aSize), mType(aType), mUsageSource(aUsageSource), mFeatureUsage(aFeatureUsage) {} static CanvasUsage CreateUsage( bool aIsOffscreen, dom::CanvasContextType aContextType, CanvasExtractionAPI aApi, CSSIntSize aSize, const nsICanvasRenderingContextInternal* aContext); static inline CanvasUsageSource GetCanvasUsageSource( bool isOffscreen, dom::CanvasContextType contextType, CanvasExtractionAPI api); }; struct CanvasFingerprintingEvent { // The identity or alias of the entity doing the fingerprinting. CanvasFingerprinterAlias alias; // A bitmask of all of the known canvas fingerprinting texts // non-zero indicates some known fingerprinting text was used, making the // event highly likely to be fingerprinting. uint32_t knownTextBitmask; // A bitmap of all the sources that were used to extract canvas data uint64_t sourcesBitmask; CanvasFingerprintingEvent() : alias(CanvasFingerprinterAlias::eNoneIdentified), knownTextBitmask(0), sourcesBitmask(0) {} CanvasFingerprintingEvent(CanvasFingerprinterAlias aAlias, uint32_t aKnownTextBitmask, uint64_t aSourcesBitmask) : alias(aAlias), knownTextBitmask(aKnownTextBitmask), sourcesBitmask(aSourcesBitmask) {} bool operator==(const CanvasFingerprintingEvent& other) const { return alias == other.alias && knownTextBitmask == other.knownTextBitmask && sourcesBitmask == other.sourcesBitmask; } }; // ============================================================================ // NOLINTNEXTLINE(bugprone-macro-parentheses) #define ITEM_VALUE(name, val) name = val, // The definition for fingerprinting protections. Each enum represents one // fingerprinting protection that targets one specific WebAPI our fingerprinting // surface. The enums can be found in RFPTargets.inc. enum class RFPTarget : uint64_t { #include "RFPTargets.inc" }; #undef ITEM_VALUE using RFPTargetSet = EnumSet>; template <> struct MaxEnumValue { static constexpr unsigned int value = 127; }; // ============================================================================ class nsRFPService final : public nsIObserver, public nsIRFPService { public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER NS_DECL_NSIRFPSERVICE static already_AddRefed GetOrCreate(); // _Rarely_ you will need to know if RFP is enabled, or if FPP is enabled. // 98% of the time you should use nsContentUtils::ShouldResistFingerprinting // as the difference will not matter to you. static bool IsRFPPrefEnabled(bool aIsPrivateMode); static bool IsRFPEnabledFor( bool aIsPrivateMode, RFPTarget aTarget, const Maybe& aOverriddenFingerprintingSettings); static bool IsSystemPrincipalOrAboutFingerprintingProtection(JSContext*, JSObject*); // -------------------------------------------------------------------------- static double TimerResolution(RTPCallerType aRTPCallerType); enum TimeScale { Seconds = 1, MilliSeconds = 1000, MicroSeconds = 1000000 }; // The following Reduce methods can be called off main thread. static double ReduceTimePrecisionAsUSecs(double aTime, int64_t aContextMixin, RTPCallerType aRTPCallerType); static double ReduceTimePrecisionAsMSecs(double aTime, int64_t aContextMixin, RTPCallerType aRTPCallerType); static double ReduceTimePrecisionAsMSecsRFPOnly(double aTime, int64_t aContextMixin, RTPCallerType aRTPCallerType); static double ReduceTimePrecisionAsSecs(double aTime, int64_t aContextMixin, RTPCallerType aRTPCallerType); static double ReduceTimePrecisionAsSecsRFPOnly(double aTime, int64_t aContextMixin, RTPCallerType aRTPCallerType); // Public only for testing purposes static double ReduceTimePrecisionImpl(double aTime, TimeScale aTimeScale, double aResolutionUSec, int64_t aContextMixin, TimerPrecisionType aType); static nsresult RandomMidpoint(long long aClampedTimeUSec, long long aResolutionUSec, int64_t aContextMixin, long long* aMidpointOut, uint8_t* aSecretSeed = nullptr); // -------------------------------------------------------------------------- // This method calculates the video resolution (i.e. height x width) based // on the video quality (480p, 720p, etc). static uint32_t CalculateTargetVideoResolution(uint32_t aVideoQuality); // Methods for getting spoofed media statistics and the return value will // depend on the video resolution. static uint32_t GetSpoofedTotalFrames(double aTime); static uint32_t GetSpoofedDroppedFrames(double aTime, uint32_t aWidth, uint32_t aHeight); static uint32_t GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t aHeight); // -------------------------------------------------------------------------- // This method generates the spoofed value of User Agent. static void GetSpoofedUserAgent(nsACString& userAgent, bool aAndroidDesktopMode = false); // -------------------------------------------------------------------------- // This method generates the locale string (e.g. "en-US") that should be // spoofed by the JavaScript engine. static nsCString GetSpoofedJSLocale(); // -------------------------------------------------------------------------- // This method generates the time zone string (e.g. "Atlantic/Reykjavik") that // should be spoofed by the JavaScript engine. static nsCString GetSpoofedJSTimeZone(); // -------------------------------------------------------------------------- /** * This method for getting spoofed modifier states for the given keyboard * event. * * @param aDoc [in] the owner's document for getting content * language. * @param aKeyboardEvent [in] the keyboard event that needs to be spoofed. * @param aModifier [in] the modifier that needs to be spoofed. * @param aOut [out] the spoofed state for the given modifier. * @return true if there is a spoofed state for the modifier. */ static bool GetSpoofedModifierStates( const mozilla::dom::Document* aDoc, const WidgetKeyboardEvent* aKeyboardEvent, const Modifiers aModifier, bool& aOut); /** * This method for getting spoofed code for the given keyboard event. * * @param aDoc [in] the owner's document for getting content * language. * @param aKeyboardEvent [in] the keyboard event that needs to be spoofed. * @param aOut [out] the spoofed code. * @return true if there is a spoofed code in the fake keyboard * layout. */ static bool GetSpoofedCode(const dom::Document* aDoc, const WidgetKeyboardEvent* aKeyboardEvent, nsAString& aOut); /** * This method for getting spoofed keyCode for the given keyboard event. * * @param aDoc [in] the owner's document for getting content * language. * @param aKeyboardEvent [in] the keyboard event that needs to be spoofed. * @param aOut [out] the spoofed keyCode. * @return true if there is a spoofed keyCode in the fake * keyboard layout. */ static bool GetSpoofedKeyCode(const mozilla::dom::Document* aDoc, const WidgetKeyboardEvent* aKeyboardEvent, uint32_t& aOut); // -------------------------------------------------------------------------- // The method to generate the key for randomization. It can return nothing if // the session key is not available due to the randomization is disabled. static Maybe> GenerateKey(nsIChannel* aChannel); static Maybe> GenerateKeyForServiceWorker( nsIURI* aFirstPartyURI, nsIPrincipal* aPrincipal, bool aForeignByAncestorContext); static void PotentiallyDumpImage(nsIPrincipal* aPrincipal, gfx::DataSourceSurface* aSurface); static void PotentiallyDumpImage(nsIPrincipal* aPrincipal, uint8_t* aData, uint32_t aWidth, uint32_t aHeight, uint32_t aSize); // This function is plumbed to RandomizeElements function. static nsresult RandomizePixels(nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal, uint8_t* aData, uint32_t aWidth, uint32_t aHeight, uint32_t aSize, mozilla::gfx::SurfaceFormat aSurfaceFormat); // This function is used to randomize the elements in the given data // according to the given parameters. For example, for an RGBA pixel, by group // in this context, we refer to a single pixel and by element, we refer to // channels. So, if we have an RGBA pixel, we have 4 elements per group, i.e. // 4 channels per pixel. We use aElementsPerGroup to randomize at most one of // elements per group, i.e. one channel per pixel. static nsresult RandomizeElements( nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal, uint8_t* aData, uint32_t aSizeInBytes, uint8_t aElementsPerGroup, uint8_t aBytesPerElement, uint8_t aElementOffset, bool aSkipLastElement); // -------------------------------------------------------------------------- // The method for getting the granular fingerprinting protection override of // the given channel. Due to WebCompat reason, there can be a granular // overrides to replace default enabled RFPTargets for the context of the // channel. The method will return Nothing() to indicate using the default // RFPTargets static Maybe GetOverriddenFingerprintingSettingsForChannel( nsIChannel* aChannel); // The method for getting the granular fingerprinting protection override of // the given first-party and third-party URIs. It will return the granular // overrides if there is one defined for the context of the first-party URI // and third-party URI. Otherwise, it will return Nothing() to indicate using // the default RFPTargets. static Maybe GetOverriddenFingerprintingSettingsForURI( nsIURI* aFirstPartyURI, nsIURI* aThirdPartyURI, bool aIsPrivate); // -------------------------------------------------------------------------- static void MaybeReportCanvasFingerprinter(nsTArray& aUses, nsIChannel* aChannel, nsIURI* aURI, const nsACString& aOriginNoSuffix); static void MaybeReportFontFingerprinter(nsIChannel* aChannel, nsIURI* aURI, const nsACString& aOriginNoSuffix); // -------------------------------------------------------------------------- // Generates a fake media device name with given kind and index. // Example: Internal Microphone static void GetMediaDeviceName(nsString& aName, mozilla::dom::MediaDeviceKind aKind); // Generates a fake media device group name with given kind and index. // Example: Audio Group static void GetMediaDeviceGroup(nsString& aGroup, mozilla::dom::MediaDeviceKind aKind); // Converts the viewport size to the angle. static uint16_t ViewportSizeToAngle(int32_t aWidth, int32_t aHeight); // Converts the viewport size to the orientation type. static dom::OrientationType ViewportSizeToOrientationType(int32_t aWidth, int32_t aHeight); // Returns the default orientation type for the given platform. static dom::OrientationType GetDefaultOrientationType(); // Returns the default pixel density for RFP. static float GetDefaultPixelDensity(); // Returns the device pixel ratio at the given zoom level. static double GetDevicePixelRatioAtZoom(float aZoom); // Returns the value of privacy.resistFingerprinting.exemptedDomains pref static void GetExemptedDomainsLowercase(nsCString& aExemptedDomains); static CSSIntRect GetSpoofedScreenAvailSize(const nsRect& aRect, float aScale, bool aIsFullscreen); static uint64_t GetSpoofedStorageLimit(); static bool ExposeWebCodecsAPI(JSContext* aCx, JSObject* aObj); static bool ExposeWebCodecsAPIImageDecoder(JSContext* aCx, JSObject* aObj); static bool IsWebCodecsRFPTargetEnabled(JSContext* aCx); static uint32_t CollapseMaxTouchPoints(uint32_t aMaxTouchPoints); static void CalculateFontLocaleAllowlist(); static bool FontIsAllowedByLocale(const nsACString& aName); static Maybe TextToRFPTarget(const nsAString& aText); static void GetFingerprintingRandomizationKeyAsString( nsICookieJarSettings* aCookieJarSettings, nsACString& aRandomizationKeyStr); static nsresult GenerateRandomizationKeyFromHash( const nsACString& aRandomizationKeyStr, uint32_t aContentHash, nsACString& aHex); private: nsresult Init(); nsRFPService() = default; ~nsRFPService() = default; void UpdateFPPOverrideList(); void StartShutdown(); void PrefChanged(const char* aPref); static void PrefChanged(const char* aPref, void* aSelf); // -------------------------------------------------------------------------- static void MaybeCreateSpoofingKeyCodes(const KeyboardLangs aLang, const KeyboardRegions aRegion); static void MaybeCreateSpoofingKeyCodesForEnUS(); static void GetKeyboardLangAndRegion(const nsAString& aLanguage, KeyboardLangs& aLocale, KeyboardRegions& aRegion); static bool GetSpoofedKeyCodeInfo(const mozilla::dom::Document* aDoc, const WidgetKeyboardEvent* aKeyboardEvent, SpoofingKeyboardCode& aOut); static nsTHashMap* sSpoofingKeyboardCodes; // -------------------------------------------------------------------------- // Used by the JS Engine static double ReduceTimePrecisionAsUSecsWrapper( double aTime, JS::RTPCallerTypeToken aCallerType, JSContext* aCx); static TimerPrecisionType GetTimerPrecisionType(RTPCallerType aRTPCallerType); static TimerPrecisionType GetTimerPrecisionTypeRFPOnly( RTPCallerType aRTPCallerType); static void TypeToText(TimerPrecisionType aType, nsACString& aText); // -------------------------------------------------------------------------- // A helper function to generate canvas key from the given image data and // randomization key. static nsresult GenerateCanvasKeyFromImageData( nsICookieJarSettings* aCookieJarSettings, uint8_t* aImageData, uint32_t aSize, nsTArray& aCanvasKey); // Generate the session key if it hasn't been generated. nsresult GetBrowsingSessionKey(const OriginAttributes& aOriginAttributes, nsID& aBrowsingSessionKey); void ClearBrowsingSessionKey(const OriginAttributesPattern& aPattern); void ClearBrowsingSessionKey(const OriginAttributes& aOriginAttributes); // The keys that represent the browsing session. The lifetime of the key ties // to the browsing session. For normal windows, the key is generated when // loading the first http channel after the browser startup and persists until // the browser shuts down. For private windows, the key is generated when // opening a http channel on a private window and reset after all private // windows close, i.e. private browsing session ends. // // The key will be used to generate the randomization noise used to fiddle the // browser fingerprints. Note that this key lives and can only be accessed in // the parent process. nsTHashMap mBrowsingSessionKeys; nsCOMPtr mWebCompatService; nsTHashMap mFingerprintingOverrides; // A helper function to create the domain key for the fingerprinting // overrides. The key can be in the following five formats. // 1. {first-party domain}: The override only apply to the first-party domain. // 2. {first-party domain, *}: The overrides apply to every contexts under the // top-level domain, including itself. // 3. {*, third-party domain}: The overrides apply to the third-party domain // under any top-level domain. // 4. {first-party domain, third-party domain}: the overrides apply to the // specific third-party domain under the given first-party domain. // 5. {*}: A global overrides that will apply to every context. static nsresult CreateOverrideDomainKey(nsIFingerprintingOverride* aOverride, nsACString& aDomainKey); // A helper function to create the RFPTarget bitfield based on the given // overrides text and the based overrides bitfield. The function will parse // the text and update the based overrides bitfield accordingly. Then, it will // return the updated bitfield. static RFPTargetSet CreateOverridesFromText( const nsString& aOverridesText, RFPTargetSet aBaseOverrides = RFPTargetSet()); enum FingerprintingProtectionType : uint8_t { RFP, FPP, Baseline, None, }; static FingerprintingProtectionType GetFingerprintingProtectionType( bool aIsPrivateMode); static Maybe HandleExceptionalRFPTargets( RFPTarget aTarget, bool aIsPrivateMode, FingerprintingProtectionType aMode); static bool IsTargetActiveForMode(RFPTarget aTarget, FingerprintingProtectionType aMode); static nsCString* sExemptedDomainsLowercase; }; } // namespace mozilla #endif /* _nsRFPService_h_ */