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

Side by Side Diff: chrome/browser/gtk/pk11_password_dialog.cc

Issue 3186021: DONOTLAND: Start of PK11 password dialog for Linux/NSS (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Start of hooking up the hang monitor, probably requires WebKit changes Created 10 years, 3 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
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/gtk/pk11_password_dialog.h"
6
7 #include <gtk/gtk.h>
8 #include <pk11pub.h>
9
10 #include "app/gtk_signal.h"
11 #include "app/l10n_util.h"
12 #include "base/basictypes.h"
13 #include "base/crypto/scoped_nss_types.h"
14 #include "base/nss_util_internal.h"
15 #include "base/task.h"
16 #include "base/utf_string_conversions.h"
17 #include "base/waitable_event.h"
18 #include "chrome/browser/chrome_thread.h"
19 #include "chrome/browser/gtk/gtk_util.h"
20 #include "googleurl/src/gurl.h"
21 #include "grit/generated_resources.h"
22
23 namespace {
24
25 class PK11BlockingDialogDelegate : public base::PK11BlockingPasswordDelegate {
26 public:
27 PK11BlockingDialogDelegate(browser::PK11PasswordReason reason,
28 const GURL& url)
29 : event_(false, false),
30 reason_(reason),
31 url_(url),
32 password_(NULL) {
33 }
34
35 // base::PK11BlockingDialogDelegate implementation.
36 virtual char* RequestPassword(PK11SlotInfo* slot, PRBool retry) {
37 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI));
38 DCHECK(!event_.IsSignaled());
39 DCHECK(password_ == NULL);
40 event_.Reset();
41 if (ChromeThread::PostTask(
42 ChromeThread::UI, FROM_HERE,
43 NewRunnableMethod(this, &PK11BlockingDialogDelegate::ShowDialog,
44 slot, retry != PR_FALSE))) {
45 event_.Wait();
46 }
47 char* password = password_;
48 password_ = NULL;
49 return password;
50 }
51
52 private:
53 void ShowDialog(PK11SlotInfo* slot, bool retry) {
54 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
55 ShowPK11PasswordDialog(
56 slot, retry, reason_, url_,
57 NewCallback(this, &PK11BlockingDialogDelegate::GotPassword));
58 }
59 void GotPassword(const char* password) {
60 password_ = password ? PL_strdup(password) : NULL;
61 event_.Signal();
62 }
63 base::WaitableEvent event_;
64 browser::PK11PasswordReason reason_;
65 GURL url_;
66 char* password_;
67
68 DISALLOW_COPY_AND_ASSIGN(PK11BlockingDialogDelegate);
69 };
70
71 class PK11PasswordDialog {
72 public:
73 PK11PasswordDialog(PK11SlotInfo* slot,
74 bool retry,
75 browser::PK11PasswordReason reason,
76 const GURL& url,
77 browser::PK11PasswordCallback* callback);
78 void Show();
79 void Close();
80
81 private:
82 CHROMEGTK_CALLBACK_1(PK11PasswordDialog, void, OnResponse, int);
83 CHROMEGTK_CALLBACK_1(PK11PasswordDialog, gboolean,
84 OnWindowDeleteEvent, GdkEvent*);
85 CHROMEGTK_CALLBACK_0(PK11PasswordDialog, void, OnWindowDestroy);
86
87 base::ScopedPK11Slot slot_;
88 bool retry_;
89 browser::PK11PasswordReason reason_;
90 GURL url_;
91 scoped_ptr<browser::PK11PasswordCallback> callback_;
92
93 GtkWidget* dialog_;
94 GtkWidget* password_entry_;
95
96 DISALLOW_COPY_AND_ASSIGN(PK11PasswordDialog);
97 };
98
99 PK11PasswordDialog::PK11PasswordDialog(PK11SlotInfo* slot,
100 bool retry,
101 browser::PK11PasswordReason reason,
102 const GURL& url,
103 browser::PK11PasswordCallback* callback)
104 : slot_(PK11_ReferenceSlot(slot)),
105 retry_(retry),
106 reason_(reason),
107 url_(url),
108 callback_(callback) {
109 dialog_ = gtk_dialog_new_with_buttons(
110 l10n_util::GetStringUTF8(IDS_PK11_AUTH_DIALOG_TITLE).c_str(),
111 NULL,
112 GTK_DIALOG_NO_SEPARATOR,
113 NULL); // Populate the buttons later, for control over the OK button.
114 GtkWidget* ok_button = gtk_button_new_from_stock(GTK_STOCK_OK);
115 gtk_button_set_label(
116 GTK_BUTTON(ok_button),
117 l10n_util::GetStringUTF8(IDS_PK11_AUTH_DIALOG_OK_BUTTON_LABEL).c_str());
118 gtk_dialog_add_action_widget(GTK_DIALOG(dialog_),
119 ok_button, GTK_RESPONSE_ACCEPT);
120 gtk_dialog_add_button(GTK_DIALOG(dialog_),
121 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
122 GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
123 gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
124
125 // Select an appropriate text for the reason.
126 std::string text;
127 const string16& host = UTF8ToUTF16(url.host());
128 const string16& token = UTF8ToUTF16(PK11_GetTokenName(slot));
129 switch (reason) {
130 case browser::kPK11PasswordKeygen:
131 text = l10n_util::GetStringFUTF8(IDS_PK11_AUTH_DIALOG_TEXT_KEYGEN,
132 token, host);
133 break;
134 case browser::kPK11PasswordCertEnrollment:
135 text = l10n_util::GetStringFUTF8(IDS_PK11_AUTH_DIALOG_TEXT_CERT_IMPORT,
136 token, host);
137 break;
138 case browser::kPK11PasswordClientAuth:
139 text = l10n_util::GetStringFUTF8(IDS_PK11_AUTH_DIALOG_TEXT_CLIENT_AUTH,
140 token, host);
141 break;
142 default:
143 NOTREACHED();
144 }
145 GtkWidget* label = gtk_label_new(text.c_str());
146 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
147 gtk_util::LeftAlignMisc(label);
148 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), label,
149 FALSE, FALSE, 0);
150
151 password_entry_ = gtk_entry_new();
152 gtk_entry_set_activates_default(GTK_ENTRY(password_entry_), TRUE);
153 gtk_entry_set_visibility(GTK_ENTRY(password_entry_), FALSE);
154
155 GtkWidget* password_box = gtk_hbox_new(FALSE, gtk_util::kLabelSpacing);
156 gtk_box_pack_start(GTK_BOX(password_box),
157 gtk_label_new(l10n_util::GetStringUTF8(
158 IDS_PK11_AUTH_DIALOG_PASSWORD_FIELD).c_str()),
159 FALSE, FALSE, 0);
160 gtk_box_pack_start(GTK_BOX(password_box), password_entry_,
161 TRUE, TRUE, 0);
162
163 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), password_box,
164 FALSE, FALSE, 0);
165
166 g_signal_connect(dialog_, "response",
167 G_CALLBACK(OnResponseThunk), this);
168 g_signal_connect(dialog_, "delete-event",
169 G_CALLBACK(OnWindowDeleteEventThunk), this);
170 g_signal_connect(dialog_, "destroy",
171 G_CALLBACK(OnWindowDestroyThunk), this);
172 }
173
174 void PK11PasswordDialog::Show() {
175 gtk_util::ShowDialog(dialog_);
176 }
177
178 void PK11PasswordDialog::Close() {
179 // Under the model that we've inherited from Windows, dialogs can receive
180 // more than one Close() call inside the current message loop event.
181 if (dialog_) {
182 gtk_widget_destroy(GTK_WIDGET(dialog_));
183 dialog_ = NULL;
184 }
185 }
186
187 void PK11PasswordDialog::OnResponse(GtkWidget* dialog, int response_id) {
188 if (response_id == GTK_RESPONSE_ACCEPT) {
189 callback_->Run(gtk_entry_get_text(GTK_ENTRY(password_entry_)));
190 } else {
191 callback_->Run(static_cast<const char*>(NULL));
192 }
193 Close();
194 }
195
196 gboolean PK11PasswordDialog::OnWindowDeleteEvent(GtkWidget* widget,
197 GdkEvent* event) {
198 Close();
199
200 // Return true to prevent the gtk dialog from being destroyed. Close will
201 // destroy it for us and the default gtk_dialog_delete_event_handler() will
202 // force the destruction without us being able to stop it.
203 return TRUE;
204 }
205
206 void PK11PasswordDialog::OnWindowDestroy(GtkWidget* widget) {
207 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
208 }
209
210 } // namespace
211
212 // Every post-task we do blocks, so there's no need to ref-count.
213 DISABLE_RUNNABLE_METHOD_REFCOUNT(PK11BlockingDialogDelegate);
214
215 namespace browser {
216
217 void ShowPK11PasswordDialog(PK11SlotInfo* slot,
218 bool retry,
219 PK11PasswordReason reason,
220 const GURL& url,
221 PK11PasswordCallback* callback) {
222 (new PK11PasswordDialog(slot, retry, reason, url, callback))->Show();
223 }
224
225 base::PK11BlockingPasswordDelegate* NewPK11BlockingDialogDelegate(
226 PK11PasswordReason reason,
227 const GURL& url) {
228 return new PK11BlockingDialogDelegate(reason, url);
229 }
230
231 } // namespace browser
OLDNEW
« no previous file with comments | « chrome/browser/gtk/pk11_password_dialog.h ('k') | chrome/browser/renderer_host/resource_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698