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

Contents of /trunk/Src/wptPassphraseCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 9847 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


1 /* wptPassphraseCB.cpp - GPGME Passphrase Callback
2 * Copyright (C) 2001, 2002, 2003 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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 GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <windows.h>
22 #include <ctype.h>
23
24 #include "../resource.h"
25 #include "wptNLS.h"
26 #include "wptW32API.h"
27 #include "wptVersion.h"
28 #include "wptGPG.h"
29 #include "wptCommonCtl.h"
30 #include "wptContext.h"
31 #include "wptDlgs.h"
32 #include "wptUTF8.h"
33 #include "wptErrors.h"
34 #include "wptTypes.h"
35 #include "wptAgent.h"
36 #include "wptRegistry.h"
37
38
39 #define item_ctrl_id( cmd ) \
40 ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)
41
42 #define item_ctrl_id2(cmd) \
43 ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_HIDE : IDC_DECRYPT_SIGN_HIDE)
44
45
46 BOOL CALLBACK
47 passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
48 {
49 static passphrase_cb_s * c;
50 gpgme_key_t key;
51 const char * s, * id;
52 char info[768] = {0};
53 void * ctx = NULL, * item;
54 unsigned int pkalgo;
55
56 switch( msg ) {
57 case WM_INITDIALOG:
58 c = (passphrase_cb_s *)lparam;
59 if (!c)
60 BUG (0);
61 SetWindowText (dlg, c->title);
62 if (c->gpg_cmd == GPG_CMD_DECRYPT) {
63 SetDlgItemText( dlg, IDC_DECRYPT_LISTINF,
64 _("Encrypted with the following public key(s)") );
65 CheckDlgButton( dlg, IDC_DECRYPT_HIDE, BST_CHECKED );
66 }
67 else if( c->gpg_cmd == GPG_CMD_SIGN )
68 CheckDlgButton( dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED );
69 if( c->enc_to && c->gpg_cmd == GPG_CMD_DECRYPT ) {
70 gpgme_recipients_enum_open( c->enc_to, &ctx );
71 while ( (s = gpgme_recipients_enum_read( c->enc_to, &ctx )) ) {
72 pkalgo = *s; s++;
73 get_pubkey( s, &key );
74 if( key ) {
75 char * uid = NULL;
76 id = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
77 if( !id )
78 id = _("Invalid User ID");
79 uid = utf8_to_wincp (id, strlen (id));
80 _snprintf( info, sizeof info - 1, "%s (%s, 0x%s)", uid,
81 gpgme_key_expand_attr( GPGME_ATTR_ALGO, pkalgo ), s+8 );
82 free( uid );
83 }
84 else
85 _snprintf( info, sizeof info - 1, _("Unknown (key ID 0x%s)"),
86 s? s + 8 : "DEADBEEF" );
87 listbox_add_string( GetDlgItem( dlg, IDC_DECRYPT_LIST ), info );
88 }
89 gpgme_recipients_enum_close( c->enc_to, &ctx );
90 }
91 SetDlgItemText( dlg, c->gpg_cmd == GPG_CMD_DECRYPT?
92 IDC_DECRYPT_PWDINFO : IDC_DECRYPT_SIGN_PWDINFO,
93 _("Please enter your passphrase") );
94 if( c->gpg_cmd == GPG_CMD_DECRYPT ) {
95 SetFocus( GetDlgItem( dlg, IDC_DECRYPT_PWD ) );
96 SetDlgItemText( dlg, IDC_DECRYPT_MSG, c->info );
97 }
98 else {
99 SetFocus( GetDlgItem( dlg, IDC_DECRYPT_SIGN_PWD ) );
100 SetDlgItemText( dlg, IDC_DECRYPT_SIGN_MSG, c->info );
101 }
102 center_window( dlg );
103 SetForegroundWindow( dlg );
104 set_active_window( dlg );
105 return FALSE;
106
107 case WM_SYSCOMMAND:
108 if( LOWORD( wparam ) == SC_CLOSE ) {
109 SetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), "" );
110 c->cancel = 1;
111 EndDialog( dlg, TRUE );
112 }
113 return FALSE;
114
115 case WM_COMMAND:
116 switch( HIWORD( wparam ) ) {
117 case BN_CLICKED:
118 if ( LOWORD( wparam ) == IDC_DECRYPT_HIDE
119 || LOWORD( wparam ) == IDC_DECRYPT_SIGN_HIDE ) {
120 HWND hwnd;
121 int hide = IsDlgButtonChecked (dlg, item_ctrl_id2 (c->gpg_cmd));
122 hwnd = GetDlgItem (dlg, item_ctrl_id (c->gpg_cmd));
123 SendMessage( hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );
124 SetFocus (hwnd);
125 }
126 }
127
128 switch (LOWORD (wparam)) {
129 case IDOK:
130 /* fixme: the item is even cached when the passphrase is not
131 correct, which means that the user needs to delete all
132 cached entries to continue. */
133 GetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), c->pwd, sizeof (c->pwd) -1);
134 if (reg_prefs.cache_time > 0 && !c->is_card && !strstr (c->keyid, "missing")) {
135 if (agent_get_cache (c->keyid, &item))
136 agent_unlock_cache_entry (&item);
137 else
138 agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
139 }
140 EndDialog (dlg, TRUE);
141 return TRUE;
142
143 case IDCANCEL:
144 SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "" );
145 c->cancel = 1;
146 EndDialog (dlg, FALSE);
147 return FALSE;
148 }
149 break;
150 }
151
152 return FALSE;
153 } /* passphrase_callback_proc */
154
155
156 static const char *
157 parse_gpg_keyid (const char * desc)
158 {
159 static char keyid[16+1];
160 char * p;
161
162 p = strrchr (desc, '\n');
163 if( !p )
164 return NULL;
165 /* the format of the desc buffer looks like this:
166 request_keyid[16] main_keyid[16] keytype[1] keylength[4]
167 we use the main keyid to use only one cache entry. */
168 strncpy (keyid, desc+(p-desc+1+17), 16);
169 return keyid;
170 } /* parse_gpg_keyid */
171
172
173 static void
174 parse_gpg_description( char * desc, int size )
175 {
176 char * buffer = NULL, ch, uid[128] = {0}, * uid2 = NULL;
177 char usedkey[16+1] = {0}, mainkey[16+1] = {0};
178 const char * buf;
179 int i, algo, try_again = 0;
180
181 if( stristr( desc, "[User ID hint missing]" )
182 || stristr( desc, "[passphrase info missing]" ) ) {
183 _snprintf( desc, size-1,
184 _("You need a passphrase to unlock the secret key for\n"
185 "user: [UserID hint missing]\n"
186 " [passphrase info missing]\n") );
187 return;
188 }
189
190 buffer = new char[size+1];
191 if( !buffer )
192 BUG( NULL );
193 strcpy( buffer, desc );
194 buf = buffer;
195 if( strstr( buf, "TRY_AGAIN" ) ) {
196 buf += strlen( "TRY_AGAIN\n" );
197 try_again = 1;
198 }
199 else if( strstr( buf, "ENTER_PASSPHRASE" ) )
200 buf += strlen( "ENTER_PASSPHRASE\n" );
201 else
202 BUG( NULL );
203 buf += 17;
204 for( i = 0; i < sizeof uid-1; i++ ) {
205 ch = *buf++;
206 if( ch == '\n' ) {
207 uid[i] = '\0';
208 break;
209 }
210 uid[i] = ch;
211 }
212 memcpy( usedkey, buf, 16 );
213 usedkey[16] = '\0';
214 buf += 17;
215 memcpy( mainkey, buf, 16 );
216 mainkey[16] = '\0';
217 buf += 17;
218 if( !buf )
219 BUG( NULL );
220 algo = atol( buf );
221 free_if_alloc( buffer );
222
223 uid2 = utf8_to_wincp (uid, strlen (uid));
224
225 if( strcmp( usedkey, mainkey ) )
226 _snprintf( desc, size-1,
227 _("You need a passphrase to unlock the secret key for\n"
228 "user: \"%s\"\n"
229 "%s key, ID %s (main key ID %s)\n"),
230 uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),
231 usedkey+8, mainkey+8 );
232 else if( !strcmp( usedkey, mainkey ) )
233 _snprintf( desc, size-1,
234 _("You need a passphrase to unlock the secret key for\n"
235 "user: \"%s\"\n"
236 "%s key, ID %s\n"),
237 uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),
238 usedkey+8 );
239 free( uid2 );
240 } /* parse_gpg_describtion */
241
242
243 static int inline
244 is_hexstring( const char * p )
245 {
246 size_t i;
247 for( i=0; i < strlen( p ); i++ ) {
248 if( !isxdigit( p[i] ) )
249 return -1;
250 }
251 return 0;
252 }
253
254
255 const char *
256 passphrase_cb( void * opaque, const char * desc, void * r_hd )
257 {
258 passphrase_cb_s * c = (passphrase_cb_s *)opaque;
259 void * item;
260 const char * pass, * keyid;
261 int rc = 0;
262
263 if( !c )
264 return NULL;
265
266 if( desc ) {
267 keyid = parse_gpg_keyid (desc);
268 pass = agent_get_cache( keyid, &item );
269 if( pass ) {
270 agent_unlock_cache_entry( &item );
271 c->pwd_init = 0;
272 return pass;
273 }
274 }
275
276 if( c->pwd_init ) {
277 c->keyid = keyid;
278 /* if the desc has a length of 32 and only hex digits, we assume a
279 smart card has been used. */
280 /*log_box( "", 0, "%s %d %d", desc,strlen( desc), is_hexstring( desc ) );*/
281 if( desc && strlen( desc ) == 32 && !is_hexstring( desc ) ) {
282 char buf[16];
283 memset( buf, 0, sizeof buf );
284 strncpy( buf, desc+20, 8 );
285 _snprintf( c->info, sizeof c->info-1,
286 _("Please enter the PIN to unlock your secret card key\n"
287 "Card: %s"), buf );
288 c->is_card = 1;
289 }
290 else if(desc) {
291 strcpy (c->info, desc);
292 parse_gpg_description (c->info, sizeof c->info - 1);
293 }
294 if( c->gpg_cmd == GPG_CMD_DECRYPT ) {
295 rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,
296 (HWND)c->hwnd, passphrase_callback_proc,
297 (LPARAM)c );
298 }
299 else if( c->gpg_cmd == GPG_CMD_SIGN ) {
300 rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT_SIGN,
301 (HWND)c->hwnd, passphrase_callback_proc,
302 (LPARAM)c );
303 }
304 if( rc == -1 )
305 return NULL;
306 c->pwd_init = 0;
307 }
308
309 if( c->cancel )
310 return NULL;
311
312 return c->pwd;
313 } /* passphrase_cb */
314
315
316 void
317 set_gpg_passphrase_cb (gpgme_ctx_t c, passphrase_cb_s *ctx, int cmd,
318 HWND hwnd, const char *title)
319 {
320 ctx->gpg_cmd = cmd;
321 ctx->is_card = 0;
322 ctx->cancel = 0;
323 ctx->hwnd = hwnd;
324 ctx->pwd_init = 1;
325 if (strlen (title) > 256)
326 BUG (NULL); /* check bounds */
327 strcpy (ctx->title, title);
328 gpgme_set_passphrase_cb (c, passphrase_cb, ctx);
329 } /* set_gpg_passphrase_cb */
330
331
332 int
333 check_passwd_quality (const char *pass, int strict)
334 {
335 int i, nd=0, nc=0, n;
336
337 n = strlen (pass);
338 if (n < 8)
339 return -1;
340
341 for (i=0; i < n; i++) {
342 if (isdigit (pass[i])) nd++;
343 if (isalpha (pass[i])) nc++;
344 }
345
346 if (nd == n || nc == n)
347 return -1;
348
349 return 0;
350 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26