Bug 1382001 - Part 2: Use a DAFSA for kSTSPreloadList. r=keeler
This switches the STS preload list over to a more compact representation by using a DAFSA. `getHSTSPreloadList.js` is updated to output data in the gperf format expected by `make_dafsa.py`. We then add a generated file that gets created by pumping `nsSTSPreloadList.inc` through `make_dafsa.py`. `nsSiteSecurityService` is updated to use the DAFSA which either returns -1 (kNotFound) if an entry is not present or (0, 1) indicating whether or not to use subdomains. `nsSTSPreloadList.inc` is an automated conversion to the new gperf-like format.
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
// influence its HSTS status via include subdomains, however).
|
||||
// This prevents the preload list from overriding the site's current
|
||||
// desired HSTS status.
|
||||
#include "nsSTSPreloadList.inc"
|
||||
#include "nsSTSPreloadList.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::psm;
|
||||
@@ -495,6 +495,7 @@ nsSiteSecurityService::nsSiteSecurityService()
|
||||
: mMaxMaxAge(kSixtyDaysInSeconds)
|
||||
, mUsePreloadList(true)
|
||||
, mPreloadListTimeOffset(0)
|
||||
, mDafsa(kDafsa)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -730,7 +731,7 @@ nsSiteSecurityService::RemoveStateInternal(
|
||||
mozilla::DataStorage_Persistent);
|
||||
RefPtr<SiteHSTSState> dynamicState =
|
||||
new SiteHSTSState(aHost, aOriginAttributes, value);
|
||||
if (GetPreloadListEntry(aHost.get()) ||
|
||||
if (GetPreloadStatus(aHost) ||
|
||||
dynamicState->mHSTSState != SecurityPropertyUnset) {
|
||||
SSSLOG(("SSS: storing knockout entry for %s", aHost.get()));
|
||||
RefPtr<SiteHSTSState> siteState = new SiteHSTSState(
|
||||
@@ -1370,29 +1371,31 @@ nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI,
|
||||
source, aResult);
|
||||
}
|
||||
|
||||
int STSPreloadCompare(const void *key, const void *entry)
|
||||
// Checks if the given host is in the preload list.
|
||||
//
|
||||
// @param aHost The host to match. Only does exact host matching.
|
||||
// @param aIncludeSubdomains Out, optional. Indicates whether or not to include
|
||||
// subdomains. Only set if the host is matched and this function returns
|
||||
// true.
|
||||
//
|
||||
// @return True if the host is matched, false otherwise.
|
||||
bool
|
||||
nsSiteSecurityService::GetPreloadStatus(const nsACString& aHost,
|
||||
bool* aIncludeSubdomains) const
|
||||
{
|
||||
const char *keyStr = (const char *)key;
|
||||
const nsSTSPreload *preloadEntry = (const nsSTSPreload *)entry;
|
||||
return strcmp(keyStr, &kSTSHostTable[preloadEntry->mHostIndex]);
|
||||
}
|
||||
const int kIncludeSubdomains = 1;
|
||||
bool found = false;
|
||||
|
||||
// Returns the preload list entry for the given host, if it exists.
|
||||
// Only does exact host matching - the user must decide how to use the returned
|
||||
// data. May return null.
|
||||
const nsSTSPreload *
|
||||
nsSiteSecurityService::GetPreloadListEntry(const char *aHost)
|
||||
{
|
||||
PRTime currentTime = PR_Now() + (mPreloadListTimeOffset * PR_USEC_PER_SEC);
|
||||
if (mUsePreloadList && currentTime < gPreloadListExpirationTime) {
|
||||
return (const nsSTSPreload *) bsearch(aHost,
|
||||
kSTSPreloadList,
|
||||
mozilla::ArrayLength(kSTSPreloadList),
|
||||
sizeof(nsSTSPreload),
|
||||
STSPreloadCompare);
|
||||
int result = mDafsa.Lookup(aHost);
|
||||
found = (result != mozilla::Dafsa::kKeyNotFound);
|
||||
if (found && aIncludeSubdomains) {
|
||||
*aIncludeSubdomains = (result == kIncludeSubdomains);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return found;
|
||||
}
|
||||
|
||||
// Allows us to determine if we have an HSTS entry for a given host (and, if
|
||||
@@ -1476,7 +1479,7 @@ nsSiteSecurityService::HostHasHSTSEntry(
|
||||
if (dynamicState->mHSTSState == SecurityPropertyUnset) {
|
||||
SSSLOG(("No dynamic preload - checking for static preload"));
|
||||
// Now check the static preload list.
|
||||
if (!GetPreloadListEntry(aHost.get())) {
|
||||
if (!GetPreloadStatus(aHost)) {
|
||||
SSSLOG(("No static preload - removing expired entry"));
|
||||
mSiteStateStorage->Remove(storageKey, storageType);
|
||||
}
|
||||
@@ -1520,7 +1523,7 @@ nsSiteSecurityService::HostHasHSTSEntry(
|
||||
} else {
|
||||
// if a dynamic preload has expired and is not in the static preload
|
||||
// list, we can remove it.
|
||||
if (!GetPreloadListEntry(aHost.get())) {
|
||||
if (!GetPreloadStatus(aHost)) {
|
||||
mPreloadStateStorage->Remove(preloadKey,
|
||||
mozilla::DataStorage_Persistent);
|
||||
}
|
||||
@@ -1528,18 +1531,18 @@ nsSiteSecurityService::HostHasHSTSEntry(
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsSTSPreload* preload = nullptr;
|
||||
bool includeSubdomains = false;
|
||||
|
||||
// Finally look in the static preload list.
|
||||
if (siteState->mHSTSState == SecurityPropertyUnset &&
|
||||
dynamicState->mHSTSState == SecurityPropertyUnset &&
|
||||
(preload = GetPreloadListEntry(aHost.get())) != nullptr) {
|
||||
GetPreloadStatus(aHost, &includeSubdomains)) {
|
||||
SSSLOG(("%s is a preloaded HSTS host", aHost.get()));
|
||||
*aResult = aRequireIncludeSubdomains ? preload->mIncludeSubdomains
|
||||
*aResult = aRequireIncludeSubdomains ? includeSubdomains
|
||||
: true;
|
||||
if (aCached) {
|
||||
// Only set cached if this includes subdomains
|
||||
*aCached = aRequireIncludeSubdomains ? preload->mIncludeSubdomains
|
||||
*aCached = aRequireIncludeSubdomains ? includeSubdomains
|
||||
: true;
|
||||
}
|
||||
if (aSource) {
|
||||
|
||||
Reference in New Issue
Block a user