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