2 * Copyright (C) 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #import "AuthenticationMac.h"
30 #import "AuthenticationChallenge.h"
31 #import "AuthenticationClient.h"
32 #import "Credential.h"
33 #import "ProtectionSpace.h"
35 #import <Foundation/NSURLAuthenticationChallenge.h>
36 #import <Foundation/NSURLCredential.h>
37 #import <Foundation/NSURLProtectionSpace.h>
39 using namespace WebCore;
41 @interface WebCoreAuthenticationClientAsChallengeSender : NSObject <NSURLAuthenticationChallengeSender>
43 AuthenticationClient* m_client;
45 - (id)initWithAuthenticationClient:(AuthenticationClient*)client;
46 - (AuthenticationClient*)client;
50 @implementation WebCoreAuthenticationClientAsChallengeSender
52 - (id)initWithAuthenticationClient:(AuthenticationClient*)client
61 - (AuthenticationClient*)client
71 - (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
74 m_client->receivedCredential(core(challenge), core(credential));
77 - (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
80 m_client->receivedRequestToContinueWithoutCredential(core(challenge));
83 - (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
86 m_client->receivedCancellation(core(challenge));
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";
99 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
100 const Credential& proposedCredential,
101 unsigned previousFailureCount,
102 const ResourceResponse& response,
103 const ResourceError& error)
104 : AuthenticationChallengeBase(protectionSpace,
106 previousFailureCount,
112 AuthenticationChallenge::AuthenticationChallenge(NSURLAuthenticationChallenge *challenge)
113 : AuthenticationChallengeBase(core([challenge protectionSpace]),
114 core([challenge proposedCredential]),
115 [challenge previousFailureCount],
116 [challenge failureResponse],
118 , m_sender([challenge sender])
119 , m_nsChallenge(challenge)
123 void AuthenticationChallenge::setAuthenticationClient(AuthenticationClient* client)
126 m_sender.adoptNS([[WebCoreAuthenticationClientAsChallengeSender alloc] initWithAuthenticationClient:client]);
127 m_nsChallenge.adoptNS([[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:m_nsChallenge.get() sender:m_sender.get()]);
129 if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
130 [(WebCoreAuthenticationClientAsChallengeSender *)m_sender.get() detachClient];
134 AuthenticationClient* AuthenticationChallenge::authenticationClient() const
136 if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
137 return [static_cast<WebCoreAuthenticationClientAsChallengeSender*>(m_sender.get()) client];
142 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
144 if (a.sender() != b.sender())
147 if (a.nsURLAuthenticationChallenge() != b.nsURLAuthenticationChallenge())
153 NSURLAuthenticationChallenge *mac(const AuthenticationChallenge& coreChallenge)
155 if (coreChallenge.nsURLAuthenticationChallenge())
156 return coreChallenge.nsURLAuthenticationChallenge();
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];
166 NSURLProtectionSpace *mac(const ProtectionSpace& coreSpace)
168 NSString *proxyType = nil;
169 NSString *protocol = nil;
170 switch (coreSpace.serverType()) {
171 case ProtectionSpaceServerHTTP:
174 case ProtectionSpaceServerHTTPS:
177 case ProtectionSpaceServerFTP:
180 case ProtectionSpaceServerFTPS:
183 case ProtectionSpaceProxyHTTP:
184 proxyType = NSURLProtectionSpaceHTTPProxy;
186 case ProtectionSpaceProxyHTTPS:
187 proxyType = NSURLProtectionSpaceHTTPSProxy;
189 case ProtectionSpaceProxyFTP:
190 proxyType = NSURLProtectionSpaceFTPProxy;
192 case ProtectionSpaceProxySOCKS:
193 proxyType = NSURLProtectionSpaceSOCKSProxy;
196 ASSERT_NOT_REACHED();
199 NSString *method = nil;
200 switch (coreSpace.authenticationScheme()) {
201 case ProtectionSpaceAuthenticationSchemeDefault:
202 method = NSURLAuthenticationMethodDefault;
204 case ProtectionSpaceAuthenticationSchemeHTTPBasic:
205 method = NSURLAuthenticationMethodHTTPBasic;
207 case ProtectionSpaceAuthenticationSchemeHTTPDigest:
208 method = NSURLAuthenticationMethodHTTPDigest;
210 case ProtectionSpaceAuthenticationSchemeHTMLForm:
211 method = NSURLAuthenticationMethodHTMLForm;
213 case ProtectionSpaceAuthenticationSchemeNTLM:
214 method = NSURLAuthenticationMethodNTLM;
216 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
217 case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
218 method = NSURLAuthenticationMethodServerTrust;
220 case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
221 method = NSURLAuthenticationMethodClientCertificate;
225 ASSERT_NOT_REACHED();
229 return [[[NSURLProtectionSpace alloc] initWithProxyHost:coreSpace.host()
230 port:coreSpace.port()
232 realm:coreSpace.realm()
233 authenticationMethod:method] autorelease];
234 return [[[NSURLProtectionSpace alloc] initWithHost:coreSpace.host()
235 port:coreSpace.port()
237 realm:coreSpace.realm()
238 authenticationMethod:method] autorelease];
241 NSURLCredential *mac(const Credential& coreCredential)
243 if (coreCredential.isEmpty())
246 NSURLCredentialPersistence persistence = NSURLCredentialPersistenceNone;
247 switch (coreCredential.persistence()) {
248 case CredentialPersistenceNone:
250 case CredentialPersistenceForSession:
251 persistence = NSURLCredentialPersistenceForSession;
253 case CredentialPersistencePermanent:
254 persistence = NSURLCredentialPersistencePermanent;
257 ASSERT_NOT_REACHED();
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]
269 return [[[NSURLCredential alloc] initWithUser:coreCredential.user()
270 password:coreCredential.password()
271 persistence:persistence]
275 AuthenticationChallenge core(NSURLAuthenticationChallenge *macChallenge)
277 return AuthenticationChallenge(macChallenge);
280 ProtectionSpace core(NSURLProtectionSpace *macSpace)
282 ProtectionSpaceServerType serverType = ProtectionSpaceProxyHTTP;
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;
295 ASSERT_NOT_REACHED();
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;
307 ASSERT_NOT_REACHED();
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;
329 scheme = ProtectionSpaceAuthenticationSchemeUnknown;
330 ASSERT_NOT_REACHED();
333 return ProtectionSpace([macSpace host], [macSpace port], serverType, [macSpace realm], scheme);
337 Credential core(NSURLCredential *macCredential)
339 CredentialPersistence persistence = CredentialPersistenceNone;
340 switch ([macCredential persistence]) {
341 case NSURLCredentialPersistenceNone:
343 case NSURLCredentialPersistenceForSession:
344 persistence = CredentialPersistenceForSession;
346 case NSURLCredentialPersistencePermanent:
347 persistence = CredentialPersistencePermanent;
350 ASSERT_NOT_REACHED();
353 #if CERTIFICATE_CREDENTIALS_SUPPORTED
354 SecIdentityRef identity = [macCredential identity];
356 return Credential(identity, (CFArrayRef)[macCredential certificates], persistence);
359 return Credential([macCredential user], [macCredential password], persistence);
362 } // namespace WebCore
364 #endif // !USE(CFNETWORK)