Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm

Issue 859213006: Cancel client auth requests when not promptable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@client-auth-cancel-1
Patch Set: worker_common.js was missing a license header (also a rebase) Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h" 5 #import "chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h"
6 6
7 #import <SecurityInterface/SFChooseIdentityPanel.h> 7 #import <SecurityInterface/SFChooseIdentityPanel.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/strings/sys_string_conversions.h" 12 #include "base/strings/sys_string_conversions.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/ssl/ssl_client_auth_observer.h" 14 #include "chrome/browser/ssl/ssl_client_auth_observer.h"
15 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" 15 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
16 #include "chrome/grit/generated_resources.h" 16 #include "chrome/grit/generated_resources.h"
17 #include "components/web_modal/popup_manager.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/client_certificate_delegate.h"
18 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
19 #include "net/cert/x509_certificate.h" 21 #include "net/cert/x509_certificate.h"
20 #include "net/cert/x509_util_mac.h" 22 #include "net/cert/x509_util_mac.h"
21 #include "net/ssl/ssl_cert_request_info.h" 23 #include "net/ssl/ssl_cert_request_info.h"
22 #include "ui/base/cocoa/window_size_constants.h" 24 #include "ui/base/cocoa/window_size_constants.h"
23 #include "ui/base/l10n/l10n_util_mac.h" 25 #include "ui/base/l10n/l10n_util_mac.h"
24 26
25 using content::BrowserThread; 27 using content::BrowserThread;
26 28
27 @interface SFChooseIdentityPanel (SystemPrivate) 29 @interface SFChooseIdentityPanel (SystemPrivate)
28 // A system-private interface that dismisses a panel whose sheet was started by 30 // A system-private interface that dismisses a panel whose sheet was started by
29 // -beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:identities:mess age: 31 // -beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:identities:mess age:
30 // as though the user clicked the button identified by returnCode. Verified 32 // as though the user clicked the button identified by returnCode. Verified
31 // present in 10.5 through 10.8. 33 // present in 10.5 through 10.8.
32 - (void)_dismissWithCode:(NSInteger)code; 34 - (void)_dismissWithCode:(NSInteger)code;
33 @end 35 @end
34 36
35 @interface SSLClientCertificateSelectorCocoa () 37 @interface SSLClientCertificateSelectorCocoa ()
36 - (void)onConstrainedWindowClosed; 38 - (void)onConstrainedWindowClosed;
37 @end 39 @end
38 40
39 class SSLClientAuthObserverCocoaBridge : public SSLClientAuthObserver, 41 class SSLClientAuthObserverCocoaBridge : public SSLClientAuthObserver,
40 public ConstrainedWindowMacDelegate { 42 public ConstrainedWindowMacDelegate {
41 public: 43 public:
42 SSLClientAuthObserverCocoaBridge( 44 SSLClientAuthObserverCocoaBridge(
43 const content::BrowserContext* browser_context, 45 const content::BrowserContext* browser_context,
44 net::SSLCertRequestInfo* cert_request_info, 46 net::SSLCertRequestInfo* cert_request_info,
45 const chrome::SelectCertificateCallback& callback, 47 scoped_ptr<content::ClientCertificateDelegate> delegate,
46 SSLClientCertificateSelectorCocoa* controller) 48 SSLClientCertificateSelectorCocoa* controller)
47 : SSLClientAuthObserver(browser_context, cert_request_info, callback), 49 : SSLClientAuthObserver(browser_context,
48 controller_(controller) { 50 cert_request_info,
49 } 51 delegate.Pass()),
52 controller_(controller) {}
50 53
51 // SSLClientAuthObserver implementation: 54 // SSLClientAuthObserver implementation:
52 void OnCertSelectedByNotification() override { 55 void OnCertSelectedByNotification() override {
53 [controller_ closeWebContentsModalDialog]; 56 [controller_ closeWebContentsModalDialog];
54 } 57 }
55 58
56 // ConstrainedWindowMacDelegate implementation: 59 // ConstrainedWindowMacDelegate implementation:
57 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override { 60 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override {
58 // |onConstrainedWindowClosed| will delete the sheet which might be still 61 // |onConstrainedWindowClosed| will delete the sheet which might be still
59 // in use higher up the call stack. Wait for the next cycle of the event 62 // in use higher up the call stack. Wait for the next cycle of the event
60 // loop to call this function. 63 // loop to call this function.
61 [controller_ performSelector:@selector(onConstrainedWindowClosed) 64 [controller_ performSelector:@selector(onConstrainedWindowClosed)
62 withObject:nil 65 withObject:nil
63 afterDelay:0]; 66 afterDelay:0];
64 } 67 }
65 68
66 private: 69 private:
67 SSLClientCertificateSelectorCocoa* controller_; // weak 70 SSLClientCertificateSelectorCocoa* controller_; // weak
68 }; 71 };
69 72
70 namespace chrome { 73 namespace chrome {
71 74
72 void ShowSSLClientCertificateSelector( 75 void ShowSSLClientCertificateSelector(
73 content::WebContents* contents, 76 content::WebContents* contents,
74 net::SSLCertRequestInfo* cert_request_info, 77 net::SSLCertRequestInfo* cert_request_info,
75 const SelectCertificateCallback& callback) { 78 scoped_ptr<content::ClientCertificateDelegate> delegate) {
76 DCHECK_CURRENTLY_ON(BrowserThread::UI); 79 DCHECK_CURRENTLY_ON(BrowserThread::UI);
80
81 // Not all WebContentses can show modal dialogs.
82 //
83 // TODO(davidben): Move this hook to the WebContentsDelegate and only try to
84 // show a dialog in Browser's implementation. https://crbug.com/456255
85 if (web_modal::PopupManager::FromWebContents(contents) == nullptr)
86 return;
87
77 // The dialog manages its own lifetime. 88 // The dialog manages its own lifetime.
78 SSLClientCertificateSelectorCocoa* selector = 89 SSLClientCertificateSelectorCocoa* selector =
79 [[SSLClientCertificateSelectorCocoa alloc] 90 [[SSLClientCertificateSelectorCocoa alloc]
80 initWithBrowserContext:contents->GetBrowserContext() 91 initWithBrowserContext:contents->GetBrowserContext()
81 certRequestInfo:cert_request_info 92 certRequestInfo:cert_request_info
82 callback:callback]; 93 delegate:delegate.Pass()];
83 [selector displayForWebContents:contents]; 94 [selector displayForWebContents:contents];
84 } 95 }
85 96
86 } // namespace chrome 97 } // namespace chrome
87 98
88 @implementation SSLClientCertificateSelectorCocoa 99 @implementation SSLClientCertificateSelectorCocoa
89 100
90 - (id)initWithBrowserContext:(const content::BrowserContext*)browserContext 101 - (id)initWithBrowserContext:(const content::BrowserContext*)browserContext
91 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo 102 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo
92 callback:(const chrome::SelectCertificateCallback&)callback { 103 delegate:(scoped_ptr<content::ClientCertificateDelegate>)
104 delegate {
93 DCHECK(browserContext); 105 DCHECK(browserContext);
94 DCHECK(certRequestInfo); 106 DCHECK(certRequestInfo);
95 if ((self = [super init])) { 107 if ((self = [super init])) {
96 observer_.reset(new SSLClientAuthObserverCocoaBridge( 108 observer_.reset(new SSLClientAuthObserverCocoaBridge(
97 browserContext, certRequestInfo, callback, self)); 109 browserContext, certRequestInfo, delegate.Pass(), self));
98 } 110 }
99 return self; 111 return self;
100 } 112 }
101 113
102 - (void)sheetDidEnd:(NSWindow*)parent 114 - (void)sheetDidEnd:(NSWindow*)parent
103 returnCode:(NSInteger)returnCode 115 returnCode:(NSInteger)returnCode
104 context:(void*)context { 116 context:(void*)context {
105 net::X509Certificate* cert = NULL; 117 net::X509Certificate* cert = NULL;
106 if (returnCode == NSFileHandlingPanelOKButton) { 118 if (returnCode == NSFileHandlingPanelOKButton) {
107 CFRange range = CFRangeMake(0, CFArrayGetCount(identities_)); 119 CFRange range = CFRangeMake(0, CFArrayGetCount(identities_));
108 CFIndex index = 120 CFIndex index =
109 CFArrayGetFirstIndexOfValue(identities_, range, [panel_ identity]); 121 CFArrayGetFirstIndexOfValue(identities_, range, [panel_ identity]);
110 if (index != -1) 122 if (index != -1)
111 cert = certificates_[index].get(); 123 cert = certificates_[index].get();
112 else 124 else
113 NOTREACHED(); 125 NOTREACHED();
114 } 126 }
115 127
116 // Finally, tell the backend which identity (or none) the user selected. 128 if (!closePending_) {
117 observer_->StopObserving(); 129 // If |closePending_| is already set, |closeSheetWithAnimation:| was called
118 observer_->CertificateSelected(cert); 130 // already to cancel the selection rather than continue with no
131 // certificate. Otherwise, tell the backend which identity (or none) the
132 // user selected.
133 userResponded_ = YES;
134 observer_->CertificateSelected(cert);
119 135
120 if (!closePending_)
121 constrainedWindow_->CloseWebContentsModalDialog(); 136 constrainedWindow_->CloseWebContentsModalDialog();
137 }
122 } 138 }
123 139
124 - (void)displayForWebContents:(content::WebContents*)webContents { 140 - (void)displayForWebContents:(content::WebContents*)webContents {
125 // Create an array of CFIdentityRefs for the certificates: 141 // Create an array of CFIdentityRefs for the certificates:
126 size_t numCerts = observer_->cert_request_info()->client_certs.size(); 142 size_t numCerts = observer_->cert_request_info()->client_certs.size();
127 identities_.reset(CFArrayCreateMutable( 143 identities_.reset(CFArrayCreateMutable(
128 kCFAllocatorDefault, numCerts, &kCFTypeArrayCallBacks)); 144 kCFAllocatorDefault, numCerts, &kCFTypeArrayCallBacks));
129 for (size_t i = 0; i < numCerts; ++i) { 145 for (size_t i = 0; i < numCerts; ++i) {
130 SecCertificateRef cert = 146 SecCertificateRef cert =
131 observer_->cert_request_info()->client_certs[i]->os_cert_handle(); 147 observer_->cert_request_info()->client_certs[i]->os_cert_handle();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 overlayWindow_.reset([window retain]); 193 overlayWindow_.reset([window retain]);
178 [panel_ beginSheetForWindow:window 194 [panel_ beginSheetForWindow:window
179 modalDelegate:self 195 modalDelegate:self
180 didEndSelector:@selector(sheetDidEnd:returnCode:context:) 196 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
181 contextInfo:NULL 197 contextInfo:NULL
182 identities:base::mac::CFToNSCast(identities_) 198 identities:base::mac::CFToNSCast(identities_)
183 message:title]; 199 message:title];
184 } 200 }
185 201
186 - (void)closeSheetWithAnimation:(BOOL)withAnimation { 202 - (void)closeSheetWithAnimation:(BOOL)withAnimation {
203 if (!userResponded_) {
204 // If the sheet is closed by closing the tab rather than the user explicitly
205 // hitting Cancel, |closeSheetWithAnimation:| gets called before
206 // |sheetDidEnd:|. In this case, the selection should be canceled rather
207 // than continue with no certificate. The |returnCode| parameter to
208 // |sheetDidEnd:| is the same in both cases.
209 observer_->CancelCertificateSelection();
210 }
187 closePending_ = YES; 211 closePending_ = YES;
188 overlayWindow_.reset(); 212 overlayWindow_.reset();
189 // Closing the sheet using -[NSApp endSheet:] doesn't work so use the private 213 // Closing the sheet using -[NSApp endSheet:] doesn't work so use the private
190 // method. 214 // method.
191 [panel_ _dismissWithCode:NSFileHandlingPanelCancelButton]; 215 [panel_ _dismissWithCode:NSFileHandlingPanelCancelButton];
192 } 216 }
193 217
194 - (void)hideSheet { 218 - (void)hideSheet {
195 NSWindow* sheetWindow = [overlayWindow_ attachedSheet]; 219 NSWindow* sheetWindow = [overlayWindow_ attachedSheet];
196 [sheetWindow setAlphaValue:0.0]; 220 [sheetWindow setAlphaValue:0.0];
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 } 256 }
233 257
234 - (void)onConstrainedWindowClosed { 258 - (void)onConstrainedWindowClosed {
235 observer_->StopObserving(); 259 observer_->StopObserving();
236 panel_.reset(); 260 panel_.reset();
237 constrainedWindow_.reset(); 261 constrainedWindow_.reset();
238 [self release]; 262 [self release];
239 } 263 }
240 264
241 @end 265 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698