Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/browser/ssl_client_certificate_selector.h" | 5 #include "chrome/browser/ssl_client_certificate_selector.h" |
| 6 | 6 |
| 7 #import <SecurityInterface/SFChooseIdentityPanel.h> | 7 #import <SecurityInterface/SFChooseIdentityPanel.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #import "base/memory/scoped_nsobject.h" | 13 #import "base/memory/scoped_nsobject.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "base/sys_string_conversions.h" | 15 #include "base/sys_string_conversions.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "chrome/browser/ssl/ssl_client_auth_observer.h" | |
| 17 #import "chrome/browser/ui/cocoa/constrained_window_mac.h" | 18 #import "chrome/browser/ui/cocoa/constrained_window_mac.h" |
| 18 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 19 #include "content/browser/ssl/ssl_client_auth_handler.h" | |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "grit/generated_resources.h" | 21 #include "grit/generated_resources.h" |
| 22 #include "net/base/ssl_cert_request_info.h" | |
| 22 #include "net/base/x509_certificate.h" | 23 #include "net/base/x509_certificate.h" |
| 23 #include "ui/base/l10n/l10n_util_mac.h" | 24 #include "ui/base/l10n/l10n_util_mac.h" |
| 24 | 25 |
| 25 using content::BrowserThread; | 26 using content::BrowserThread; |
| 26 | 27 |
| 27 @interface SFChooseIdentityPanel (SystemPrivate) | 28 @interface SFChooseIdentityPanel (SystemPrivate) |
| 28 // A system-private interface that dismisses a panel whose sheet was started by | 29 // A system-private interface that dismisses a panel whose sheet was started by |
| 29 // beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:identities:messa ge: | 30 // beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:identities:messa ge: |
| 30 // as though the user clicked the button identified by returnCode. Verified | 31 // as though the user clicked the button identified by returnCode. Verified |
| 31 // present in 10.5, 10.6, and 10.7. | 32 // present in 10.5, 10.6, and 10.7. |
| 32 - (void)_dismissWithCode:(NSInteger)code; | 33 - (void)_dismissWithCode:(NSInteger)code; |
| 33 @end | 34 @end |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 class NotificationProxy; | 37 class NotificationProxy; |
| 37 } // namespace | 38 } // namespace |
| 38 | 39 |
| 39 @interface SSLClientCertificateSelectorCocoa : NSObject { | 40 @interface SSLClientCertificateSelectorCocoa : NSObject { |
| 40 @private | 41 @private |
| 41 // The handler to report back to. | |
| 42 scoped_refptr<SSLClientAuthHandler> handler_; | |
| 43 // The certificate request we serve. | |
| 44 scoped_refptr<net::SSLCertRequestInfo> certRequestInfo_; | |
| 45 // The list of identities offered to the user. | 42 // The list of identities offered to the user. |
| 46 scoped_nsobject<NSMutableArray> identities_; | 43 scoped_nsobject<NSMutableArray> identities_; |
| 47 // The corresponding list of certificates. | 44 // The corresponding list of certificates. |
| 48 std::vector<scoped_refptr<net::X509Certificate> > certificates_; | 45 std::vector<scoped_refptr<net::X509Certificate> > certificates_; |
| 49 // The currently open dialog. | 46 // The currently open dialog. |
| 50 ConstrainedWindow* window_; | 47 ConstrainedWindow* window_; |
| 51 // A C++ object to proxy SSLClientAuthObserver notifications to us. | 48 // A C++ object to proxy SSLClientAuthObserver notifications to us. |
| 52 scoped_ptr<NotificationProxy> observer_; | 49 scoped_ptr<NotificationProxy> observer_; |
| 53 } | 50 } |
| 54 | 51 |
| 55 - (id)initWithHandler:(SSLClientAuthHandler*)handler | 52 - (id)initObserver:(const net::HttpNetworkSession*)networkSession |
|
Avi (use Gerrit)
2012/02/13 20:10:37
initWithObserver (and all the places that's used)
jam
2012/02/13 20:59:00
Done.
| |
| 56 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo; | 53 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo |
| 54 callback:(const base::Callback<void(net::X509Certificate*)>&) callback ; | |
|
Avi (use Gerrit)
2012/02/13 20:10:37
80 columns. Even in ObjC. Also, there's no space a
jam
2012/02/13 20:59:00
Done.
| |
| 57 - (void)onNotification; | 55 - (void)onNotification; |
| 58 - (void)displayDialog:(TabContentsWrapper*)wrapper; | 56 - (void)displayDialog:(TabContentsWrapper*)wrapper; |
| 59 @end | 57 @end |
| 60 | 58 |
| 61 namespace { | 59 namespace { |
| 62 | 60 |
| 63 class ConstrainedSFChooseIdentityPanel | 61 class ConstrainedSFChooseIdentityPanel |
| 64 : public ConstrainedWindowMacDelegateSystemSheet { | 62 : public ConstrainedWindowMacDelegateSystemSheet { |
| 65 public: | 63 public: |
| 66 ConstrainedSFChooseIdentityPanel(SFChooseIdentityPanel* panel, | 64 ConstrainedSFChooseIdentityPanel(SFChooseIdentityPanel* panel, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 } | 104 } |
| 107 | 105 |
| 108 private: | 106 private: |
| 109 scoped_nsobject<NSArray> identities_; | 107 scoped_nsobject<NSArray> identities_; |
| 110 scoped_nsobject<NSString> message_; | 108 scoped_nsobject<NSString> message_; |
| 111 DISALLOW_COPY_AND_ASSIGN(ConstrainedSFChooseIdentityPanel); | 109 DISALLOW_COPY_AND_ASSIGN(ConstrainedSFChooseIdentityPanel); |
| 112 }; | 110 }; |
| 113 | 111 |
| 114 class NotificationProxy : public SSLClientAuthObserver { | 112 class NotificationProxy : public SSLClientAuthObserver { |
| 115 public: | 113 public: |
| 116 NotificationProxy(net::SSLCertRequestInfo* cert_request_info, | 114 NotificationProxy(const net::HttpNetworkSession* network_session, |
| 117 SSLClientAuthHandler* handler, | 115 net::SSLCertRequestInfo* cert_request_info, |
| 116 const base::Callback<void(net::X509Certificate*)>& callback, | |
| 118 SSLClientCertificateSelectorCocoa* controller) | 117 SSLClientCertificateSelectorCocoa* controller) |
| 119 : SSLClientAuthObserver(cert_request_info, handler), | 118 : SSLClientAuthObserver(network_session, cert_request_info, callback), |
| 120 controller_(controller) { | 119 controller_(controller) { |
| 121 } | 120 } |
| 122 | 121 |
| 123 // SSLClientAuthObserver implementation: | 122 // SSLClientAuthObserver implementation: |
| 124 virtual void OnCertSelectedByNotification() { | 123 virtual void OnCertSelectedByNotification() { |
| 125 [controller_ onNotification]; | 124 [controller_ onNotification]; |
| 126 } | 125 } |
| 127 | 126 |
| 128 private: | 127 private: |
| 129 SSLClientCertificateSelectorCocoa* controller_; | 128 SSLClientCertificateSelectorCocoa* controller_; |
| 130 }; | 129 }; |
| 131 | 130 |
| 132 } // namespace | 131 } // namespace |
| 133 | 132 |
| 134 namespace browser { | 133 namespace browser { |
| 135 | 134 |
| 136 void ShowSSLClientCertificateSelector( | 135 void ShowSSLClientCertificateSelector( |
| 137 TabContentsWrapper* wrapper, | 136 TabContentsWrapper* wrapper, |
| 137 const net::HttpNetworkSession* network_session, | |
| 138 net::SSLCertRequestInfo* cert_request_info, | 138 net::SSLCertRequestInfo* cert_request_info, |
| 139 SSLClientAuthHandler* delegate) { | 139 const base::Callback<void(net::X509Certificate*)>& callback) { |
| 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 141 SSLClientCertificateSelectorCocoa* selector = | 141 SSLClientCertificateSelectorCocoa* selector = |
| 142 [[[SSLClientCertificateSelectorCocoa alloc] | 142 [[[SSLClientCertificateSelectorCocoa alloc] |
| 143 initWithHandler:delegate | 143 initObserver:network_session |
| 144 certRequestInfo:cert_request_info] autorelease]; | 144 certRequestInfo:cert_request_info |
| 145 callback:callback] autorelease]; | |
| 145 [selector displayDialog:wrapper]; | 146 [selector displayDialog:wrapper]; |
| 146 } | 147 } |
| 147 | 148 |
| 148 } // namespace browser | 149 } // namespace browser |
| 149 | 150 |
| 150 @implementation SSLClientCertificateSelectorCocoa | 151 @implementation SSLClientCertificateSelectorCocoa |
| 151 | 152 |
| 152 - (id)initWithHandler:(SSLClientAuthHandler*)handler | 153 - (id)initObserver:(const net::HttpNetworkSession*)networkSession |
| 153 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo { | 154 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo |
| 154 DCHECK(handler); | 155 callback:(const base::Callback<void(net::X509Certificate*)>&) callback { |
|
Avi (use Gerrit)
2012/02/13 20:10:37
same 80 col issue, same removal of space to fix it
jam
2012/02/13 20:59:00
Done.
| |
| 156 DCHECK(networkSession); | |
| 155 DCHECK(certRequestInfo); | 157 DCHECK(certRequestInfo); |
| 156 if ((self = [super init])) { | 158 if ((self = [super init])) { |
| 157 handler_ = handler; | |
| 158 certRequestInfo_ = certRequestInfo; | |
| 159 window_ = NULL; | 159 window_ = NULL; |
| 160 observer_.reset(new NotificationProxy(certRequestInfo, handler, self)); | 160 observer_.reset(new NotificationProxy( |
| 161 networkSession, certRequestInfo, callback, self)); | |
| 161 } | 162 } |
| 162 return self; | 163 return self; |
| 163 } | 164 } |
| 164 | 165 |
| 165 - (void)sheetDidEnd:(NSWindow*)parent | 166 - (void)sheetDidEnd:(NSWindow*)parent |
| 166 returnCode:(NSInteger)returnCode | 167 returnCode:(NSInteger)returnCode |
| 167 context:(void*)context { | 168 context:(void*)context { |
| 168 DCHECK(context); | 169 DCHECK(context); |
| 169 SFChooseIdentityPanel* panel = static_cast<SFChooseIdentityPanel*>(context); | 170 SFChooseIdentityPanel* panel = static_cast<SFChooseIdentityPanel*>(context); |
| 170 | 171 |
| 171 net::X509Certificate* cert = NULL; | 172 net::X509Certificate* cert = NULL; |
| 172 if (returnCode == NSFileHandlingPanelOKButton) { | 173 if (returnCode == NSFileHandlingPanelOKButton) { |
| 173 NSUInteger index = [identities_ indexOfObject:(id)[panel identity]]; | 174 NSUInteger index = [identities_ indexOfObject:(id)[panel identity]]; |
| 174 if (index != NSNotFound) | 175 if (index != NSNotFound) |
| 175 cert = certificates_[index]; | 176 cert = certificates_[index]; |
| 176 else | 177 else |
| 177 NOTREACHED(); | 178 NOTREACHED(); |
| 178 } | 179 } |
| 179 | 180 |
| 180 // Finally, tell the backend which identity (or none) the user selected. | 181 // Finally, tell the backend which identity (or none) the user selected. |
| 181 observer_->StopObserving(); | 182 observer_->StopObserving(); |
| 182 if (handler_) { | 183 observer_->CertificateSelected(cert); |
| 183 handler_->CertificateSelected(cert); | |
| 184 handler_ = NULL; | |
| 185 } | |
| 186 // Close the constrained window. | 184 // Close the constrained window. |
| 187 DCHECK(window_); | 185 DCHECK(window_); |
| 188 window_->CloseConstrainedWindow(); | 186 window_->CloseConstrainedWindow(); |
| 189 } | 187 } |
| 190 | 188 |
| 191 - (void)onNotification { | 189 - (void)onNotification { |
| 192 handler_ = NULL; | |
| 193 window_->CloseConstrainedWindow(); | 190 window_->CloseConstrainedWindow(); |
| 194 } | 191 } |
| 195 | 192 |
| 196 - (void)displayDialog:(TabContentsWrapper*)wrapper { | 193 - (void)displayDialog:(TabContentsWrapper*)wrapper { |
| 197 DCHECK(!window_); | 194 DCHECK(!window_); |
| 198 // Create an array of CFIdentityRefs for the certificates: | 195 // Create an array of CFIdentityRefs for the certificates: |
| 199 size_t numCerts = certRequestInfo_->client_certs.size(); | 196 size_t numCerts = observer_->cert_request_info()->client_certs.size(); |
| 200 identities_.reset([[NSMutableArray alloc] initWithCapacity:numCerts]); | 197 identities_.reset([[NSMutableArray alloc] initWithCapacity:numCerts]); |
| 201 for (size_t i = 0; i < numCerts; ++i) { | 198 for (size_t i = 0; i < numCerts; ++i) { |
| 202 SecCertificateRef cert; | 199 SecCertificateRef cert; |
| 203 cert = certRequestInfo_->client_certs[i]->os_cert_handle(); | 200 cert = observer_->cert_request_info()->client_certs[i]->os_cert_handle(); |
| 204 SecIdentityRef identity; | 201 SecIdentityRef identity; |
| 205 if (SecIdentityCreateWithCertificate(NULL, cert, &identity) == noErr) { | 202 if (SecIdentityCreateWithCertificate(NULL, cert, &identity) == noErr) { |
| 206 [identities_ addObject:(id)identity]; | 203 [identities_ addObject:(id)identity]; |
| 207 CFRelease(identity); | 204 CFRelease(identity); |
| 208 certificates_.push_back(certRequestInfo_->client_certs[i]); | 205 certificates_.push_back(observer_->cert_request_info()->client_certs[i]); |
| 209 } | 206 } |
| 210 } | 207 } |
| 211 | 208 |
| 212 // Get the message to display: | 209 // Get the message to display: |
| 213 NSString* title = l10n_util::GetNSString(IDS_CLIENT_CERT_DIALOG_TITLE); | 210 NSString* title = l10n_util::GetNSString(IDS_CLIENT_CERT_DIALOG_TITLE); |
| 214 NSString* message = l10n_util::GetNSStringF( | 211 NSString* message = l10n_util::GetNSStringF( |
| 215 IDS_CLIENT_CERT_DIALOG_TEXT, | 212 IDS_CLIENT_CERT_DIALOG_TEXT, |
| 216 ASCIIToUTF16(certRequestInfo_->host_and_port)); | 213 ASCIIToUTF16(observer_->cert_request_info()->host_and_port)); |
| 217 | 214 |
| 218 // Create and set up a system choose-identity panel. | 215 // Create and set up a system choose-identity panel. |
| 219 SFChooseIdentityPanel* panel = [[SFChooseIdentityPanel alloc] init]; | 216 SFChooseIdentityPanel* panel = [[SFChooseIdentityPanel alloc] init]; |
| 220 [panel setInformativeText:message]; | 217 [panel setInformativeText:message]; |
| 221 [panel setDefaultButtonTitle:l10n_util::GetNSString(IDS_OK)]; | 218 [panel setDefaultButtonTitle:l10n_util::GetNSString(IDS_OK)]; |
| 222 [panel setAlternateButtonTitle:l10n_util::GetNSString(IDS_CANCEL)]; | 219 [panel setAlternateButtonTitle:l10n_util::GetNSString(IDS_CANCEL)]; |
| 223 SecPolicyRef sslPolicy; | 220 SecPolicyRef sslPolicy; |
| 224 if (net::X509Certificate::CreateSSLClientPolicy(&sslPolicy) == noErr) { | 221 if (net::X509Certificate::CreateSSLClientPolicy(&sslPolicy) == noErr) { |
| 225 [panel setPolicies:(id)sslPolicy]; | 222 [panel setPolicies:(id)sslPolicy]; |
| 226 CFRelease(sslPolicy); | 223 CFRelease(sslPolicy); |
| 227 } | 224 } |
| 228 | 225 |
| 229 window_ = new ConstrainedWindowMac( | 226 window_ = new ConstrainedWindowMac( |
| 230 wrapper, | 227 wrapper, |
| 231 new ConstrainedSFChooseIdentityPanel( | 228 new ConstrainedSFChooseIdentityPanel( |
| 232 panel, self, | 229 panel, self, |
| 233 @selector(sheetDidEnd:returnCode:context:), | 230 @selector(sheetDidEnd:returnCode:context:), |
| 234 identities_, title)); | 231 identities_, title)); |
| 235 observer_->StartObserving(); | 232 observer_->StartObserving(); |
| 236 // Note: SFChooseIdentityPanel does not take a reference to itself while the | 233 // Note: SFChooseIdentityPanel does not take a reference to itself while the |
| 237 // sheet is open. ConstrainedSFChooseIdentityPanel will release ownership | 234 // sheet is open. ConstrainedSFChooseIdentityPanel will release ownership |
| 238 // on destruction. | 235 // on destruction. |
| 239 } | 236 } |
| 240 | 237 |
| 241 @end | 238 @end |
| OLD | NEW |