Index: chrome/browser/gtk/ssl_client_certificate_selector.cc |
=================================================================== |
--- chrome/browser/gtk/ssl_client_certificate_selector.cc (revision 71352) |
+++ chrome/browser/gtk/ssl_client_certificate_selector.cc (working copy) |
@@ -1,378 +0,0 @@ |
-// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/ssl_client_certificate_selector.h" |
- |
-#include <gtk/gtk.h> |
- |
-#include <string> |
-#include <vector> |
- |
-#include "app/gtk_signal.h" |
-#include "app/l10n_util.h" |
-#include "base/i18n/time_formatting.h" |
-#include "base/logging.h" |
-#include "base/nss_util.h" |
-#include "base/utf_string_conversions.h" |
-#include "chrome/browser/certificate_viewer.h" |
-#include "chrome/browser/gtk/constrained_window_gtk.h" |
-#include "chrome/browser/gtk/gtk_util.h" |
-#include "chrome/browser/gtk/owned_widget_gtk.h" |
-#include "chrome/browser/ssl/ssl_client_auth_handler.h" |
-#include "chrome/browser/tab_contents/tab_contents.h" |
-#include "chrome/browser/ui/pk11_password_dialog.h" |
-#include "chrome/common/net/x509_certificate_model.h" |
-#include "gfx/native_widget_types.h" |
-#include "grit/generated_resources.h" |
-#include "net/base/x509_certificate.h" |
- |
-namespace { |
- |
-enum { |
- RESPONSE_SHOW_CERT_INFO = 1, |
-}; |
- |
-/////////////////////////////////////////////////////////////////////////////// |
-// SSLClientCertificateSelector |
- |
-class SSLClientCertificateSelector : public ConstrainedDialogDelegate { |
- public: |
- explicit SSLClientCertificateSelector( |
- TabContents* parent, |
- net::SSLCertRequestInfo* cert_request_info, |
- SSLClientAuthHandler* delegate); |
- ~SSLClientCertificateSelector(); |
- |
- void Show(); |
- |
- // ConstrainedDialogDelegate implementation: |
- virtual GtkWidget* GetWidgetRoot() { return root_widget_.get(); } |
- virtual void DeleteDelegate(); |
- |
- private: |
- void PopulateCerts(); |
- |
- net::X509Certificate* GetSelectedCert(); |
- |
- static std::string FormatComboBoxText( |
- net::X509Certificate::OSCertHandle cert, |
- const std::string& nickname); |
- static std::string FormatDetailsText( |
- net::X509Certificate::OSCertHandle cert); |
- |
- // Callback after unlocking certificate slot. |
- void Unlocked(); |
- |
- CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnComboBoxChanged); |
- CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnViewClicked); |
- CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnCancelClicked); |
- CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnOkClicked); |
- CHROMEGTK_CALLBACK_1(SSLClientCertificateSelector, void, OnPromptShown, |
- GtkWidget*); |
- |
- scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; |
- |
- std::vector<std::string> details_strings_; |
- |
- GtkWidget* cert_combo_box_; |
- GtkTextBuffer* cert_details_buffer_; |
- |
- scoped_refptr<SSLClientAuthHandler> delegate_; |
- |
- OwnedWidgetGtk root_widget_; |
- // Hold on to the select button to focus it. |
- GtkWidget* select_button_; |
- |
- TabContents* parent_; |
- ConstrainedWindow* window_; |
- |
- DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelector); |
-}; |
- |
-SSLClientCertificateSelector::SSLClientCertificateSelector( |
- TabContents* parent, |
- net::SSLCertRequestInfo* cert_request_info, |
- SSLClientAuthHandler* delegate) |
- : cert_request_info_(cert_request_info), |
- delegate_(delegate), |
- parent_(parent), |
- window_(NULL) { |
- root_widget_.Own(gtk_vbox_new(FALSE, gtk_util::kControlSpacing)); |
- |
- GtkWidget* site_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |
- gtk_box_pack_start(GTK_BOX(root_widget_.get()), site_vbox, |
- FALSE, FALSE, 0); |
- |
- GtkWidget* site_description_label = gtk_util::CreateBoldLabel( |
- l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_SITE_DESCRIPTION_LABEL)); |
- gtk_box_pack_start(GTK_BOX(site_vbox), site_description_label, |
- FALSE, FALSE, 0); |
- |
- GtkWidget* site_label = gtk_label_new( |
- cert_request_info->host_and_port.c_str()); |
- gtk_util::LeftAlignMisc(site_label); |
- gtk_box_pack_start(GTK_BOX(site_vbox), site_label, FALSE, FALSE, 0); |
- |
- GtkWidget* selector_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |
- gtk_box_pack_start(GTK_BOX(root_widget_.get()), selector_vbox, |
- TRUE, TRUE, 0); |
- |
- GtkWidget* choose_description_label = gtk_util::CreateBoldLabel( |
- l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CHOOSE_DESCRIPTION_LABEL)); |
- gtk_box_pack_start(GTK_BOX(selector_vbox), choose_description_label, |
- FALSE, FALSE, 0); |
- |
- |
- cert_combo_box_ = gtk_combo_box_new_text(); |
- g_signal_connect(cert_combo_box_, "changed", |
- G_CALLBACK(OnComboBoxChangedThunk), this); |
- gtk_box_pack_start(GTK_BOX(selector_vbox), cert_combo_box_, |
- FALSE, FALSE, 0); |
- |
- GtkWidget* details_label = gtk_label_new(l10n_util::GetStringUTF8( |
- IDS_CERT_SELECTOR_DETAILS_DESCRIPTION_LABEL).c_str()); |
- gtk_util::LeftAlignMisc(details_label); |
- gtk_box_pack_start(GTK_BOX(selector_vbox), details_label, FALSE, FALSE, 0); |
- |
- // TODO(mattm): fix text view coloring (should have grey background). |
- GtkWidget* cert_details_view = gtk_text_view_new(); |
- gtk_text_view_set_editable(GTK_TEXT_VIEW(cert_details_view), FALSE); |
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(cert_details_view), GTK_WRAP_WORD); |
- cert_details_buffer_ = gtk_text_view_get_buffer( |
- GTK_TEXT_VIEW(cert_details_view)); |
- // We put the details in a frame instead of a scrolled window so that the |
- // entirety will be visible without requiring scrolling or expanding the |
- // dialog. This does however mean the dialog will grow itself if you switch |
- // to different cert that has longer details text. |
- GtkWidget* details_frame = gtk_frame_new(NULL); |
- gtk_frame_set_shadow_type(GTK_FRAME(details_frame), GTK_SHADOW_ETCHED_IN); |
- gtk_container_add(GTK_CONTAINER(details_frame), cert_details_view); |
- gtk_box_pack_start(GTK_BOX(selector_vbox), details_frame, TRUE, TRUE, 0); |
- |
- // And then create a set of buttons like a GtkDialog would. |
- GtkWidget* button_box = gtk_hbutton_box_new(); |
- gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END); |
- gtk_box_set_spacing(GTK_BOX(button_box), gtk_util::kControlSpacing); |
- gtk_box_pack_end(GTK_BOX(root_widget_.get()), button_box, FALSE, FALSE, 0); |
- |
- GtkWidget* view_button = gtk_button_new_with_mnemonic( |
- l10n_util::GetStringUTF8(IDS_PAGEINFO_CERT_INFO_BUTTON).c_str()); |
- gtk_box_pack_start(GTK_BOX(button_box), view_button, FALSE, FALSE, 0); |
- g_signal_connect(view_button, "clicked", |
- G_CALLBACK(OnViewClickedThunk), this); |
- |
- GtkWidget* cancel_button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); |
- gtk_box_pack_end(GTK_BOX(button_box), cancel_button, FALSE, FALSE, 0); |
- g_signal_connect(cancel_button, "clicked", |
- G_CALLBACK(OnCancelClickedThunk), this); |
- |
- GtkWidget* select_button = gtk_button_new_from_stock(GTK_STOCK_OK); |
- gtk_box_pack_end(GTK_BOX(button_box), select_button, FALSE, FALSE, 0); |
- g_signal_connect(select_button, "clicked", |
- G_CALLBACK(OnOkClickedThunk), this); |
- |
- // When we are attached to a window, focus the select button. |
- select_button_ = select_button; |
- g_signal_connect(root_widget_.get(), "hierarchy-changed", |
- G_CALLBACK(OnPromptShownThunk), this); |
- PopulateCerts(); |
- |
- gtk_widget_show_all(root_widget_.get()); |
-} |
- |
-SSLClientCertificateSelector::~SSLClientCertificateSelector() { |
- root_widget_.Destroy(); |
-} |
- |
-void SSLClientCertificateSelector::Show() { |
- DCHECK(!window_); |
- window_ = parent_->CreateConstrainedDialog(this); |
-} |
- |
-void SSLClientCertificateSelector::DeleteDelegate() { |
- if (delegate_) { |
- // The dialog was closed by escape key. |
- delegate_->CertificateSelected(NULL); |
- } |
- delete this; |
-} |
- |
-void SSLClientCertificateSelector::PopulateCerts() { |
- std::vector<std::string> nicknames; |
- x509_certificate_model::GetNicknameStringsFromCertList( |
- cert_request_info_->client_certs, |
- l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_EXPIRED), |
- l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_NOT_YET_VALID), |
- &nicknames); |
- |
- DCHECK_EQ(nicknames.size(), |
- cert_request_info_->client_certs.size()); |
- |
- for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) { |
- net::X509Certificate::OSCertHandle cert = |
- cert_request_info_->client_certs[i]->os_cert_handle(); |
- |
- details_strings_.push_back(FormatDetailsText(cert)); |
- |
- gtk_combo_box_append_text( |
- GTK_COMBO_BOX(cert_combo_box_), |
- FormatComboBoxText(cert, nicknames[i]).c_str()); |
- } |
- |
- // Auto-select the first cert. |
- gtk_combo_box_set_active(GTK_COMBO_BOX(cert_combo_box_), 0); |
-} |
- |
-net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() { |
- int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(cert_combo_box_)); |
- if (selected >= 0 && |
- selected < static_cast<int>( |
- cert_request_info_->client_certs.size())) |
- return cert_request_info_->client_certs[selected]; |
- return NULL; |
-} |
- |
-// static |
-std::string SSLClientCertificateSelector::FormatComboBoxText( |
- net::X509Certificate::OSCertHandle cert, const std::string& nickname) { |
- std::string rv(nickname); |
- rv += " ["; |
- rv += x509_certificate_model::GetSerialNumberHexified(cert, ""); |
- rv += ']'; |
- return rv; |
-} |
- |
-// static |
-std::string SSLClientCertificateSelector::FormatDetailsText( |
- net::X509Certificate::OSCertHandle cert) { |
- std::string rv; |
- |
- rv += l10n_util::GetStringFUTF8( |
- IDS_CERT_SUBJECTNAME_FORMAT, |
- UTF8ToUTF16(x509_certificate_model::GetSubjectName(cert))); |
- |
- rv += "\n "; |
- rv += l10n_util::GetStringFUTF8( |
- IDS_CERT_SERIAL_NUMBER_FORMAT, |
- UTF8ToUTF16( |
- x509_certificate_model::GetSerialNumberHexified(cert, ""))); |
- |
- base::Time issued, expires; |
- if (x509_certificate_model::GetTimes(cert, &issued, &expires)) { |
- string16 issued_str = base::TimeFormatShortDateAndTime(issued); |
- string16 expires_str = base::TimeFormatShortDateAndTime(expires); |
- rv += "\n "; |
- rv += l10n_util::GetStringFUTF8(IDS_CERT_VALIDITY_RANGE_FORMAT, |
- issued_str, expires_str); |
- } |
- |
- std::vector<std::string> usages; |
- x509_certificate_model::GetUsageStrings(cert, &usages); |
- if (usages.size()) { |
- rv += "\n "; |
- rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_EXTENDED_KEY_USAGE_FORMAT, |
- UTF8ToUTF16(JoinString(usages, ','))); |
- } |
- |
- std::string key_usage_str = x509_certificate_model::GetKeyUsageString(cert); |
- if (!key_usage_str.empty()) { |
- rv += "\n "; |
- rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_KEY_USAGE_FORMAT, |
- UTF8ToUTF16(key_usage_str)); |
- } |
- |
- std::vector<std::string> email_addresses; |
- x509_certificate_model::GetEmailAddresses(cert, &email_addresses); |
- if (email_addresses.size()) { |
- rv += "\n "; |
- rv += l10n_util::GetStringFUTF8( |
- IDS_CERT_EMAIL_ADDRESSES_FORMAT, |
- UTF8ToUTF16(JoinString(email_addresses, ','))); |
- } |
- |
- rv += '\n'; |
- rv += l10n_util::GetStringFUTF8( |
- IDS_CERT_ISSUERNAME_FORMAT, |
- UTF8ToUTF16(x509_certificate_model::GetIssuerName(cert))); |
- |
- string16 token(UTF8ToUTF16(x509_certificate_model::GetTokenName(cert))); |
- if (!token.empty()) { |
- rv += '\n'; |
- rv += l10n_util::GetStringFUTF8(IDS_CERT_TOKEN_FORMAT, token); |
- } |
- |
- return rv; |
-} |
- |
-void SSLClientCertificateSelector::Unlocked() { |
- // TODO(mattm): refactor so we don't need to call GetSelectedCert again. |
- net::X509Certificate* cert = GetSelectedCert(); |
- delegate_->CertificateSelected(cert); |
- delegate_ = NULL; |
- DCHECK(window_); |
- window_->CloseConstrainedWindow(); |
-} |
- |
-void SSLClientCertificateSelector::OnComboBoxChanged(GtkWidget* combo_box) { |
- int selected = gtk_combo_box_get_active( |
- GTK_COMBO_BOX(cert_combo_box_)); |
- if (selected < 0) |
- return; |
- gtk_text_buffer_set_text(cert_details_buffer_, |
- details_strings_[selected].c_str(), |
- details_strings_[selected].size()); |
-} |
- |
-void SSLClientCertificateSelector::OnViewClicked(GtkWidget* button) { |
- net::X509Certificate* cert = GetSelectedCert(); |
- if (cert) { |
- GtkWidget* toplevel = gtk_widget_get_toplevel(root_widget_.get()); |
- ShowCertificateViewer(GTK_WINDOW(toplevel), cert); |
- } |
-} |
- |
-void SSLClientCertificateSelector::OnCancelClicked(GtkWidget* button) { |
- delegate_->CertificateSelected(NULL); |
- delegate_ = NULL; |
- DCHECK(window_); |
- window_->CloseConstrainedWindow(); |
-} |
- |
-void SSLClientCertificateSelector::OnOkClicked(GtkWidget* button) { |
- net::X509Certificate* cert = GetSelectedCert(); |
- |
- browser::UnlockCertSlotIfNecessary( |
- cert, |
- browser::kPK11PasswordClientAuth, |
- cert_request_info_->host_and_port, |
- NewCallback(this, &SSLClientCertificateSelector::Unlocked)); |
-} |
- |
-void SSLClientCertificateSelector::OnPromptShown(GtkWidget* widget, |
- GtkWidget* previous_toplevel) { |
- if (!root_widget_.get() || |
- !GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(root_widget_.get()))) |
- return; |
- GTK_WIDGET_SET_FLAGS(select_button_, GTK_CAN_DEFAULT); |
- gtk_widget_grab_default(select_button_); |
- gtk_widget_grab_focus(select_button_); |
-} |
- |
-} // namespace |
- |
-/////////////////////////////////////////////////////////////////////////////// |
-// SSLClientAuthHandler platform specific implementation: |
- |
-namespace browser { |
- |
-void ShowSSLClientCertificateSelector( |
- TabContents* parent, |
- net::SSLCertRequestInfo* cert_request_info, |
- SSLClientAuthHandler* delegate) { |
- (new SSLClientCertificateSelector(parent, |
- cert_request_info, |
- delegate))->Show(); |
-} |
- |
-} // namespace browser |