Bug 816956 - Don't try to check all parent hosts in the Permission Manager (but only until the domain name). r=sicking

This commit is contained in:
Mounir Lamouri 2013-02-04 23:41:52 +00:00
Родитель 8ad54869c8
Коммит a13145c6a8
3 изменённых файлов: 100 добавлений и 26 удалений

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsIScriptSecurityManager.h"
#include "nsIAppsService.h"
#include "mozIApplication.h"
#include "nsIEffectiveTLDService.h"
static nsPermissionManager *gPermissionManager = nullptr;
@ -126,6 +127,27 @@ GetHostForPrincipal(nsIPrincipal* aPrincipal, nsACString& aHost)
return NS_OK;
}
nsCString
GetNextSubDomainForHost(const nsACString& aHost)
{
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (!tldService) {
NS_ERROR("Should have a tld service!");
return EmptyCString();
}
nsCString subDomain;
nsresult rv = tldService->GetNextSubDomain(aHost, subDomain);
// We can fail if there is no more subdomain or if the host can't have a
// subdomain.
if (NS_FAILED(rv)) {
return EmptyCString();
}
return subDomain;
}
class AppClearDataObserver MOZ_FINAL : public nsIObserver {
public:
NS_DECL_ISUPPORTS
@ -1059,41 +1081,36 @@ nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
uint32_t aType,
bool aExactHostMatch)
{
uint32_t offset = 0;
PermissionHashKey* entry;
int64_t now = PR_Now() / 1000;
PermissionHashKey* entry = nullptr;
do {
nsRefPtr<PermissionKey> key = new PermissionKey(Substring(aHost, offset), aAppId, aIsInBrowserElement);
entry = mPermissionTable.GetEntry(key);
nsRefPtr<PermissionKey> key = new PermissionKey(aHost, aAppId, aIsInBrowserElement);
entry = mPermissionTable.GetEntry(key);
if (entry) {
PermissionEntry permEntry = entry->GetPermission(aType);
if (entry) {
PermissionEntry permEntry = entry->GetPermission(aType);
// if the entry is expired, remove and keep looking for others.
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
permEntry.mExpireTime <= now) {
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipal(aHost, aAppId, aIsInBrowserElement, getter_AddRefs(principal)))) {
return nullptr;
}
RemoveFromPrincipal(principal, mTypeArray[aType].get());
} else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION) {
break;
// if the entry is expired, remove and keep looking for others.
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
permEntry.mExpireTime <= (PR_Now() / 1000)) {
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipal(aHost, aAppId, aIsInBrowserElement, getter_AddRefs(principal)))) {
return nullptr;
}
// reset entry, to be able to return null on failure
entry = nullptr;
RemoveFromPrincipal(principal, mTypeArray[aType].get());
} else if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
entry = nullptr;
}
if (aExactHostMatch)
break; // do not try super domains
}
offset = aHost.FindChar('.', offset) + 1;
if (!entry && !aExactHostMatch) {
nsCString domain = GetNextSubDomainForHost(aHost);
if (!domain.IsEmpty()) {
return GetPermissionHashKey(domain, aAppId, aIsInBrowserElement, aType, aExactHostMatch);
}
}
// walk up the domaintree (we stop as soon as we find a match,
// which will be the most specific domain we have an entry for).
} while (offset > 0);
return entry;
}

Просмотреть файл

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function getPrincipalFromURI(uri) {
return Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(NetUtil.newURI(uri));
}
function run_test() {
var pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
// Adds a permission to a sub-domain. Checks if it is working.
let sub1Principal = getPrincipalFromURI("http://sub1.example.com");
pm.addFromPrincipal(sub1Principal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
do_check_eq(pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"), pm.ALLOW_ACTION);
// A sub-sub-domain should get the permission.
let subsubPrincipal = getPrincipalFromURI("http://sub.sub1.example.com");
do_check_eq(pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"), pm.ALLOW_ACTION);
// Another sub-domain shouldn't get the permission.
let sub2Principal = getPrincipalFromURI("http://sub2.example.com");
do_check_eq(pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
// Remove current permissions.
pm.removeFromPrincipal(sub1Principal, "test/subdomains");
do_check_eq(pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
// Adding the permission to the main domain. Checks if it is working.
let mainPrincipal = getPrincipalFromURI("http://example.com");
pm.addFromPrincipal(mainPrincipal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
do_check_eq(pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"), pm.ALLOW_ACTION);
// All sub-domains should have the permission now.
do_check_eq(pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"), pm.ALLOW_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"), pm.ALLOW_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"), pm.ALLOW_ACTION);
// Remove current permissions.
pm.removeFromPrincipal(mainPrincipal, "test/subdomains");
do_check_eq(pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"), pm.UNKNOWN_ACTION);
// A sanity check that the previous implementation wasn't passing...
let crazyPrincipal = getPrincipalFromURI("http://com");
pm.addFromPrincipal(crazyPrincipal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
do_check_eq(pm.testPermissionFromPrincipal(crazyPrincipal, "test/subdomains"), pm.ALLOW_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"), pm.UNKNOWN_ACTION);
}

Просмотреть файл

@ -21,6 +21,7 @@ tail =
[test_permmanager_load_invalid_entries.js]
skip-if = debug == true
[test_permmanager_idn.js]
[test_permmanager_subdomains.js]
[test_permmanager_cleardata.js]
[test_schema_2_migration.js]
[test_schema_3_migration.js]