2 * Copyright (C) 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "AuthenticationCF.h"
31 #include "AuthenticationChallenge.h"
32 #include "AuthenticationClient.h"
33 #include "Credential.h"
34 #include "ProtectionSpace.h"
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>
40 #include <CFNetwork/CFURLAuthChallengePriv.h>
41 #include <CFNetwork/CFURLCredentialPriv.h>
42 #include <CFNetwork/CFURLProtectionSpacePriv.h>
46 static uint64_t generateUniqueIdentifier()
48 static uint64_t uniqueIdentifier;
49 return ++uniqueIdentifier;
52 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
53 const Credential& proposedCredential,
54 unsigned previousFailureCount,
55 const ResourceResponse& response,
56 const ResourceError& error,
58 : AuthenticationChallengeBase(protectionSpace,
64 m_identifier = identifier;
67 AuthenticationChallenge::AuthenticationChallenge(CFURLAuthChallengeRef cfChallenge,
68 AuthenticationClient* authenticationClient)
69 : AuthenticationChallengeBase(core(CFURLAuthChallengeGetProtectionSpace(cfChallenge)),
70 core(CFURLAuthChallengeGetProposedCredential(cfChallenge)),
71 CFURLAuthChallengeGetPreviousFailureCount(cfChallenge),
72 (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(cfChallenge),
73 CFURLAuthChallengeGetError(cfChallenge))
74 , m_authenticationClient(authenticationClient)
75 , m_cfChallenge(cfChallenge)
77 m_identifier = generateUniqueIdentifier();
80 AuthenticationClient* AuthenticationChallenge::authenticationClient() const
82 return m_authenticationClient.get();
85 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
87 if (a.authenticationClient() != b.authenticationClient())
90 if (a.cfURLAuthChallengeRef() != b.cfURLAuthChallengeRef())
96 CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge)
98 // FIXME: Why not cache CFURLAuthChallengeRef in m_cfChallenge? Foundation counterpart does that.
100 CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace());
101 CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential());
103 CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential,
104 coreChallenge.previousFailureCount(),
105 coreChallenge.failureResponse().cfURLResponse(),
106 coreChallenge.error());
107 CFRelease(protectionSpace);
108 CFRelease(credential);
112 CFURLCredentialRef createCF(const Credential& coreCredential)
114 CFURLCredentialPersistence persistence = kCFURLCredentialPersistenceNone;
115 switch (coreCredential.persistence()) {
116 case CredentialPersistenceNone:
118 case CredentialPersistenceForSession:
119 persistence = kCFURLCredentialPersistenceForSession;
121 case CredentialPersistencePermanent:
122 persistence = kCFURLCredentialPersistencePermanent;
125 ASSERT_NOT_REACHED();
128 #if CERTIFICATE_CREDENTIALS_SUPPORTED
129 if (coreCredential.type() == CredentialTypeClientCertificate)
130 return CFURLCredentialCreateWithIdentityAndCertificateArray(kCFAllocatorDefault, coreCredential.identity(), coreCredential.certificates(), persistence);
133 return CFURLCredentialCreate(0, coreCredential.user().createCFString().get(), coreCredential.password().createCFString().get(), 0, persistence);
136 CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace)
138 CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP;
139 switch (coreSpace.serverType()) {
140 case ProtectionSpaceServerHTTP:
141 serverType = kCFURLProtectionSpaceServerHTTP;
143 case ProtectionSpaceServerHTTPS:
144 serverType = kCFURLProtectionSpaceServerHTTPS;
146 case ProtectionSpaceServerFTP:
147 serverType = kCFURLProtectionSpaceServerFTP;
149 case ProtectionSpaceServerFTPS:
150 serverType = kCFURLProtectionSpaceServerFTPS;
152 case ProtectionSpaceProxyHTTP:
153 serverType = kCFURLProtectionSpaceProxyHTTP;
155 case ProtectionSpaceProxyHTTPS:
156 serverType = kCFURLProtectionSpaceProxyHTTPS;
158 case ProtectionSpaceProxyFTP:
159 serverType = kCFURLProtectionSpaceProxyFTP;
161 case ProtectionSpaceProxySOCKS:
162 serverType = kCFURLProtectionSpaceProxySOCKS;
165 ASSERT_NOT_REACHED();
168 CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
169 switch (coreSpace.authenticationScheme()) {
170 case ProtectionSpaceAuthenticationSchemeDefault:
171 scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
173 case ProtectionSpaceAuthenticationSchemeHTTPBasic:
174 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic;
176 case ProtectionSpaceAuthenticationSchemeHTTPDigest:
177 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest;
179 case ProtectionSpaceAuthenticationSchemeHTMLForm:
180 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm;
182 case ProtectionSpaceAuthenticationSchemeNTLM:
183 scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM;
185 case ProtectionSpaceAuthenticationSchemeNegotiate:
186 scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate;
188 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
189 case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
190 scheme = kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
192 case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
193 scheme = kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested;
197 ASSERT_NOT_REACHED();
200 return CFURLProtectionSpaceCreate(0, coreSpace.host().createCFString().get(), coreSpace.port(), serverType, coreSpace.realm().createCFString().get(), scheme);
203 Credential core(CFURLCredentialRef cfCredential)
208 CredentialPersistence persistence = CredentialPersistenceNone;
209 switch (CFURLCredentialGetPersistence(cfCredential)) {
210 case kCFURLCredentialPersistenceNone:
212 case kCFURLCredentialPersistenceForSession:
213 persistence = CredentialPersistenceForSession;
215 case kCFURLCredentialPersistencePermanent:
216 persistence = CredentialPersistencePermanent;
219 ASSERT_NOT_REACHED();
222 #if CERTIFICATE_CREDENTIALS_SUPPORTED
223 SecIdentityRef identity = CFURLCredentialGetCertificateIdentity(cfCredential);
225 return Credential(identity, CFURLCredentialGetCertificateArray(cfCredential), persistence);
228 RetainPtr<CFStringRef> password(AdoptCF, CFURLCredentialCopyPassword(cfCredential));
229 return Credential(CFURLCredentialGetUsername(cfCredential), password.get(), persistence);
232 ProtectionSpace core(CFURLProtectionSpaceRef cfSpace)
234 ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP;
236 switch (CFURLProtectionSpaceGetServerType(cfSpace)) {
237 case kCFURLProtectionSpaceServerHTTP:
239 case kCFURLProtectionSpaceServerHTTPS:
240 serverType = ProtectionSpaceServerHTTPS;
242 case kCFURLProtectionSpaceServerFTP:
243 serverType = ProtectionSpaceServerFTP;
245 case kCFURLProtectionSpaceServerFTPS:
246 serverType = ProtectionSpaceServerFTPS;
248 case kCFURLProtectionSpaceProxyHTTP:
249 serverType = ProtectionSpaceProxyHTTP;
251 case kCFURLProtectionSpaceProxyHTTPS:
252 serverType = ProtectionSpaceProxyHTTPS;
254 case kCFURLProtectionSpaceProxyFTP:
255 serverType = ProtectionSpaceProxyFTP;
257 case kCFURLProtectionSpaceProxySOCKS:
258 serverType = ProtectionSpaceProxySOCKS;
261 ASSERT_NOT_REACHED();
264 ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
266 switch (CFURLProtectionSpaceGetAuthenticationScheme(cfSpace)) {
267 case kCFURLProtectionSpaceAuthenticationSchemeDefault:
268 scheme = ProtectionSpaceAuthenticationSchemeDefault;
270 case kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic:
271 scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
273 case kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest:
274 scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
276 case kCFURLProtectionSpaceAuthenticationSchemeHTMLForm:
277 scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
279 case kCFURLProtectionSpaceAuthenticationSchemeNTLM:
280 scheme = ProtectionSpaceAuthenticationSchemeNTLM;
282 case kCFURLProtectionSpaceAuthenticationSchemeNegotiate:
283 scheme = ProtectionSpaceAuthenticationSchemeNegotiate;
285 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
286 case kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested:
287 scheme = ProtectionSpaceAuthenticationSchemeClientCertificateRequested;
289 case kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
290 scheme = ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
294 scheme = ProtectionSpaceAuthenticationSchemeUnknown;
295 ASSERT_NOT_REACHED();
298 return ProtectionSpace(CFURLProtectionSpaceGetHost(cfSpace),
299 CFURLProtectionSpaceGetPort(cfSpace),
301 CFURLProtectionSpaceGetRealm(cfSpace),
307 #endif // USE(CFNETWORK)