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

Annotation of /trunk/Src/wptPassphraseCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 9407 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26