From d1ff4c4a384eff93487104f9c4176df9687e2b33 Mon Sep 17 00:00:00 2001 From: "mstoltz%netscape.com" Date: Sat, 27 Jan 2001 01:42:20 +0000 Subject: [PATCH] Bug 66369, adding support for per-file permissions granting to caps. r=jst, sr=jband. --- caps/idl/nsICodebasePrincipal.idl | 2 + caps/include/nsScriptSecurityManager.h | 3 + caps/src/nsAggregatePrincipal.cpp | 13 +++ caps/src/nsCodebasePrincipal.cpp | 115 +++++++++++++------------ caps/src/nsScriptSecurityManager.cpp | 41 +++++++-- 5 files changed, 112 insertions(+), 62 deletions(-) diff --git a/caps/idl/nsICodebasePrincipal.idl b/caps/idl/nsICodebasePrincipal.idl index 0432883a611..90c163bc07f 100644 --- a/caps/idl/nsICodebasePrincipal.idl +++ b/caps/idl/nsICodebasePrincipal.idl @@ -34,5 +34,7 @@ interface nsICodebasePrincipal : nsISupports { readonly attribute nsIURI URI; readonly attribute string origin; + + readonly attribute string spec; }; diff --git a/caps/include/nsScriptSecurityManager.h b/caps/include/nsScriptSecurityManager.h index 20d176761ae..6641b49d2b5 100644 --- a/caps/include/nsScriptSecurityManager.h +++ b/caps/include/nsScriptSecurityManager.h @@ -97,6 +97,9 @@ public: JSContext * GetCurrentContextQuick(); private: + NS_IMETHOD + CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result); + NS_IMETHOD GetSubjectPrincipal(JSContext *aCx, nsIPrincipal **result); diff --git a/caps/src/nsAggregatePrincipal.cpp b/caps/src/nsAggregatePrincipal.cpp index c310566f31b..1953f6e575b 100644 --- a/caps/src/nsAggregatePrincipal.cpp +++ b/caps/src/nsAggregatePrincipal.cpp @@ -102,6 +102,19 @@ nsAggregatePrincipal::GetOrigin(char** aOrigin) return codebase->GetOrigin(aOrigin); } +NS_IMETHODIMP +nsAggregatePrincipal::GetSpec(char** aSpec) +{ + if (!mCodebase) + { + *aSpec = nsnull; + return NS_ERROR_FAILURE; + } + + nsCOMPtr codebase = do_QueryInterface(mCodebase); + return codebase->GetSpec(aSpec); +} + //////////////////////////////////////////////// // Methods implementing nsIAggregatePrincipal // //////////////////////////////////////////////// diff --git a/caps/src/nsCodebasePrincipal.cpp b/caps/src/nsCodebasePrincipal.cpp index a4ae15d4dc3..27157087146 100644 --- a/caps/src/nsCodebasePrincipal.cpp +++ b/caps/src/nsCodebasePrincipal.cpp @@ -57,7 +57,8 @@ NS_IMETHODIMP nsCodebasePrincipal::GetPreferences(char** aPrefName, char** aID, char** aGrantedList, char** aDeniedList) { - if (!mPrefName) { + if (!mPrefName) + { nsCAutoString s; s.Assign("capability.principal.codebase.p"); s.AppendInt(mCapabilitiesOrdinal++); @@ -71,10 +72,10 @@ nsCodebasePrincipal::GetPreferences(char** aPrefName, char** aID, NS_IMETHODIMP nsCodebasePrincipal::HashValue(PRUint32 *result) { - nsXPIDLCString origin; - if (NS_FAILED(GetOrigin(getter_Copies(origin)))) + nsXPIDLCString spec; + if (NS_FAILED(GetSpec(getter_Copies(spec)))) return NS_ERROR_FAILURE; - *result = nsCRT::HashCode(origin, nsnull); + *result = nsCRT::HashCode(spec, nsnull); return NS_OK; } @@ -89,7 +90,8 @@ nsCodebasePrincipal::CanEnableCapability(const char *capability, if (NS_FAILED(rv)) return NS_ERROR_FAILURE; PRBool enabled; - if (NS_FAILED(prefs->GetBoolPref(pref, &enabled)) || !enabled) { + if (NS_FAILED(prefs->GetBoolPref(pref, &enabled)) || !enabled) + { // Deny unless subject is executing from file: or resource: nsXPIDLCString scheme; if (NS_FAILED(mURI->GetScheme(getter_Copies(scheme))) || @@ -128,92 +130,96 @@ nsCodebasePrincipal::GetOrigin(char **origin) nsCAutoString t; t.Assign(s); t.Append("://"); - if (NS_SUCCEEDED(mURI->GetHost(getter_Copies(s)))) { + if (NS_SUCCEEDED(mURI->GetHost(getter_Copies(s)))) + { t.Append(s); - } else if (NS_SUCCEEDED(mURI->GetSpec(getter_Copies(s)))) { - // Some URIs (e.g., nsSimpleURI) don't support host. Just - // get the full spec. - t.Assign(s); - } else { + } + else if (NS_SUCCEEDED(mURI->GetSpec(getter_Copies(s)))) + // Some URIs (e.g., nsSimpleURI) don't support host. Just + // get the full spec. + t.Assign(s); + else return NS_ERROR_FAILURE; - } - *origin = t.ToNewCString(); + + *origin = t.ToNewCString(); return *origin ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } +NS_IMETHODIMP +nsCodebasePrincipal::GetSpec(char **spec) +{ + return mURI->GetSpec(spec); +} + + NS_IMETHODIMP nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result) { //-- Equals is defined as object equality or same origin *result = PR_FALSE; - if (this == other) { + if (this == other) + { *result = PR_TRUE; return NS_OK; } - if (other == nsnull) { - *result = PR_FALSE; + if (other == nsnull) + // return false return NS_OK; - } nsCOMPtr otherCodebase; if (NS_FAILED(other->QueryInterface( NS_GET_IID(nsICodebasePrincipal), (void **) getter_AddRefs(otherCodebase)))) - { return NS_OK; - } nsCOMPtr otherURI; - if (NS_FAILED(otherCodebase->GetURI(getter_AddRefs(otherURI)))) { + if (NS_FAILED(otherCodebase->GetURI(getter_AddRefs(otherURI)))) return NS_ERROR_FAILURE; - } - char *scheme1 = nsnull; - nsresult rv = otherURI->GetScheme(&scheme1); - char *scheme2 = nsnull; + nsXPIDLCString otherScheme; + nsresult rv = otherURI->GetScheme(getter_Copies(otherScheme)); + nsXPIDLCString myScheme; if (NS_SUCCEEDED(rv)) - rv = mURI->GetScheme(&scheme2); - if (NS_SUCCEEDED(rv) && PL_strcmp(scheme1, scheme2) == 0) { + rv = mURI->GetScheme(getter_Copies(myScheme)); + if (NS_SUCCEEDED(rv) && PL_strcmp(otherScheme, myScheme) == 0) + { - if (PL_strcmp(scheme1, "file") == 0) { - // All file: urls are considered to have the same origin. - *result = PR_TRUE; - } else if (PL_strcmp(scheme1, "imap") == 0 || - PL_strcmp(scheme1, "mailbox") == 0 || - PL_strcmp(scheme1, "news") == 0) + if (PL_strcmp(otherScheme, "imap") == 0 || + PL_strcmp(otherScheme, "mailbox") == 0 || + PL_strcmp(otherScheme, "news") == 0) { // Each message is a distinct trust domain; use the // whole spec for comparison - nsXPIDLCString spec1; - if (NS_FAILED(otherURI->GetSpec(getter_Copies(spec1)))) + nsXPIDLCString otherSpec; + if (NS_FAILED(otherURI->GetSpec(getter_Copies(otherSpec)))) return NS_ERROR_FAILURE; - nsXPIDLCString spec2; - if (NS_FAILED(mURI->GetSpec(getter_Copies(spec2)))) + nsXPIDLCString mySpec; + if (NS_FAILED(mURI->GetSpec(getter_Copies(mySpec)))) return NS_ERROR_FAILURE; - *result = PL_strcmp(spec1, spec2) == 0; - } else { + *result = PL_strcmp(otherSpec, mySpec) == 0; + } + else + { // Need to check the host - char *host1 = nsnull; - rv = otherURI->GetHost(&host1); - char *host2 = nsnull; + nsXPIDLCString otherHost; + rv = otherURI->GetHost(getter_Copies(otherHost)); + nsXPIDLCString myHost; if (NS_SUCCEEDED(rv)) - rv = mURI->GetHost(&host2); - *result = NS_SUCCEEDED(rv) && PL_strcmp(host1, host2) == 0; - if (*result) { - int port1; - rv = otherURI->GetPort(&port1); - int port2; + rv = mURI->GetHost(getter_Copies(myHost)); + *result = NS_SUCCEEDED(rv) && PL_strcmp(otherHost, myHost) == 0; + if (*result) + { + int otherPort; + rv = otherURI->GetPort(&otherPort); + int myPort; if (NS_SUCCEEDED(rv)) - rv = mURI->GetPort(&port2); - *result = NS_SUCCEEDED(rv) && port1 == port2; + rv = mURI->GetPort(&myPort); + *result = NS_SUCCEEDED(rv) && otherPort == myPort; } - if (host1) nsCRT::free(host1); - if (host2) nsCRT::free(host2); } } - if (scheme1) nsCRT::free(scheme1); - if (scheme2) nsCRT::free(scheme2); return NS_OK; } + ///////////////////////////////////////////// // Constructor, Destructor, initialization // ///////////////////////////////////////////// @@ -229,7 +235,8 @@ nsCodebasePrincipal::Init(nsIURI *uri) char *codebase; if (uri == nsnull || NS_FAILED(uri->GetSpec(&codebase))) return NS_ERROR_FAILURE; - if (NS_FAILED(mJSPrincipals.Init(codebase))) { + if (NS_FAILED(mJSPrincipals.Init(codebase))) + { nsCRT::free(codebase); return NS_ERROR_FAILURE; } diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 17e76bc16ed..6aac1996453 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -726,11 +726,10 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID, return NS_OK; } -NS_IMETHODIMP -nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI, - nsIPrincipal **result) +nsresult +nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **result) { - nsresult rv; + nsresult rv = NS_OK; nsCodebasePrincipal *codebase = new nsCodebasePrincipal(); if (!codebase) return NS_ERROR_OUT_OF_MEMORY; @@ -739,17 +738,43 @@ nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI, NS_RELEASE(codebase); return NS_ERROR_FAILURE; } - nsCOMPtr principal = - do_QueryInterface((nsBasePrincipal*)codebase, &rv); + rv = CallQueryInterface((nsBasePrincipal*)codebase, result); NS_RELEASE(codebase); - if (NS_FAILED(rv)) return rv; + return rv; +} + +NS_IMETHODIMP +nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI, + nsIPrincipal **result) +{ + nsresult rv; + nsCOMPtr principal; + rv = CreateCodebasePrincipal(aURI, getter_AddRefs(principal)); + if (NS_FAILED(rv)) return rv; if (mPrincipals) { - // Check to see if we already have this principal. + //-- Check to see if we already have this principal. nsIPrincipalKey key(principal); nsCOMPtr fromTable = (nsIPrincipal *) mPrincipals->Get(&key); if (fromTable) principal = fromTable; + else //-- Check to see if we have a more general principal + { + nsCOMPtr codebasePrin = do_QueryInterface(principal); + nsXPIDLCString originUrl; + rv = codebasePrin->GetOrigin(getter_Copies(originUrl)); + if (NS_FAILED(rv)) return rv; + nsCOMPtr newURI; + rv = NS_NewURI(getter_AddRefs(newURI), originUrl, nsnull); + if (NS_FAILED(rv)) return rv; + nsCOMPtr principal2; + rv = CreateCodebasePrincipal(newURI, getter_AddRefs(principal2)); + if (NS_FAILED(rv)) return rv; + nsIPrincipalKey key2(principal2); + fromTable = (nsIPrincipal *) mPrincipals->Get(&key2); + if (fromTable) + principal = fromTable; + } } //-- Bundle this codebase principal into an aggregate principal