Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "nsContentSecurityManager.h"
7 : #include "nsSecCheckWrapChannel.h"
8 : #include "nsIForcePendingChannel.h"
9 : #include "nsIStreamListener.h"
10 : #include "mozilla/Logging.h"
11 : #include "nsCOMPtr.h"
12 :
13 : namespace mozilla {
14 : namespace net {
15 :
16 : static LazyLogModule gChannelWrapperLog("ChannelWrapper");
17 : #define CHANNELWRAPPERLOG(args) MOZ_LOG(gChannelWrapperLog, LogLevel::Debug, args)
18 :
19 0 : NS_IMPL_ADDREF(nsSecCheckWrapChannelBase)
20 0 : NS_IMPL_RELEASE(nsSecCheckWrapChannelBase)
21 :
22 0 : NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase)
23 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
24 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
25 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel)
26 0 : NS_INTERFACE_MAP_ENTRY(nsIRequest)
27 0 : NS_INTERFACE_MAP_ENTRY(nsIChannel)
28 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
29 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel2, mUploadChannel2)
30 0 : NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel)
31 0 : NS_INTERFACE_MAP_END
32 :
33 : //---------------------------------------------------------
34 : // nsSecCheckWrapChannelBase implementation
35 : //---------------------------------------------------------
36 :
37 0 : nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel)
38 : : mChannel(aChannel)
39 : , mHttpChannel(do_QueryInterface(aChannel))
40 : , mHttpChannelInternal(do_QueryInterface(aChannel))
41 : , mRequest(do_QueryInterface(aChannel))
42 : , mUploadChannel(do_QueryInterface(aChannel))
43 0 : , mUploadChannel2(do_QueryInterface(aChannel))
44 : {
45 0 : MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel");
46 0 : }
47 :
48 0 : nsSecCheckWrapChannelBase::~nsSecCheckWrapChannelBase()
49 : {
50 0 : }
51 :
52 : //---------------------------------------------------------
53 : // nsISecCheckWrapChannel implementation
54 : //---------------------------------------------------------
55 :
56 : NS_IMETHODIMP
57 0 : nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel)
58 : {
59 0 : NS_IF_ADDREF(*aInnerChannel = mChannel);
60 0 : return NS_OK;
61 : }
62 :
63 : //---------------------------------------------------------
64 : // nsSecCheckWrapChannel implementation
65 : //---------------------------------------------------------
66 :
67 0 : nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel,
68 0 : nsILoadInfo* aLoadInfo)
69 : : nsSecCheckWrapChannelBase(aChannel)
70 0 : , mLoadInfo(aLoadInfo)
71 : {
72 : {
73 0 : nsCOMPtr<nsIURI> uri;
74 0 : mChannel->GetURI(getter_AddRefs(uri));
75 0 : CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",
76 : this, uri ? uri->GetSpecOrDefault().get() : ""));
77 : }
78 0 : }
79 :
80 : // static
81 : already_AddRefed<nsIChannel>
82 0 : nsSecCheckWrapChannel::MaybeWrap(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
83 : {
84 : // Maybe a custom protocol handler actually returns a gecko
85 : // http/ftpChannel - To check this we will check whether the channel
86 : // implements a gecko non-scriptable interface e.g. nsIForcePendingChannel.
87 0 : nsCOMPtr<nsIForcePendingChannel> isGeckoChannel = do_QueryInterface(aChannel);
88 :
89 0 : nsCOMPtr<nsIChannel> channel;
90 0 : if (isGeckoChannel) {
91 : // If it is a gecko channel (ftp or http) we do not need to wrap it.
92 0 : channel = aChannel;
93 0 : channel->SetLoadInfo(aLoadInfo);
94 : } else {
95 0 : channel = new nsSecCheckWrapChannel(aChannel, aLoadInfo);
96 : }
97 0 : return channel.forget();
98 : }
99 :
100 0 : nsSecCheckWrapChannel::~nsSecCheckWrapChannel()
101 : {
102 0 : }
103 :
104 : //---------------------------------------------------------
105 : // SecWrapChannelStreamListener helper
106 : //---------------------------------------------------------
107 :
108 : class SecWrapChannelStreamListener final : public nsIStreamListener
109 : {
110 : public:
111 0 : SecWrapChannelStreamListener(nsIRequest *aRequest,
112 : nsIStreamListener *aStreamListener)
113 0 : : mRequest(aRequest)
114 0 : , mListener(aStreamListener) {}
115 :
116 : NS_DECL_ISUPPORTS
117 : NS_DECL_NSISTREAMLISTENER
118 : NS_DECL_NSIREQUESTOBSERVER
119 :
120 : private:
121 0 : ~SecWrapChannelStreamListener() {}
122 :
123 : nsCOMPtr<nsIRequest> mRequest;
124 : nsCOMPtr<nsIStreamListener> mListener;
125 : };
126 :
127 0 : NS_IMPL_ISUPPORTS(SecWrapChannelStreamListener,
128 : nsIStreamListener,
129 : nsIRequestObserver)
130 :
131 : NS_IMETHODIMP
132 0 : SecWrapChannelStreamListener::OnStartRequest(nsIRequest *aRequest,
133 : nsISupports *aContext)
134 : {
135 0 : return mListener->OnStartRequest(mRequest, aContext);
136 : }
137 :
138 : NS_IMETHODIMP
139 0 : SecWrapChannelStreamListener::OnStopRequest(nsIRequest *aRequest,
140 : nsISupports *aContext,
141 : nsresult aStatus)
142 : {
143 0 : return mListener->OnStopRequest(mRequest, aContext, aStatus);
144 : }
145 :
146 : NS_IMETHODIMP
147 0 : SecWrapChannelStreamListener::OnDataAvailable(nsIRequest *aRequest,
148 : nsISupports *aContext,
149 : nsIInputStream *aInStream,
150 : uint64_t aOffset,
151 : uint32_t aCount)
152 : {
153 0 : return mListener->OnDataAvailable(mRequest, aContext, aInStream, aOffset, aCount);
154 : }
155 :
156 : //---------------------------------------------------------
157 : // nsIChannel implementation
158 : //---------------------------------------------------------
159 :
160 : NS_IMETHODIMP
161 0 : nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
162 : {
163 0 : CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this));
164 0 : NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
165 0 : return NS_OK;
166 : }
167 :
168 : NS_IMETHODIMP
169 0 : nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
170 : {
171 0 : CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this));
172 0 : mLoadInfo = aLoadInfo;
173 0 : return NS_OK;
174 : }
175 :
176 : NS_IMETHODIMP
177 0 : nsSecCheckWrapChannel::AsyncOpen2(nsIStreamListener *aListener)
178 : {
179 : nsCOMPtr<nsIStreamListener> secWrapChannelListener =
180 0 : new SecWrapChannelStreamListener(this, aListener);
181 0 : nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, secWrapChannelListener);
182 0 : NS_ENSURE_SUCCESS(rv, rv);
183 0 : return AsyncOpen(secWrapChannelListener, nullptr);
184 : }
185 :
186 : NS_IMETHODIMP
187 0 : nsSecCheckWrapChannel::Open2(nsIInputStream** aStream)
188 : {
189 0 : nsCOMPtr<nsIStreamListener> listener;
190 0 : nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
191 0 : NS_ENSURE_SUCCESS(rv, rv);
192 0 : return Open(aStream);
193 : }
194 :
195 : } // namespace net
196 : } // namespace mozilla
|