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 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 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#include <CFNetwork/CFURLAuthChallengePriv.h> 36#include <CFNetwork/CFURLCredentialPriv.h> 37#include <CFNetwork/CFURLProtectionSpacePriv.h> 38 39namespace WebCore { 40 41AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace, 42 const Credential& proposedCredential, 43 unsigned previousFailureCount, 44 const ResourceResponse& response, 45 const ResourceError& error) 46 : AuthenticationChallengeBase(protectionSpace, 47 proposedCredential, 48 previousFailureCount, 49 response, 50 error) 51{ 52} 53 54AuthenticationChallenge::AuthenticationChallenge(CFURLAuthChallengeRef cfChallenge, 55 AuthenticationClient* authenticationClient) 56#if PLATFORM(COCOA) 57 : AuthenticationChallengeBase(ProtectionSpace(CFURLAuthChallengeGetProtectionSpace(cfChallenge)), 58#else 59 : AuthenticationChallengeBase(core(CFURLAuthChallengeGetProtectionSpace(cfChallenge)), 60#endif 61 core(CFURLAuthChallengeGetProposedCredential(cfChallenge)), 62 CFURLAuthChallengeGetPreviousFailureCount(cfChallenge), 63 (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(cfChallenge), 64 CFURLAuthChallengeGetError(cfChallenge)) 65 , m_authenticationClient(authenticationClient) 66 , m_cfChallenge(cfChallenge) 67{ 68} 69 70void AuthenticationChallenge::setAuthenticationClient(AuthenticationClient* client) 71{ 72 m_authenticationClient = client; 73} 74 75AuthenticationClient* AuthenticationChallenge::authenticationClient() const 76{ 77 return m_authenticationClient.get(); 78} 79 80bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b) 81{ 82 if (a.authenticationClient() != b.authenticationClient()) 83 return false; 84 85 if (a.cfURLAuthChallengeRef() != b.cfURLAuthChallengeRef()) 86 return false; 87 88 return true; 89} 90 91CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge) 92{ 93 // FIXME: Why not cache CFURLAuthChallengeRef in m_cfChallenge? Foundation counterpart does that. 94 95 CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential()); 96 97#if PLATFORM(COCOA) 98 CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, coreChallenge.protectionSpace().cfSpace(), credential, 99#else 100 RetainPtr<CFURLProtectionSpaceRef> protectionSpace = adoptCF(createCF(coreChallenge.protectionSpace())); 101 102 CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace.get(), credential, 103#endif 104 coreChallenge.previousFailureCount(), 105 coreChallenge.failureResponse().cfURLResponse(), 106 coreChallenge.error()); 107 CFRelease(credential); 108 return result; 109} 110 111CFURLCredentialRef createCF(const Credential& coreCredential) 112{ 113 CFURLCredentialPersistence persistence = kCFURLCredentialPersistenceNone; 114 switch (coreCredential.persistence()) { 115 case CredentialPersistenceNone: 116 break; 117 case CredentialPersistenceForSession: 118 persistence = kCFURLCredentialPersistenceForSession; 119 break; 120 case CredentialPersistencePermanent: 121 persistence = kCFURLCredentialPersistencePermanent; 122 break; 123 default: 124 ASSERT_NOT_REACHED(); 125 } 126 127#if CERTIFICATE_CREDENTIALS_SUPPORTED 128 if (coreCredential.type() == CredentialTypeClientCertificate) 129 return CFURLCredentialCreateWithIdentityAndCertificateArray(kCFAllocatorDefault, coreCredential.identity(), coreCredential.certificates(), persistence); 130#endif 131 132 return CFURLCredentialCreate(0, coreCredential.user().createCFString().get(), coreCredential.password().createCFString().get(), 0, persistence); 133} 134 135#if PLATFORM(WIN) 136CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace) 137{ 138 CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP; 139 switch (coreSpace.serverType()) { 140 case ProtectionSpaceServerHTTP: 141 serverType = kCFURLProtectionSpaceServerHTTP; 142 break; 143 case ProtectionSpaceServerHTTPS: 144 serverType = kCFURLProtectionSpaceServerHTTPS; 145 break; 146 case ProtectionSpaceServerFTP: 147 serverType = kCFURLProtectionSpaceServerFTP; 148 break; 149 case ProtectionSpaceServerFTPS: 150 serverType = kCFURLProtectionSpaceServerFTPS; 151 break; 152 case ProtectionSpaceProxyHTTP: 153 serverType = kCFURLProtectionSpaceProxyHTTP; 154 break; 155 case ProtectionSpaceProxyHTTPS: 156 serverType = kCFURLProtectionSpaceProxyHTTPS; 157 break; 158 case ProtectionSpaceProxyFTP: 159 serverType = kCFURLProtectionSpaceProxyFTP; 160 break; 161 case ProtectionSpaceProxySOCKS: 162 serverType = kCFURLProtectionSpaceProxySOCKS; 163 break; 164 default: 165 ASSERT_NOT_REACHED(); 166 } 167 168 CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; 169 switch (coreSpace.authenticationScheme()) { 170 case ProtectionSpaceAuthenticationSchemeDefault: 171 scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; 172 break; 173 case ProtectionSpaceAuthenticationSchemeHTTPBasic: 174 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic; 175 break; 176 case ProtectionSpaceAuthenticationSchemeHTTPDigest: 177 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest; 178 break; 179 case ProtectionSpaceAuthenticationSchemeHTMLForm: 180 scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm; 181 break; 182 case ProtectionSpaceAuthenticationSchemeNTLM: 183 scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM; 184 break; 185 case ProtectionSpaceAuthenticationSchemeNegotiate: 186 scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate; 187 break; 188#if USE(PROTECTION_SPACE_AUTH_CALLBACK) 189 case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested: 190 scheme = kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested; 191 break; 192 case ProtectionSpaceAuthenticationSchemeClientCertificateRequested: 193 scheme = kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested; 194 break; 195#endif 196 default: 197 ASSERT_NOT_REACHED(); 198 } 199 200 return CFURLProtectionSpaceCreate(0, coreSpace.host().createCFString().get(), coreSpace.port(), serverType, coreSpace.realm().createCFString().get(), scheme); 201} 202#endif // PLATFORM(WIN) 203 204Credential core(CFURLCredentialRef cfCredential) 205{ 206 if (!cfCredential) 207 return Credential(); 208 209 CredentialPersistence persistence = CredentialPersistenceNone; 210 switch (CFURLCredentialGetPersistence(cfCredential)) { 211 case kCFURLCredentialPersistenceNone: 212 break; 213 case kCFURLCredentialPersistenceForSession: 214 persistence = CredentialPersistenceForSession; 215 break; 216 case kCFURLCredentialPersistencePermanent: 217 persistence = CredentialPersistencePermanent; 218 break; 219 default: 220 ASSERT_NOT_REACHED(); 221 } 222 223#if CERTIFICATE_CREDENTIALS_SUPPORTED 224 SecIdentityRef identity = CFURLCredentialGetCertificateIdentity(cfCredential); 225 if (identity) 226 return Credential(identity, CFURLCredentialGetCertificateArray(cfCredential), persistence); 227#endif 228 229 RetainPtr<CFStringRef> password = adoptCF(CFURLCredentialCopyPassword(cfCredential)); 230 return Credential(CFURLCredentialGetUsername(cfCredential), password.get(), persistence); 231} 232 233#if PLATFORM(WIN) 234ProtectionSpace core(CFURLProtectionSpaceRef cfSpace) 235{ 236 ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP; 237 238 switch (CFURLProtectionSpaceGetServerType(cfSpace)) { 239 case kCFURLProtectionSpaceServerHTTP: 240 break; 241 case kCFURLProtectionSpaceServerHTTPS: 242 serverType = ProtectionSpaceServerHTTPS; 243 break; 244 case kCFURLProtectionSpaceServerFTP: 245 serverType = ProtectionSpaceServerFTP; 246 break; 247 case kCFURLProtectionSpaceServerFTPS: 248 serverType = ProtectionSpaceServerFTPS; 249 break; 250 case kCFURLProtectionSpaceProxyHTTP: 251 serverType = ProtectionSpaceProxyHTTP; 252 break; 253 case kCFURLProtectionSpaceProxyHTTPS: 254 serverType = ProtectionSpaceProxyHTTPS; 255 break; 256 case kCFURLProtectionSpaceProxyFTP: 257 serverType = ProtectionSpaceProxyFTP; 258 break; 259 case kCFURLProtectionSpaceProxySOCKS: 260 serverType = ProtectionSpaceProxySOCKS; 261 break; 262 default: 263 ASSERT_NOT_REACHED(); 264 } 265 266 ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault; 267 268 switch (CFURLProtectionSpaceGetAuthenticationScheme(cfSpace)) { 269 case kCFURLProtectionSpaceAuthenticationSchemeDefault: 270 scheme = ProtectionSpaceAuthenticationSchemeDefault; 271 break; 272 case kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic: 273 scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic; 274 break; 275 case kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest: 276 scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest; 277 break; 278 case kCFURLProtectionSpaceAuthenticationSchemeHTMLForm: 279 scheme = ProtectionSpaceAuthenticationSchemeHTMLForm; 280 break; 281 case kCFURLProtectionSpaceAuthenticationSchemeNTLM: 282 scheme = ProtectionSpaceAuthenticationSchemeNTLM; 283 break; 284 case kCFURLProtectionSpaceAuthenticationSchemeNegotiate: 285 scheme = ProtectionSpaceAuthenticationSchemeNegotiate; 286 break; 287#if USE(PROTECTION_SPACE_AUTH_CALLBACK) 288 case kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested: 289 scheme = ProtectionSpaceAuthenticationSchemeClientCertificateRequested; 290 break; 291 case kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested: 292 scheme = ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested; 293 break; 294#endif 295 default: 296 scheme = ProtectionSpaceAuthenticationSchemeUnknown; 297 ASSERT_NOT_REACHED(); 298 } 299 300 return ProtectionSpace(CFURLProtectionSpaceGetHost(cfSpace), 301 CFURLProtectionSpaceGetPort(cfSpace), 302 serverType, 303 CFURLProtectionSpaceGetRealm(cfSpace), 304 scheme); 305} 306#endif // PLATFORM(WIN) 307 308}; 309 310#endif // USE(CFNETWORK) 311