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 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
47 const Credential& proposedCredential,
48 unsigned previousFailureCount,
49 const ResourceResponse& response,
50 const ResourceError& error)
51 : AuthenticationChallengeBase(protectionSpace,
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)
71 AuthenticationClient* AuthenticationChallenge::authenticationClient() const
73 return m_authenticationClient.get();
76 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
78 if (a.authenticationClient() != b.authenticationClient())
81 if (a.cfURLAuthChallengeRef() != b.cfURLAuthChallengeRef())
87 CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge)
89 // FIXME: Why not cache CFURLAuthChallengeRef in m_cfChallenge? Foundation counterpart does that.
91 CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace());
92 CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential());
94 CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential,
95 coreChallenge.previousFailureCount(),
96 coreChallenge.failureResponse().cfURLResponse(),
97 coreChallenge.error());
98 CFRelease(protectionSpace);
99 CFRelease(credential);
103 CFURLCredentialRef createCF(const Credential& coreCredential)
105 CFURLCredentialPersistence persistence = kCFURLCredentialPersistenceNone;
106 switch (coreCredential.persistence()) {
107 case CredentialPersistenceNone:
109 case CredentialPersistenceForSession:
110 persistence = kCFURLCredentialPersistenceForSession;
112 case CredentialPersistencePermanent:
113 persistence = kCFURLCredentialPersistencePermanent;
116 ASSERT_NOT_REACHED();
119 #if CERTIFICATE_CREDENTIALS_SUPPORTED
120 if (coreCredential.type() == CredentialTypeClientCertificate)
121 return CFURLCredentialCreateWithIdentityAndCertificateArray(kCFAllocatorDefault, coreCredential.identity(), coreCredential.certificates(), persistence);
124 return CFURLCredentialCreate(0, coreCredential.user().createCFString().get(), coreCredential.password().createCFString().get(), 0, persistence);
127 CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace)
129 CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP;
130 switch (coreSpace.serverType()) {
131 case ProtectionSpaceServerHTTP:
132 serverType = kCFURLProtectionSpaceServerHTTP;
134 case ProtectionSpaceServerHTTPS:
135 serverType = kCFURLProtectionSpaceServerHTTPS;
137 case ProtectionSpaceServerFTP:
138 serverType = kCFURLProtectionSpaceServerFTP;
140 case ProtectionSpaceServerFTPS:
141 serverType = kCFURLProtectionSpaceServerFTPS;
143 case ProtectionSpaceProxyHTTP:
144 serverType = kCFURLProtectionSpaceProxyHTTP;
146 case ProtectionSpaceProxyHTTPS:
147 serverType = kCFURLProtectionSpaceProxyHTTPS;
149 case ProtectionSpaceProxyFTP:
150 serverType = kCFURLProtectionSpaceProxyFTP;
152 case ProtectionSpaceProxySOCKS:
153 serverType = kCFURLProtectionSpaceProxySOCKS;
156 ASSERT_NOT_REACHED();
159 CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
160 switch (coreSpace.authenticationScheme()) {
161 case ProtectionSpaceAuthenticationSchemeDefault:
162 scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
164 case ProtectionSpaceAuthenticationSchemeHTTPBasic:
165 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic;
167 case ProtectionSpaceAuthenticationSchemeHTTPDigest:
168 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest;
170 case ProtectionSpaceAuthenticationSchemeHTMLForm:
171 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm;
173 case ProtectionSpaceAuthenticationSchemeNTLM:
174 scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM;
176 case ProtectionSpaceAuthenticationSchemeNegotiate:
177 scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate;
179 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
180 case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
181 scheme = kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
183 case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
184 scheme = kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested;
188 ASSERT_NOT_REACHED();
191 return CFURLProtectionSpaceCreate(0, coreSpace.host().createCFString().get(), coreSpace.port(), serverType, coreSpace.realm().createCFString().get(), scheme);
194 Credential core(CFURLCredentialRef cfCredential)
199 CredentialPersistence persistence = CredentialPersistenceNone;
200 switch (CFURLCredentialGetPersistence(cfCredential)) {
201 case kCFURLCredentialPersistenceNone:
203 case kCFURLCredentialPersistenceForSession:
204 persistence = CredentialPersistenceForSession;
206 case kCFURLCredentialPersistencePermanent:
207 persistence = CredentialPersistencePermanent;
210 ASSERT_NOT_REACHED();
213 #if CERTIFICATE_CREDENTIALS_SUPPORTED
214 SecIdentityRef identity = CFURLCredentialGetCertificateIdentity(cfCredential);
216 return Credential(identity, CFURLCredentialGetCertificateArray(cfCredential), persistence);
219 RetainPtr<CFStringRef> password(AdoptCF, CFURLCredentialCopyPassword(cfCredential));
220 return Credential(CFURLCredentialGetUsername(cfCredential), password.get(), persistence);
223 ProtectionSpace core(CFURLProtectionSpaceRef cfSpace)
225 ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP;
227 switch (CFURLProtectionSpaceGetServerType(cfSpace)) {
228 case kCFURLProtectionSpaceServerHTTP:
230 case kCFURLProtectionSpaceServerHTTPS:
231 serverType = ProtectionSpaceServerHTTPS;
233 case kCFURLProtectionSpaceServerFTP:
234 serverType = ProtectionSpaceServerFTP;
236 case kCFURLProtectionSpaceServerFTPS:
237 serverType = ProtectionSpaceServerFTPS;
239 case kCFURLProtectionSpaceProxyHTTP:
240 serverType = ProtectionSpaceProxyHTTP;
242 case kCFURLProtectionSpaceProxyHTTPS:
243 serverType = ProtectionSpaceProxyHTTPS;
245 case kCFURLProtectionSpaceProxyFTP:
246 serverType = ProtectionSpaceProxyFTP;
248 case kCFURLProtectionSpaceProxySOCKS:
249 serverType = ProtectionSpaceProxySOCKS;
252 ASSERT_NOT_REACHED();
255 ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
257 switch (CFURLProtectionSpaceGetAuthenticationScheme(cfSpace)) {
258 case kCFURLProtectionSpaceAuthenticationSchemeDefault:
259 scheme = ProtectionSpaceAuthenticationSchemeDefault;
261 case kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic:
262 scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
264 case kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest:
265 scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
267 case kCFURLProtectionSpaceAuthenticationSchemeHTMLForm:
268 scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
270 case kCFURLProtectionSpaceAuthenticationSchemeNTLM:
271 scheme = ProtectionSpaceAuthenticationSchemeNTLM;
273 case kCFURLProtectionSpaceAuthenticationSchemeNegotiate:
274 scheme = ProtectionSpaceAuthenticationSchemeNegotiate;
276 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
277 case kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested:
278 scheme = ProtectionSpaceAuthenticationSchemeClientCertificateRequested;
280 case kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
281 scheme = ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
285 scheme = ProtectionSpaceAuthenticationSchemeUnknown;
286 ASSERT_NOT_REACHED();
289 return ProtectionSpace(CFURLProtectionSpaceGetHost(cfSpace),
290 CFURLProtectionSpaceGetPort(cfSpace),
292 CFURLProtectionSpaceGetRealm(cfSpace),
298 #endif // USE(CFNETWORK)