Line data Source code
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 3 : NS_IMPL_CLASSINFO(nsPermission, nullptr, 0, {0})
15 152 : NS_IMPL_ISUPPORTS_CI(nsPermission, nsIPermission)
16 :
17 14 : nsPermission::nsPermission(nsIPrincipal* aPrincipal,
18 : const nsACString &aType,
19 : uint32_t aCapability,
20 : uint32_t aExpireType,
21 14 : int64_t aExpireTime)
22 : : mPrincipal(aPrincipal)
23 : , mType(aType)
24 : , mCapability(aCapability)
25 : , mExpireType(aExpireType)
26 14 : , mExpireTime(aExpireTime)
27 : {
28 14 : }
29 :
30 : already_AddRefed<nsPermission>
31 14 : nsPermission::Create(nsIPrincipal* aPrincipal,
32 : const nsACString &aType,
33 : uint32_t aCapability,
34 : uint32_t aExpireType,
35 : int64_t aExpireTime)
36 : {
37 14 : NS_ENSURE_TRUE(aPrincipal, nullptr);
38 : nsCOMPtr<nsIPrincipal> principal =
39 28 : mozilla::BasePrincipal::Cast(aPrincipal)->CloneStrippingUserContextIdAndFirstPartyDomain();
40 :
41 14 : NS_ENSURE_TRUE(principal, nullptr);
42 :
43 : RefPtr<nsPermission> permission =
44 42 : new nsPermission(principal, aType, aCapability, aExpireType, aExpireTime);
45 14 : return permission.forget();
46 : }
47 :
48 : NS_IMETHODIMP
49 0 : nsPermission::GetPrincipal(nsIPrincipal** aPrincipal)
50 : {
51 0 : nsCOMPtr<nsIPrincipal> copy = mPrincipal;
52 0 : copy.forget(aPrincipal);
53 0 : return NS_OK;
54 : }
55 :
56 : NS_IMETHODIMP
57 14 : nsPermission::GetType(nsACString &aType)
58 : {
59 14 : aType = mType;
60 14 : return NS_OK;
61 : }
62 :
63 : NS_IMETHODIMP
64 0 : nsPermission::GetCapability(uint32_t *aCapability)
65 : {
66 0 : *aCapability = mCapability;
67 0 : return NS_OK;
68 : }
69 :
70 : NS_IMETHODIMP
71 0 : nsPermission::GetExpireType(uint32_t *aExpireType)
72 : {
73 0 : *aExpireType = mExpireType;
74 0 : return NS_OK;
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : nsPermission::GetExpireTime(int64_t *aExpireTime)
79 : {
80 0 : *aExpireTime = mExpireTime;
81 0 : return NS_OK;
82 : }
83 :
84 : NS_IMETHODIMP
85 0 : nsPermission::Matches(nsIPrincipal* aPrincipal, bool aExactHost, bool* aMatches)
86 : {
87 0 : NS_ENSURE_ARG_POINTER(aPrincipal);
88 0 : NS_ENSURE_ARG_POINTER(aMatches);
89 :
90 0 : *aMatches = false;
91 :
92 : nsCOMPtr<nsIPrincipal> principal =
93 0 : mozilla::BasePrincipal::Cast(aPrincipal)->CloneStrippingUserContextIdAndFirstPartyDomain();
94 :
95 0 : if (!principal) {
96 0 : *aMatches = false;
97 0 : return NS_OK;
98 : }
99 :
100 : // If the principals are equal, then they match.
101 0 : if (mPrincipal->Equals(principal)) {
102 0 : *aMatches = true;
103 0 : return NS_OK;
104 : }
105 :
106 : // If we are matching with an exact host, we're done now - the permissions don't match
107 : // otherwise, we need to start comparing subdomains!
108 0 : if (aExactHost) {
109 0 : return NS_OK;
110 : }
111 :
112 : // Compare their OriginAttributes
113 0 : const mozilla::OriginAttributes& theirAttrs = principal->OriginAttributesRef();
114 0 : const mozilla::OriginAttributes& ourAttrs = mPrincipal->OriginAttributesRef();
115 :
116 0 : if (theirAttrs != ourAttrs) {
117 0 : return NS_OK;
118 : }
119 :
120 0 : nsCOMPtr<nsIURI> theirURI;
121 0 : nsresult rv = principal->GetURI(getter_AddRefs(theirURI));
122 0 : NS_ENSURE_SUCCESS(rv, rv);
123 :
124 0 : nsCOMPtr<nsIURI> ourURI;
125 0 : rv = mPrincipal->GetURI(getter_AddRefs(ourURI));
126 0 : NS_ENSURE_SUCCESS(rv, rv);
127 :
128 : // Compare schemes
129 0 : nsAutoCString theirScheme;
130 0 : rv = theirURI->GetScheme(theirScheme);
131 0 : NS_ENSURE_SUCCESS(rv, rv);
132 :
133 0 : nsAutoCString ourScheme;
134 0 : rv = ourURI->GetScheme(ourScheme);
135 0 : NS_ENSURE_SUCCESS(rv, rv);
136 :
137 0 : if (theirScheme != ourScheme) {
138 0 : return NS_OK;
139 : }
140 :
141 : // Compare ports
142 : int32_t theirPort;
143 0 : rv = theirURI->GetPort(&theirPort);
144 0 : NS_ENSURE_SUCCESS(rv, rv);
145 :
146 : int32_t ourPort;
147 0 : rv = ourURI->GetPort(&ourPort);
148 0 : NS_ENSURE_SUCCESS(rv, rv);
149 :
150 0 : if (theirPort != ourPort) {
151 0 : return NS_OK;
152 : }
153 :
154 : // 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 : }
160 :
161 0 : nsAutoCString ourHost;
162 0 : rv = ourURI->GetHost(ourHost);
163 0 : if (NS_FAILED(rv) || ourHost.IsEmpty()) {
164 0 : return NS_OK;
165 : }
166 :
167 : 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 : }
173 :
174 : // This loop will not loop forever, as GetNextSubDomain will eventually fail
175 : // 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 : } else {
182 0 : return rv;
183 : }
184 : }
185 : }
186 :
187 0 : *aMatches = true;
188 0 : return NS_OK;
189 : }
190 :
191 : NS_IMETHODIMP
192 0 : nsPermission::MatchesURI(nsIURI* aURI, bool aExactHost, bool* aMatches)
193 : {
194 0 : NS_ENSURE_ARG_POINTER(aURI);
195 :
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 :
200 0 : return Matches(principal, aExactHost, aMatches);
201 : }
|