1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "AuthenticationCF.h"
28
29 #if USE(CFNETWORK)
30
31 #include "AuthenticationChallenge.h"
32 #include "AuthenticationClient.h"
33 #include "Credential.h"
34 #include "ProtectionSpace.h"
35
36 // This header must come before all other CFNetwork headers to work around a CFNetwork bug. It can
37 // be removed entirely once <rdar://problem/9042114> is fixed.
38 #include <CFNetwork/CFURLConnectionPriv.h>
39
40 #include <CFNetwork/CFURLAuthChallengePriv.h>
41 #include <CFNetwork/CFURLCredentialPriv.h>
42 #include <CFNetwork/CFURLProtectionSpacePriv.h>
43
44 namespace WebCore {
45
AuthenticationChallenge(const ProtectionSpace & protectionSpace,const Credential & proposedCredential,unsigned previousFailureCount,const ResourceResponse & response,const ResourceError & error)46 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
47 const Credential& proposedCredential,
48 unsigned previousFailureCount,
49 const ResourceResponse& response,
50 const ResourceError& error)
51 : AuthenticationChallengeBase(protectionSpace,
52 proposedCredential,
53 previousFailureCount,
54 response,
55 error)
56 {
57 }
58
AuthenticationChallenge(CFURLAuthChallengeRef cfChallenge,AuthenticationClient * authenticationClient)59 AuthenticationChallenge::AuthenticationChallenge(CFURLAuthChallengeRef cfChallenge,
60 AuthenticationClient* authenticationClient)
61 : AuthenticationChallengeBase(core(CFURLAuthChallengeGetProtectionSpace(cfChallenge)),
62 core(CFURLAuthChallengeGetProposedCredential(cfChallenge)),
63 CFURLAuthChallengeGetPreviousFailureCount(cfChallenge),
64 (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(cfChallenge),
65 CFURLAuthChallengeGetError(cfChallenge))
66 , m_authenticationClient(authenticationClient)
67 , m_cfChallenge(cfChallenge)
68 {
69 }
70
platformCompare(const AuthenticationChallenge & a,const AuthenticationChallenge & b)71 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
72 {
73 if (a.authenticationClient() != b.authenticationClient())
74 return false;
75
76 if (a.cfURLAuthChallengeRef() != b.cfURLAuthChallengeRef())
77 return false;
78
79 return true;
80 }
81
createCF(const AuthenticationChallenge & coreChallenge)82 CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge)
83 {
84 CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace());
85 CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential());
86
87 CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential,
88 coreChallenge.previousFailureCount(),
89 coreChallenge.failureResponse().cfURLResponse(),
90 coreChallenge.error());
91 CFRelease(protectionSpace);
92 CFRelease(credential);
93 return result;
94 }
95
createCF(const Credential & coreCredential)96 CFURLCredentialRef createCF(const Credential& coreCredential)
97 {
98 CFURLCredentialPersistence persistence = kCFURLCredentialPersistenceNone;
99 switch (coreCredential.persistence()) {
100 case CredentialPersistenceNone:
101 break;
102 case CredentialPersistenceForSession:
103 persistence = kCFURLCredentialPersistenceForSession;
104 break;
105 case CredentialPersistencePermanent:
106 persistence = kCFURLCredentialPersistencePermanent;
107 break;
108 default:
109 ASSERT_NOT_REACHED();
110 }
111
112 CFStringRef user = coreCredential.user().createCFString();
113 CFStringRef password = coreCredential.password().createCFString();
114 CFURLCredentialRef result = CFURLCredentialCreate(0, user, password, 0, persistence);
115 CFRelease(user);
116 CFRelease(password);
117
118 return result;
119 }
120
createCF(const ProtectionSpace & coreSpace)121 CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace)
122 {
123 CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP;
124 switch (coreSpace.serverType()) {
125 case ProtectionSpaceServerHTTP:
126 serverType = kCFURLProtectionSpaceServerHTTP;
127 break;
128 case ProtectionSpaceServerHTTPS:
129 serverType = kCFURLProtectionSpaceServerHTTPS;
130 break;
131 case ProtectionSpaceServerFTP:
132 serverType = kCFURLProtectionSpaceServerFTP;
133 break;
134 case ProtectionSpaceServerFTPS:
135 serverType = kCFURLProtectionSpaceServerFTPS;
136 break;
137 case ProtectionSpaceProxyHTTP:
138 serverType = kCFURLProtectionSpaceProxyHTTP;
139 break;
140 case ProtectionSpaceProxyHTTPS:
141 serverType = kCFURLProtectionSpaceProxyHTTPS;
142 break;
143 case ProtectionSpaceProxyFTP:
144 serverType = kCFURLProtectionSpaceProxyFTP;
145 break;
146 case ProtectionSpaceProxySOCKS:
147 serverType = kCFURLProtectionSpaceProxySOCKS;
148 break;
149 default:
150 ASSERT_NOT_REACHED();
151 }
152
153 CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
154 switch (coreSpace.authenticationScheme()) {
155 case ProtectionSpaceAuthenticationSchemeDefault:
156 scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
157 break;
158 case ProtectionSpaceAuthenticationSchemeHTTPBasic:
159 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic;
160 break;
161 case ProtectionSpaceAuthenticationSchemeHTTPDigest:
162 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest;
163 break;
164 case ProtectionSpaceAuthenticationSchemeHTMLForm:
165 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm;
166 break;
167 case ProtectionSpaceAuthenticationSchemeNTLM:
168 scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM;
169 break;
170 case ProtectionSpaceAuthenticationSchemeNegotiate:
171 scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate;
172 break;
173 default:
174 ASSERT_NOT_REACHED();
175 }
176
177 CFStringRef host = coreSpace.host().createCFString();
178 CFStringRef realm = coreSpace.realm().createCFString();
179 CFURLProtectionSpaceRef result = CFURLProtectionSpaceCreate(0, host, coreSpace.port(), serverType, realm, scheme);
180 CFRelease(host);
181 CFRelease(realm);
182
183 return result;
184 }
185
core(CFURLCredentialRef cfCredential)186 Credential core(CFURLCredentialRef cfCredential)
187 {
188 if (!cfCredential)
189 return Credential();
190
191 CredentialPersistence persistence = CredentialPersistenceNone;
192 switch (CFURLCredentialGetPersistence(cfCredential)) {
193 case kCFURLCredentialPersistenceNone:
194 break;
195 case kCFURLCredentialPersistenceForSession:
196 persistence = CredentialPersistenceForSession;
197 break;
198 case kCFURLCredentialPersistencePermanent:
199 persistence = CredentialPersistencePermanent;
200 break;
201 default:
202 ASSERT_NOT_REACHED();
203 }
204
205 return Credential(CFURLCredentialGetUsername(cfCredential), CFURLCredentialCopyPassword(cfCredential), persistence);
206 }
207
core(CFURLProtectionSpaceRef cfSpace)208 ProtectionSpace core(CFURLProtectionSpaceRef cfSpace)
209 {
210 ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP;
211
212 switch (CFURLProtectionSpaceGetServerType(cfSpace)) {
213 case kCFURLProtectionSpaceServerHTTP:
214 break;
215 case kCFURLProtectionSpaceServerHTTPS:
216 serverType = ProtectionSpaceServerHTTPS;
217 break;
218 case kCFURLProtectionSpaceServerFTP:
219 serverType = ProtectionSpaceServerFTP;
220 break;
221 case kCFURLProtectionSpaceServerFTPS:
222 serverType = ProtectionSpaceServerFTPS;
223 break;
224 case kCFURLProtectionSpaceProxyHTTP:
225 serverType = ProtectionSpaceProxyHTTP;
226 break;
227 case kCFURLProtectionSpaceProxyHTTPS:
228 serverType = ProtectionSpaceProxyHTTPS;
229 break;
230 case kCFURLProtectionSpaceProxyFTP:
231 serverType = ProtectionSpaceProxyFTP;
232 break;
233 case kCFURLProtectionSpaceProxySOCKS:
234 serverType = ProtectionSpaceProxySOCKS;
235 break;
236 default:
237 ASSERT_NOT_REACHED();
238 }
239
240 ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
241
242 switch (CFURLProtectionSpaceGetAuthenticationScheme(cfSpace)) {
243 case kCFURLProtectionSpaceAuthenticationSchemeDefault:
244 scheme = ProtectionSpaceAuthenticationSchemeDefault;
245 break;
246 case kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic:
247 scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
248 break;
249 case kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest:
250 scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
251 break;
252 case kCFURLProtectionSpaceAuthenticationSchemeHTMLForm:
253 scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
254 break;
255 case kCFURLProtectionSpaceAuthenticationSchemeNTLM:
256 scheme = ProtectionSpaceAuthenticationSchemeNTLM;
257 break;
258 case kCFURLProtectionSpaceAuthenticationSchemeNegotiate:
259 scheme = ProtectionSpaceAuthenticationSchemeNegotiate;
260 break;
261 default:
262 scheme = ProtectionSpaceAuthenticationSchemeUnknown;
263 ASSERT_NOT_REACHED();
264 }
265
266 return ProtectionSpace(CFURLProtectionSpaceGetHost(cfSpace),
267 CFURLProtectionSpaceGetPort(cfSpace),
268 serverType,
269 CFURLProtectionSpaceGetRealm(cfSpace),
270 scheme);
271 }
272
273 };
274
275 #endif // USE(CFNETWORK)
276