2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 sw=2 et tw=80: */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nscore.h"
|
|
|
|
#include "nsScriptSecurityManager.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "plstr.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsIURI.h"
|
2008-03-22 09:50:47 -07:00
|
|
|
#include "nsIFileURL.h"
|
|
|
|
#include "nsIProtocolHandler.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "nsJSPrincipals.h"
|
2009-06-16 05:38:51 -07:00
|
|
|
#include "nsVoidArray.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsHashtable.h"
|
|
|
|
#include "nsIObjectInputStream.h"
|
|
|
|
#include "nsIObjectOutputStream.h"
|
|
|
|
#include "nsIClassInfoImpl.h"
|
2012-07-27 07:03:27 -07:00
|
|
|
#include "nsError.h"
|
2010-01-22 13:38:21 -08:00
|
|
|
#include "nsIContentSecurityPolicy.h"
|
2012-07-12 01:10:15 -07:00
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "jswrapper.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsPrincipal.h"
|
|
|
|
|
2011-06-19 20:00:16 -07:00
|
|
|
#include "mozilla/Preferences.h"
|
2012-03-12 15:53:18 -07:00
|
|
|
#include "mozilla/HashFunctions.h"
|
2009-06-16 04:00:06 -07:00
|
|
|
|
2012-08-27 19:43:57 -07:00
|
|
|
#include "nsIAppsService.h"
|
|
|
|
#include "mozIApplication.h"
|
|
|
|
|
2011-06-19 20:00:16 -07:00
|
|
|
using namespace mozilla;
|
2009-06-16 04:00:06 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool gCodeBasePrincipalSupport = false;
|
|
|
|
static bool gIsObservingCodeBasePrincipalSupport = false;
|
2009-06-16 04:00:06 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool URIIsImmutable(nsIURI* aURI)
|
2007-06-18 08:07:02 -07:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isMutable;
|
2007-06-18 08:07:02 -07:00
|
|
|
return
|
|
|
|
mutableObj &&
|
|
|
|
NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
|
|
|
|
!isMutable;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Static member variables
|
2012-06-09 15:19:26 -07:00
|
|
|
const char nsBasePrincipal::sInvalid[] = "Invalid";
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::AddRef()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-22 08:56:38 -07:00
|
|
|
NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
|
2007-03-22 10:30:00 -07:00
|
|
|
// XXXcaa does this need to be threadsafe? See bug 143559.
|
2012-03-09 01:48:50 -08:00
|
|
|
nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_LOG_ADDREF(this, count, "nsBasePrincipal", sizeof(*this));
|
2007-03-22 10:30:00 -07:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::Release()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-03-09 01:48:50 -08:00
|
|
|
NS_PRECONDITION(0 != refcount, "dup release");
|
|
|
|
nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_LOG_RELEASE(this, count, "nsBasePrincipal");
|
2007-03-22 10:30:00 -07:00
|
|
|
if (count == 0) {
|
2010-07-05 02:42:18 -07:00
|
|
|
delete this;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2012-10-21 23:29:55 -07:00
|
|
|
nsBasePrincipal::nsBasePrincipal() : mSecurityPolicy(nullptr)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-06-19 20:00:16 -07:00
|
|
|
if (!gIsObservingCodeBasePrincipalSupport) {
|
|
|
|
nsresult rv =
|
|
|
|
Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
|
|
|
|
"signed.applets.codebase_principal_support",
|
2011-10-17 07:59:28 -07:00
|
|
|
false);
|
2011-06-19 20:00:16 -07:00
|
|
|
gIsObservingCodeBasePrincipalSupport = NS_SUCCEEDED(rv);
|
|
|
|
NS_WARN_IF_FALSE(gIsObservingCodeBasePrincipalSupport,
|
|
|
|
"Installing gCodeBasePrincipalSupport failed!");
|
2009-06-16 04:00:06 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::~nsBasePrincipal(void)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
SetSecurityPolicy(nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetSecurityPolicy(void** aSecurityPolicy)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (mSecurityPolicy && mSecurityPolicy->IsInvalid())
|
2012-07-30 07:20:58 -07:00
|
|
|
SetSecurityPolicy(nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
*aSecurityPolicy = (void *) mSecurityPolicy;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::SetSecurityPolicy(void* aSecurityPolicy)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
DomainPolicy *newPolicy = reinterpret_cast<DomainPolicy *>(aSecurityPolicy);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (newPolicy)
|
|
|
|
newPolicy->Hold();
|
|
|
|
|
|
|
|
if (mSecurityPolicy)
|
|
|
|
mSecurityPolicy->Drop();
|
|
|
|
|
|
|
|
mSecurityPolicy = newPolicy;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::CertificateEquals(nsIPrincipal *aOther)
|
2011-05-19 04:31:54 -07:00
|
|
|
{
|
2011-09-28 23:19:26 -07:00
|
|
|
bool otherHasCert;
|
2011-05-19 04:31:54 -07:00
|
|
|
aOther->GetHasCertificate(&otherHasCert);
|
2012-07-30 07:20:58 -07:00
|
|
|
if (otherHasCert != (mCert != nullptr)) {
|
2011-05-19 04:31:54 -07:00
|
|
|
// One has a cert while the other doesn't. Not equal.
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2011-05-19 04:31:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!mCert)
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2011-05-19 04:31:54 -07:00
|
|
|
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString str;
|
2011-05-19 04:31:54 -07:00
|
|
|
aOther->GetFingerprint(str);
|
|
|
|
if (!str.Equals(mCert->fingerprint))
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2011-05-19 04:31:54 -07:00
|
|
|
|
2012-10-21 23:29:55 -07:00
|
|
|
// If either subject name is empty, just let the result stand, but if they're
|
2011-05-19 04:31:54 -07:00
|
|
|
// both non-empty, only claim equality if they're equal.
|
|
|
|
if (!mCert->subjectName.IsEmpty()) {
|
|
|
|
// Check the other principal's subject name
|
|
|
|
aOther->GetSubjectName(str);
|
|
|
|
return str.Equals(mCert->subjectName) || str.IsEmpty();
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2011-05-19 04:31:54 -07:00
|
|
|
}
|
|
|
|
|
2008-02-26 19:45:29 -08:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetHasCertificate(bool* aResult)
|
2008-02-26 19:45:29 -08:00
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
*aResult = (mCert != nullptr);
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
nsresult
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::SetCertificate(const nsACString& aFingerprint,
|
|
|
|
const nsACString& aSubjectName,
|
|
|
|
const nsACString& aPrettyName,
|
|
|
|
nsISupports* aCert)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(!mCert);
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (aFingerprint.IsEmpty()) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
mCert = new Certificate(aFingerprint, aSubjectName, aPrettyName, aCert);
|
|
|
|
if (!mCert) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetFingerprint(nsACString& aFingerprint)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mCert);
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
aFingerprint = mCert->fingerprint;
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetPrettyName(nsACString& aName)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mCert);
|
2008-03-22 09:50:47 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
aName = mCert->prettyName;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetSubjectName(nsACString& aName)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mCert);
|
|
|
|
|
|
|
|
aName = mCert->subjectName;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetCertificate(nsISupports** aCertificate)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
if (mCert) {
|
|
|
|
NS_IF_ADDREF(*aCertificate = mCert->cert);
|
2008-02-26 19:45:29 -08:00
|
|
|
}
|
2012-06-09 15:19:26 -07:00
|
|
|
else {
|
2012-07-30 07:20:58 -07:00
|
|
|
*aCertificate = nullptr;
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-02-26 19:45:29 -08:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_IF_ADDREF(*aCsp = mCSP);
|
2008-02-26 19:45:29 -08:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
// If CSP was already set, it should not be destroyed! Instead, it should
|
|
|
|
// get set anew when a new principal is created.
|
|
|
|
if (mCSP)
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
mCSP = aCsp;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2012-06-09 15:19:26 -07:00
|
|
|
nsBasePrincipal::EnsureCertData(const nsACString& aSubjectName,
|
|
|
|
const nsACString& aPrettyName,
|
|
|
|
nsISupports* aCert)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mCert);
|
|
|
|
|
|
|
|
if (!mCert->subjectName.IsEmpty() &&
|
|
|
|
!mCert->subjectName.Equals(aSubjectName)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
mCert->subjectName = aSubjectName;
|
|
|
|
mCert->prettyName = aPrettyName;
|
|
|
|
mCert->cert = aCert;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
void nsPrincipal::dumpImpl()
|
|
|
|
{
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString str;
|
2012-06-09 15:19:26 -07:00
|
|
|
GetScriptLocation(str);
|
2012-07-19 22:44:03 -07:00
|
|
|
fprintf(stderr, "nsPrincipal (%p) = %s\n", static_cast<void*>(this), str.get());
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_IMPL_CLASSINFO(nsPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
|
|
|
|
NS_PRINCIPAL_CID)
|
|
|
|
NS_IMPL_QUERY_INTERFACE2_CI(nsPrincipal,
|
|
|
|
nsIPrincipal,
|
|
|
|
nsISerializable)
|
|
|
|
NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal,
|
|
|
|
nsIPrincipal,
|
|
|
|
nsISerializable)
|
2012-06-10 12:25:17 -07:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal)
|
2012-06-09 15:19:26 -07:00
|
|
|
|
|
|
|
nsPrincipal::nsPrincipal()
|
2012-07-19 22:44:03 -07:00
|
|
|
: mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
|
|
|
|
, mInMozBrowser(false)
|
|
|
|
, mCodebaseImmutable(false)
|
2012-06-10 12:25:17 -07:00
|
|
|
, mDomainImmutable(false)
|
|
|
|
, mInitialized(false)
|
2012-06-09 15:19:26 -07:00
|
|
|
{ }
|
|
|
|
|
|
|
|
nsPrincipal::~nsPrincipal()
|
|
|
|
{ }
|
|
|
|
|
2012-05-02 14:57:34 -07:00
|
|
|
nsresult
|
2012-06-09 15:19:26 -07:00
|
|
|
nsPrincipal::Init(const nsACString& aCertFingerprint,
|
|
|
|
const nsACString& aSubjectName,
|
|
|
|
const nsACString& aPrettyName,
|
|
|
|
nsISupports* aCert,
|
2012-07-19 22:44:03 -07:00
|
|
|
nsIURI *aCodebase,
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t aAppId,
|
2012-07-19 22:44:03 -07:00
|
|
|
bool aInMozBrowser)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(!mInitialized);
|
|
|
|
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these.
|
|
|
|
|
|
|
|
mInitialized = true;
|
|
|
|
|
|
|
|
mCodebase = NS_TryToMakeImmutable(aCodebase);
|
|
|
|
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
|
|
|
|
2012-07-19 22:44:03 -07:00
|
|
|
mAppId = aAppId;
|
|
|
|
mInMozBrowser = aInMozBrowser;
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (aCertFingerprint.IsEmpty())
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
return SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPrincipal::GetScriptLocation(nsACString &aStr)
|
|
|
|
{
|
|
|
|
if (mCert) {
|
|
|
|
aStr.Assign(mCert->fingerprint);
|
|
|
|
} else {
|
|
|
|
mCodebase->GetSpec(aStr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-18 21:23:44 -07:00
|
|
|
/* static */ nsresult
|
|
|
|
nsPrincipal::GetOriginForURI(nsIURI* aURI, char **aOrigin)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-07-18 21:23:44 -07:00
|
|
|
if (!aURI) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2012-07-30 07:20:58 -07:00
|
|
|
*aOrigin = nullptr;
|
2012-06-09 15:19:26 -07:00
|
|
|
|
2012-07-18 21:23:44 -07:00
|
|
|
nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
|
2012-06-09 15:19:26 -07:00
|
|
|
if (!origin) {
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-09-28 07:31:04 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString hostPort;
|
2012-06-09 15:19:26 -07:00
|
|
|
|
|
|
|
// chrome: URLs don't have a meaningful origin, so make
|
|
|
|
// sure we just get the full spec for them.
|
|
|
|
// XXX this should be removed in favor of the solution in
|
|
|
|
// bug 160042.
|
|
|
|
bool isChrome;
|
|
|
|
nsresult rv = origin->SchemeIs("chrome", &isChrome);
|
|
|
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
|
|
|
rv = origin->GetAsciiHost(hostPort);
|
|
|
|
// Some implementations return an empty string, treat it as no support
|
|
|
|
// for asciiHost by that implementation.
|
2012-07-18 21:23:44 -07:00
|
|
|
if (hostPort.IsEmpty()) {
|
2012-06-09 15:19:26 -07:00
|
|
|
rv = NS_ERROR_FAILURE;
|
2012-07-18 21:23:44 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t port;
|
2012-06-09 15:19:26 -07:00
|
|
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
|
|
|
rv = origin->GetPort(&port);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
|
|
|
if (port != -1) {
|
|
|
|
hostPort.AppendLiteral(":");
|
|
|
|
hostPort.AppendInt(port, 10);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString scheme;
|
2012-06-09 15:19:26 -07:00
|
|
|
rv = origin->GetScheme(scheme);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-07-18 21:23:44 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
*aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Some URIs (e.g., nsSimpleURI) don't support asciiHost. Just
|
|
|
|
// get the full spec.
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString spec;
|
2012-06-09 15:19:26 -07:00
|
|
|
// XXX nsMozIconURI and nsJARURI don't implement this correctly, they
|
|
|
|
// both fall back to GetSpec. That needs to be fixed.
|
|
|
|
rv = origin->GetAsciiSpec(spec);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-07-18 21:23:44 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
*aOrigin = ToNewCString(spec);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-07-18 21:23:44 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetOrigin(char **aOrigin)
|
|
|
|
{
|
|
|
|
return GetOriginForURI(mCodebase, aOrigin);
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsPrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
if (!aOther) {
|
|
|
|
NS_WARNING("Need a principal to compare this to!");
|
|
|
|
*aResult = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2012-06-09 15:19:26 -07:00
|
|
|
|
|
|
|
if (this != aOther) {
|
|
|
|
if (!CertificateEquals(aOther)) {
|
|
|
|
*aResult = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (mCert) {
|
|
|
|
// If either principal has no URI, it's the saved principal from
|
|
|
|
// preferences; in that case, test true. Do NOT test true if the two
|
|
|
|
// principals have URIs with different codebases.
|
|
|
|
nsCOMPtr<nsIURI> otherURI;
|
|
|
|
nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
*aResult = false;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!otherURI || !mCodebase) {
|
|
|
|
*aResult = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fall through to the codebase comparison.
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
// Codebases are equal if they have the same origin.
|
|
|
|
*aResult =
|
|
|
|
NS_SUCCEEDED(nsScriptSecurityManager::CheckSameOriginPrincipal(this,
|
|
|
|
aOther));
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
*aResult = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
if (this == aOther) {
|
|
|
|
*aResult = true;
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
*aResult = false;
|
|
|
|
if (!CertificateEquals(aOther)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
nsCOMPtr<nsIURI> otherURI;
|
|
|
|
nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_ASSERTION(mCodebase,
|
|
|
|
"shouldn't be calling this on principals from preferences");
|
|
|
|
|
|
|
|
// Compare codebases.
|
|
|
|
*aResult = nsScriptSecurityManager::SecurityCompareURIs(mCodebase,
|
|
|
|
otherURI);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-06-09 15:19:26 -07:00
|
|
|
nsPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
return Equals(aOther, aResult);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
|
|
|
|
{
|
|
|
|
return EqualsIgnoringDomain(aOther, aResult);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetURI(nsIURI** aURI)
|
|
|
|
{
|
2007-06-18 08:07:02 -07:00
|
|
|
if (mCodebaseImmutable) {
|
|
|
|
NS_ADDREF(*aURI = mCodebase);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!mCodebase) {
|
2012-07-30 07:20:58 -07:00
|
|
|
*aURI = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_EnsureSafeToReturn(mCodebase, aURI);
|
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
static bool
|
|
|
|
URIIsLocalFile(nsIURI *aURI)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
bool isFile;
|
|
|
|
nsCOMPtr<nsINetUtil> util = do_GetNetUtil();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return util && NS_SUCCEEDED(util->ProtocolHasFlags(aURI,
|
|
|
|
nsIProtocolHandler::URI_IS_LOCAL_FILE,
|
|
|
|
&isFile)) &&
|
|
|
|
isFile;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-20 11:34:33 -07:00
|
|
|
nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-20 11:34:33 -07:00
|
|
|
if (aAllowIfInheritsPrincipal) {
|
|
|
|
// If the caller specified to allow loads of URIs that inherit
|
|
|
|
// our principal, allow the load if this URI inherits its principal
|
|
|
|
if (nsPrincipal::IsPrincipalInherited(aURI)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (!nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
|
|
|
|
if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
|
|
|
|
URIIsLocalFile(aURI)) {
|
|
|
|
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(aURI));
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (!URIIsLocalFile(mCodebase)) {
|
|
|
|
// If the codebase is not also a file: uri then forget it
|
|
|
|
// (don't want resource: principals in a file: doc)
|
|
|
|
//
|
|
|
|
// note: we're not de-nesting jar: uris here, we want to
|
|
|
|
// keep archive content bottled up in its own little island
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (aReport) {
|
|
|
|
nsScriptSecurityManager::ReportError(
|
2012-07-30 07:20:58 -07:00
|
|
|
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
//
|
|
|
|
// pull out the internal files
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIFileURL> codebaseFileURL(do_QueryInterface(mCodebase));
|
|
|
|
nsCOMPtr<nsIFile> targetFile;
|
|
|
|
nsCOMPtr<nsIFile> codebaseFile;
|
|
|
|
bool targetIsDir;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
// Make sure targetFile is not a directory (bug 209234)
|
|
|
|
// and that it exists w/out unescaping (bug 395343)
|
|
|
|
|
|
|
|
if (!codebaseFileURL || !fileURL ||
|
|
|
|
NS_FAILED(fileURL->GetFile(getter_AddRefs(targetFile))) ||
|
|
|
|
NS_FAILED(codebaseFileURL->GetFile(getter_AddRefs(codebaseFile))) ||
|
|
|
|
!targetFile || !codebaseFile ||
|
|
|
|
NS_FAILED(targetFile->Normalize()) ||
|
|
|
|
NS_FAILED(codebaseFile->Normalize()) ||
|
|
|
|
NS_FAILED(targetFile->IsDirectory(&targetIsDir)) ||
|
|
|
|
targetIsDir) {
|
|
|
|
if (aReport) {
|
|
|
|
nsScriptSecurityManager::ReportError(
|
2012-07-30 07:20:58 -07:00
|
|
|
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
//
|
|
|
|
// If the file to be loaded is in a subdirectory of the codebase
|
|
|
|
// (or same-dir if codebase is not a directory) then it will
|
|
|
|
// inherit its codebase principal and be scriptable by that codebase.
|
|
|
|
//
|
|
|
|
bool codebaseIsDir;
|
|
|
|
bool contained = false;
|
|
|
|
nsresult rv = codebaseFile->IsDirectory(&codebaseIsDir);
|
|
|
|
if (NS_SUCCEEDED(rv) && codebaseIsDir) {
|
|
|
|
rv = codebaseFile->Contains(targetFile, true, &contained);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIFile> codebaseParent;
|
|
|
|
rv = codebaseFile->GetParent(getter_AddRefs(codebaseParent));
|
|
|
|
if (NS_SUCCEEDED(rv) && codebaseParent) {
|
|
|
|
rv = codebaseParent->Contains(targetFile, true, &contained);
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (NS_SUCCEEDED(rv) && contained) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
if (aReport) {
|
|
|
|
nsScriptSecurityManager::ReportError(
|
2012-07-30 07:20:58 -07:00
|
|
|
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2012-06-09 15:19:26 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
void
|
|
|
|
nsPrincipal::SetURI(nsIURI* aURI)
|
2010-01-22 13:38:21 -08:00
|
|
|
{
|
2012-06-09 15:19:26 -07:00
|
|
|
mCodebase = NS_TryToMakeImmutable(aURI);
|
|
|
|
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
2010-01-22 13:38:21 -08:00
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsPrincipal::GetHashValue(uint32_t* aValue)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(mCert || mCodebase, "Need a cert or codebase");
|
|
|
|
|
|
|
|
// If there is a certificate, it takes precendence over the codebase.
|
|
|
|
if (mCert) {
|
2012-03-12 15:53:18 -07:00
|
|
|
*aValue = HashString(mCert->fingerprint);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
else {
|
2008-10-08 06:16:27 -07:00
|
|
|
*aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetDomain(nsIURI** aDomain)
|
|
|
|
{
|
|
|
|
if (!mDomain) {
|
2012-07-30 07:20:58 -07:00
|
|
|
*aDomain = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-06-18 08:07:02 -07:00
|
|
|
if (mDomainImmutable) {
|
|
|
|
NS_ADDREF(*aDomain = mDomain);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_EnsureSafeToReturn(mDomain, aDomain);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::SetDomain(nsIURI* aDomain)
|
|
|
|
{
|
|
|
|
mDomain = NS_TryToMakeImmutable(aDomain);
|
2007-06-18 08:07:02 -07:00
|
|
|
mDomainImmutable = URIIsImmutable(mDomain);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Domain has changed, forget cached security policy
|
2012-07-30 07:20:58 -07:00
|
|
|
SetSecurityPolicy(nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-07-12 01:10:15 -07:00
|
|
|
// Recompute all wrappers between compartments using this principal and other
|
|
|
|
// non-chrome compartments.
|
|
|
|
JSContext *cx = nsContentUtils::GetSafeJSContext();
|
|
|
|
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
|
|
|
JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
|
|
|
|
bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
|
|
|
|
js::CompartmentsWithPrincipals(principals));
|
|
|
|
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
|
|
|
success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
|
|
|
|
js::ContentCompartmentsOnly());
|
|
|
|
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-07-19 22:44:03 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
|
|
|
|
|
|
|
mozilla::GetExtendedOrigin(mCodebase, mAppId, mInMozBrowser, aExtendedOrigin);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsPrincipal::GetAppStatus(uint16_t* aAppStatus)
|
2012-07-19 22:44:03 -07:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
|
|
|
|
|
|
|
*aAppStatus = GetAppStatus();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsPrincipal::GetAppId(uint32_t* aAppId)
|
2012-07-19 22:44:03 -07:00
|
|
|
{
|
|
|
|
if (mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aAppId = mAppId;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-07-31 08:47:20 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
|
|
|
|
{
|
|
|
|
*aIsInBrowserElement = mInMozBrowser;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-09-25 16:28:17 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::GetUnknownAppId(bool* aUnknownAppId)
|
|
|
|
{
|
|
|
|
*aUnknownAppId = mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::Read(nsIObjectInputStream* aStream)
|
|
|
|
{
|
2011-09-28 23:19:26 -07:00
|
|
|
bool haveCert;
|
2012-10-21 23:29:55 -07:00
|
|
|
nsresult rv = aStream->ReadBoolean(&haveCert);
|
2007-09-17 15:18:28 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCString fingerprint;
|
|
|
|
nsCString subjectName;
|
|
|
|
nsCString prettyName;
|
|
|
|
nsCOMPtr<nsISupports> cert;
|
|
|
|
if (haveCert) {
|
|
|
|
rv = NS_ReadOptionalCString(aStream, fingerprint);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
rv = NS_ReadOptionalCString(aStream, subjectName);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = NS_ReadOptionalCString(aStream, prettyName);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = aStream->ReadObject(true, getter_AddRefs(cert));
|
2007-09-17 15:18:28 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
nsCOMPtr<nsIURI> codebase;
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase));
|
2007-09-17 15:18:28 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-07-25 17:12:03 -07:00
|
|
|
nsCOMPtr<nsIURI> domain;
|
|
|
|
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(domain));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t appId;
|
2012-07-19 22:44:03 -07:00
|
|
|
rv = aStream->Read32(&appId);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
bool inMozBrowser;
|
|
|
|
rv = aStream->ReadBoolean(&inMozBrowser);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = Init(fingerprint, subjectName, prettyName, cert, codebase, appId, inMozBrowser);
|
2007-09-17 15:18:28 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
SetDomain(domain);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
|
|
|
{
|
2007-09-17 15:18:28 -07:00
|
|
|
NS_ENSURE_STATE(mCert || mCodebase);
|
|
|
|
|
2012-10-21 23:29:55 -07:00
|
|
|
nsresult rv = aStream->WriteBoolean(mCert != nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
if (mCert) {
|
|
|
|
NS_ENSURE_STATE(mCert->cert);
|
|
|
|
|
|
|
|
rv = NS_WriteOptionalStringZ(aStream, mCert->fingerprint.get());
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = NS_WriteOptionalStringZ(aStream, mCert->subjectName.get());
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = NS_WriteOptionalStringZ(aStream, mCert->prettyName.get());
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2007-09-17 15:18:28 -07:00
|
|
|
|
|
|
|
rv = aStream->WriteCompoundObject(mCert->cert, NS_GET_IID(nsISupports),
|
2011-10-17 07:59:28 -07:00
|
|
|
true);
|
2007-09-17 15:18:28 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-09-17 15:18:28 -07:00
|
|
|
|
|
|
|
// mSecurityPolicy is an optimization; it'll get looked up again as needed.
|
|
|
|
// Don't bother saving and restoring it, esp. since it might change if
|
|
|
|
// preferences change.
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
|
2011-10-17 07:59:28 -07:00
|
|
|
true);
|
2007-09-17 15:18:28 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
|
2011-10-17 07:59:28 -07:00
|
|
|
true);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-07-19 22:44:03 -07:00
|
|
|
aStream->Write32(mAppId);
|
|
|
|
aStream->WriteBoolean(mInMozBrowser);
|
|
|
|
|
2007-09-17 15:18:28 -07:00
|
|
|
// mCodebaseImmutable and mDomainImmutable will be recomputed based
|
|
|
|
// on the deserialized URIs in Read().
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2012-06-09 15:19:26 -07:00
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
uint16_t
|
2012-07-19 22:44:03 -07:00
|
|
|
nsPrincipal::GetAppStatus()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
|
|
|
|
|
|
|
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
|
|
|
|
// and they are not inside a mozbrowser.
|
2012-08-27 19:43:57 -07:00
|
|
|
if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
|
|
|
|
mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
|
|
|
|
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
|
|
|
NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
|
|
|
nsCOMPtr<mozIDOMApplication> domApp;
|
|
|
|
appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
|
|
|
|
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
|
|
|
|
NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
|
|
|
uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
|
|
|
|
NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
|
|
|
|
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString origin;
|
2012-08-27 19:43:57 -07:00
|
|
|
NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
|
|
|
|
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
nsString appOrigin;
|
|
|
|
NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
|
|
|
|
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
|
|
|
// We go from string -> nsIURI -> origin to be sure we
|
|
|
|
// compare two punny-encoded origins.
|
|
|
|
nsCOMPtr<nsIURI> appURI;
|
|
|
|
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
|
|
|
|
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString appOriginPunned;
|
2012-08-27 19:43:57 -07:00
|
|
|
NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
|
|
|
|
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
|
|
|
|
|
|
|
if (!appOriginPunned.Equals(origin)) {
|
|
|
|
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2012-07-19 22:44:03 -07:00
|
|
|
}
|
2012-06-09 15:19:26 -07:00
|
|
|
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
|
|
|
|
static const char EXPANDED_PRINCIPAL_SPEC[] = "[Expanded Principal]";
|
|
|
|
|
|
|
|
NS_IMPL_CLASSINFO(nsExpandedPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
|
|
|
|
NS_EXPANDEDPRINCIPAL_CID)
|
|
|
|
NS_IMPL_QUERY_INTERFACE2_CI(nsExpandedPrincipal,
|
|
|
|
nsIPrincipal,
|
|
|
|
nsIExpandedPrincipal)
|
|
|
|
NS_IMPL_CI_INTERFACE_GETTER2(nsExpandedPrincipal,
|
|
|
|
nsIPrincipal,
|
|
|
|
nsIExpandedPrincipal)
|
2012-06-10 12:25:17 -07:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
|
2012-06-09 15:19:26 -07:00
|
|
|
|
|
|
|
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr <nsIPrincipal> > &aWhiteList)
|
|
|
|
{
|
|
|
|
mPrincipals.AppendElements(aWhiteList);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsExpandedPrincipal::~nsExpandedPrincipal()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
|
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
*aDomain = nullptr;
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetOrigin(char** aOrigin)
|
|
|
|
{
|
|
|
|
*aOrigin = ToNewCString(NS_LITERAL_CSTRING(EXPANDED_PRINCIPAL_SPEC));
|
|
|
|
return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef nsresult (NS_STDCALL nsIPrincipal::*nsIPrincipalMemFn)(nsIPrincipal* aOther,
|
|
|
|
bool* aResult);
|
|
|
|
#define CALL_MEMBER_FUNCTION(THIS,MEM_FN) ((THIS)->*(MEM_FN))
|
|
|
|
|
|
|
|
// nsExpandedPrincipal::Equals and nsExpandedPrincipal::EqualsIgnoringDomain
|
|
|
|
// shares the same logic. The difference only that Equals requires 'this'
|
|
|
|
// and 'aOther' to Subsume each other while EqualsIgnoringDomain requires
|
|
|
|
// bidirectional SubsumesIgnoringDomain.
|
|
|
|
static nsresult
|
|
|
|
Equals(nsExpandedPrincipal* aThis, nsIPrincipalMemFn aFn, nsIPrincipal* aOther,
|
|
|
|
bool* aResult)
|
|
|
|
{
|
|
|
|
// If (and only if) 'aThis' and 'aOther' both Subsume/SubsumesIgnoringDomain
|
|
|
|
// each other, then they are Equal.
|
|
|
|
*aResult = false;
|
|
|
|
// Calling the corresponding subsume function on this (aFn).
|
|
|
|
nsresult rv = CALL_MEMBER_FUNCTION(aThis, aFn)(aOther, aResult);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!*aResult)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Calling the corresponding subsume function on aOther (aFn).
|
|
|
|
rv = CALL_MEMBER_FUNCTION(aOther, aFn)(aThis, aResult);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::Equals(nsIPrincipal* aOther, bool* aResult)
|
|
|
|
{
|
|
|
|
return ::Equals(this, &nsIPrincipal::Subsumes, aOther, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::EqualsIgnoringDomain(nsIPrincipal* aOther, bool* aResult)
|
|
|
|
{
|
|
|
|
return ::Equals(this, &nsIPrincipal::SubsumesIgnoringDomain, aOther, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsExpandedPrincipal::Subsumes and nsExpandedPrincipal::SubsumesIgnoringDomain
|
|
|
|
// shares the same logic. The difference only that Subsumes calls are replaced
|
|
|
|
//with SubsumesIgnoringDomain calls in the second case.
|
|
|
|
static nsresult
|
|
|
|
Subsumes(nsExpandedPrincipal* aThis, nsIPrincipalMemFn aFn, nsIPrincipal* aOther,
|
|
|
|
bool* aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
|
|
|
|
if (expanded) {
|
|
|
|
// If aOther is an ExpandedPrincipal too, check if all of its
|
|
|
|
// principals are subsumed.
|
|
|
|
nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
|
|
|
|
expanded->GetWhiteList(&otherList);
|
|
|
|
for (uint32_t i = 0; i < otherList->Length(); ++i){
|
|
|
|
rv = CALL_MEMBER_FUNCTION(aThis, aFn)((*otherList)[i], aResult);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!*aResult) {
|
|
|
|
// If we don't subsume at least one principal of aOther, return false.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// For a regular aOther, one of our principals must subsume it.
|
|
|
|
nsTArray< nsCOMPtr<nsIPrincipal> >* list;
|
|
|
|
aThis->GetWhiteList(&list);
|
|
|
|
for (uint32_t i = 0; i < list->Length(); ++i){
|
|
|
|
rv = CALL_MEMBER_FUNCTION((*list)[i], aFn)(aOther, aResult);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (*aResult) {
|
|
|
|
// If one of our principal subsumes it, return true.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef CALL_MEMBER_FUNCTION
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult)
|
|
|
|
{
|
|
|
|
return ::Subsumes(this, &nsIPrincipal::Subsumes, aOther, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::SubsumesIgnoringDomain(nsIPrincipal* aOther, bool* aResult)
|
|
|
|
{
|
|
|
|
return ::Subsumes(this, &nsIPrincipal::SubsumesIgnoringDomain, aOther, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-20 11:34:33 -07:00
|
|
|
nsExpandedPrincipal::CheckMayLoad(nsIURI* uri, bool aReport, bool aAllowIfInheritsPrincipal)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
|
2012-08-20 11:34:33 -07:00
|
|
|
rv = mPrincipals[i]->CheckMayLoad(uri, aReport, aAllowIfInheritsPrincipal);
|
2012-06-09 15:19:26 -07:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsExpandedPrincipal::GetHashValue(uint32_t* result)
|
2012-06-09 15:19:26 -07:00
|
|
|
{
|
|
|
|
MOZ_NOT_REACHED("extended principal should never be used as key in a hash map");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetURI(nsIURI** aURI)
|
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
*aURI = nullptr;
|
2012-06-09 15:19:26 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
|
|
|
|
{
|
|
|
|
*aWhiteList = &mPrincipals;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-07-19 22:44:03 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
|
|
|
{
|
2012-10-09 05:47:46 -07:00
|
|
|
return GetOrigin(getter_Copies(aExtendedOrigin));
|
2012-07-19 22:44:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsExpandedPrincipal::GetAppStatus(uint16_t* aAppStatus)
|
2012-07-19 22:44:03 -07:00
|
|
|
{
|
2012-10-09 05:47:46 -07:00
|
|
|
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
|
|
|
return NS_OK;
|
2012-07-19 22:44:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsExpandedPrincipal::GetAppId(uint32_t* aAppId)
|
2012-07-19 22:44:03 -07:00
|
|
|
{
|
2012-10-09 05:47:46 -07:00
|
|
|
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
|
|
return NS_OK;
|
2012-07-19 22:44:03 -07:00
|
|
|
}
|
|
|
|
|
2012-07-31 08:47:20 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
|
|
|
|
{
|
2012-10-09 05:47:46 -07:00
|
|
|
*aIsInBrowserElement = false;
|
|
|
|
return NS_OK;
|
2012-07-31 08:47:20 -07:00
|
|
|
}
|
|
|
|
|
2012-09-25 16:28:17 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::GetUnknownAppId(bool* aUnknownAppId)
|
|
|
|
{
|
|
|
|
*aUnknownAppId = false;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-06-09 15:19:26 -07:00
|
|
|
void
|
|
|
|
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
|
|
|
{
|
|
|
|
if (mCert) {
|
|
|
|
aStr.Assign(mCert->fingerprint);
|
|
|
|
} else {
|
|
|
|
// Is that a good idea to list it's principals?
|
|
|
|
aStr.Assign(EXPANDED_PRINCIPAL_SPEC);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
void nsExpandedPrincipal::dumpImpl()
|
|
|
|
{
|
2012-07-19 22:44:03 -07:00
|
|
|
fprintf(stderr, "nsExpandedPrincipal (%p)\n", static_cast<void*>(this));
|
2012-06-09 15:19:26 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//////////////////////////////////////////
|
|
|
|
// Methods implementing nsISerializable //
|
|
|
|
//////////////////////////////////////////
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|