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

Annotation of /trunk/Src/wptPassphraseCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide 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 twoaday 2 /* 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 twoaday 4 passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
45 twoaday 2 {
46     static passphrase_cb_s * c;
47 twoaday 4 static int hide = 1;
48 twoaday 2 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 twoaday 4 hide = 1;
57 twoaday 2 c = (passphrase_cb_s *)lparam;
58 twoaday 4 if (!c)
59     BUG (0);
60     SetWindowText (dlg, c->title);
61     if (c->gpg_cmd == GPG_CMD_DECRYPT) {
62 twoaday 2 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 twoaday 4 hide ^= 1;
121 twoaday 2 hwnd = GetDlgItem( dlg, item_ctrl_id( c->gpg_cmd ) );
122 twoaday 4 SendMessage( hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );
123 twoaday 2 SetFocus( hwnd );
124     }
125     }
126    
127 twoaday 4 switch (LOWORD (wparam)) {
128     case IDOK:
129 twoaday 2 /* 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 twoaday 4 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 twoaday 2 else
137 twoaday 4 agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
138 twoaday 2 }
139 twoaday 4 EndDialog (dlg, TRUE);
140 twoaday 2 return TRUE;
141    
142     case IDCANCEL:
143 twoaday 4 SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "" );
144 twoaday 2 c->cancel = 1;
145 twoaday 4 EndDialog (dlg, FALSE);
146 twoaday 2 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