8f9cbf6e647f1f7fdc8ef60f2705adbc33d0199f
[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 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 #import "config.h"
26 #import "AuthenticationMac.h"
27
28 #import "AuthenticationCF.h"
29 #import "AuthenticationChallenge.h"
30 #import "AuthenticationClient.h"
31 #import "Credential.h"
32 #import <Foundation/NSURLAuthenticationChallenge.h>
33 #import <Foundation/NSURLProtectionSpace.h>
34
35 #if USE(CFURLCONNECTION)
36 #import <pal/spi/cocoa/CFNSURLConnectionSPI.h>
37 #endif
38
39 using namespace WebCore;
40
41 @interface WebCoreAuthenticationClientAsChallengeSender : NSObject <NSURLAuthenticationChallengeSender>
42 {
43     AuthenticationClient* m_client;
44 #if USE(CFURLCONNECTION)
45     CFURLAuthChallengeRef m_cfChallenge;
46 #endif
47 }
48 - (id)initWithAuthenticationClient:(AuthenticationClient*)client;
49 - (AuthenticationClient*)client;
50 - (void)detachClient;
51 @end
52
53 @implementation WebCoreAuthenticationClientAsChallengeSender
54
55 - (id)initWithAuthenticationClient:(AuthenticationClient*)client
56 {
57     self = [self init];
58     if (!self)
59         return nil;
60     m_client = client;
61     return self;
62 }
63
64 - (AuthenticationClient*)client
65 {
66     return m_client;
67 }
68
69 - (void)detachClient
70 {
71     m_client = 0;
72 }
73
74 - (void)performDefaultHandlingForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
75 {
76     if (m_client)
77         m_client->receivedRequestToPerformDefaultHandling(core(challenge));
78 }
79
80 - (void)rejectProtectionSpaceAndContinueWithChallenge:(NSURLAuthenticationChallenge *)challenge
81 {
82     if (m_client)
83         m_client->receivedChallengeRejection(core(challenge));
84 }
85
86 - (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
87 {
88     if (m_client)
89         m_client->receivedCredential(core(challenge), Credential(credential));
90 }
91
92 - (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
93 {
94     if (m_client)
95         m_client->receivedRequestToContinueWithoutCredential(core(challenge));
96 }
97
98 - (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
99 {
100     if (m_client)
101         m_client->receivedCancellation(core(challenge));
102 }
103
104 #if USE(CFURLCONNECTION)
105 - (void)setCFChallenge:(CFURLAuthChallengeRef)challenge
106 {
107     m_cfChallenge = challenge;
108 }
109
110 - (CFURLAuthChallengeRef)cfChallenge
111 {
112     return m_cfChallenge;
113 }
114 #endif
115
116 @end
117
118 namespace WebCore {
119
120 #if USE(CFURLCONNECTION)
121
122 AuthenticationChallenge core(NSURLAuthenticationChallenge *macChallenge)
123 {
124     WebCoreAuthenticationClientAsChallengeSender *challengeSender = (WebCoreAuthenticationClientAsChallengeSender*) [macChallenge sender];
125     return AuthenticationChallenge([challengeSender cfChallenge], [challengeSender client]);
126 }
127
128 NSURLAuthenticationChallenge *mac(const AuthenticationChallenge& coreChallenge)
129 {
130     AuthenticationClient* authClient = coreChallenge.authenticationClient();
131     RetainPtr<WebCoreAuthenticationClientAsChallengeSender> challengeSender = adoptNS([[WebCoreAuthenticationClientAsChallengeSender alloc] initWithAuthenticationClient:authClient]);
132     RetainPtr<CFURLAuthChallengeRef> authChallenge = coreChallenge.cfURLAuthChallengeRef();
133     if (!authChallenge)
134         authChallenge = adoptCF(createCF(coreChallenge));
135     [challengeSender.get() setCFChallenge:authChallenge.get()];
136 #if PLATFORM(IOS)
137     return [[NSURLAuthenticationChallenge _createAuthenticationChallengeForCFAuthChallenge:authChallenge.get() sender:challengeSender.get()] autorelease];
138 #else
139     return [[NSURLAuthenticationChallenge _authenticationChallengeForCFAuthChallenge:authChallenge.get() sender:challengeSender.get()] autorelease];
140 #endif
141 }
142
143 #else
144
145 AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
146                                                  const Credential& proposedCredential,
147                                                  unsigned previousFailureCount,
148                                                  const ResourceResponse& response,
149                                                  const ResourceError& error)
150     : AuthenticationChallengeBase(protectionSpace,
151                                   proposedCredential,
152                                   previousFailureCount,
153                                   response,
154                                   error)
155 {
156 }
157
158 AuthenticationChallenge::AuthenticationChallenge(NSURLAuthenticationChallenge *challenge)
159     : AuthenticationChallengeBase(ProtectionSpace([challenge protectionSpace]),
160                                   Credential([challenge proposedCredential]),
161                                   [challenge previousFailureCount],
162                                   [challenge failureResponse],
163                                   [challenge error])
164     , m_sender([challenge sender])
165     , m_nsChallenge(challenge)
166 {
167 }
168
169 void AuthenticationChallenge::setAuthenticationClient(AuthenticationClient* client)
170 {
171     if (client) {
172         m_sender = adoptNS([[WebCoreAuthenticationClientAsChallengeSender alloc] initWithAuthenticationClient:client]);
173         if (m_nsChallenge)
174             m_nsChallenge = adoptNS([[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:m_nsChallenge.get() sender:m_sender.get()]);
175     } else {
176         if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
177             [(WebCoreAuthenticationClientAsChallengeSender *)m_sender.get() detachClient];
178     }
179 }
180
181 AuthenticationClient* AuthenticationChallenge::authenticationClient() const
182 {
183     if ([m_sender.get() isMemberOfClass:[WebCoreAuthenticationClientAsChallengeSender class]])
184         return [static_cast<WebCoreAuthenticationClientAsChallengeSender*>(m_sender.get()) client];
185     
186     return 0;
187 }
188
189 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
190 {
191     if (a.sender() != b.sender())
192         return false;
193         
194     if (a.nsURLAuthenticationChallenge() != b.nsURLAuthenticationChallenge())
195         return false;
196
197     return true;
198 }
199
200 NSURLAuthenticationChallenge *mac(const AuthenticationChallenge& coreChallenge)
201 {
202     if (coreChallenge.nsURLAuthenticationChallenge())
203         return coreChallenge.nsURLAuthenticationChallenge();
204         
205     return [[[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:coreChallenge.protectionSpace().nsSpace()
206                                                        proposedCredential:coreChallenge.proposedCredential().nsCredential()
207                                                      previousFailureCount:coreChallenge.previousFailureCount()
208                                                           failureResponse:coreChallenge.failureResponse().nsURLResponse()
209                                                                     error:coreChallenge.error()
210                                                                    sender:coreChallenge.sender()] autorelease];
211 }
212
213 AuthenticationChallenge core(NSURLAuthenticationChallenge *macChallenge)
214 {
215     return AuthenticationChallenge(macChallenge);
216 }
217
218 #endif // USE(CFURLCONNECTION)
219
220 } // namespace WebCore