Make adjustMIMETypeIfNecessary use CFNetwork directly
[WebKit-https.git] / Source / WebCore / platform / network / mac / AuthenticationMac.mm
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 #import "config.h"
26 #import "AuthenticationMac.h"
27
28 #if !USE(CFNETWORK)
29
30 #import "AuthenticationChallenge.h"
31 #import "AuthenticationClient.h"
32 #import "Credential.h"
33 #import "ProtectionSpace.h"
34
35 #import <Foundation/NSURLAuthenticationChallenge.h>
36 #import <Foundation/NSURLCredential.h>
37 #import <Foundation/NSURLProtectionSpace.h>
38
39 using namespace WebCore;
40
41 @interface WebCoreAuthenticationClientAsChallengeSender : NSObject <NSURLAuthenticationChallengeSender>
42 {
43     AuthenticationClient* m_client;
44 }
45 - (id)initWithAuthenticationClient:(AuthenticationClient*)client;
46 - (AuthenticationClient*)client;
47 - (void)detachClient;
48 @end
49
50 @implementation WebCoreAuthenticationClientAsChallengeSender
51
52 - (id)initWithAuthenticationClient:(AuthenticationClient*)client
53 {
54     self = [self init];
55     if (!self)
56         return nil;
57     m_client = client;
58     return self;
59 }
60
61 - (AuthenticationClient*)client
62 {
63     return m_client;
64 }
65
66 - (void)detachClient
67 {
68     m_client = 0;
69 }
70
71 - (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
72 {
73     if (m_client)
74         m_client->receivedCredential(core(challenge), core(credential));
75 }
76
77 - (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
78 {
79     if (m_client)
80         m_client->receivedRequestToContinueWithoutCredential(core(challenge));
81 }
82
83 - (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
84 {
85     if (m_client)
86         m_client->receivedCancellation(core(challenge));
87 }
88
89 @end
90
91 namespace WebCore {
92
93 #if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
94 // There is no constant in headers, but NTLM is supported.
95 NSString * const NSURLAuthenticationMethodNTLM = @"NSURLAuthenticationMethodNTLM";
96 #endif
97
98
99 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
100                                                  const Credential& proposedCredential,
101                                                  unsigned previousFailureCount,
102                                                  const ResourceResponse& response,
103                                                  const ResourceError& error)
104     : AuthenticationChallengeBase(protectionSpace,
105                                   proposedCredential,
106                                   previousFailureCount,
107                                   response,
108                                   error)
109 {
110 }
111
112 AuthenticationChallenge::AuthenticationChallenge(NSURLAuthenticationChallenge *challenge)
113     : AuthenticationChallengeBase(core([challenge protectionSpace]),
114                                   core([challenge proposedCredential]),
115                                   [challenge previousFailureCount],
116                                   [challenge failureResponse],
117                                   [challenge error])
118     , m_sender([challenge sender])
119     , m_nsChallenge(challenge)
120 {
121 }
122
123 void AuthenticationChallenge::setAuthenticationClient(AuthenticationClient* client)
124 {
125     if (client) {
126         m_sender.adoptNS([[WebCoreAuthenticationClientAsChallengeSender alloc] initWithAuthenticationClient:client]);
127         m_nsChallenge.adoptNS([[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:m_nsChallenge.get() sender:m_sender.get()]);
128     } else {
129         if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
130             [(WebCoreAuthenticationClientAsChallengeSender *)m_sender.get() detachClient];
131     }
132 }
133
134 AuthenticationClient* AuthenticationChallenge::authenticationClient() const
135 {
136     if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
137         return [static_cast<WebCoreAuthenticationClientAsChallengeSender*>(m_sender.get()) client];
138     
139     return 0;
140 }
141
142 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
143 {
144     if (a.sender() != b.sender())
145         return false;
146         
147     if (a.nsURLAuthenticationChallenge() != b.nsURLAuthenticationChallenge())
148         return false;
149
150     return true;
151 }
152
153 NSURLAuthenticationChallenge *mac(const AuthenticationChallenge& coreChallenge)
154 {
155     if (coreChallenge.nsURLAuthenticationChallenge())
156         return coreChallenge.nsURLAuthenticationChallenge();
157         
158     return [[[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:mac(coreChallenge.protectionSpace())
159                                                        proposedCredential:mac(coreChallenge.proposedCredential())
160                                                      previousFailureCount:coreChallenge.previousFailureCount()
161                                                           failureResponse:coreChallenge.failureResponse().nsURLResponse()
162                                                                     error:coreChallenge.error()
163                                                                    sender:coreChallenge.sender()] autorelease];
164 }
165
166 NSURLProtectionSpace *mac(const ProtectionSpace& coreSpace)
167 {
168     NSString *proxyType = nil;
169     NSString *protocol = nil;
170     switch (coreSpace.serverType()) {
171         case ProtectionSpaceServerHTTP:
172             protocol = @"http";
173             break;
174         case ProtectionSpaceServerHTTPS:
175             protocol = @"https";
176             break;
177         case ProtectionSpaceServerFTP:
178             protocol = @"ftp";
179             break;
180         case ProtectionSpaceServerFTPS:
181             protocol = @"ftps";
182             break;
183         case ProtectionSpaceProxyHTTP:
184             proxyType = NSURLProtectionSpaceHTTPProxy;
185             break;
186         case ProtectionSpaceProxyHTTPS:
187             proxyType = NSURLProtectionSpaceHTTPSProxy;
188             break;
189         case ProtectionSpaceProxyFTP:
190             proxyType = NSURLProtectionSpaceFTPProxy;
191             break;
192         case ProtectionSpaceProxySOCKS:
193             proxyType = NSURLProtectionSpaceSOCKSProxy;
194             break;
195         default:
196             ASSERT_NOT_REACHED();
197     }
198   
199     NSString *method = nil;
200     switch (coreSpace.authenticationScheme()) {
201         case ProtectionSpaceAuthenticationSchemeDefault:
202             method = NSURLAuthenticationMethodDefault;
203             break;
204         case ProtectionSpaceAuthenticationSchemeHTTPBasic:
205             method = NSURLAuthenticationMethodHTTPBasic;
206             break;
207         case ProtectionSpaceAuthenticationSchemeHTTPDigest:
208             method = NSURLAuthenticationMethodHTTPDigest;
209             break;
210         case ProtectionSpaceAuthenticationSchemeHTMLForm:
211             method = NSURLAuthenticationMethodHTMLForm;
212             break;
213         case ProtectionSpaceAuthenticationSchemeNTLM:
214             method = NSURLAuthenticationMethodNTLM;
215             break;
216 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
217         case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
218             method = NSURLAuthenticationMethodServerTrust;
219             break;
220         case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
221             method = NSURLAuthenticationMethodClientCertificate;
222             break;
223 #endif
224         default:
225             ASSERT_NOT_REACHED();
226     }
227     
228     if (proxyType)
229         return [[[NSURLProtectionSpace alloc] initWithProxyHost:coreSpace.host()
230                                                            port:coreSpace.port()
231                                                            type:proxyType
232                                                           realm:coreSpace.realm()
233                                            authenticationMethod:method] autorelease];
234     return [[[NSURLProtectionSpace alloc] initWithHost:coreSpace.host()
235                                                   port:coreSpace.port()
236                                               protocol:protocol
237                                                  realm:coreSpace.realm()
238                                   authenticationMethod:method] autorelease];
239 }
240
241 NSURLCredential *mac(const Credential& coreCredential)
242 {
243     if (coreCredential.isEmpty())
244         return nil;
245
246     NSURLCredentialPersistence persistence = NSURLCredentialPersistenceNone;
247     switch (coreCredential.persistence()) {
248         case CredentialPersistenceNone:
249             break;
250         case CredentialPersistenceForSession:
251             persistence = NSURLCredentialPersistenceForSession;
252             break;
253         case CredentialPersistencePermanent:
254             persistence = NSURLCredentialPersistencePermanent;
255             break;
256         default:
257             ASSERT_NOT_REACHED();
258     }
259
260 #if CERTIFICATE_CREDENTIALS_SUPPORTED
261     if (coreCredential.type() == CredentialTypeClientCertificate) {
262         return [[[NSURLCredential alloc] initWithIdentity:coreCredential.identity()
263                                              certificates:(NSArray *)coreCredential.certificates()
264                                               persistence:persistence]
265                                               autorelease];
266     }
267 #endif
268
269     return [[[NSURLCredential alloc] initWithUser:coreCredential.user()
270                                         password:coreCredential.password()
271                                      persistence:persistence]
272                                      autorelease];
273 }
274
275 AuthenticationChallenge core(NSURLAuthenticationChallenge *macChallenge)
276 {
277     return AuthenticationChallenge(macChallenge);
278 }
279
280 ProtectionSpace core(NSURLProtectionSpace *macSpace)
281 {
282     ProtectionSpaceServerType serverType = ProtectionSpaceProxyHTTP;
283     
284     if ([macSpace isProxy]) {
285         NSString *proxyType = [macSpace proxyType];
286         if ([proxyType isEqualToString:NSURLProtectionSpaceHTTPProxy])
287             serverType = ProtectionSpaceProxyHTTP;
288         else if ([proxyType isEqualToString:NSURLProtectionSpaceHTTPSProxy])
289             serverType = ProtectionSpaceProxyHTTPS;
290         else if ([proxyType isEqualToString:NSURLProtectionSpaceFTPProxy])
291             serverType = ProtectionSpaceProxyFTP;
292         else if ([proxyType isEqualToString:NSURLProtectionSpaceSOCKSProxy])
293             serverType = ProtectionSpaceProxySOCKS;
294         else 
295             ASSERT_NOT_REACHED();
296     } else {
297         NSString *protocol = [macSpace protocol];
298         if ([protocol caseInsensitiveCompare:@"http"] == NSOrderedSame)
299             serverType = ProtectionSpaceServerHTTP;
300         else if ([protocol caseInsensitiveCompare:@"https"] == NSOrderedSame)
301             serverType = ProtectionSpaceServerHTTPS;
302         else if ([protocol caseInsensitiveCompare:@"ftp"] == NSOrderedSame)
303             serverType = ProtectionSpaceServerFTP;
304         else if ([protocol caseInsensitiveCompare:@"ftps"] == NSOrderedSame)
305             serverType = ProtectionSpaceServerFTPS;
306         else
307             ASSERT_NOT_REACHED();
308     }
309
310     ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
311     NSString *method = [macSpace authenticationMethod];
312     if ([method isEqualToString:NSURLAuthenticationMethodDefault])
313         scheme = ProtectionSpaceAuthenticationSchemeDefault;
314     else if ([method isEqualToString:NSURLAuthenticationMethodHTTPBasic])
315         scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
316     else if ([method isEqualToString:NSURLAuthenticationMethodHTTPDigest])
317         scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
318     else if ([method isEqualToString:NSURLAuthenticationMethodHTMLForm])
319         scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
320     else if ([method isEqualToString:NSURLAuthenticationMethodNTLM])
321         scheme = ProtectionSpaceAuthenticationSchemeNTLM;
322 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
323     else if ([method isEqualToString:NSURLAuthenticationMethodClientCertificate])
324         scheme = ProtectionSpaceAuthenticationSchemeClientCertificateRequested;
325     else if ([method isEqualToString:NSURLAuthenticationMethodServerTrust])
326         scheme = ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
327 #endif
328     else {
329         scheme = ProtectionSpaceAuthenticationSchemeUnknown;
330         ASSERT_NOT_REACHED();
331     }
332         
333     return ProtectionSpace([macSpace host], [macSpace port], serverType, [macSpace realm], scheme);
334
335 }
336
337 Credential core(NSURLCredential *macCredential)
338 {
339     CredentialPersistence persistence = CredentialPersistenceNone;
340     switch ([macCredential persistence]) {
341         case NSURLCredentialPersistenceNone:
342             break;
343         case NSURLCredentialPersistenceForSession:
344             persistence = CredentialPersistenceForSession;
345             break;
346         case NSURLCredentialPersistencePermanent:
347             persistence = CredentialPersistencePermanent;
348             break;
349         default:
350             ASSERT_NOT_REACHED();
351     }
352
353 #if CERTIFICATE_CREDENTIALS_SUPPORTED
354     SecIdentityRef identity = [macCredential identity];
355     if (identity)
356         return Credential(identity, (CFArrayRef)[macCredential certificates], persistence);
357 #endif
358     
359     return Credential([macCredential user], [macCredential password], persistence);
360 }
361
362 } // namespace WebCore
363
364 #endif // !USE(CFNETWORK)