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

Contents of /trunk/Src/wptPassphraseCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Sun Feb 6 11:11:40 2005 UTC (20 years ago) by twoaday
File size: 9434 byte(s)
2005-02-02  Timo Schulz  <twoaday@freakmail.de>
                                                                                                                            
        * wptPassphraseDlg.cpp (passwd_dlg_proc): use center_window2, otherwise
        it is invisible.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Do not cache symmetric
        passphrases.
        * Enable the progress dialog for symmetric encryption.
        * wptFileManager.cpp (fm_check_file_type): Also check for 'SYMKEYENC' in
        FM_ENCRYPT mode.
        * WinPT.cpp (WinMain): SETUP_EXISTING implemented.
        * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Reset 'Locale directory' when
        no value is entered.
                                                                                                                            
2005-02-04  Timo Schulz  <twoaday@freakmail.de>
                                                                                                                            
        * wptProgressDlg.cpp (progress_cb_thread): Set root window if available.
        If the progress window survives by accident, it will be closed when the
        File Manager (root window) is closed.
                                                                                                                            


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26