/[winpt]/trunk/Src/wptPassphraseDlg.cpp
ViewVC logotype

Contents of /trunk/Src/wptPassphraseDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (show annotations)
Fri Sep 25 16:07:38 2009 UTC (15 years, 5 months ago) by twoaday
File size: 9095 byte(s)


1 /* wptPassphraseDlg.cpp - Dialog to get the passphrase
2 * Copyright (C) 2001-2006, 2009 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include <windows.h>
21
22 #include "resource.h"
23 #include "wptGPG.h"
24 #include "wptCommonCtl.h"
25 #include "wptContext.h"
26 #include "wptDlgs.h"
27 #include "wptNLS.h"
28 #include "wptW32API.h"
29 #include "wptUTF8.h"
30 #include "wptVersion.h"
31 #include "wptTypes.h"
32 #include "wptRegistry.h"
33 #include "wptErrors.h"
34 #include "StringBuffer.h"
35
36
37 struct passphrase_s {
38 char *title; /* Title of the dialog. */
39 // FIXME: do not use static buffer
40 char pwd[2048]; /* The actual passphrase. */
41 int strict; /* Do a simple check how good the passphrase is. */
42 int repeat; /* Indicate last try was wrong. */
43 int cancel; /* 1 if user cancelled operation. */
44 int warn_utf8;
45 int not_empty;
46 gpgme_key_t key;
47 };
48
49
50 const char* get_keyinfo (gpgme_key_t key);
51
52 static subclass_s passwd_edit_proc;
53
54 /* We sub-class the passphrase edit control to monitor
55 the structure of the passphrase. This output is used
56 as a quality INDICATOR(!). */
57 static BOOL CALLBACK
58 edit_subclass_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
59 {
60 HWND dlg = passwd_edit_proc.dlg;
61 switch (msg) {
62 case WM_CHAR:
63 int n, pos = 0;
64 n = GetWindowTextLength (GetDlgItem (dlg, IDC_PASSWD_PWD));
65 if (n > 0)
66 pos = n*6;
67 if (pos > 100)
68 pos = 100;
69 SendDlgItemMessage (dlg, IDC_PASSWD_QOP, PBM_SETPOS, (WPARAM)pos, 0);
70 break;
71 }
72
73 return CallWindowProc (passwd_edit_proc.old, hwnd, msg, wparam, lparam);
74 }
75
76
77 /* Fill in the key information in the combo box,
78 according to the key in @key. */
79 static void
80 set_passphrase_hint (HWND dlg, gpgme_key_t key)
81 {
82 StringBuffer p;
83 char *uid;
84
85 uid = utf8_to_native (key->uids->name);
86 p = p + uid + " (" + get_keyinfo (key) + ")";
87
88 SendDlgItemMessage (dlg, IDC_PASSWD_KEYINF,
89 CB_ADDSTRING, 0, (LPARAM)(char *)p.getBuffer ());
90 SendDlgItemMessage (dlg, IDC_PASSWD_KEYINF, CB_SETCURSEL, 0, 0);
91 EnableWindow (GetDlgItem (dlg, IDC_PASSWD_KEYINF), FALSE);
92 free_if_alloc (uid);
93 }
94
95
96 /* Dialog procedure to request a passphrase from the user. */
97 static BOOL CALLBACK
98 passwd_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
99 {
100 static passphrase_s *pwd;
101 int nbytes;
102 int cancel;
103
104 switch (msg) {
105 case WM_INITDIALOG:
106 pwd = (passphrase_s *)lparam;
107 if (!pwd)
108 BUG (0);
109 SetWindowText (dlg, _("Passphrase Dialog"));
110 CheckDlgButton (dlg, IDC_PASSWD_HIDE, BST_CHECKED);
111 if (pwd->title)
112 SetWindowText (dlg, pwd->title);
113 if (pwd->repeat)
114 SetDlgItemText (dlg, IDC_PASSWD_INFO, _("Repeat Passphrase"));
115 else
116 SetDlgItemText (dlg, IDC_PASSWD_INFO, _("Enter Passphrase"));
117 if (pwd->key) {
118 ShowWindow (GetDlgItem (dlg, IDC_PASSWD_QOPINF), SW_HIDE);
119 ShowWindow (GetDlgItem (dlg, IDC_PASSWD_QOP), SW_HIDE);
120 set_passphrase_hint (dlg, pwd->key);
121 }
122 else
123 ShowWindow (GetDlgItem (dlg, IDC_PASSWD_KEYINF), SW_HIDE);
124 SetDlgItemText (dlg, IDC_PASSWD_HIDE, _("&Hide Typing"));
125 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
126 SetDlgItemText (dlg, IDOK, _("&OK"));
127 SetDlgItemText (dlg, IDC_PASSWD_QOPINF, _("Quality indicator:"));
128
129 if (!pwd->key) {
130 HWND hwnd;
131 hwnd = GetDlgItem (dlg, IDC_PASSWD_PWD);
132 passwd_edit_proc.dlg = dlg;
133 passwd_edit_proc.current = (WNDPROC)edit_subclass_proc;
134 passwd_edit_proc.old = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);
135 if (passwd_edit_proc.old) {
136 if (!SetWindowLong (hwnd, GWL_WNDPROC, (LONG)passwd_edit_proc.current)) {
137 msg_box (dlg, "Could not set keylist window procedure.",
138 _("Key Manager"), MB_ERR);
139 BUG (NULL);
140 }
141 }
142 }
143
144 SetFocus (GetDlgItem (dlg, IDC_PASSWD_PWD));
145 center_window2 (dlg, NULL, HWND_TOPMOST);
146 center_window (dlg, NULL);
147 SetForegroundWindow (dlg);
148 return FALSE;
149
150 case WM_ACTIVATE:
151 /* See comment in wptPassphraseCBDlg.cpp for more information. */
152 if (!reg_prefs.no_safe_pwd_ctrl)
153 safe_edit_control_init (dlg, IDC_PASSWD_PWD);
154 break;
155
156 case WM_DESTROY:
157 if (!reg_prefs.no_safe_pwd_ctrl)
158 safe_edit_control_free (dlg, IDC_PASSWD_PWD);
159 balloon_msg_disable ();
160 break;
161
162 case WM_COMMAND:
163 if (HIWORD (wparam) == BN_CLICKED &&
164 LOWORD (wparam) == IDC_PASSWD_HIDE) {
165 HWND hwnd = GetDlgItem (dlg, IDC_PASSWD_PWD);
166 int hide = IsDlgButtonChecked (dlg, IDC_PASSWD_HIDE);
167
168 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
169 SetFocus (hwnd);
170 }
171
172 switch (LOWORD (wparam)) {
173 case IDOK:
174 pwd->cancel = 0;
175 nbytes = SafeGetDlgItemText (dlg, IDC_PASSWD_PWD,
176 pwd->pwd, DIM (pwd->pwd)-1);
177 if (!nbytes && pwd->not_empty) {
178 show_balloon_msg (GetDlgItem (dlg, IDC_PASSWD_PWD),
179 _("Please enter a passphrase."), IDI_ERROR);
180 return TRUE;
181 }
182
183 if (!nbytes)
184 strcpy (pwd->pwd, "");
185 else if (pwd->strict && check_passwd_quality (pwd->pwd, 0)) {
186 int id = msg_box (dlg, _("Your passphrase should be at least 8 characters"
187 " long\nand should contain non-alphabetic characters."
188 "\n\nContinue?"),
189 _("Key Generation"), MB_ICONWARNING|MB_YESNO);
190 if (id == IDNO)
191 return TRUE;
192 }
193 if (pwd->warn_utf8 && !pwd->repeat &&
194 is_8bit_string (pwd->pwd)) {
195 cancel = msg_box (dlg,
196 _("The passphrase contains 8-bit characters.\n"
197 "Make sure that all systems you work on properly support UTF-8 handling.\n"
198 "Continue?"),
199 _("Key Generation"), MB_ICONWARNING|MB_YESNO);
200 if (cancel == IDNO) {
201 wipememory (pwd->pwd, sizeof (pwd->pwd));
202 return TRUE;
203 }
204 }
205 SetDlgItemText (dlg, IDC_PASSWD_PWD, "");
206 EndDialog (dlg, 1);
207 return TRUE;
208
209 case IDCANCEL:
210 pwd->cancel = 1;
211 EndDialog (dlg, 0);
212 return TRUE;
213 }
214 break;
215 }
216
217 return FALSE;
218 }
219
220
221 /* Same as request_passphrase(), but with an additional hint about the
222 key to unprotect. */
223 char*
224 request_key_passphrase (gpgme_key_t key, const char *title, int *ret_cancel)
225 {
226 passphrase_s pass;
227 char *p;
228
229 *ret_cancel = 0;
230 memset (&pass, 0, sizeof (pass));
231 pass.key = key;
232 pass.title = title? m_strdup (title) : NULL;
233
234 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PASSWD, glob_hwnd,
235 passwd_dlg_proc, (LPARAM)&pass);
236 free_if_alloc (pass.title);
237 if (pass.cancel == 1) {
238 *ret_cancel = 1;
239 return NULL;
240 }
241 if (emulate_utf8_bug)
242 p = native_to_utf8 (pass.pwd);
243 else
244 p = m_strdup (pass.pwd);
245 wipememory (pass.pwd, sizeof (pass.pwd));
246 return p;
247 }
248
249
250 /* Request a passphrase from the user. @title is the title of the
251 dialog and @ret_cancel is true if user cancelled the operation.
252 Return value: the passphrase or NUL for an error. */
253 char*
254 request_passphrase (const char *title, int flags, int *ret_cancel)
255 {
256 passphrase_s pass;
257 char *p;
258
259 *ret_cancel = 0; /* reset */
260 memset (&pass, 0, sizeof (pass));
261 if (title && *title)
262 pass.title = m_strdup (title);
263 pass.repeat = flags & PASSDLG_INIT? 0 : 1;
264 pass.strict = flags & PASSDLG_STRICT? 1 : 0;
265 pass.not_empty = flags & PASSDLG_NOTEMPTY? 1: 0;
266 pass.warn_utf8 = flags & PASSDLG_WARN_UTF8? 1 : 0;
267 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PASSWD, glob_hwnd,
268 passwd_dlg_proc, (LPARAM)&pass);
269 free_if_alloc (pass.title);
270 if (pass.cancel == 1) {
271 *ret_cancel = 1;
272 return NULL;
273 }
274 if (emulate_utf8_bug)
275 p = native_to_utf8 (pass.pwd);
276 else
277 p = m_strdup (pass.pwd);
278 wipememory (pass.pwd, sizeof (pass.pwd));
279 return p;
280 }
281
282
283 /* Request a passphrase from the user but also confirm the passphrase
284 to make sure there is no typo. Arguments same as in the normal version
285 of the function. */
286 char*
287 request_passphrase2 (const char *title, int flags, int *ret_cancel)
288 {
289 char *pass1, *pass2;
290 int equal = 0, cancel = 0;
291
292 *ret_cancel = 1;
293 while (!equal) {
294 pass1 = request_passphrase (title, PASSDLG_INIT|flags, &cancel);
295 if (cancel)
296 return NULL;
297 pass2 = request_passphrase (title, PASSDLG_REPEAT, &cancel);
298 if (cancel) {
299 sfree_if_alloc (pass1);
300 return NULL;
301 }
302
303 if (strcmp (pass1, pass2)) {
304 msg_box (NULL, _("Passphrases do not match. Please try again."),
305 title, MB_INFO);
306 sfree_if_alloc (pass1);
307 sfree_if_alloc (pass2);
308 }
309 else
310 equal = 1;
311 }
312 sfree_if_alloc (pass2);
313 *ret_cancel = 0;
314 return pass1;
315 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26