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

Annotation of /trunk/Src/wptPassphraseCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide 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 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 twoaday 22 #define item_ctrl_id2(cmd) \
43     ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_HIDE : IDC_DECRYPT_SIGN_HIDE)
44 twoaday 2
45 twoaday 22
46 twoaday 2 BOOL CALLBACK
47 twoaday 4 passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
48 twoaday 2 {
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 twoaday 4 if (!c)
60     BUG (0);
61     SetWindowText (dlg, c->title);
62     if (c->gpg_cmd == GPG_CMD_DECRYPT) {
63 twoaday 2 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 twoaday 22 int hide = IsDlgButtonChecked (dlg, item_ctrl_id2 (c->gpg_cmd));
122     hwnd = GetDlgItem (dlg, item_ctrl_id (c->gpg_cmd));
123 twoaday 4 SendMessage( hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );
124 twoaday 22 SetFocus (hwnd);
125 twoaday 2 }
126     }
127    
128 twoaday 4 switch (LOWORD (wparam)) {
129     case IDOK:
130 twoaday 2 /* 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 twoaday 4 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 twoaday 2 else
138 twoaday 4 agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
139 twoaday 2 }
140 twoaday 4 EndDialog (dlg, TRUE);
141 twoaday 2 return TRUE;
142    
143     case IDCANCEL:
144 twoaday 4 SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "" );
145 twoaday 2 c->cancel = 1;
146 twoaday 4 EndDialog (dlg, FALSE);
147 twoaday 2 return FALSE;
148     }
149     break;
150     }
151    
152     return FALSE;
153     } /* passphrase_callback_proc */
154    
155    
156     static const char *
157 twoaday 22 parse_gpg_keyid (const char * desc)
158 twoaday 2 {
159     static char keyid[16+1];
160     char * p;
161    
162 twoaday 22 p = strrchr (desc, '\n');
163 twoaday 2 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 twoaday 22 strncpy (keyid, desc+(p-desc+1+17), 16);
169 twoaday 2 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 twoaday 22 keyid = parse_gpg_keyid (desc);
268 twoaday 2 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 twoaday 22 else if(desc) {
291     strcpy (c->info, desc);
292     parse_gpg_description (c->info, sizeof c->info - 1);
293 twoaday 2 }
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 twoaday 22 set_gpg_passphrase_cb (gpgme_ctx_t c, passphrase_cb_s *ctx, int cmd,
318     HWND hwnd, const char *title)
319 twoaday 2 {
320     ctx->gpg_cmd = cmd;
321     ctx->is_card = 0;
322     ctx->cancel = 0;
323     ctx->hwnd = hwnd;
324     ctx->pwd_init = 1;
325 twoaday 22 if (strlen (title) > 256)
326     BUG (NULL); /* check bounds */
327     strcpy (ctx->title, title);
328     gpgme_set_passphrase_cb (c, passphrase_cb, ctx);
329 twoaday 2 } /* set_gpg_passphrase_cb */
330 twoaday 22
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