/src/mozilla-central/extensions/cookie/nsPermission.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "nsPermission.h" |
7 | | #include "nsContentUtils.h" |
8 | | #include "nsIClassInfoImpl.h" |
9 | | #include "nsIEffectiveTLDService.h" |
10 | | #include "mozilla/BasePrincipal.h" |
11 | | |
12 | | // nsPermission Implementation |
13 | | |
14 | | NS_IMPL_CLASSINFO(nsPermission, nullptr, 0, {0}) |
15 | | NS_IMPL_ISUPPORTS_CI(nsPermission, nsIPermission) |
16 | | |
17 | | nsPermission::nsPermission(nsIPrincipal* aPrincipal, |
18 | | const nsACString &aType, |
19 | | uint32_t aCapability, |
20 | | uint32_t aExpireType, |
21 | | int64_t aExpireTime) |
22 | | : mPrincipal(aPrincipal) |
23 | | , mType(aType) |
24 | | , mCapability(aCapability) |
25 | | , mExpireType(aExpireType) |
26 | | , mExpireTime(aExpireTime) |
27 | 0 | { |
28 | 0 | } |
29 | | |
30 | | already_AddRefed<nsPermission> |
31 | | nsPermission::Create(nsIPrincipal* aPrincipal, |
32 | | const nsACString &aType, |
33 | | uint32_t aCapability, |
34 | | uint32_t aExpireType, |
35 | | int64_t aExpireTime) |
36 | 0 | { |
37 | 0 | NS_ENSURE_TRUE(aPrincipal, nullptr); |
38 | 0 | nsCOMPtr<nsIPrincipal> principal = |
39 | 0 | mozilla::BasePrincipal::Cast(aPrincipal)->CloneStrippingUserContextIdAndFirstPartyDomain(); |
40 | 0 |
|
41 | 0 | NS_ENSURE_TRUE(principal, nullptr); |
42 | 0 |
|
43 | 0 | RefPtr<nsPermission> permission = |
44 | 0 | new nsPermission(principal, aType, aCapability, aExpireType, aExpireTime); |
45 | 0 | return permission.forget(); |
46 | 0 | } |
47 | | |
48 | | NS_IMETHODIMP |
49 | | nsPermission::GetPrincipal(nsIPrincipal** aPrincipal) |
50 | 0 | { |
51 | 0 | nsCOMPtr<nsIPrincipal> copy = mPrincipal; |
52 | 0 | copy.forget(aPrincipal); |
53 | 0 | return NS_OK; |
54 | 0 | } |
55 | | |
56 | | NS_IMETHODIMP |
57 | | nsPermission::GetType(nsACString &aType) |
58 | 0 | { |
59 | 0 | aType = mType; |
60 | 0 | return NS_OK; |
61 | 0 | } |
62 | | |
63 | | NS_IMETHODIMP |
64 | | nsPermission::GetCapability(uint32_t *aCapability) |
65 | 0 | { |
66 | 0 | *aCapability = mCapability; |
67 | 0 | return NS_OK; |
68 | 0 | } |
69 | | |
70 | | NS_IMETHODIMP |
71 | | nsPermission::GetExpireType(uint32_t *aExpireType) |
72 | 0 | { |
73 | 0 | *aExpireType = mExpireType; |
74 | 0 | return NS_OK; |
75 | 0 | } |
76 | | |
77 | | NS_IMETHODIMP |
78 | | nsPermission::GetExpireTime(int64_t *aExpireTime) |
79 | 0 | { |
80 | 0 | *aExpireTime = mExpireTime; |
81 | 0 | return NS_OK; |
82 | 0 | } |
83 | | |
84 | | NS_IMETHODIMP |
85 | | nsPermission::Matches(nsIPrincipal* aPrincipal, bool aExactHost, bool* aMatches) |
86 | 0 | { |
87 | 0 | NS_ENSURE_ARG_POINTER(aPrincipal); |
88 | 0 | NS_ENSURE_ARG_POINTER(aMatches); |
89 | 0 |
|
90 | 0 | *aMatches = false; |
91 | 0 |
|
92 | 0 | nsCOMPtr<nsIPrincipal> principal = |
93 | 0 | mozilla::BasePrincipal::Cast(aPrincipal)->CloneStrippingUserContextIdAndFirstPartyDomain(); |
94 | 0 |
|
95 | 0 | if (!principal) { |
96 | 0 | *aMatches = false; |
97 | 0 | return NS_OK; |
98 | 0 | } |
99 | 0 | |
100 | 0 | // If the principals are equal, then they match. |
101 | 0 | if (mPrincipal->Equals(principal)) { |
102 | 0 | *aMatches = true; |
103 | 0 | return NS_OK; |
104 | 0 | } |
105 | 0 | |
106 | 0 | // If we are matching with an exact host, we're done now - the permissions don't match |
107 | 0 | // otherwise, we need to start comparing subdomains! |
108 | 0 | if (aExactHost) { |
109 | 0 | return NS_OK; |
110 | 0 | } |
111 | 0 | |
112 | 0 | // Compare their OriginAttributes |
113 | 0 | const mozilla::OriginAttributes& theirAttrs = principal->OriginAttributesRef(); |
114 | 0 | const mozilla::OriginAttributes& ourAttrs = mPrincipal->OriginAttributesRef(); |
115 | 0 |
|
116 | 0 | if (theirAttrs != ourAttrs) { |
117 | 0 | return NS_OK; |
118 | 0 | } |
119 | 0 | |
120 | 0 | nsCOMPtr<nsIURI> theirURI; |
121 | 0 | nsresult rv = principal->GetURI(getter_AddRefs(theirURI)); |
122 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
123 | 0 |
|
124 | 0 | nsCOMPtr<nsIURI> ourURI; |
125 | 0 | rv = mPrincipal->GetURI(getter_AddRefs(ourURI)); |
126 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
127 | 0 |
|
128 | 0 | // Compare schemes |
129 | 0 | nsAutoCString theirScheme; |
130 | 0 | rv = theirURI->GetScheme(theirScheme); |
131 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
132 | 0 |
|
133 | 0 | nsAutoCString ourScheme; |
134 | 0 | rv = ourURI->GetScheme(ourScheme); |
135 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
136 | 0 |
|
137 | 0 | if (theirScheme != ourScheme) { |
138 | 0 | return NS_OK; |
139 | 0 | } |
140 | 0 | |
141 | 0 | // Compare ports |
142 | 0 | int32_t theirPort; |
143 | 0 | rv = theirURI->GetPort(&theirPort); |
144 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
145 | 0 |
|
146 | 0 | int32_t ourPort; |
147 | 0 | rv = ourURI->GetPort(&ourPort); |
148 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
149 | 0 |
|
150 | 0 | if (theirPort != ourPort) { |
151 | 0 | return NS_OK; |
152 | 0 | } |
153 | 0 | |
154 | 0 | // Check if the host or any subdomain of their host matches. |
155 | 0 | nsAutoCString theirHost; |
156 | 0 | rv = theirURI->GetHost(theirHost); |
157 | 0 | if (NS_FAILED(rv) || theirHost.IsEmpty()) { |
158 | 0 | return NS_OK; |
159 | 0 | } |
160 | 0 | |
161 | 0 | nsAutoCString ourHost; |
162 | 0 | rv = ourURI->GetHost(ourHost); |
163 | 0 | if (NS_FAILED(rv) || ourHost.IsEmpty()) { |
164 | 0 | return NS_OK; |
165 | 0 | } |
166 | 0 | |
167 | 0 | nsCOMPtr<nsIEffectiveTLDService> tldService = |
168 | 0 | do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); |
169 | 0 | if (!tldService) { |
170 | 0 | NS_ERROR("Should have a tld service!"); |
171 | 0 | return NS_ERROR_FAILURE; |
172 | 0 | } |
173 | 0 |
|
174 | 0 | // This loop will not loop forever, as GetNextSubDomain will eventually fail |
175 | 0 | // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS. |
176 | 0 | while (theirHost != ourHost) { |
177 | 0 | rv = tldService->GetNextSubDomain(theirHost, theirHost); |
178 | 0 | if (NS_FAILED(rv)) { |
179 | 0 | if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) { |
180 | 0 | return NS_OK; |
181 | 0 | } else { |
182 | 0 | return rv; |
183 | 0 | } |
184 | 0 | } |
185 | 0 | } |
186 | 0 |
|
187 | 0 | *aMatches = true; |
188 | 0 | return NS_OK; |
189 | 0 | } |
190 | | |
191 | | NS_IMETHODIMP |
192 | | nsPermission::MatchesURI(nsIURI* aURI, bool aExactHost, bool* aMatches) |
193 | 0 | { |
194 | 0 | NS_ENSURE_ARG_POINTER(aURI); |
195 | 0 |
|
196 | 0 | mozilla::OriginAttributes attrs; |
197 | 0 | nsCOMPtr<nsIPrincipal> principal = mozilla::BasePrincipal::CreateCodebasePrincipal(aURI, attrs); |
198 | 0 | NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE); |
199 | 0 |
|
200 | 0 | return Matches(principal, aExactHost, aMatches); |
201 | 0 | } |