Bug 152725 - Get URL passed to cookie module from document principal, not document URL.

THis ensures that cookies set by javascript URL pages are set in the correct domain.
r=morse, sr=dveditz.


git-svn-id: svn://10.0.0.236/trunk@124514 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mstoltz%netscape.com
2002-07-02 17:58:24 +00:00
parent 515e16e79d
commit 8946598190
6 changed files with 133 additions and 32 deletions

View File

@@ -50,6 +50,7 @@ interface nsIAggregatePrincipal : nsISupports {
attribute nsIPrincipal certificate;
attribute nsIPrincipal codebase;
readonly attribute nsIPrincipal originalCodebase;
readonly attribute nsIPrincipal primaryChild;
void intersect(in nsIPrincipal other);

View File

@@ -108,6 +108,7 @@ public:
protected:
nsCOMPtr<nsIPrincipal> mCertificate;
nsCOMPtr<nsIPrincipal> mCodebase;
nsCOMPtr<nsIPrincipal> mOriginalCodebase;
};
#endif // _NS_AGGREGATE_PRINCIPAL_H_

View File

@@ -185,27 +185,41 @@ NS_IMETHODIMP
nsAggregatePrincipal::SetCodebase(nsIPrincipal* aCodebase)
{
nsresult rv;
//-- Make sure this really is a codebase principal
if (aCodebase)
nsCOMPtr<nsIPrincipal> newCodebase(aCodebase);
//-- If newCodebase is an aggregate, get its underlying codebase
nsCOMPtr<nsIAggregatePrincipal> agg =
do_QueryInterface(newCodebase, &rv);
if (NS_SUCCEEDED(rv))
{
rv = agg->GetCodebase(getter_AddRefs(newCodebase));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
}
else
{ //-- Make sure this really is a codebase principal
nsCOMPtr<nsICodebasePrincipal> tempCodebase =
do_QueryInterface(aCodebase, &rv);
do_QueryInterface(newCodebase, &rv);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
}
//-- If aCodebase is an aggregate, get its underlying codebase
nsCOMPtr<nsIAggregatePrincipal> agg =
do_QueryInterface(aCodebase, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIPrincipal> underlying;
rv = agg->GetCodebase(getter_AddRefs(underlying));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
mCodebase = underlying.get();
}
else
mCodebase = aCodebase;
mCodebase = newCodebase;
//-- If this is the first codebase set, remember it
if (!mOriginalCodebase)
mOriginalCodebase = newCodebase;
return NS_OK;
}
NS_IMETHODIMP
nsAggregatePrincipal::GetOriginalCodebase(nsIPrincipal** aOriginalCodebase)
{
NS_ENSURE_ARG_POINTER(aOriginalCodebase);
*aOriginalCodebase = mOriginalCodebase;
NS_IF_ADDREF(*aOriginalCodebase);
return NS_OK;
}

View File

@@ -116,6 +116,8 @@
#include "nsVoidArray.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsICodebasePrincipal.h"
#include "nsIAggregatePrincipal.h"
#include "nsTextFragment.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
@@ -4547,11 +4549,31 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsIH
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(docShell);
rv = webNav->GetCurrentURI(getter_AddRefs(baseURI));
// Get a URI from the document principal
// We use the original codebase in case the codebase was changed by SetDomain
nsCOMPtr<nsIPrincipal> docPrincipal;
rv = mDocument->GetPrincipal(getter_AddRefs(docPrincipal));
if (NS_FAILED(rv)) return rv;
if (!docPrincipal) return NS_OK;
nsCOMPtr<nsIAggregatePrincipal> agg(do_QueryInterface(docPrincipal, &rv));
// Document principal should always be an aggregate
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> originalPrincipal;
rv = agg->GetOriginalCodebase(getter_AddRefs(originalPrincipal));
nsCOMPtr<nsICodebasePrincipal> originalCodebase(
do_QueryInterface(originalPrincipal, &rv));
if (NS_FAILED(rv)) {
// Document's principal is not a codebase (may be system), so can't set cookies
return NS_OK;
}
nsCOMPtr<nsIURI> codebaseURI;
rv = originalCodebase->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
char *cookie = ToNewUTF8String(aValue);
nsCOMPtr<nsIScriptGlobalObject> globalObj;
nsCOMPtr<nsIPrompt> prompt;
@@ -4571,7 +4593,7 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsIH
}
}
rv = cookieServ->SetCookieString(baseURI, prompt, cookie, httpChannel);
rv = cookieServ->SetCookieString(codebaseURI, prompt, cookie, httpChannel);
nsCRT::free(cookie);
if (NS_FAILED(rv)) return rv;
} // END set-cookie

View File

@@ -291,7 +291,8 @@ nsHTMLDocument::nsHTMLDocument()
mBaseTarget(nsnull),
mLastModified(nsnull),
mReferrer(nsnull),
mIsWriting(0)
mIsWriting(0),
mDomainWasSet(PR_FALSE)
{
mImages = nsnull;
mApplets = nsnull;
@@ -322,7 +323,6 @@ nsHTMLDocument::nsHTMLDocument()
//nsCOMPtr<nsIRDFService> gRDF(do_GetService(kRDFServiceCID,
//&rv));
}
mDomainWasSet = PR_FALSE; // Bug 13871: Frameset spoofing
}
nsHTMLDocument::~nsHTMLDocument()
@@ -1950,8 +1950,9 @@ nsHTMLDocument::GetDomain(nsAString& aDomain)
NS_IMETHODIMP
nsHTMLDocument::SetDomain(const nsAString& aDomain)
{
// Check new domain
// Check new domain - must be a superdomain of the current host
// For example, a page from foo.bar.com may set domain to bar.com,
// but not to ar.com, baz.com, or fi.foo.bar.com.
nsAutoString current;
if (NS_FAILED(GetDomain(current)))
return NS_ERROR_FAILURE;
@@ -2228,11 +2229,30 @@ nsHTMLDocument::GetCookie(nsAString& aCookie)
nsresult result = NS_OK;
nsAutoString str;
nsCOMPtr<nsICookieService> service = do_GetService(kCookieServiceCID, &result);
if (NS_SUCCEEDED(result) && service && mDocumentURL) {
if (NS_SUCCEEDED(result) && service) {
// Get a URI from the document principal
// We use the original codebase in case the codebase was changed by SetDomain
nsCOMPtr<nsIAggregatePrincipal> agg(do_QueryInterface(mPrincipal, &result));
// Document principal should always be an aggregate
NS_ENSURE_SUCCESS(result, result);
nsCOMPtr<nsIPrincipal> originalPrincipal;
result = agg->GetOriginalCodebase(getter_AddRefs(originalPrincipal));
nsCOMPtr<nsICodebasePrincipal> originalCodebase(
do_QueryInterface(originalPrincipal, &result));
if (NS_FAILED(result)) {
// Document's principal is not a codebase, so can't get cookies
return NS_OK;
}
nsCOMPtr<nsIURI> codebaseURI;
result = originalCodebase->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(result, result);
nsXPIDLCString cookie;
result = service->GetCookieString(mDocumentURL, getter_Copies(cookie));
result = service->GetCookieString(codebaseURI, getter_Copies(cookie));
if (NS_SUCCEEDED(result) && cookie)
CopyASCIItoUCS2(nsDependentCString(cookie), aCookie);
}
@@ -2265,10 +2285,30 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie)
window->GetPrompter(getter_AddRefs(prompt));
}
}
// Get a URI from the document principal
// We use the original codebase in case the codebase was changed by SetDomain
nsCOMPtr<nsIAggregatePrincipal> agg(do_QueryInterface(mPrincipal, &result));
// Document principal should always be an aggregate
NS_ENSURE_SUCCESS(result, result);
nsCOMPtr<nsIPrincipal> originalPrincipal;
result = agg->GetOriginalCodebase(getter_AddRefs(originalPrincipal));
nsCOMPtr<nsICodebasePrincipal> originalCodebase(
do_QueryInterface(originalPrincipal, &result));
if (NS_FAILED(result)) {
// Document's principal is not a codebase, so can't set cookies
return NS_OK;
}
nsCOMPtr<nsIURI> codebaseURI;
result = originalCodebase->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(result, result);
result = NS_ERROR_OUT_OF_MEMORY;
char* cookie = ToNewCString(aCookie);
if (cookie) {
result = service->SetCookieString(mDocumentURL, prompt, cookie, mHttpChannel);
result = service->SetCookieString(codebaseURI, prompt, cookie, mHttpChannel);
nsCRT::free(cookie);
}
}

View File

@@ -104,6 +104,9 @@
#include "nsIDOMWindowInternal.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsIPrincipal.h"
#include "nsIAggregatePrincipal.h"
#include "nsICodebasePrincipal.h"
// XXX misnamed header file, but oh well
#include "nsHTMLTokens.h"
@@ -953,10 +956,30 @@ nsXMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsI
nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(docShell);
rv = webNav->GetCurrentURI(getter_AddRefs(baseURI));
// Get a URI from the document principal
// We use the original codebase in case the codebase was changed by SetDomain
nsCOMPtr<nsIPrincipal> docPrincipal;
rv = mDocument->GetPrincipal(getter_AddRefs(docPrincipal));
if (NS_FAILED(rv)) return rv;
if (!docPrincipal) return NS_OK;
nsCOMPtr<nsIAggregatePrincipal> agg(do_QueryInterface(docPrincipal, &rv));
// Document principal should always be an aggregate
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> originalPrincipal;
rv = agg->GetOriginalCodebase(getter_AddRefs(originalPrincipal));
nsCOMPtr<nsICodebasePrincipal> originalCodebase(
do_QueryInterface(originalPrincipal, &rv));
if (NS_FAILED(rv)) {
// Document's principal is not a codebase (may be system), so can't set cookies
return NS_OK;
}
nsCOMPtr<nsIURI> codebaseURI;
rv = originalCodebase->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
char *cookie = ToNewUTF8String(aValue);
nsCOMPtr<nsIScriptGlobalObject> globalObj;
nsCOMPtr<nsIPrompt> prompt;
@@ -976,7 +999,7 @@ nsXMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsI
}
}
rv = cookieServ->SetCookieString(baseURI, prompt, cookie, httpChannel);
rv = cookieServ->SetCookieString(codebaseURI, prompt, cookie, httpChannel);
nsCRT::free(cookie);
if (NS_FAILED(rv)) return rv;
} // END set-cookie