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