caps/src/nsNullPrincipal.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /**
michael@0 7 * This is the principal that has no rights and can't be accessed by
michael@0 8 * anything other than itself and chrome; null principals are not
michael@0 9 * same-origin with anything but themselves.
michael@0 10 */
michael@0 11
michael@0 12 #include "mozilla/ArrayUtils.h"
michael@0 13
michael@0 14 #include "nsNullPrincipal.h"
michael@0 15 #include "nsNullPrincipalURI.h"
michael@0 16 #include "nsMemory.h"
michael@0 17 #include "nsIUUIDGenerator.h"
michael@0 18 #include "nsID.h"
michael@0 19 #include "nsNetUtil.h"
michael@0 20 #include "nsIClassInfoImpl.h"
michael@0 21 #include "nsNetCID.h"
michael@0 22 #include "nsError.h"
michael@0 23 #include "nsIScriptSecurityManager.h"
michael@0 24 #include "nsPrincipal.h"
michael@0 25 #include "nsScriptSecurityManager.h"
michael@0 26 #include "pratom.h"
michael@0 27
michael@0 28 using namespace mozilla;
michael@0 29
michael@0 30 NS_IMPL_CLASSINFO(nsNullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
michael@0 31 NS_NULLPRINCIPAL_CID)
michael@0 32 NS_IMPL_QUERY_INTERFACE_CI(nsNullPrincipal,
michael@0 33 nsIPrincipal,
michael@0 34 nsISerializable)
michael@0 35 NS_IMPL_CI_INTERFACE_GETTER(nsNullPrincipal,
michael@0 36 nsIPrincipal,
michael@0 37 nsISerializable)
michael@0 38
michael@0 39 NS_IMETHODIMP_(MozExternalRefCountType)
michael@0 40 nsNullPrincipal::AddRef()
michael@0 41 {
michael@0 42 NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
michael@0 43 nsrefcnt count = ++refcount;
michael@0 44 NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this));
michael@0 45 return count;
michael@0 46 }
michael@0 47
michael@0 48 NS_IMETHODIMP_(MozExternalRefCountType)
michael@0 49 nsNullPrincipal::Release()
michael@0 50 {
michael@0 51 NS_PRECONDITION(0 != refcount, "dup release");
michael@0 52 nsrefcnt count = --refcount;
michael@0 53 NS_LOG_RELEASE(this, count, "nsNullPrincipal");
michael@0 54 if (count == 0) {
michael@0 55 delete this;
michael@0 56 }
michael@0 57
michael@0 58 return count;
michael@0 59 }
michael@0 60
michael@0 61 nsNullPrincipal::nsNullPrincipal()
michael@0 62 {
michael@0 63 }
michael@0 64
michael@0 65 nsNullPrincipal::~nsNullPrincipal()
michael@0 66 {
michael@0 67 }
michael@0 68
michael@0 69 #define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":"
michael@0 70
michael@0 71 nsresult
michael@0 72 nsNullPrincipal::Init()
michael@0 73 {
michael@0 74 // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
michael@0 75 nsresult rv;
michael@0 76 nsCOMPtr<nsIUUIDGenerator> uuidgen =
michael@0 77 do_GetService("@mozilla.org/uuid-generator;1", &rv);
michael@0 78 NS_ENSURE_SUCCESS(rv, rv);
michael@0 79
michael@0 80 nsID id;
michael@0 81 rv = uuidgen->GenerateUUIDInPlace(&id);
michael@0 82 NS_ENSURE_SUCCESS(rv, rv);
michael@0 83
michael@0 84 char chars[NSID_LENGTH];
michael@0 85 id.ToProvidedString(chars);
michael@0 86
michael@0 87 uint32_t suffixLen = NSID_LENGTH - 1;
michael@0 88 uint32_t prefixLen = ArrayLength(NS_NULLPRINCIPAL_PREFIX) - 1;
michael@0 89
michael@0 90 // Use an nsCString so we only do the allocation once here and then share
michael@0 91 // with nsJSPrincipals
michael@0 92 nsCString str;
michael@0 93 str.SetCapacity(prefixLen + suffixLen);
michael@0 94
michael@0 95 str.Append(NS_NULLPRINCIPAL_PREFIX);
michael@0 96 str.Append(chars);
michael@0 97
michael@0 98 if (str.Length() != prefixLen + suffixLen) {
michael@0 99 NS_WARNING("Out of memory allocating null-principal URI");
michael@0 100 return NS_ERROR_OUT_OF_MEMORY;
michael@0 101 }
michael@0 102
michael@0 103 mURI = new nsNullPrincipalURI(str);
michael@0 104 NS_ENSURE_TRUE(mURI, NS_ERROR_OUT_OF_MEMORY);
michael@0 105
michael@0 106 return NS_OK;
michael@0 107 }
michael@0 108
michael@0 109 void
michael@0 110 nsNullPrincipal::GetScriptLocation(nsACString &aStr)
michael@0 111 {
michael@0 112 mURI->GetSpec(aStr);
michael@0 113 }
michael@0 114
michael@0 115 #ifdef DEBUG
michael@0 116 void nsNullPrincipal::dumpImpl()
michael@0 117 {
michael@0 118 nsAutoCString str;
michael@0 119 mURI->GetSpec(str);
michael@0 120 fprintf(stderr, "nsNullPrincipal (%p) = %s\n", this, str.get());
michael@0 121 }
michael@0 122 #endif
michael@0 123
michael@0 124 /**
michael@0 125 * nsIPrincipal implementation
michael@0 126 */
michael@0 127
michael@0 128 NS_IMETHODIMP
michael@0 129 nsNullPrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
michael@0 130 {
michael@0 131 // Just equal to ourselves. Note that nsPrincipal::Equals will return false
michael@0 132 // for us since we have a unique domain/origin/etc.
michael@0 133 *aResult = (aOther == this);
michael@0 134 return NS_OK;
michael@0 135 }
michael@0 136
michael@0 137 NS_IMETHODIMP
michael@0 138 nsNullPrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
michael@0 139 {
michael@0 140 return Equals(aOther, aResult);
michael@0 141 }
michael@0 142
michael@0 143 NS_IMETHODIMP
michael@0 144 nsNullPrincipal::GetHashValue(uint32_t *aResult)
michael@0 145 {
michael@0 146 *aResult = (NS_PTR_TO_INT32(this) >> 2);
michael@0 147 return NS_OK;
michael@0 148 }
michael@0 149
michael@0 150 NS_IMETHODIMP
michael@0 151 nsNullPrincipal::GetURI(nsIURI** aURI)
michael@0 152 {
michael@0 153 return NS_EnsureSafeToReturn(mURI, aURI);
michael@0 154 }
michael@0 155
michael@0 156 NS_IMETHODIMP
michael@0 157 nsNullPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
michael@0 158 {
michael@0 159 NS_IF_ADDREF(*aCsp = mCSP);
michael@0 160 return NS_OK;
michael@0 161 }
michael@0 162
michael@0 163 NS_IMETHODIMP
michael@0 164 nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
michael@0 165 {
michael@0 166 // If CSP was already set, it should not be destroyed! Instead, it should
michael@0 167 // get set anew when a new principal is created.
michael@0 168 if (mCSP)
michael@0 169 return NS_ERROR_ALREADY_INITIALIZED;
michael@0 170
michael@0 171 mCSP = aCsp;
michael@0 172 return NS_OK;
michael@0 173 }
michael@0 174
michael@0 175 NS_IMETHODIMP
michael@0 176 nsNullPrincipal::GetDomain(nsIURI** aDomain)
michael@0 177 {
michael@0 178 return NS_EnsureSafeToReturn(mURI, aDomain);
michael@0 179 }
michael@0 180
michael@0 181 NS_IMETHODIMP
michael@0 182 nsNullPrincipal::SetDomain(nsIURI* aDomain)
michael@0 183 {
michael@0 184 // I think the right thing to do here is to just throw... Silently failing
michael@0 185 // seems counterproductive.
michael@0 186 return NS_ERROR_NOT_AVAILABLE;
michael@0 187 }
michael@0 188
michael@0 189 NS_IMETHODIMP
michael@0 190 nsNullPrincipal::GetOrigin(char** aOrigin)
michael@0 191 {
michael@0 192 *aOrigin = nullptr;
michael@0 193
michael@0 194 nsAutoCString str;
michael@0 195 nsresult rv = mURI->GetSpec(str);
michael@0 196 NS_ENSURE_SUCCESS(rv, rv);
michael@0 197
michael@0 198 *aOrigin = ToNewCString(str);
michael@0 199 NS_ENSURE_TRUE(*aOrigin, NS_ERROR_OUT_OF_MEMORY);
michael@0 200
michael@0 201 return NS_OK;
michael@0 202 }
michael@0 203
michael@0 204 NS_IMETHODIMP
michael@0 205 nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
michael@0 206 {
michael@0 207 // We don't subsume anything except ourselves. Note that nsPrincipal::Equals
michael@0 208 // will return false for us, since we're not about:blank and not Equals to
michael@0 209 // reasonable nsPrincipals.
michael@0 210 *aResult = (aOther == this);
michael@0 211 return NS_OK;
michael@0 212 }
michael@0 213
michael@0 214 NS_IMETHODIMP
michael@0 215 nsNullPrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
michael@0 216 {
michael@0 217 return Subsumes(aOther, aResult);
michael@0 218 }
michael@0 219
michael@0 220 NS_IMETHODIMP
michael@0 221 nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
michael@0 222 {
michael@0 223 if (aAllowIfInheritsPrincipal) {
michael@0 224 if (nsPrincipal::IsPrincipalInherited(aURI)) {
michael@0 225 return NS_OK;
michael@0 226 }
michael@0 227
michael@0 228 // Also allow the load if the principal of the URI being checked is exactly
michael@0 229 // us ie this.
michael@0 230 nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
michael@0 231 if (uriPrinc) {
michael@0 232 nsCOMPtr<nsIPrincipal> principal;
michael@0 233 uriPrinc->GetPrincipal(getter_AddRefs(principal));
michael@0 234
michael@0 235 if (principal && principal == this) {
michael@0 236 return NS_OK;
michael@0 237 }
michael@0 238 }
michael@0 239 }
michael@0 240
michael@0 241 if (aReport) {
michael@0 242 nsScriptSecurityManager::ReportError(
michael@0 243 nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI);
michael@0 244 }
michael@0 245
michael@0 246 return NS_ERROR_DOM_BAD_URI;
michael@0 247 }
michael@0 248
michael@0 249 NS_IMETHODIMP
michael@0 250 nsNullPrincipal::GetJarPrefix(nsACString& aJarPrefix)
michael@0 251 {
michael@0 252 aJarPrefix.Truncate();
michael@0 253 return NS_OK;
michael@0 254 }
michael@0 255
michael@0 256 NS_IMETHODIMP
michael@0 257 nsNullPrincipal::GetAppStatus(uint16_t* aAppStatus)
michael@0 258 {
michael@0 259 *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
michael@0 260 return NS_OK;
michael@0 261 }
michael@0 262
michael@0 263 NS_IMETHODIMP
michael@0 264 nsNullPrincipal::GetAppId(uint32_t* aAppId)
michael@0 265 {
michael@0 266 *aAppId = nsIScriptSecurityManager::NO_APP_ID;
michael@0 267 return NS_OK;
michael@0 268 }
michael@0 269
michael@0 270 NS_IMETHODIMP
michael@0 271 nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
michael@0 272 {
michael@0 273 *aIsInBrowserElement = false;
michael@0 274 return NS_OK;
michael@0 275 }
michael@0 276
michael@0 277 NS_IMETHODIMP
michael@0 278 nsNullPrincipal::GetUnknownAppId(bool* aUnknownAppId)
michael@0 279 {
michael@0 280 *aUnknownAppId = false;
michael@0 281 return NS_OK;
michael@0 282 }
michael@0 283
michael@0 284 NS_IMETHODIMP
michael@0 285 nsNullPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
michael@0 286 {
michael@0 287 *aIsNullPrincipal = true;
michael@0 288 return NS_OK;
michael@0 289 }
michael@0 290
michael@0 291 NS_IMETHODIMP
michael@0 292 nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
michael@0 293 {
michael@0 294 // For a null principal, we use our unique uuid as the base domain.
michael@0 295 return mURI->GetPath(aBaseDomain);
michael@0 296 }
michael@0 297
michael@0 298 /**
michael@0 299 * nsISerializable implementation
michael@0 300 */
michael@0 301 NS_IMETHODIMP
michael@0 302 nsNullPrincipal::Read(nsIObjectInputStream* aStream)
michael@0 303 {
michael@0 304 // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
michael@0 305 // is not really relevant.
michael@0 306 return NS_OK;
michael@0 307 }
michael@0 308
michael@0 309 NS_IMETHODIMP
michael@0 310 nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
michael@0 311 {
michael@0 312 // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
michael@0 313 // is not really relevant.
michael@0 314 return NS_OK;
michael@0 315 }
michael@0 316

mercurial