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 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 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 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 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 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 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 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 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