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