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

Annotation of /trunk/Src/wptPassphraseDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 340 - (hide annotations)
Sun Nov 27 13:15:07 2011 UTC (13 years, 3 months ago) by twoaday
File size: 8968 byte(s)


1 werner 36 /* wptPassphraseDlg.cpp - Dialog to get the passphrase
2 twoaday 328 * Copyright (C) 2001-2006, 2009 Timo Schulz
3 werner 36 *
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 werner 47 #include "resource.h"
23 werner 36 #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 twoaday 297 #include "wptRegistry.h"
33 twoaday 328 #include "wptErrors.h"
34 twoaday 278 #include "StringBuffer.h"
35 werner 36
36    
37     struct passphrase_s {
38 twoaday 225 char *title; /* Title of the dialog. */
39 twoaday 328 // FIXME: do not use static buffer
40     char pwd[2048]; /* The actual passphrase. */
41 twoaday 225 int strict; /* Do a simple check how good the passphrase is. */
42 werner 36 int repeat; /* Indicate last try was wrong. */
43     int cancel; /* 1 if user cancelled operation. */
44 twoaday 229 int warn_utf8;
45 twoaday 181 int not_empty;
46 twoaday 225 gpgme_key_t key;
47 werner 36 };
48    
49    
50 twoaday 225 const char* get_keyinfo (gpgme_key_t key);
51    
52 twoaday 328 static subclass_s passwd_edit_proc;
53 twoaday 225
54 twoaday 328 /* 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 twoaday 225 /* 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 twoaday 278 StringBuffer p;
83     char *uid;
84 twoaday 225
85     uid = utf8_to_native (key->uids->name);
86 twoaday 278 p = p + uid + " (" + get_keyinfo (key) + ")";
87    
88 twoaday 225 SendDlgItemMessage (dlg, IDC_PASSWD_KEYINF,
89 twoaday 278 CB_ADDSTRING, 0, (LPARAM)(char *)p.getBuffer ());
90 twoaday 225 SendDlgItemMessage (dlg, IDC_PASSWD_KEYINF, CB_SETCURSEL, 0, 0);
91 twoaday 278 EnableWindow (GetDlgItem (dlg, IDC_PASSWD_KEYINF), FALSE);
92 twoaday 225 free_if_alloc (uid);
93     }
94    
95    
96 werner 36 /* 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 twoaday 181 static passphrase_s *pwd;
101 werner 36 int nbytes;
102 twoaday 229 int cancel;
103 werner 36
104     switch (msg) {
105     case WM_INITDIALOG:
106     pwd = (passphrase_s *)lparam;
107 twoaday 225 if (!pwd)
108     BUG (0);
109 werner 36 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 twoaday 328 if (pwd->key) {
118     ShowWindow (GetDlgItem (dlg, IDC_PASSWD_QOPINF), SW_HIDE);
119     ShowWindow (GetDlgItem (dlg, IDC_PASSWD_QOP), SW_HIDE);
120 twoaday 225 set_passphrase_hint (dlg, pwd->key);
121 twoaday 328 }
122 twoaday 225 else
123     ShowWindow (GetDlgItem (dlg, IDC_PASSWD_KEYINF), SW_HIDE);
124 twoaday 78 SetDlgItemText (dlg, IDC_PASSWD_HIDE, _("&Hide Typing"));
125 twoaday 101 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
126 twoaday 225 SetDlgItemText (dlg, IDOK, _("&OK"));
127 twoaday 328 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 twoaday 225 SetFocus (GetDlgItem (dlg, IDC_PASSWD_PWD));
145 werner 36 center_window2 (dlg, NULL, HWND_TOPMOST);
146     center_window (dlg, NULL);
147     SetForegroundWindow (dlg);
148     return FALSE;
149 twoaday 181
150     case WM_ACTIVATE:
151 twoaday 297 /* 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 twoaday 181 break;
155    
156     case WM_DESTROY:
157 twoaday 297 if (!reg_prefs.no_safe_pwd_ctrl)
158     safe_edit_control_free (dlg, IDC_PASSWD_PWD);
159 twoaday 328 balloon_msg_disable ();
160 twoaday 181 break;
161 werner 36
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 twoaday 225
168 werner 36 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
169     SetFocus (hwnd);
170     }
171    
172     switch (LOWORD (wparam)) {
173     case IDOK:
174     pwd->cancel = 0;
175 twoaday 181 nbytes = SafeGetDlgItemText (dlg, IDC_PASSWD_PWD,
176     pwd->pwd, DIM (pwd->pwd)-1);
177     if (!nbytes && pwd->not_empty) {
178 twoaday 328 show_balloon_msg (GetDlgItem (dlg, IDC_PASSWD_PWD),
179     _("Please enter a passphrase."), IDI_ERROR);
180 twoaday 181 return TRUE;
181     }
182    
183 werner 36 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 twoaday 248 "\n\nContinue?"),
189 werner 36 _("Key Generation"), MB_ICONWARNING|MB_YESNO);
190     if (id == IDNO)
191     return TRUE;
192     }
193 twoaday 229 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 twoaday 328 "Make sure that all systems you work on properly support UTF-8 handling.\n"
198 twoaday 248 "Continue?"),
199 twoaday 229 _("Key Generation"), MB_ICONWARNING|MB_YESNO);
200     if (cancel == IDNO) {
201     wipememory (pwd->pwd, sizeof (pwd->pwd));
202     return TRUE;
203     }
204     }
205 werner 36 SetDlgItemText (dlg, IDC_PASSWD_PWD, "");
206 twoaday 225 EndDialog (dlg, 1);
207 werner 36 return TRUE;
208    
209     case IDCANCEL:
210     pwd->cancel = 1;
211 twoaday 225 EndDialog (dlg, 0);
212 werner 36 return TRUE;
213     }
214     break;
215     }
216    
217     return FALSE;
218     }
219    
220    
221 twoaday 225 /* 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 twoaday 340
242     p = m_strdup (pass.pwd);
243 twoaday 225 wipememory (pass.pwd, sizeof (pass.pwd));
244     return p;
245     }
246    
247    
248 werner 36 /* Request a passphrase from the user. @title is the title of the
249     dialog and @ret_cancel is true if user cancelled the operation.
250     Return value: the passphrase or NUL for an error. */
251     char*
252     request_passphrase (const char *title, int flags, int *ret_cancel)
253     {
254     passphrase_s pass;
255     char *p;
256    
257 twoaday 170 *ret_cancel = 0; /* reset */
258 werner 36 memset (&pass, 0, sizeof (pass));
259 twoaday 225 if (title && *title)
260 werner 36 pass.title = m_strdup (title);
261     pass.repeat = flags & PASSDLG_INIT? 0 : 1;
262     pass.strict = flags & PASSDLG_STRICT? 1 : 0;
263 twoaday 181 pass.not_empty = flags & PASSDLG_NOTEMPTY? 1: 0;
264 twoaday 229 pass.warn_utf8 = flags & PASSDLG_WARN_UTF8? 1 : 0;
265 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PASSWD, glob_hwnd,
266     passwd_dlg_proc, (LPARAM)&pass);
267 twoaday 225 free_if_alloc (pass.title);
268 werner 36 if (pass.cancel == 1) {
269     *ret_cancel = 1;
270     return NULL;
271     }
272 twoaday 340 p = m_strdup (pass.pwd);
273 twoaday 225 wipememory (pass.pwd, sizeof (pass.pwd));
274 werner 36 return p;
275     }
276    
277    
278     /* Request a passphrase from the user but also confirm the passphrase
279     to make sure there is no typo. Arguments same as in the normal version
280     of the function. */
281     char*
282     request_passphrase2 (const char *title, int flags, int *ret_cancel)
283     {
284     char *pass1, *pass2;
285     int equal = 0, cancel = 0;
286    
287     *ret_cancel = 1;
288     while (!equal) {
289     pass1 = request_passphrase (title, PASSDLG_INIT|flags, &cancel);
290     if (cancel)
291     return NULL;
292     pass2 = request_passphrase (title, PASSDLG_REPEAT, &cancel);
293     if (cancel) {
294     sfree_if_alloc (pass1);
295     return NULL;
296     }
297    
298     if (strcmp (pass1, pass2)) {
299     msg_box (NULL, _("Passphrases do not match. Please try again."),
300     title, MB_INFO);
301     sfree_if_alloc (pass1);
302     sfree_if_alloc (pass2);
303     }
304 twoaday 229 else
305     equal = 1;
306 werner 36 }
307     sfree_if_alloc (pass2);
308     *ret_cancel = 0;
309     return pass1;
310     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26