1 | /* |
2 | * Copyright (C) 2010 Apple Inc. All rights reserved. |
3 | * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. |
4 | * Portions Copyright (c) 2013 Company 100 Inc. All rights reserved. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
17 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | * THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #include "config.h" |
29 | #include "DataReference.h" |
30 | #include "WebCoreArgumentCoders.h" |
31 | |
32 | #include <WebCore/CertificateInfo.h> |
33 | #include <WebCore/DictionaryPopupInfo.h> |
34 | #include <WebCore/FontAttributes.h> |
35 | #include <WebCore/ResourceError.h> |
36 | #include <WebCore/ResourceRequest.h> |
37 | #include <WebCore/ResourceResponse.h> |
38 | #include <WebCore/SoupNetworkProxySettings.h> |
39 | #include <wtf/text/CString.h> |
40 | |
41 | namespace IPC { |
42 | using namespace WebCore; |
43 | |
44 | void ArgumentCoder<ResourceRequest>::encodePlatformData(Encoder& encoder, const ResourceRequest& resourceRequest) |
45 | { |
46 | resourceRequest.encodeWithPlatformData(encoder); |
47 | } |
48 | |
49 | bool ArgumentCoder<ResourceRequest>::decodePlatformData(Decoder& decoder, ResourceRequest& resourceRequest) |
50 | { |
51 | return resourceRequest.decodeWithPlatformData(decoder); |
52 | } |
53 | |
54 | void ArgumentCoder<CertificateInfo>::encode(Encoder& encoder, const CertificateInfo& certificateInfo) |
55 | { |
56 | auto* certificate = certificateInfo.certificate(); |
57 | if (!certificate) { |
58 | encoder << 0; |
59 | return; |
60 | } |
61 | |
62 | Vector<GRefPtr<GByteArray>> certificatesDataList; |
63 | for (; certificate; certificate = g_tls_certificate_get_issuer(certificate)) { |
64 | GByteArray* certificateData = nullptr; |
65 | g_object_get(G_OBJECT(certificate), "certificate" , &certificateData, nullptr); |
66 | |
67 | if (!certificateData) { |
68 | certificatesDataList.clear(); |
69 | break; |
70 | } |
71 | |
72 | certificatesDataList.append(adoptGRef(certificateData)); |
73 | } |
74 | |
75 | encoder << static_cast<uint32_t>(certificatesDataList.size()); |
76 | |
77 | if (certificatesDataList.isEmpty()) |
78 | return; |
79 | |
80 | // Encode starting from the root certificate. |
81 | for (size_t i = certificatesDataList.size(); i > 0; --i) { |
82 | GByteArray* certificate = certificatesDataList[i - 1].get(); |
83 | encoder.encodeVariableLengthByteArray(IPC::DataReference(certificate->data, certificate->len)); |
84 | } |
85 | |
86 | encoder << static_cast<uint32_t>(certificateInfo.tlsErrors()); |
87 | } |
88 | |
89 | bool ArgumentCoder<CertificateInfo>::decode(Decoder& decoder, CertificateInfo& certificateInfo) |
90 | { |
91 | uint32_t chainLength; |
92 | if (!decoder.decode(chainLength)) |
93 | return false; |
94 | |
95 | if (!chainLength) |
96 | return true; |
97 | |
98 | GType certificateType = g_tls_backend_get_certificate_type(g_tls_backend_get_default()); |
99 | GRefPtr<GTlsCertificate> certificate; |
100 | for (uint32_t i = 0; i < chainLength; i++) { |
101 | IPC::DataReference certificateDataReference; |
102 | if (!decoder.decodeVariableLengthByteArray(certificateDataReference)) |
103 | return false; |
104 | |
105 | GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size()); |
106 | GRefPtr<GByteArray> certificateBytes = adoptGRef(g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size())); |
107 | |
108 | certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new( |
109 | certificateType, nullptr, nullptr, "certificate" , certificateBytes.get(), "issuer" , certificate.get(), nullptr))); |
110 | } |
111 | |
112 | uint32_t tlsErrors; |
113 | if (!decoder.decode(tlsErrors)) |
114 | return false; |
115 | |
116 | certificateInfo.setCertificate(certificate.get()); |
117 | certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors)); |
118 | |
119 | return true; |
120 | } |
121 | |
122 | void ArgumentCoder<ResourceError>::encodePlatformData(Encoder& encoder, const ResourceError& resourceError) |
123 | { |
124 | encoder << resourceError.domain(); |
125 | encoder << resourceError.errorCode(); |
126 | encoder << resourceError.failingURL().string(); |
127 | encoder << resourceError.localizedDescription(); |
128 | |
129 | encoder << CertificateInfo(resourceError); |
130 | } |
131 | |
132 | bool ArgumentCoder<ResourceError>::decodePlatformData(Decoder& decoder, ResourceError& resourceError) |
133 | { |
134 | String domain; |
135 | if (!decoder.decode(domain)) |
136 | return false; |
137 | |
138 | int errorCode; |
139 | if (!decoder.decode(errorCode)) |
140 | return false; |
141 | |
142 | String failingURL; |
143 | if (!decoder.decode(failingURL)) |
144 | return false; |
145 | |
146 | String localizedDescription; |
147 | if (!decoder.decode(localizedDescription)) |
148 | return false; |
149 | |
150 | resourceError = ResourceError(domain, errorCode, URL(URL(), failingURL), localizedDescription); |
151 | |
152 | CertificateInfo certificateInfo; |
153 | if (!decoder.decode(certificateInfo)) |
154 | return false; |
155 | |
156 | resourceError.setCertificate(certificateInfo.certificate()); |
157 | resourceError.setTLSErrors(certificateInfo.tlsErrors()); |
158 | return true; |
159 | } |
160 | |
161 | void ArgumentCoder<SoupNetworkProxySettings>::encode(Encoder& encoder, const SoupNetworkProxySettings& settings) |
162 | { |
163 | ASSERT(!settings.isEmpty()); |
164 | encoder.encodeEnum(settings.mode); |
165 | if (settings.mode != SoupNetworkProxySettings::Mode::Custom) |
166 | return; |
167 | |
168 | encoder << settings.defaultProxyURL; |
169 | uint32_t ignoreHostsCount = settings.ignoreHosts ? g_strv_length(settings.ignoreHosts.get()) : 0; |
170 | encoder << ignoreHostsCount; |
171 | if (ignoreHostsCount) { |
172 | for (uint32_t i = 0; settings.ignoreHosts.get()[i]; ++i) |
173 | encoder << CString(settings.ignoreHosts.get()[i]); |
174 | } |
175 | encoder << settings.proxyMap; |
176 | } |
177 | |
178 | bool ArgumentCoder<SoupNetworkProxySettings>::decode(Decoder& decoder, SoupNetworkProxySettings& settings) |
179 | { |
180 | if (!decoder.decodeEnum(settings.mode)) |
181 | return false; |
182 | |
183 | if (settings.mode != SoupNetworkProxySettings::Mode::Custom) |
184 | return true; |
185 | |
186 | if (!decoder.decode(settings.defaultProxyURL)) |
187 | return false; |
188 | |
189 | uint32_t ignoreHostsCount; |
190 | if (!decoder.decode(ignoreHostsCount)) |
191 | return false; |
192 | |
193 | if (ignoreHostsCount) { |
194 | settings.ignoreHosts.reset(g_new0(char*, ignoreHostsCount + 1)); |
195 | for (uint32_t i = 0; i < ignoreHostsCount; ++i) { |
196 | CString host; |
197 | if (!decoder.decode(host)) |
198 | return false; |
199 | |
200 | settings.ignoreHosts.get()[i] = g_strdup(host.data()); |
201 | } |
202 | } |
203 | |
204 | if (!decoder.decode(settings.proxyMap)) |
205 | return false; |
206 | |
207 | return !settings.isEmpty(); |
208 | } |
209 | |
210 | void ArgumentCoder<ProtectionSpace>::encodePlatformData(Encoder&, const ProtectionSpace&) |
211 | { |
212 | ASSERT_NOT_REACHED(); |
213 | } |
214 | |
215 | bool ArgumentCoder<ProtectionSpace>::decodePlatformData(Decoder&, ProtectionSpace&) |
216 | { |
217 | ASSERT_NOT_REACHED(); |
218 | return false; |
219 | } |
220 | |
221 | void ArgumentCoder<Credential>::encodePlatformData(Encoder&, const Credential&) |
222 | { |
223 | ASSERT_NOT_REACHED(); |
224 | } |
225 | |
226 | bool ArgumentCoder<Credential>::decodePlatformData(Decoder&, Credential&) |
227 | { |
228 | ASSERT_NOT_REACHED(); |
229 | return false; |
230 | } |
231 | |
232 | void ArgumentCoder<FontAttributes>::encodePlatformData(Encoder&, const FontAttributes&) |
233 | { |
234 | ASSERT_NOT_REACHED(); |
235 | } |
236 | |
237 | Optional<FontAttributes> ArgumentCoder<FontAttributes>::decodePlatformData(Decoder&, FontAttributes&) |
238 | { |
239 | ASSERT_NOT_REACHED(); |
240 | return WTF::nullopt; |
241 | } |
242 | |
243 | void ArgumentCoder<DictionaryPopupInfo>::(Encoder&, const DictionaryPopupInfo&) |
244 | { |
245 | ASSERT_NOT_REACHED(); |
246 | } |
247 | |
248 | bool ArgumentCoder<DictionaryPopupInfo>::(Decoder&, DictionaryPopupInfo&) |
249 | { |
250 | ASSERT_NOT_REACHED(); |
251 | return false; |
252 | } |
253 | |
254 | } |
255 | |
256 | |