mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changesets 5f8a88c6d0c8 and 97fcb5a154d8 (bug 887052) for OSX mochitest-other orange.
--HG-- rename : netwerk/base/public/nsISiteSecurityService.idl => netwerk/base/public/nsIStrictTransportSecurityService.idl rename : security/manager/boot/src/nsSiteSecurityService.cpp => security/manager/boot/src/nsStrictTransportSecurityService.cpp rename : security/manager/boot/src/nsSiteSecurityService.h => security/manager/boot/src/nsStrictTransportSecurityService.h
This commit is contained in:
parent
cb73405190
commit
f5e9dc8c73
@ -1230,14 +1230,14 @@ function test41()
|
|||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||||
var thehost = ios.newURI("http://example.com", null, null);
|
var thehost = ios.newURI("http://example.com", null, null);
|
||||||
var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
|
var stss = Cc["@mozilla.org/stsservice;1"].getService(Ci.nsIStrictTransportSecurityService);
|
||||||
var loadContext = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
var loadContext = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
.QueryInterface(Ci.nsILoadContext);
|
.QueryInterface(Ci.nsILoadContext);
|
||||||
var flags = 0;
|
var flags = 0;
|
||||||
if (loadContext.usePrivateBrowsing)
|
if (loadContext.usePrivateBrowsing)
|
||||||
flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
|
flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
|
||||||
sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags);
|
stss.removeStsState(thehost, flags);
|
||||||
doTest(42);
|
doTest(42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@
|
|||||||
#include "nsIDOMHTMLAnchorElement.h"
|
#include "nsIDOMHTMLAnchorElement.h"
|
||||||
#include "nsIWebBrowserChrome3.h"
|
#include "nsIWebBrowserChrome3.h"
|
||||||
#include "nsITabChild.h"
|
#include "nsITabChild.h"
|
||||||
#include "nsISiteSecurityService.h"
|
#include "nsIStrictTransportSecurityService.h"
|
||||||
#include "nsStructuredCloneContainer.h"
|
#include "nsStructuredCloneContainer.h"
|
||||||
#include "nsIStructuredCloneContainer.h"
|
#include "nsIStructuredCloneContainer.h"
|
||||||
#ifdef MOZ_PLACES
|
#ifdef MOZ_PLACES
|
||||||
@ -4266,15 +4266,14 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||||||
|
|
||||||
// if this is a Strict-Transport-Security host and the cert
|
// if this is a Strict-Transport-Security host and the cert
|
||||||
// is bad, don't allow overrides (STS Spec section 7.3).
|
// is bad, don't allow overrides (STS Spec section 7.3).
|
||||||
nsCOMPtr<nsISiteSecurityService> sss =
|
nsCOMPtr<nsIStrictTransportSecurityService> stss =
|
||||||
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
|
do_GetService(NS_STSSERVICE_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
uint32_t flags =
|
uint32_t flags =
|
||||||
mInPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
mInPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
||||||
|
|
||||||
bool isStsHost = false;
|
bool isStsHost = false;
|
||||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS,
|
rv = stss->IsStsURI(aURI, flags, &isStsHost);
|
||||||
aURI, flags, &isStsHost);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
uint32_t bucketId;
|
uint32_t bucketId;
|
||||||
|
@ -85,7 +85,6 @@ XPIDL_SOURCES += [
|
|||||||
'nsISerializationHelper.idl',
|
'nsISerializationHelper.idl',
|
||||||
'nsIServerSocket.idl',
|
'nsIServerSocket.idl',
|
||||||
'nsISimpleStreamListener.idl',
|
'nsISimpleStreamListener.idl',
|
||||||
'nsISiteSecurityService.idl',
|
|
||||||
'nsISocketTransport.idl',
|
'nsISocketTransport.idl',
|
||||||
'nsISocketTransportService.idl',
|
'nsISocketTransportService.idl',
|
||||||
'nsISpeculativeConnect.idl',
|
'nsISpeculativeConnect.idl',
|
||||||
@ -94,6 +93,7 @@ XPIDL_SOURCES += [
|
|||||||
'nsIStreamListenerTee.idl',
|
'nsIStreamListenerTee.idl',
|
||||||
'nsIStreamLoader.idl',
|
'nsIStreamLoader.idl',
|
||||||
'nsIStreamTransportService.idl',
|
'nsIStreamTransportService.idl',
|
||||||
|
'nsIStrictTransportSecurityService.idl',
|
||||||
'nsISyncStreamListener.idl',
|
'nsISyncStreamListener.idl',
|
||||||
'nsISystemProxySettings.idl',
|
'nsISystemProxySettings.idl',
|
||||||
'nsIThreadRetargetableRequest.idl',
|
'nsIThreadRetargetableRequest.idl',
|
||||||
|
@ -8,13 +8,9 @@ interface nsIURI;
|
|||||||
interface nsIObserver;
|
interface nsIObserver;
|
||||||
interface nsIHttpChannel;
|
interface nsIHttpChannel;
|
||||||
|
|
||||||
[scriptable, uuid(b20a9242-5732-45bc-9fa0-a178154f2721)]
|
[scriptable, uuid(c6138514-f212-4747-98c2-7abfce3be293)]
|
||||||
interface nsISiteSecurityService : nsISupports
|
interface nsIStrictTransportSecurityService : nsISupports
|
||||||
{
|
{
|
||||||
const uint32_t HEADER_HSTS = 0;
|
|
||||||
const uint32_t HEADER_HKPK = 1;
|
|
||||||
const uint32_t HEADER_OMS = 2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a given HTTP header and records the results internally.
|
* Parses a given HTTP header and records the results internally.
|
||||||
* The format of the STS header is defined by the STS specification:
|
* The format of the STS header is defined by the STS specification:
|
||||||
@ -33,12 +29,11 @@ interface nsISiteSecurityService : nsISupports
|
|||||||
* NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
|
* NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
|
||||||
* if there are unrecognized tokens in the header.
|
* if there are unrecognized tokens in the header.
|
||||||
*/
|
*/
|
||||||
void processHeader(in uint32_t aType,
|
void processStsHeader(in nsIURI aSourceURI,
|
||||||
in nsIURI aSourceURI,
|
in string aHeader,
|
||||||
in string aHeader,
|
in uint32_t aFlags,
|
||||||
in uint32_t aFlags,
|
[optional] out unsigned long long aMaxAge,
|
||||||
[optional] out unsigned long long aMaxAge,
|
[optional] out boolean aIncludeSubdomains);
|
||||||
[optional] out boolean aIncludeSubdomains);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the STS state of a host, including the includeSubdomains state
|
* Removes the STS state of a host, including the includeSubdomains state
|
||||||
@ -48,15 +43,25 @@ interface nsISiteSecurityService : nsISupports
|
|||||||
* @param aFlags options for this request as defined in nsISocketProvider:
|
* @param aFlags options for this request as defined in nsISocketProvider:
|
||||||
* NO_PERMANENT_STORAGE
|
* NO_PERMANENT_STORAGE
|
||||||
*/
|
*/
|
||||||
void removeState(in uint32_t aType,
|
void removeStsState(in nsIURI aURI,
|
||||||
in nsIURI aURI,
|
in uint32_t aFlags);
|
||||||
in uint32_t aFlags);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given security info is for an STS host with a broken
|
* Checks if the given security info is for an STS host with a broken
|
||||||
* transport layer (certificate errors like invalid CN).
|
* transport layer (certificate errors like invalid CN).
|
||||||
*/
|
*/
|
||||||
boolean shouldIgnoreHeader(in nsISupports aSecurityInfo);
|
boolean shouldIgnoreStsHeader(in nsISupports aSecurityInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether or not the given hostname has STS state set.
|
||||||
|
* The host is an STS host if either it has the STS permission, or one of
|
||||||
|
* its super-domains has an STS "includeSubdomains" permission set.
|
||||||
|
*
|
||||||
|
* @param aHost the hostname (punycode) to query for STS state.
|
||||||
|
* @param aFlags options for this request as defined in nsISocketProvider:
|
||||||
|
* NO_PERMANENT_STORAGE
|
||||||
|
*/
|
||||||
|
boolean isStsHost(in string aHost, in uint32_t aFlags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether or not the URI's hostname has STS state set.
|
* Checks whether or not the URI's hostname has STS state set.
|
||||||
@ -70,12 +75,12 @@ interface nsISiteSecurityService : nsISupports
|
|||||||
* @param aFlags options for this request as defined in nsISocketProvider:
|
* @param aFlags options for this request as defined in nsISocketProvider:
|
||||||
* NO_PERMANENT_STORAGE
|
* NO_PERMANENT_STORAGE
|
||||||
*/
|
*/
|
||||||
boolean isSecureURI(in uint32_t aType, in nsIURI aURI, in uint32_t aFlags);
|
boolean isStsURI(in nsIURI aURI, in uint32_t aFlags);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
#define NS_SSSERVICE_CONTRACTID "@mozilla.org/ssservice;1"
|
#define NS_STSSERVICE_CONTRACTID "@mozilla.org/stsservice;1"
|
||||||
|
|
||||||
#define STS_PERMISSION "sts/use"
|
#define STS_PERMISSION "sts/use"
|
||||||
#define STS_SUBDOMAIN_PERMISSION "sts/subd"
|
#define STS_SUBDOMAIN_PERMISSION "sts/subd"
|
@ -378,18 +378,17 @@ nsHttpChannel::Connect()
|
|||||||
|
|
||||||
if (!usingSSL) {
|
if (!usingSSL) {
|
||||||
// enforce Strict-Transport-Security
|
// enforce Strict-Transport-Security
|
||||||
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
|
nsIStrictTransportSecurityService* stss = gHttpHandler->GetSTSService();
|
||||||
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(stss, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
bool isStsHost = false;
|
bool isStsHost = false;
|
||||||
uint32_t flags = mPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
uint32_t flags = mPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
||||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, mURI, flags,
|
rv = stss->IsStsURI(mURI, flags, &isStsHost);
|
||||||
&isStsHost);
|
|
||||||
|
|
||||||
// if SSS fails, there's no reason to cancel the load, but it's
|
// if STS fails, there's no reason to cancel the load, but it's
|
||||||
// worrisome.
|
// worrisome.
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||||
"Something is wrong with SSS: IsSecureURI failed.");
|
"Something is wrong with STS: IsStsURI failed.");
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && isStsHost) {
|
if (NS_SUCCEEDED(rv) && isStsHost) {
|
||||||
LOG(("nsHttpChannel::Connect() STS permissions found\n"));
|
LOG(("nsHttpChannel::Connect() STS permissions found\n"));
|
||||||
@ -1144,8 +1143,8 @@ nsHttpChannel::ProcessSTSHeader()
|
|||||||
if (PR_SUCCESS == PR_StringToNetAddr(asciiHost.get(), &hostAddr))
|
if (PR_SUCCESS == PR_StringToNetAddr(asciiHost.get(), &hostAddr))
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
|
nsIStrictTransportSecurityService* stss = gHttpHandler->GetSTSService();
|
||||||
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(stss, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
// mSecurityInfo may not always be present, and if it's not then it is okay
|
// mSecurityInfo may not always be present, and if it's not then it is okay
|
||||||
// to just disregard any STS headers since we know nothing about the
|
// to just disregard any STS headers since we know nothing about the
|
||||||
@ -1156,7 +1155,7 @@ nsHttpChannel::ProcessSTSHeader()
|
|||||||
// If there are certificate errors, we still load the data, we just ignore
|
// If there are certificate errors, we still load the data, we just ignore
|
||||||
// any STS headers that are present.
|
// any STS headers that are present.
|
||||||
bool tlsIsBroken = false;
|
bool tlsIsBroken = false;
|
||||||
rv = sss->ShouldIgnoreHeader(mSecurityInfo, &tlsIsBroken);
|
rv = stss->ShouldIgnoreStsHeader(mSecurityInfo, &tlsIsBroken);
|
||||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||||
|
|
||||||
// If this was already an STS host, the connection should have been aborted
|
// If this was already an STS host, the connection should have been aborted
|
||||||
@ -1167,8 +1166,7 @@ nsHttpChannel::ProcessSTSHeader()
|
|||||||
bool wasAlreadySTSHost;
|
bool wasAlreadySTSHost;
|
||||||
uint32_t flags =
|
uint32_t flags =
|
||||||
NS_UsePrivateBrowsing(this) ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
NS_UsePrivateBrowsing(this) ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
||||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, mURI, flags,
|
rv = stss->IsStsURI(mURI, flags, &wasAlreadySTSHost);
|
||||||
&wasAlreadySTSHost);
|
|
||||||
// Failure here means STS is broken. Don't prevent the load, but this
|
// Failure here means STS is broken. Don't prevent the load, but this
|
||||||
// shouldn't fail.
|
// shouldn't fail.
|
||||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||||
@ -1196,8 +1194,7 @@ nsHttpChannel::ProcessSTSHeader()
|
|||||||
// All other failures are fatal.
|
// All other failures are fatal.
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = sss->ProcessHeader(nsISiteSecurityService::HEADER_HSTS, mURI,
|
rv = stss->ProcessStsHeader(mURI, stsHeader.get(), flags, NULL, NULL);
|
||||||
stsHeader.get(), flags, NULL, NULL);
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
AddSecurityMessage(NS_LITERAL_STRING("InvalidSTSHeaders"),
|
AddSecurityMessage(NS_LITERAL_STRING("InvalidSTSHeaders"),
|
||||||
NS_LITERAL_STRING("Invalid HSTS Headers"));
|
NS_LITERAL_STRING("Invalid HSTS Headers"));
|
||||||
|
@ -475,12 +475,12 @@ nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsISiteSecurityService*
|
nsIStrictTransportSecurityService*
|
||||||
nsHttpHandler::GetSSService()
|
nsHttpHandler::GetSTSService()
|
||||||
{
|
{
|
||||||
if (!mSSService)
|
if (!mSTSService)
|
||||||
mSSService = do_GetService(NS_SSSERVICE_CONTRACTID);
|
mSTSService = do_GetService(NS_STSSERVICE_CONTRACTID);
|
||||||
return mSSService;
|
return mSTSService;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsICookieService *
|
nsICookieService *
|
||||||
@ -1830,9 +1830,9 @@ NS_IMETHODIMP
|
|||||||
nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
|
nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
|
||||||
nsIInterfaceRequestor *aCallbacks)
|
nsIInterfaceRequestor *aCallbacks)
|
||||||
{
|
{
|
||||||
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
|
nsIStrictTransportSecurityService* stss = gHttpHandler->GetSTSService();
|
||||||
bool isStsHost = false;
|
bool isStsHost = false;
|
||||||
if (!sss)
|
if (!stss)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(aCallbacks);
|
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(aCallbacks);
|
||||||
@ -1840,8 +1840,7 @@ nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
|
|||||||
if (loadContext && loadContext->UsePrivateBrowsing())
|
if (loadContext && loadContext->UsePrivateBrowsing())
|
||||||
flags |= nsISocketProvider::NO_PERMANENT_STORAGE;
|
flags |= nsISocketProvider::NO_PERMANENT_STORAGE;
|
||||||
nsCOMPtr<nsIURI> clone;
|
nsCOMPtr<nsIURI> clone;
|
||||||
if (NS_SUCCEEDED(sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS,
|
if (NS_SUCCEEDED(stss->IsStsURI(aURI, flags, &isStsHost)) && isStsHost) {
|
||||||
aURI, flags, &isStsHost)) && isStsHost) {
|
|
||||||
if (NS_SUCCEEDED(aURI->Clone(getter_AddRefs(clone)))) {
|
if (NS_SUCCEEDED(aURI->Clone(getter_AddRefs(clone)))) {
|
||||||
clone->SetScheme(NS_LITERAL_CSTRING("https"));
|
clone->SetScheme(NS_LITERAL_CSTRING("https"));
|
||||||
aURI = clone.get();
|
aURI = clone.get();
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "nsICacheSession.h"
|
#include "nsICacheSession.h"
|
||||||
#include "nsICookieService.h"
|
#include "nsICookieService.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsISiteSecurityService.h"
|
#include "nsIStrictTransportSecurityService.h"
|
||||||
#include "nsISpeculativeConnect.h"
|
#include "nsISpeculativeConnect.h"
|
||||||
|
|
||||||
class nsHttpConnectionInfo;
|
class nsHttpConnectionInfo;
|
||||||
@ -196,7 +196,7 @@ public:
|
|||||||
nsresult GetStreamConverterService(nsIStreamConverterService **);
|
nsresult GetStreamConverterService(nsIStreamConverterService **);
|
||||||
nsresult GetIOService(nsIIOService** service);
|
nsresult GetIOService(nsIIOService** service);
|
||||||
nsICookieService * GetCookieService(); // not addrefed
|
nsICookieService * GetCookieService(); // not addrefed
|
||||||
nsISiteSecurityService * GetSSService();
|
nsIStrictTransportSecurityService * GetSTSService();
|
||||||
|
|
||||||
// callable from socket thread only
|
// callable from socket thread only
|
||||||
uint32_t Get32BitsOfPseudoRandom();
|
uint32_t Get32BitsOfPseudoRandom();
|
||||||
@ -308,7 +308,7 @@ private:
|
|||||||
nsCOMPtr<nsIStreamConverterService> mStreamConvSvc;
|
nsCOMPtr<nsIStreamConverterService> mStreamConvSvc;
|
||||||
nsCOMPtr<nsIObserverService> mObserverService;
|
nsCOMPtr<nsIObserverService> mObserverService;
|
||||||
nsCOMPtr<nsICookieService> mCookieService;
|
nsCOMPtr<nsICookieService> mCookieService;
|
||||||
nsCOMPtr<nsISiteSecurityService> mSSService;
|
nsCOMPtr<nsIStrictTransportSecurityService> mSTSService;
|
||||||
|
|
||||||
// the authentication credentials cache
|
// the authentication credentials cache
|
||||||
nsHttpAuthCache mAuthCache;
|
nsHttpAuthCache mAuthCache;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "plstr.h"
|
#include "plstr.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
#include "nsISiteSecurityService.h"
|
#include "nsIStrictTransportSecurityService.h"
|
||||||
#include "nsIPermissionManager.h"
|
#include "nsIPermissionManager.h"
|
||||||
|
|
||||||
#define EXPECT_SUCCESS(rv, ...) \
|
#define EXPECT_SUCCESS(rv, ...) \
|
||||||
@ -40,7 +40,7 @@
|
|||||||
bool
|
bool
|
||||||
TestSuccess(const char* hdr, bool extraTokens,
|
TestSuccess(const char* hdr, bool extraTokens,
|
||||||
uint64_t expectedMaxAge, bool expectedIncludeSubdomains,
|
uint64_t expectedMaxAge, bool expectedIncludeSubdomains,
|
||||||
nsISiteSecurityService* sss,
|
nsIStrictTransportSecurityService* stss,
|
||||||
nsIPermissionManager* pm)
|
nsIPermissionManager* pm)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> dummyUri;
|
nsCOMPtr<nsIURI> dummyUri;
|
||||||
@ -49,8 +49,7 @@ TestSuccess(const char* hdr, bool extraTokens,
|
|||||||
|
|
||||||
uint64_t maxAge = 0;
|
uint64_t maxAge = 0;
|
||||||
bool includeSubdomains = false;
|
bool includeSubdomains = false;
|
||||||
rv = sss->ProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri, hdr,
|
rv = stss->ProcessStsHeader(dummyUri, hdr, 0, &maxAge, &includeSubdomains);
|
||||||
0, &maxAge, &includeSubdomains);
|
|
||||||
EXPECT_SUCCESS(rv, "Failed to process valid header: %s", hdr);
|
EXPECT_SUCCESS(rv, "Failed to process valid header: %s", hdr);
|
||||||
|
|
||||||
REQUIRE_EQUAL(maxAge, expectedMaxAge, "Did not correctly parse maxAge");
|
REQUIRE_EQUAL(maxAge, expectedMaxAge, "Did not correctly parse maxAge");
|
||||||
@ -68,15 +67,14 @@ TestSuccess(const char* hdr, bool extraTokens,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TestFailure(const char* hdr,
|
bool TestFailure(const char* hdr,
|
||||||
nsISiteSecurityService* sss,
|
nsIStrictTransportSecurityService* stss,
|
||||||
nsIPermissionManager* pm)
|
nsIPermissionManager* pm)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> dummyUri;
|
nsCOMPtr<nsIURI> dummyUri;
|
||||||
nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
|
nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
|
||||||
EXPECT_SUCCESS(rv, "Failed to create URI");
|
EXPECT_SUCCESS(rv, "Failed to create URI");
|
||||||
|
|
||||||
rv = sss->ProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri, hdr,
|
rv = stss->ProcessStsHeader(dummyUri, hdr, 0, NULL, NULL);
|
||||||
0, NULL, NULL);
|
|
||||||
EXPECT_FAILURE(rv, "Parsed invalid header: %s", hdr);
|
EXPECT_FAILURE(rv, "Parsed invalid header: %s", hdr);
|
||||||
passed(hdr);
|
passed(hdr);
|
||||||
return true;
|
return true;
|
||||||
@ -98,8 +96,8 @@ main(int32_t argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// grab handle to the service
|
// grab handle to the service
|
||||||
nsCOMPtr<nsISiteSecurityService> sss;
|
nsCOMPtr<nsIStrictTransportSecurityService> stss;
|
||||||
sss = do_GetService("@mozilla.org/ssservice;1", &rv);
|
stss = do_GetService("@mozilla.org/stsservice;1", &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, -1);
|
NS_ENSURE_SUCCESS(rv, -1);
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> pm;
|
nsCOMPtr<nsIPermissionManager> pm;
|
||||||
@ -114,42 +112,42 @@ main(int32_t argc, char *argv[])
|
|||||||
printf("*** Attempting to parse valid STS headers ...\n");
|
printf("*** Attempting to parse valid STS headers ...\n");
|
||||||
|
|
||||||
// SHOULD SUCCEED:
|
// SHOULD SUCCEED:
|
||||||
rvs.AppendElement(TestSuccess("max-age=100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age =100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age =100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess(" max-age=100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess(" max-age=100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age = 100 ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age = 100 ", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age = \"100\" ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age = \"100\" ", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age=\"100\"", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=\"100\"", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess(" max-age =\"100\" ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess(" max-age =\"100\" ", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("\tmax-age\t=\t\"100\"\t", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("\tmax-age\t=\t\"100\"\t", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age = 100 ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age = 100 ", false, 100, false, stss, pm));
|
||||||
|
|
||||||
rvs.AppendElement(TestSuccess("maX-aGe=100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("maX-aGe=100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("MAX-age =100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("MAX-age =100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-AGE=100", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-AGE=100", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("Max-Age = 100 ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("Max-Age = 100 ", false, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("MAX-AGE = 100 ", false, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("MAX-AGE = 100 ", false, 100, false, stss, pm));
|
||||||
|
|
||||||
rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age=100\t; includeSubdomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100\t; includeSubdomains", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess(" max-age=100; includeSubdomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess(" max-age=100; includeSubdomains", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age = 100 ; includeSubdomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age = 100 ; includeSubdomains", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age = 100 ; includeSubdomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age = 100 ; includeSubdomains", false, 100, true, stss, pm));
|
||||||
|
|
||||||
rvs.AppendElement(TestSuccess("maX-aGe=100; includeSUBDOMAINS", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("maX-aGe=100; includeSUBDOMAINS", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("MAX-age =100; includeSubDomains", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("MAX-age =100; includeSubDomains", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-AGE=100; iNcLuDeSuBdoMaInS", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-AGE=100; iNcLuDeSuBdoMaInS", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("Max-Age = 100; includesubdomains ", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("Max-Age = 100; includesubdomains ", false, 100, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("INCLUDESUBDOMAINS;MaX-AgE = 100 ", false, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("INCLUDESUBDOMAINS;MaX-AgE = 100 ", false, 100, true, stss, pm));
|
||||||
// Turns out, the actual directive is entirely optional (hence the
|
// Turns out, the actual directive is entirely optional (hence the
|
||||||
// trailing semicolon)
|
// trailing semicolon)
|
||||||
rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains;", true, 100, true, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains;", true, 100, true, stss, pm));
|
||||||
|
|
||||||
// these are weird tests, but are testing that some extended syntax is
|
// these are weird tests, but are testing that some extended syntax is
|
||||||
// still allowed (but it is ignored)
|
// still allowed (but it is ignored)
|
||||||
rvs.AppendElement(TestSuccess("max-age=100 ; includesubdomainsSomeStuff", true, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100 ; includesubdomainsSomeStuff", true, 100, false, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("\r\n\t\t \tcompletelyUnrelated = foobar; max-age= 34520103 \t \t; alsoUnrelated;asIsThis;\tincludeSubdomains\t\t \t", true, 34520103, true, sss, pm));
|
rvs.AppendElement(TestSuccess("\r\n\t\t \tcompletelyUnrelated = foobar; max-age= 34520103 \t \t; alsoUnrelated;asIsThis;\tincludeSubdomains\t\t \t", true, 34520103, true, stss, pm));
|
||||||
rvs.AppendElement(TestSuccess("max-age=100; unrelated=\"quoted \\\"thingy\\\"\"", true, 100, false, sss, pm));
|
rvs.AppendElement(TestSuccess("max-age=100; unrelated=\"quoted \\\"thingy\\\"\"", true, 100, false, stss, pm));
|
||||||
|
|
||||||
rv0 = rvs.Contains(false) ? 1 : 0;
|
rv0 = rvs.Contains(false) ? 1 : 0;
|
||||||
if (rv0 == 0)
|
if (rv0 == 0)
|
||||||
@ -160,37 +158,37 @@ main(int32_t argc, char *argv[])
|
|||||||
// SHOULD FAIL:
|
// SHOULD FAIL:
|
||||||
printf("*** Attempting to parse invalid STS headers (should not parse)...\n");
|
printf("*** Attempting to parse invalid STS headers (should not parse)...\n");
|
||||||
// invalid max-ages
|
// invalid max-ages
|
||||||
rvs.AppendElement(TestFailure("max-age", sss, pm));
|
rvs.AppendElement(TestFailure("max-age", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age ", sss, pm));
|
rvs.AppendElement(TestFailure("max-age ", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=p", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=p", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=*1p2", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=*1p2", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=.20032", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=.20032", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=!20032", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=!20032", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age==20032", sss, pm));
|
rvs.AppendElement(TestFailure("max-age==20032", stss, pm));
|
||||||
|
|
||||||
// invalid headers
|
// invalid headers
|
||||||
rvs.AppendElement(TestFailure("foobar", sss, pm));
|
rvs.AppendElement(TestFailure("foobar", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("maxage=100", sss, pm));
|
rvs.AppendElement(TestFailure("maxage=100", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("maxa-ge=100", sss, pm));
|
rvs.AppendElement(TestFailure("maxa-ge=100", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-ag=100", sss, pm));
|
rvs.AppendElement(TestFailure("max-ag=100", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("includesubdomains", sss, pm));
|
rvs.AppendElement(TestFailure("includesubdomains", stss, pm));
|
||||||
rvs.AppendElement(TestFailure(";", sss, pm));
|
rvs.AppendElement(TestFailure(";", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=\"100", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=\"100", stss, pm));
|
||||||
// The max-age directive here doesn't conform to the spec, so it MUST
|
// The max-age directive here doesn't conform to the spec, so it MUST
|
||||||
// be ignored. Consequently, the REQUIRED max-age directive is not
|
// be ignored. Consequently, the REQUIRED max-age directive is not
|
||||||
// present in this header, and so it is invalid.
|
// present in this header, and so it is invalid.
|
||||||
rvs.AppendElement(TestFailure("max-age=100, max-age=200; includeSubdomains", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100, max-age=200; includeSubdomains", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=100 includesubdomains", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100 includesubdomains", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=100 bar foo", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100 bar foo", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=100randomstuffhere", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100randomstuffhere", stss, pm));
|
||||||
// All directives MUST appear only once in an STS header field.
|
// All directives MUST appear only once in an STS header field.
|
||||||
rvs.AppendElement(TestFailure("max-age=100; max-age=200", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100; max-age=200", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("includeSubdomains; max-age=200; includeSubdomains", sss, pm));
|
rvs.AppendElement(TestFailure("includeSubdomains; max-age=200; includeSubdomains", stss, pm));
|
||||||
rvs.AppendElement(TestFailure("max-age=200; includeSubdomains; includeSubdomains", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=200; includeSubdomains; includeSubdomains", stss, pm));
|
||||||
// The includeSubdomains directive is valueless.
|
// The includeSubdomains directive is valueless.
|
||||||
rvs.AppendElement(TestFailure("max-age=100; includeSubdomains=unexpected", sss, pm));
|
rvs.AppendElement(TestFailure("max-age=100; includeSubdomains=unexpected", stss, pm));
|
||||||
// LWS must have at least one space or horizontal tab
|
// LWS must have at least one space or horizontal tab
|
||||||
rvs.AppendElement(TestFailure("\r\nmax-age=200", sss, pm));
|
rvs.AppendElement(TestFailure("\r\nmax-age=200", stss, pm));
|
||||||
|
|
||||||
rv1 = rvs.Contains(false) ? 1 : 0;
|
rv1 = rvs.Contains(false) ? 1 : 0;
|
||||||
if (rv1 == 0)
|
if (rv1 == 0)
|
||||||
|
@ -12,7 +12,7 @@ CPP_SOURCES += [
|
|||||||
'nsSecureBrowserUIImpl.cpp',
|
'nsSecureBrowserUIImpl.cpp',
|
||||||
'nsSecurityHeaderParser.cpp',
|
'nsSecurityHeaderParser.cpp',
|
||||||
'nsSecurityWarningDialogs.cpp',
|
'nsSecurityWarningDialogs.cpp',
|
||||||
'nsSiteSecurityService.cpp',
|
'nsStrictTransportSecurityService.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
LIBRARY_NAME = 'pipboot'
|
LIBRARY_NAME = 'pipboot'
|
||||||
|
@ -8,23 +8,23 @@
|
|||||||
#include "nsEntropyCollector.h"
|
#include "nsEntropyCollector.h"
|
||||||
#include "nsSecureBrowserUIImpl.h"
|
#include "nsSecureBrowserUIImpl.h"
|
||||||
#include "nsSecurityWarningDialogs.h"
|
#include "nsSecurityWarningDialogs.h"
|
||||||
#include "nsSiteSecurityService.h"
|
#include "nsStrictTransportSecurityService.h"
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntropyCollector)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntropyCollector)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecureBrowserUIImpl)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecureBrowserUIImpl)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSecurityWarningDialogs, Init)
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSecurityWarningDialogs, Init)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSiteSecurityService, Init)
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStrictTransportSecurityService, Init)
|
||||||
|
|
||||||
NS_DEFINE_NAMED_CID(NS_ENTROPYCOLLECTOR_CID);
|
NS_DEFINE_NAMED_CID(NS_ENTROPYCOLLECTOR_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_SECURITYWARNINGDIALOGS_CID);
|
NS_DEFINE_NAMED_CID(NS_SECURITYWARNINGDIALOGS_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID);
|
NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID);
|
NS_DEFINE_NAMED_CID(NS_STRICT_TRANSPORT_SECURITY_CID);
|
||||||
|
|
||||||
static const mozilla::Module::CIDEntry kBOOTCIDs[] = {
|
static const mozilla::Module::CIDEntry kBOOTCIDs[] = {
|
||||||
{ &kNS_ENTROPYCOLLECTOR_CID, false, nullptr, nsEntropyCollectorConstructor },
|
{ &kNS_ENTROPYCOLLECTOR_CID, false, nullptr, nsEntropyCollectorConstructor },
|
||||||
{ &kNS_SECURITYWARNINGDIALOGS_CID, false, nullptr, nsSecurityWarningDialogsConstructor },
|
{ &kNS_SECURITYWARNINGDIALOGS_CID, false, nullptr, nsSecurityWarningDialogsConstructor },
|
||||||
{ &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor },
|
{ &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor },
|
||||||
{ &kNS_SITE_SECURITY_SERVICE_CID, false, nullptr, nsSiteSecurityServiceConstructor },
|
{ &kNS_STRICT_TRANSPORT_SECURITY_CID, false, nullptr, nsStrictTransportSecurityServiceConstructor },
|
||||||
{ nullptr }
|
{ nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ static const mozilla::Module::ContractIDEntry kBOOTContracts[] = {
|
|||||||
{ NS_ENTROPYCOLLECTOR_CONTRACTID, &kNS_ENTROPYCOLLECTOR_CID },
|
{ NS_ENTROPYCOLLECTOR_CONTRACTID, &kNS_ENTROPYCOLLECTOR_CID },
|
||||||
{ NS_SECURITYWARNINGDIALOGS_CONTRACTID, &kNS_SECURITYWARNINGDIALOGS_CID },
|
{ NS_SECURITYWARNINGDIALOGS_CONTRACTID, &kNS_SECURITYWARNINGDIALOGS_CID },
|
||||||
{ NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID },
|
{ NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID },
|
||||||
{ NS_SSSERVICE_CONTRACTID, &kNS_SITE_SECURITY_SERVICE_CID },
|
{ NS_STSSERVICE_CONTRACTID, &kNS_STRICT_TRANSPORT_SECURITY_CID },
|
||||||
{ nullptr }
|
{ nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "nsIPermissionManager.h"
|
#include "nsIPermissionManager.h"
|
||||||
#include "nsISSLStatus.h"
|
#include "nsISSLStatus.h"
|
||||||
#include "nsISSLStatusProvider.h"
|
#include "nsISSLStatusProvider.h"
|
||||||
#include "nsSiteSecurityService.h"
|
#include "nsStrictTransportSecurityService.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
@ -49,7 +49,7 @@ GetSTSLog()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsSSSHostEntry::nsSSSHostEntry(const char* aHost)
|
nsSTSHostEntry::nsSTSHostEntry(const char* aHost)
|
||||||
: mHost(aHost)
|
: mHost(aHost)
|
||||||
, mExpireTime(0)
|
, mExpireTime(0)
|
||||||
, mStsPermission(STS_UNSET)
|
, mStsPermission(STS_UNSET)
|
||||||
@ -58,7 +58,7 @@ nsSSSHostEntry::nsSSSHostEntry(const char* aHost)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSSSHostEntry::nsSSSHostEntry(const nsSSSHostEntry& toCopy)
|
nsSTSHostEntry::nsSTSHostEntry(const nsSTSHostEntry& toCopy)
|
||||||
: mHost(toCopy.mHost)
|
: mHost(toCopy.mHost)
|
||||||
, mExpireTime(toCopy.mExpireTime)
|
, mExpireTime(toCopy.mExpireTime)
|
||||||
, mStsPermission(toCopy.mStsPermission)
|
, mStsPermission(toCopy.mStsPermission)
|
||||||
@ -70,21 +70,21 @@ nsSSSHostEntry::nsSSSHostEntry(const nsSSSHostEntry& toCopy)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
nsSiteSecurityService::nsSiteSecurityService()
|
nsStrictTransportSecurityService::nsStrictTransportSecurityService()
|
||||||
: mUsePreloadList(true)
|
: mUsePreloadList(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSiteSecurityService::~nsSiteSecurityService()
|
nsStrictTransportSecurityService::~nsStrictTransportSecurityService()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsSiteSecurityService,
|
NS_IMPL_ISUPPORTS2(nsStrictTransportSecurityService,
|
||||||
nsIObserver,
|
nsIObserver,
|
||||||
nsISiteSecurityService)
|
nsIStrictTransportSecurityService)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::Init()
|
nsStrictTransportSecurityService::Init()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ nsSiteSecurityService::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::GetHost(nsIURI *aURI, nsACString &aResult)
|
nsStrictTransportSecurityService::GetHost(nsIURI *aURI, nsACString &aResult)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||||
if (!innerURI) return NS_ERROR_FAILURE;
|
if (!innerURI) return NS_ERROR_FAILURE;
|
||||||
@ -117,8 +117,8 @@ nsSiteSecurityService::GetHost(nsIURI *aURI, nsACString &aResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::GetPrincipalForURI(nsIURI* aURI,
|
nsStrictTransportSecurityService::GetPrincipalForURI(nsIURI* aURI,
|
||||||
nsIPrincipal** aPrincipal)
|
nsIPrincipal** aPrincipal)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
||||||
@ -140,16 +140,15 @@ nsSiteSecurityService::GetPrincipalForURI(nsIURI* aURI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::SetState(uint32_t aType,
|
nsStrictTransportSecurityService::SetStsState(nsIURI* aSourceURI,
|
||||||
nsIURI* aSourceURI,
|
int64_t maxage,
|
||||||
int64_t maxage,
|
bool includeSubdomains,
|
||||||
bool includeSubdomains,
|
uint32_t flags)
|
||||||
uint32_t flags)
|
|
||||||
{
|
{
|
||||||
// If max-age is zero, that's an indication to immediately remove the
|
// If max-age is zero, that's an indication to immediately remove the
|
||||||
// permissions, so here's a shortcut.
|
// permissions, so here's a shortcut.
|
||||||
if (!maxage) {
|
if (!maxage) {
|
||||||
return RemoveState(aType, aSourceURI, flags);
|
return RemoveStsState(aSourceURI, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expire time is millis from now. Since STS max-age is in seconds, and
|
// Expire time is millis from now. Since STS max-age is in seconds, and
|
||||||
@ -192,14 +191,11 @@ nsSiteSecurityService::SetState(uint32_t aType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI, uint32_t aFlags)
|
nsStrictTransportSecurityService::RemoveStsState(nsIURI* aURI, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
// Should be called on the main thread (or via proxy) since the permission
|
// Should be called on the main thread (or via proxy) since the permission
|
||||||
// manager is used and it's not threadsafe.
|
// manager is used and it's not threadsafe.
|
||||||
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
||||||
// Only HSTS is supported at the moment.
|
|
||||||
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS,
|
|
||||||
NS_ERROR_NOT_IMPLEMENTED);
|
|
||||||
|
|
||||||
nsAutoCString hostname;
|
nsAutoCString hostname;
|
||||||
nsresult rv = GetHost(aURI, hostname);
|
nsresult rv = GetHost(aURI, hostname);
|
||||||
@ -219,19 +215,15 @@ nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI, uint32_t aFlags
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSiteSecurityService::ProcessHeader(uint32_t aType,
|
nsStrictTransportSecurityService::ProcessStsHeader(nsIURI* aSourceURI,
|
||||||
nsIURI* aSourceURI,
|
const char* aHeader,
|
||||||
const char* aHeader,
|
uint32_t aFlags,
|
||||||
uint32_t aFlags,
|
uint64_t *aMaxAge,
|
||||||
uint64_t *aMaxAge,
|
bool *aIncludeSubdomains)
|
||||||
bool *aIncludeSubdomains)
|
|
||||||
{
|
{
|
||||||
// Should be called on the main thread (or via proxy) since the permission
|
// Should be called on the main thread (or via proxy) since the permission
|
||||||
// manager is used and it's not threadsafe.
|
// manager is used and it's not threadsafe.
|
||||||
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
||||||
// Only HSTS is supported at the moment.
|
|
||||||
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS,
|
|
||||||
NS_ERROR_NOT_IMPLEMENTED);
|
|
||||||
|
|
||||||
if (aMaxAge != nullptr) {
|
if (aMaxAge != nullptr) {
|
||||||
*aMaxAge = 0;
|
*aMaxAge = 0;
|
||||||
@ -243,19 +235,18 @@ nsSiteSecurityService::ProcessHeader(uint32_t aType,
|
|||||||
|
|
||||||
char * header = NS_strdup(aHeader);
|
char * header = NS_strdup(aHeader);
|
||||||
if (!header) return NS_ERROR_OUT_OF_MEMORY;
|
if (!header) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
nsresult rv = ProcessHeaderMutating(aType, aSourceURI, header, aFlags,
|
nsresult rv = ProcessStsHeaderMutating(aSourceURI, header, aFlags,
|
||||||
aMaxAge, aIncludeSubdomains);
|
aMaxAge, aIncludeSubdomains);
|
||||||
NS_Free(header);
|
NS_Free(header);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::ProcessHeaderMutating(uint32_t aType,
|
nsStrictTransportSecurityService::ProcessStsHeaderMutating(nsIURI* aSourceURI,
|
||||||
nsIURI* aSourceURI,
|
char* aHeader,
|
||||||
char* aHeader,
|
uint32_t aFlags,
|
||||||
uint32_t aFlags,
|
uint64_t *aMaxAge,
|
||||||
uint64_t *aMaxAge,
|
bool *aIncludeSubdomains)
|
||||||
bool *aIncludeSubdomains)
|
|
||||||
{
|
{
|
||||||
STSLOG(("STS: processing header '%s'", aHeader));
|
STSLOG(("STS: processing header '%s'", aHeader));
|
||||||
|
|
||||||
@ -351,7 +342,7 @@ nsSiteSecurityService::ProcessHeaderMutating(uint32_t aType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record the successfully parsed header data.
|
// record the successfully parsed header data.
|
||||||
SetState(aType, aSourceURI, maxAge, foundIncludeSubdomains, aFlags);
|
SetStsState(aSourceURI, maxAge, foundIncludeSubdomains, aFlags);
|
||||||
|
|
||||||
if (aMaxAge != nullptr) {
|
if (aMaxAge != nullptr) {
|
||||||
*aMaxAge = (uint64_t)maxAge;
|
*aMaxAge = (uint64_t)maxAge;
|
||||||
@ -366,6 +357,21 @@ nsSiteSecurityService::ProcessHeaderMutating(uint32_t aType,
|
|||||||
NS_OK;
|
NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsStrictTransportSecurityService::IsStsHost(const char* aHost, uint32_t aFlags, bool* aResult)
|
||||||
|
{
|
||||||
|
// Should be called on the main thread (or via proxy) since the permission
|
||||||
|
// manager is used and it's not threadsafe.
|
||||||
|
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
nsDependentCString hostString(aHost);
|
||||||
|
nsresult rv = NS_NewURI(getter_AddRefs(uri),
|
||||||
|
NS_LITERAL_CSTRING("https://") + hostString);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
return IsStsURI(uri, aFlags, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
int STSPreloadCompare(const void *key, const void *entry)
|
int STSPreloadCompare(const void *key, const void *entry)
|
||||||
{
|
{
|
||||||
const char *keyStr = (const char *)key;
|
const char *keyStr = (const char *)key;
|
||||||
@ -377,7 +383,7 @@ int STSPreloadCompare(const void *key, const void *entry)
|
|||||||
// Only does exact host matching - the user must decide how to use the returned
|
// Only does exact host matching - the user must decide how to use the returned
|
||||||
// data. May return null.
|
// data. May return null.
|
||||||
const nsSTSPreload *
|
const nsSTSPreload *
|
||||||
nsSiteSecurityService::GetPreloadListEntry(const char *aHost)
|
nsStrictTransportSecurityService::GetPreloadListEntry(const char *aHost)
|
||||||
{
|
{
|
||||||
PRTime currentTime = PR_Now();
|
PRTime currentTime = PR_Now();
|
||||||
int32_t timeOffset = 0;
|
int32_t timeOffset = 0;
|
||||||
@ -399,15 +405,11 @@ nsSiteSecurityService::GetPreloadListEntry(const char *aHost)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI,
|
nsStrictTransportSecurityService::IsStsURI(nsIURI* aURI, uint32_t aFlags, bool* aResult)
|
||||||
uint32_t aFlags, bool* aResult)
|
|
||||||
{
|
{
|
||||||
// Should be called on the main thread (or via proxy) since the permission
|
// Should be called on the main thread (or via proxy) since the permission
|
||||||
// manager is used and it's not threadsafe.
|
// manager is used and it's not threadsafe.
|
||||||
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
|
||||||
// Only HSTS is supported at the moment.
|
|
||||||
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS,
|
|
||||||
NS_ERROR_NOT_IMPLEMENTED);
|
|
||||||
|
|
||||||
// set default in case if we can't find any STS information
|
// set default in case if we can't find any STS information
|
||||||
*aResult = false;
|
*aResult = false;
|
||||||
@ -417,7 +419,7 @@ nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI,
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
const nsSTSPreload *preload = nullptr;
|
const nsSTSPreload *preload = nullptr;
|
||||||
nsSSSHostEntry *pbEntry = nullptr;
|
nsSTSHostEntry *pbEntry = nullptr;
|
||||||
|
|
||||||
bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE;
|
bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE;
|
||||||
if (isPrivate) {
|
if (isPrivate) {
|
||||||
@ -544,8 +546,8 @@ nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI,
|
|||||||
|
|
||||||
// Verify the trustworthiness of the security info (are there any cert errors?)
|
// Verify the trustworthiness of the security info (are there any cert errors?)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSiteSecurityService::ShouldIgnoreHeader(nsISupports* aSecurityInfo,
|
nsStrictTransportSecurityService::ShouldIgnoreStsHeader(nsISupports* aSecurityInfo,
|
||||||
bool* aResult)
|
bool* aResult)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
bool tlsIsBroken = false;
|
bool tlsIsBroken = false;
|
||||||
@ -575,13 +577,13 @@ nsSiteSecurityService::ShouldIgnoreHeader(nsISupports* aSecurityInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// nsSiteSecurityService::nsIObserver
|
// nsStrictTransportSecurityService::nsIObserver
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSiteSecurityService::Observe(nsISupports *subject,
|
nsStrictTransportSecurityService::Observe(nsISupports *subject,
|
||||||
const char *topic,
|
const char *topic,
|
||||||
const PRUnichar *data)
|
const PRUnichar *data)
|
||||||
{
|
{
|
||||||
if (strcmp(topic, "last-pb-context-exited") == 0) {
|
if (strcmp(topic, "last-pb-context-exited") == 0) {
|
||||||
mPrivateModeHostTable.Clear();
|
mPrivateModeHostTable.Clear();
|
||||||
@ -598,12 +600,12 @@ nsSiteSecurityService::Observe(nsISupports *subject,
|
|||||||
// we're in private browsing mode.
|
// we're in private browsing mode.
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::AddPermission(nsIURI *aURI,
|
nsStrictTransportSecurityService::AddPermission(nsIURI *aURI,
|
||||||
const char *aType,
|
const char *aType,
|
||||||
uint32_t aPermission,
|
uint32_t aPermission,
|
||||||
uint32_t aExpireType,
|
uint32_t aExpireType,
|
||||||
int64_t aExpireTime,
|
int64_t aExpireTime,
|
||||||
bool aIsPrivate)
|
bool aIsPrivate)
|
||||||
{
|
{
|
||||||
// Private mode doesn't address user-set (EXPIRE_NEVER) permissions: let
|
// Private mode doesn't address user-set (EXPIRE_NEVER) permissions: let
|
||||||
// those be stored persistently.
|
// those be stored persistently.
|
||||||
@ -634,7 +636,7 @@ nsSiteSecurityService::AddPermission(nsIURI *aURI,
|
|||||||
|
|
||||||
// PutEntry returns an existing entry if there already is one, or it
|
// PutEntry returns an existing entry if there already is one, or it
|
||||||
// creates a new one if there isn't.
|
// creates a new one if there isn't.
|
||||||
nsSSSHostEntry* entry = mPrivateModeHostTable.PutEntry(host.get());
|
nsSTSHostEntry* entry = mPrivateModeHostTable.PutEntry(host.get());
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@ -644,7 +646,7 @@ nsSiteSecurityService::AddPermission(nsIURI *aURI,
|
|||||||
// includeSubdomains (first for the main permission and second for the
|
// includeSubdomains (first for the main permission and second for the
|
||||||
// subdomains permission). If AddPermission() gets called a second time
|
// subdomains permission). If AddPermission() gets called a second time
|
||||||
// with the STS_SUBDOMAIN_PERMISSION, we just have to flip that bit in
|
// with the STS_SUBDOMAIN_PERMISSION, we just have to flip that bit in
|
||||||
// the nsSSSHostEntry.
|
// the nsSTSHostEntry.
|
||||||
if (strcmp(aType, STS_SUBDOMAIN_PERMISSION) == 0) {
|
if (strcmp(aType, STS_SUBDOMAIN_PERMISSION) == 0) {
|
||||||
entry->mIncludeSubdomains = true;
|
entry->mIncludeSubdomains = true;
|
||||||
}
|
}
|
||||||
@ -658,9 +660,9 @@ nsSiteSecurityService::AddPermission(nsIURI *aURI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSiteSecurityService::RemovePermission(const nsCString &aHost,
|
nsStrictTransportSecurityService::RemovePermission(const nsCString &aHost,
|
||||||
const char *aType,
|
const char *aType,
|
||||||
bool aIsPrivate)
|
bool aIsPrivate)
|
||||||
{
|
{
|
||||||
// Build up a principal for use with the permission manager.
|
// Build up a principal for use with the permission manager.
|
||||||
// normalize all URIs with https://
|
// normalize all URIs with https://
|
||||||
@ -684,7 +686,7 @@ nsSiteSecurityService::RemovePermission(const nsCString &aHost,
|
|||||||
|
|
||||||
// Make changes in mPrivateModeHostTable only, so any changes will be
|
// Make changes in mPrivateModeHostTable only, so any changes will be
|
||||||
// rolled back when exiting private mode.
|
// rolled back when exiting private mode.
|
||||||
nsSSSHostEntry* entry = mPrivateModeHostTable.GetEntry(aHost.get());
|
nsSTSHostEntry* entry = mPrivateModeHostTable.GetEntry(aHost.get());
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
entry = mPrivateModeHostTable.PutEntry(aHost.get());
|
entry = mPrivateModeHostTable.PutEntry(aHost.get());
|
@ -6,10 +6,10 @@
|
|||||||
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __nsSiteSecurityService_h__
|
#ifndef __nsStrictTransportSecurityService_h__
|
||||||
#define __nsSiteSecurityService_h__
|
#define __nsStrictTransportSecurityService_h__
|
||||||
|
|
||||||
#include "nsISiteSecurityService.h"
|
#include "nsIStrictTransportSecurityService.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIPermissionManager.h"
|
#include "nsIPermissionManager.h"
|
||||||
@ -20,16 +20,16 @@
|
|||||||
#include "prtime.h"
|
#include "prtime.h"
|
||||||
|
|
||||||
// {16955eee-6c48-4152-9309-c42a465138a1}
|
// {16955eee-6c48-4152-9309-c42a465138a1}
|
||||||
#define NS_SITE_SECURITY_SERVICE_CID \
|
#define NS_STRICT_TRANSPORT_SECURITY_CID \
|
||||||
{0x16955eee, 0x6c48, 0x4152, \
|
{0x16955eee, 0x6c48, 0x4152, \
|
||||||
{0x93, 0x09, 0xc4, 0x2a, 0x46, 0x51, 0x38, 0xa1} }
|
{0x93, 0x09, 0xc4, 0x2a, 0x46, 0x51, 0x38, 0xa1} }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsSSSHostEntry - similar to the nsHostEntry class in
|
// nsSTSHostEntry - similar to the nsHostEntry class in
|
||||||
// nsPermissionManager.cpp, but specific to private-mode caching of STS
|
// nsPermissionManager.cpp, but specific to private-mode caching of STS
|
||||||
// permissions.
|
// permissions.
|
||||||
//
|
//
|
||||||
// Each nsSSSHostEntry contains:
|
// Each nsSTSHostEntry contains:
|
||||||
// - Expiry time (PRTime, milliseconds)
|
// - Expiry time (PRTime, milliseconds)
|
||||||
// - Expired flag (bool, default false)
|
// - Expired flag (bool, default false)
|
||||||
// - STS permission (uint32_t, default STS_UNSET)
|
// - STS permission (uint32_t, default STS_UNSET)
|
||||||
@ -37,7 +37,7 @@
|
|||||||
//
|
//
|
||||||
// Note: the subdomains flag has no meaning if the STS permission is STS_UNSET.
|
// Note: the subdomains flag has no meaning if the STS permission is STS_UNSET.
|
||||||
//
|
//
|
||||||
// The existence of the nsSSSHostEntry implies STS state is set for the given
|
// The existence of the nsSTSHostEntry implies STS state is set for the given
|
||||||
// host -- unless the expired flag is set, in which case not only is the STS
|
// host -- unless the expired flag is set, in which case not only is the STS
|
||||||
// state not set for the host, but any permission actually present in the
|
// state not set for the host, but any permission actually present in the
|
||||||
// permission manager should be ignored.
|
// permission manager should be ignored.
|
||||||
@ -45,7 +45,7 @@
|
|||||||
// Note: Only one expiry time is stored since the subdomains and STS
|
// Note: Only one expiry time is stored since the subdomains and STS
|
||||||
// permissions are both encountered at the same time in the HTTP header; if the
|
// permissions are both encountered at the same time in the HTTP header; if the
|
||||||
// includeSubdomains directive isn't present in the header, it means to delete
|
// includeSubdomains directive isn't present in the header, it means to delete
|
||||||
// the permission, so the subdomains flag in the nsSSSHostEntry means both that
|
// the permission, so the subdomains flag in the nsSTSHostEntry means both that
|
||||||
// the permission doesn't exist and any permission in the real permission
|
// the permission doesn't exist and any permission in the real permission
|
||||||
// manager should be ignored since newer information about it has been
|
// manager should be ignored since newer information about it has been
|
||||||
// encountered in private browsing mode.
|
// encountered in private browsing mode.
|
||||||
@ -55,11 +55,11 @@
|
|||||||
// encountered. Furthermore, any user-set permissions are stored persistently
|
// encountered. Furthermore, any user-set permissions are stored persistently
|
||||||
// and can't be shadowed.
|
// and can't be shadowed.
|
||||||
|
|
||||||
class nsSSSHostEntry : public PLDHashEntryHdr
|
class nsSTSHostEntry : public PLDHashEntryHdr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit nsSSSHostEntry(const char* aHost);
|
explicit nsSTSHostEntry(const char* aHost);
|
||||||
explicit nsSSSHostEntry(const nsSSSHostEntry& toCopy);
|
explicit nsSTSHostEntry(const nsSTSHostEntry& toCopy);
|
||||||
|
|
||||||
nsCString mHost;
|
nsCString mHost;
|
||||||
PRTime mExpireTime;
|
PRTime mExpireTime;
|
||||||
@ -121,26 +121,24 @@ class nsSSSHostEntry : public PLDHashEntryHdr
|
|||||||
|
|
||||||
class nsSTSPreload;
|
class nsSTSPreload;
|
||||||
|
|
||||||
class nsSiteSecurityService : public nsISiteSecurityService
|
class nsStrictTransportSecurityService : public nsIStrictTransportSecurityService
|
||||||
, public nsIObserver
|
, public nsIObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
NS_DECL_NSISITESECURITYSERVICE
|
NS_DECL_NSISTRICTTRANSPORTSECURITYSERVICE
|
||||||
|
|
||||||
nsSiteSecurityService();
|
nsStrictTransportSecurityService();
|
||||||
nsresult Init();
|
nsresult Init();
|
||||||
virtual ~nsSiteSecurityService();
|
virtual ~nsStrictTransportSecurityService();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult GetHost(nsIURI *aURI, nsACString &aResult);
|
nsresult GetHost(nsIURI *aURI, nsACString &aResult);
|
||||||
nsresult GetPrincipalForURI(nsIURI *aURI, nsIPrincipal **aPrincipal);
|
nsresult GetPrincipalForURI(nsIURI *aURI, nsIPrincipal **aPrincipal);
|
||||||
nsresult SetState(uint32_t aType, nsIURI* aSourceURI, int64_t maxage,
|
nsresult SetStsState(nsIURI* aSourceURI, int64_t maxage, bool includeSubdomains, uint32_t flags);
|
||||||
bool includeSubdomains, uint32_t flags);
|
nsresult ProcessStsHeaderMutating(nsIURI* aSourceURI, char* aHeader, uint32_t flags,
|
||||||
nsresult ProcessHeaderMutating(uint32_t aType, nsIURI* aSourceURI,
|
uint64_t *aMaxAge, bool *aIncludeSubdomains);
|
||||||
char* aHeader, uint32_t flags,
|
|
||||||
uint64_t *aMaxAge, bool *aIncludeSubdomains);
|
|
||||||
const nsSTSPreload *GetPreloadListEntry(const char *aHost);
|
const nsSTSPreload *GetPreloadListEntry(const char *aHost);
|
||||||
|
|
||||||
// private-mode-preserving permission manager overlay functions
|
// private-mode-preserving permission manager overlay functions
|
||||||
@ -158,8 +156,8 @@ private:
|
|||||||
nsCOMPtr<nsIPermissionManager> mPermMgr;
|
nsCOMPtr<nsIPermissionManager> mPermMgr;
|
||||||
nsCOMPtr<nsIObserverService> mObserverService;
|
nsCOMPtr<nsIObserverService> mObserverService;
|
||||||
|
|
||||||
nsTHashtable<nsSSSHostEntry> mPrivateModeHostTable;
|
nsTHashtable<nsSTSHostEntry> mPrivateModeHostTable;
|
||||||
bool mUsePreloadList;
|
bool mUsePreloadList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __nsSiteSecurityService_h__
|
#endif // __nsStrictTransportSecurityService_h__
|
@ -98,7 +98,7 @@
|
|||||||
#include "CertVerifier.h"
|
#include "CertVerifier.h"
|
||||||
#include "nsIBadCertListener2.h"
|
#include "nsIBadCertListener2.h"
|
||||||
#include "nsICertOverrideService.h"
|
#include "nsICertOverrideService.h"
|
||||||
#include "nsISiteSecurityService.h"
|
#include "nsIStrictTransportSecurityService.h"
|
||||||
#include "nsNSSComponent.h"
|
#include "nsNSSComponent.h"
|
||||||
#include "nsNSSCleaner.h"
|
#include "nsNSSCleaner.h"
|
||||||
#include "nsRecentBadCerts.h"
|
#include "nsRecentBadCerts.h"
|
||||||
@ -310,26 +310,19 @@ CertErrorRunnable::CheckCertOverrides()
|
|||||||
uint32_t remaining_display_errors = mCollectedErrors;
|
uint32_t remaining_display_errors = mCollectedErrors;
|
||||||
|
|
||||||
nsresult nsrv;
|
nsresult nsrv;
|
||||||
nsCString hostString(mInfoObject->GetHostName());
|
|
||||||
|
|
||||||
// Enforce Strict-Transport-Security for hosts that are "STS" hosts:
|
// Enforce Strict-Transport-Security for hosts that are "STS" hosts:
|
||||||
// connections must be dropped when there are any certificate errors
|
// connections must be dropped when there are any certificate errors
|
||||||
// (STS Spec section 7.3).
|
// (STS Spec section 7.3).
|
||||||
bool strictTransportSecurityEnabled = false;
|
bool strictTransportSecurityEnabled = false;
|
||||||
nsCOMPtr<nsISiteSecurityService> sss
|
nsCOMPtr<nsIStrictTransportSecurityService> stss
|
||||||
= do_GetService(NS_SSSERVICE_CONTRACTID, &nsrv);
|
= do_GetService(NS_STSSERVICE_CONTRACTID, &nsrv);
|
||||||
if (NS_SUCCEEDED(nsrv)) {
|
if (NS_SUCCEEDED(nsrv)) {
|
||||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
||||||
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsrv = stss->IsStsHost(mInfoObject->GetHostName(),
|
||||||
nsrv = NS_NewURI(getter_AddRefs(uri),
|
mProviderFlags,
|
||||||
NS_LITERAL_CSTRING("https://") + hostString);
|
&strictTransportSecurityEnabled);
|
||||||
if (NS_SUCCEEDED(nsrv)) {
|
|
||||||
nsrv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS,
|
|
||||||
uri,
|
|
||||||
mProviderFlags,
|
|
||||||
&strictTransportSecurityEnabled);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (NS_FAILED(nsrv)) {
|
if (NS_FAILED(nsrv)) {
|
||||||
return new SSLServerCertVerificationResult(mInfoObject,
|
return new SSLServerCertVerificationResult(mInfoObject,
|
||||||
@ -347,6 +340,7 @@ CertErrorRunnable::CheckCertOverrides()
|
|||||||
{
|
{
|
||||||
bool haveOverride;
|
bool haveOverride;
|
||||||
bool isTemporaryOverride; // we don't care
|
bool isTemporaryOverride; // we don't care
|
||||||
|
nsCString hostString(mInfoObject->GetHostName());
|
||||||
nsrv = overrideService->HasMatchingOverride(hostString, port,
|
nsrv = overrideService->HasMatchingOverride(hostString, port,
|
||||||
mCert,
|
mCert,
|
||||||
&overrideBits,
|
&overrideBits,
|
||||||
|
@ -10,8 +10,8 @@ function test() {
|
|||||||
let windowsToClose = [];
|
let windowsToClose = [];
|
||||||
let testURI = "about:blank";
|
let testURI = "about:blank";
|
||||||
let uri;
|
let uri;
|
||||||
let gSSService = Cc["@mozilla.org/ssservice;1"].
|
let gSTSService = Cc["@mozilla.org/stsservice;1"].
|
||||||
getService(Ci.nsISiteSecurityService);
|
getService(Ci.nsIStrictTransportSecurityService);
|
||||||
|
|
||||||
function privacyFlags(aIsPrivateMode) {
|
function privacyFlags(aIsPrivateMode) {
|
||||||
return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
|
return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
|
||||||
@ -22,9 +22,8 @@ function test() {
|
|||||||
aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||||
|
|
||||||
uri = aWindow.Services.io.newURI("https://localhost/img.png", null, null);
|
uri = aWindow.Services.io.newURI("https://localhost/img.png", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTA, uri,
|
gSTSService.processStsHeader(uri, "max-age=1000", privacyFlags(aIsPrivateMode));
|
||||||
"max-age=1000", privacyFlags(aIsPrivateMode));
|
ok(gSTSService.isStsHost("localhost", privacyFlags(aIsPrivateMode)), "checking sts host");
|
||||||
ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, privacyFlags(aIsPrivateMode)), "checking sts host");
|
|
||||||
|
|
||||||
aCallback();
|
aCallback();
|
||||||
}, true);
|
}, true);
|
||||||
@ -48,8 +47,7 @@ function test() {
|
|||||||
aWin.close();
|
aWin.close();
|
||||||
});
|
});
|
||||||
uri = Services.io.newURI("http://localhost", null, null);
|
uri = Services.io.newURI("http://localhost", null, null);
|
||||||
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.removeStsState(uri, privacyFlags(true));
|
||||||
privacyFlags(true));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// test first when on private mode
|
// test first when on private mode
|
||||||
|
@ -53,8 +53,8 @@
|
|||||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||||
var thehost = ios.newURI("http://example.com", null, null);
|
var thehost = ios.newURI("http://example.com", null, null);
|
||||||
|
|
||||||
var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
|
var stss = Cc["@mozilla.org/stsservice;1"].getService(Ci.nsIStrictTransportSecurityService);
|
||||||
sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, 0);
|
stss.removeStsState(thehost, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadVerifyFrames(round) {
|
function loadVerifyFrames(round) {
|
||||||
|
@ -187,21 +187,20 @@
|
|||||||
var ios =
|
var ios =
|
||||||
Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||||
var thehost = ios.newURI("http://example.com", null, null);
|
var thehost = ios.newURI("http://example.com", null, null);
|
||||||
var sss =
|
var stss =
|
||||||
Cc["@mozilla.org/ssservice;1"].
|
Cc["@mozilla.org/stsservice;1"].
|
||||||
getService(Ci.nsISiteSecurityService);
|
getService(Ci.nsIStrictTransportSecurityService);
|
||||||
var flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0
|
var flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0
|
||||||
sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags);
|
stss.removeStsState(thehost, flags);
|
||||||
dump_STSState(isPrivate);
|
dump_STSState(isPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dump_STSState(isPrivate) {
|
function dump_STSState(isPrivate) {
|
||||||
var sss =
|
var stss =
|
||||||
Cc["@mozilla.org/ssservice;1"].
|
Cc["@mozilla.org/stsservice;1"].
|
||||||
getService(Ci.nsISiteSecurityService);
|
getService(Ci.nsIStrictTransportSecurityService);
|
||||||
var flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0
|
var flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0
|
||||||
var uri = SpecialPowers.Services.io.newURI("https://example.com", null, null);
|
SimpleTest.info("State of example.com: " + stss.isStsHost("example.com", flags));
|
||||||
SimpleTest.info("State of example.com: " + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, flags));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are executed in the order presented.
|
// These are executed in the order presented.
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
// invested in HSTS. Additionally, www.torproject.org was deemed likely to
|
// invested in HSTS. Additionally, www.torproject.org was deemed likely to
|
||||||
// continue to use HSTS.
|
// continue to use HSTS.
|
||||||
|
|
||||||
var gSSService = Cc["@mozilla.org/ssservice;1"]
|
var gSTSService = Cc["@mozilla.org/stsservice;1"]
|
||||||
.getService(Ci.nsISiteSecurityService);
|
.getService(Ci.nsIStrictTransportSecurityService);
|
||||||
|
|
||||||
function Observer() {}
|
function Observer() {}
|
||||||
Observer.prototype = {
|
Observer.prototype = {
|
||||||
@ -17,7 +17,7 @@ Observer.prototype = {
|
|||||||
|
|
||||||
var gObserver = new Observer();
|
var gObserver = new Observer();
|
||||||
|
|
||||||
// nsISiteSecurityService.removeStsState removes a given domain's
|
// nsIStrictTransportSecurityService.removeStsState removes a given domain's
|
||||||
// HSTS status. This means that a domain on the preload list will be
|
// HSTS status. This means that a domain on the preload list will be
|
||||||
// considered not HSTS if this is called. So, to reset everything to its
|
// considered not HSTS if this is called. So, to reset everything to its
|
||||||
// original state, we have to reach into the permission manager and clear
|
// original state, we have to reach into the permission manager and clear
|
||||||
@ -25,7 +25,7 @@ var gObserver = new Observer();
|
|||||||
function clearStsState() {
|
function clearStsState() {
|
||||||
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
|
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
|
||||||
.getService(Ci.nsIPermissionManager);
|
.getService(Ci.nsIPermissionManager);
|
||||||
// This is a list of every host we call processHeader with
|
// This is a list of every host we call processStsHeader with
|
||||||
// (so we can remove any state added to the sts service)
|
// (so we can remove any state added to the sts service)
|
||||||
var hosts = ["bugzilla.mozilla.org", "login.persona.org",
|
var hosts = ["bugzilla.mozilla.org", "login.persona.org",
|
||||||
"subdomain.www.torproject.org",
|
"subdomain.www.torproject.org",
|
||||||
@ -52,63 +52,54 @@ function run_test() {
|
|||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_sts_host(aHost, aFlags) {
|
|
||||||
var uri = Services.io.newURI("http://" + aHost, null, null);
|
|
||||||
return gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_part1() {
|
function test_part1() {
|
||||||
// check that a host not in the list is not identified as an sts host
|
// check that a host not in the list is not identified as an sts host
|
||||||
do_check_false(is_sts_host("nonexistent.mozilla.com", 0));
|
do_check_false(gSTSService.isStsHost("nonexistent.mozilla.com", 0));
|
||||||
|
|
||||||
// check that an ancestor domain is not identified as an sts host
|
// check that an ancestor domain is not identified as an sts host
|
||||||
do_check_false(is_sts_host("com", 0));
|
do_check_false(gSTSService.isStsHost("com", 0));
|
||||||
|
|
||||||
// check that the pref to toggle using the preload list works
|
// check that the pref to toggle using the preload list works
|
||||||
Services.prefs.setBoolPref("network.stricttransportsecurity.preloadlist", false);
|
Services.prefs.setBoolPref("network.stricttransportsecurity.preloadlist", false);
|
||||||
do_check_false(is_sts_host("bugzilla.mozilla.org", 0));
|
do_check_false(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
Services.prefs.setBoolPref("network.stricttransportsecurity.preloadlist", true);
|
Services.prefs.setBoolPref("network.stricttransportsecurity.preloadlist", true);
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// check that a subdomain is an sts host (includeSubdomains is set)
|
// check that a subdomain is an sts host (includeSubdomains is set)
|
||||||
do_check_true(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// check that another subdomain is an sts host (includeSubdomains is set)
|
// check that another subdomain is an sts host (includeSubdomains is set)
|
||||||
do_check_true(is_sts_host("a.b.c.def.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("a.b.c.def.bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// check that a subdomain is not an sts host (includeSubdomains is not set)
|
// check that a subdomain is not an sts host (includeSubdomains is not set)
|
||||||
do_check_false(is_sts_host("subdomain.www.torproject.org", 0));
|
do_check_false(gSTSService.isStsHost("subdomain.www.torproject.org", 0));
|
||||||
|
|
||||||
// check that a host with a dot on the end won't break anything
|
// check that a host with a dot on the end won't break anything
|
||||||
do_check_false(is_sts_host("notsts.nonexistent.mozilla.com.", 0));
|
do_check_false(gSTSService.isStsHost("notsts.nonexistent.mozilla.com.", 0));
|
||||||
|
|
||||||
// check that processing a header with max-age: 0 will remove a preloaded
|
// check that processing a header with max-age: 0 will remove a preloaded
|
||||||
// site from the list
|
// site from the list
|
||||||
var uri = Services.io.newURI("http://bugzilla.mozilla.org", null, null);
|
var uri = Services.io.newURI("http://bugzilla.mozilla.org", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=0", 0);
|
||||||
"max-age=0", 0);
|
do_check_false(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
do_check_false(is_sts_host("bugzilla.mozilla.org", 0));
|
do_check_false(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
do_check_false(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
|
||||||
// check that processing another header (with max-age non-zero) will
|
// check that processing another header (with max-age non-zero) will
|
||||||
// re-enable a site's sts status
|
// re-enable a site's sts status
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=1000", 0);
|
||||||
"max-age=1000", 0);
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", 0));
|
|
||||||
// but this time include subdomains was not set, so test for that
|
// but this time include subdomains was not set, so test for that
|
||||||
do_check_false(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
do_check_false(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
clearStsState();
|
clearStsState();
|
||||||
|
|
||||||
// check that processing a header with max-age: 0 from a subdomain of a site
|
// check that processing a header with max-age: 0 from a subdomain of a site
|
||||||
// will not remove that (ancestor) site from the list
|
// will not remove that (ancestor) site from the list
|
||||||
var uri = Services.io.newURI("http://subdomain.www.torproject.org", null, null);
|
var uri = Services.io.newURI("http://subdomain.www.torproject.org", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=0", 0);
|
||||||
"max-age=0", 0);
|
do_check_true(gSTSService.isStsHost("www.torproject.org", 0));
|
||||||
do_check_true(is_sts_host("www.torproject.org", 0));
|
do_check_false(gSTSService.isStsHost("subdomain.www.torproject.org", 0));
|
||||||
do_check_false(is_sts_host("subdomain.www.torproject.org", 0));
|
|
||||||
|
|
||||||
var uri = Services.io.newURI("http://subdomain.bugzilla.mozilla.org", null, null);
|
var uri = Services.io.newURI("http://subdomain.bugzilla.mozilla.org", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=0", 0);
|
||||||
"max-age=0", 0);
|
|
||||||
// we received a header with "max-age=0", so we have "no information"
|
// we received a header with "max-age=0", so we have "no information"
|
||||||
// regarding the sts state of subdomain.bugzilla.mozilla.org specifically,
|
// regarding the sts state of subdomain.bugzilla.mozilla.org specifically,
|
||||||
// but it is actually still an STS host, because of the preloaded
|
// but it is actually still an STS host, because of the preloaded
|
||||||
@ -118,21 +109,20 @@ function test_part1() {
|
|||||||
// |-- subdomain.bugzilla.mozilla.org IS sts host
|
// |-- subdomain.bugzilla.mozilla.org IS sts host
|
||||||
// | `-- another.subdomain.bugzilla.mozilla.org IS sts host
|
// | `-- another.subdomain.bugzilla.mozilla.org IS sts host
|
||||||
// `-- sibling.bugzilla.mozilla.org IS sts host
|
// `-- sibling.bugzilla.mozilla.org IS sts host
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
do_check_true(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
do_check_true(is_sts_host("sibling.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("sibling.bugzilla.mozilla.org", 0));
|
||||||
do_check_true(is_sts_host("another.subdomain.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("another.subdomain.bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=1000", 0);
|
||||||
"max-age=1000", 0);
|
|
||||||
// Here's what we have now:
|
// Here's what we have now:
|
||||||
// |-- bugzilla.mozilla.org (in preload list, includes subdomains) IS sts host
|
// |-- bugzilla.mozilla.org (in preload list, includes subdomains) IS sts host
|
||||||
// |-- subdomain.bugzilla.mozilla.org (include subdomains is false) IS sts host
|
// |-- subdomain.bugzilla.mozilla.org (include subdomains is false) IS sts host
|
||||||
// | `-- another.subdomain.bugzilla.mozilla.org IS NOT sts host
|
// | `-- another.subdomain.bugzilla.mozilla.org IS NOT sts host
|
||||||
// `-- sibling.bugzilla.mozilla.org IS sts host
|
// `-- sibling.bugzilla.mozilla.org IS sts host
|
||||||
do_check_true(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
do_check_true(is_sts_host("sibling.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("sibling.bugzilla.mozilla.org", 0));
|
||||||
do_check_false(is_sts_host("another.subdomain.bugzilla.mozilla.org", 0));
|
do_check_false(gSTSService.isStsHost("another.subdomain.bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// Simulate leaving private browsing mode
|
// Simulate leaving private browsing mode
|
||||||
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
|
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
|
||||||
@ -143,27 +133,24 @@ const IS_PRIVATE = Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
|
|||||||
function test_private_browsing1() {
|
function test_private_browsing1() {
|
||||||
clearStsState();
|
clearStsState();
|
||||||
// sanity - bugzilla.mozilla.org is preloaded, includeSubdomains set
|
// sanity - bugzilla.mozilla.org is preloaded, includeSubdomains set
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", IS_PRIVATE));
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_true(is_sts_host("a.b.c.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
do_check_true(gSTSService.isStsHost("a.b.c.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
|
|
||||||
var uri = Services.io.newURI("http://bugzilla.mozilla.org", null, null);
|
var uri = Services.io.newURI("http://bugzilla.mozilla.org", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=0", IS_PRIVATE);
|
||||||
"max-age=0", IS_PRIVATE);
|
do_check_false(gSTSService.isStsHost("bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_false(is_sts_host("bugzilla.mozilla.org", IS_PRIVATE));
|
do_check_false(gSTSService.isStsHost("a.b.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_false(is_sts_host("a.b.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
|
||||||
|
|
||||||
// check adding it back in
|
// check adding it back in
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=1000", IS_PRIVATE);
|
||||||
"max-age=1000", IS_PRIVATE);
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", IS_PRIVATE));
|
|
||||||
// but no includeSubdomains this time
|
// but no includeSubdomains this time
|
||||||
do_check_false(is_sts_host("b.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
do_check_false(gSTSService.isStsHost("b.subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
|
|
||||||
// do the hokey-pokey...
|
// do the hokey-pokey...
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=0", IS_PRIVATE);
|
||||||
"max-age=0", IS_PRIVATE);
|
do_check_false(gSTSService.isStsHost("bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_false(is_sts_host("bugzilla.mozilla.org", IS_PRIVATE));
|
do_check_false(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
||||||
do_check_false(is_sts_host("subdomain.bugzilla.mozilla.org", IS_PRIVATE));
|
|
||||||
|
|
||||||
// TODO unfortunately we don't have a good way to know when an entry
|
// TODO unfortunately we don't have a good way to know when an entry
|
||||||
// has expired in the permission manager, so we can't yet extend this test
|
// has expired in the permission manager, so we can't yet extend this test
|
||||||
@ -174,12 +161,11 @@ function test_private_browsing1() {
|
|||||||
// a site on the preload list, and that header later expires. We need to
|
// a site on the preload list, and that header later expires. We need to
|
||||||
// then treat that host as no longer an sts host.)
|
// then treat that host as no longer an sts host.)
|
||||||
// (sanity check first - this should be in the preload list)
|
// (sanity check first - this should be in the preload list)
|
||||||
do_check_true(is_sts_host("login.persona.org", IS_PRIVATE));
|
do_check_true(gSTSService.isStsHost("login.persona.org", IS_PRIVATE));
|
||||||
var uri = Services.io.newURI("http://login.persona.org", null, null);
|
var uri = Services.io.newURI("http://login.persona.org", null, null);
|
||||||
gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
|
gSTSService.processStsHeader(uri, "max-age=1", IS_PRIVATE);
|
||||||
"max-age=1", IS_PRIVATE);
|
|
||||||
do_timeout(1250, function() {
|
do_timeout(1250, function() {
|
||||||
do_check_false(is_sts_host("login.persona.org", IS_PRIVATE));
|
do_check_false(gSTSService.isStsHost("login.persona.org", IS_PRIVATE));
|
||||||
// Simulate leaving private browsing mode
|
// Simulate leaving private browsing mode
|
||||||
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
|
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
|
||||||
});
|
});
|
||||||
@ -187,13 +173,13 @@ function test_private_browsing1() {
|
|||||||
|
|
||||||
function test_private_browsing2() {
|
function test_private_browsing2() {
|
||||||
// if this test gets this far, it means there's a private browsing service
|
// if this test gets this far, it means there's a private browsing service
|
||||||
do_check_true(is_sts_host("bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
// the bugzilla.mozilla.org entry has includeSubdomains set
|
// the bugzilla.mozilla.org entry has includeSubdomains set
|
||||||
do_check_true(is_sts_host("subdomain.bugzilla.mozilla.org", 0));
|
do_check_true(gSTSService.isStsHost("subdomain.bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// Now that we're out of private browsing mode, we need to make sure
|
// Now that we're out of private browsing mode, we need to make sure
|
||||||
// we've "forgotten" that we "forgot" this site's sts status.
|
// we've "forgotten" that we "forgot" this site's sts status.
|
||||||
do_check_true(is_sts_host("login.persona.org", 0));
|
do_check_true(gSTSService.isStsHost("login.persona.org", 0));
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,20 @@
|
|||||||
// on the preload list for a long time.
|
// on the preload list for a long time.
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
let SSService = Cc["@mozilla.org/ssservice;1"]
|
let STSService = Cc["@mozilla.org/stsservice;1"]
|
||||||
.getService(Ci.nsISiteSecurityService);
|
.getService(Ci.nsIStrictTransportSecurityService);
|
||||||
|
|
||||||
let uri = Services.io.newURI("https://bugzilla.mozilla.org", null, null);
|
|
||||||
// check that a host on the preload list is identified as an sts host
|
// check that a host on the preload list is identified as an sts host
|
||||||
do_check_true(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
|
do_check_true(STSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// now simulate that it's 19 weeks later than it actually is
|
// now simulate that it's 19 weeks later than it actually is
|
||||||
let offsetSeconds = 19 * 7 * 24 * 60 * 60;
|
let offsetSeconds = 19 * 7 * 24 * 60 * 60;
|
||||||
Services.prefs.setIntPref("test.currentTimeOffsetSeconds", offsetSeconds);
|
Services.prefs.setIntPref("test.currentTimeOffsetSeconds", offsetSeconds);
|
||||||
|
|
||||||
// check that the preloaded host is no longer considered sts
|
// check that the preloaded host is no longer considered sts
|
||||||
do_check_false(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
|
do_check_false(STSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
|
|
||||||
// just make sure we can get everything back to normal
|
// just make sure we can get everything back to normal
|
||||||
Services.prefs.clearUserPref("test.currentTimeOffsetSeconds");
|
Services.prefs.clearUserPref("test.currentTimeOffsetSeconds");
|
||||||
do_check_true(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
|
do_check_true(STSService.isStsHost("bugzilla.mozilla.org", 0));
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ const HEADER = "/* This Source Code Form is subject to the terms of the Mozilla
|
|||||||
"\n" +
|
"\n" +
|
||||||
"/*****************************************************************************/\n" +
|
"/*****************************************************************************/\n" +
|
||||||
"/* This is an automatically generated file. If you're not */\n" +
|
"/* This is an automatically generated file. If you're not */\n" +
|
||||||
"/* nsSiteSecurityService.cpp, you shouldn't be #including it. */\n" +
|
"/* nsStrictTransportSecurityService.cpp, you shouldn't be #including it. */\n" +
|
||||||
"/*****************************************************************************/\n" +
|
"/*****************************************************************************/\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"#include <stdint.h>\n";
|
"#include <stdint.h>\n";
|
||||||
@ -110,8 +110,8 @@ function getHosts(rawdata) {
|
|||||||
return hosts;
|
return hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gSSService = Cc["@mozilla.org/ssservice;1"]
|
var gSTSService = Cc["@mozilla.org/stsservice;1"]
|
||||||
.getService(Ci.nsISiteSecurityService);
|
.getService(Ci.nsIStrictTransportSecurityService);
|
||||||
|
|
||||||
function processStsHeader(host, header, status) {
|
function processStsHeader(host, header, status) {
|
||||||
var maxAge = { value: 0 };
|
var maxAge = { value: 0 };
|
||||||
@ -120,7 +120,7 @@ function processStsHeader(host, header, status) {
|
|||||||
if (header != null) {
|
if (header != null) {
|
||||||
try {
|
try {
|
||||||
var uri = Services.io.newURI("https://" + host.name, null, null);
|
var uri = Services.io.newURI("https://" + host.name, null, null);
|
||||||
gSSService.processStsHeader(uri, header, 0, maxAge, includeSubdomains);
|
gSTSService.processStsHeader(uri, header, 0, maxAge, includeSubdomains);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dump("ERROR: could not process header '" + header + "' from " +
|
dump("ERROR: could not process header '" + header + "' from " +
|
||||||
|
Loading…
Reference in New Issue
Block a user