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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Thu Apr 14 12:56:25 2005 UTC (19 years, 10 months ago) by twoaday
File size: 49102 byte(s)
2005-04-11  Timo Schulz  <twoaday@freakmail.de>
 
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Reset
        'enable' flag always at the begin.
        * wptClipDecryptDlg.cpp (clip_decrypt_dlg): Show correct
        key trust. Noted by a friendly user.
        * wptListView.cpp (listview_add_item_pos): New.
        * wptKeyEditDlgs.cpp (get_subkey_fingerprint): Due to
        the fact that GPG does not return the fingerprint of
        the generated subkey any longer, we need to get it manually.
        Thanks to Maxime Brandt.
        (keyedit_addsubkey_dlg_proc): If key size too large, ask
        if this was a mistake.
        (keyedit_add_subkey): Use it here.
        (do_add_new_subkey): Fix list contrl insertion.
        * wptTypes.h (DEFAULT_KEYSIZE): Define new default keysize constant.


1 twoaday 2 /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2 twoaday 6 * Copyright (C) 2002-2005 Timo Schulz
3 twoaday 2 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (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
14     * GNU 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 <commctrl.h>
23     #include "../resource.h"
24    
25     #include "wptTypes.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 "wptNLS.h"
33     #include "wptUTF8.h"
34     #include "wptErrors.h"
35     #include "wptKeylist.h"
36     #include "wptKeyManager.h"
37     #include "wptRegistry.h"
38    
39     enum keyedit_commands {
40     CMD_ADDKEY = 0,
41     CMD_ADDUID,
42     CMD_ADDPHOTO,
43     CMD_ADDREVOKER,
44     /*CMD_FPR,*/
45     CMD_DELUID,
46     CMD_DELKEY,
47     CMD_DELPHOTO,
48     /*CMD_DELSIG,*/
49     CMD_EXPIRE,
50     /*CMD_PREF,
51     CMD_SHOWPREF,
52     CMD_SETPREF,*/
53     CMD_UPDPREF,
54     CMD_PASSWD,
55     CMD_PRIMARY,
56     CMD_TRUST,
57     /*CMD_REVSIG,*/
58     CMD_REVUID,
59     CMD_REVKEY,
60     CMD_DISABLE,
61     CMD_ENABLE,
62     /*CMD_SHOWPHOTO,*/
63     };
64    
65    
66     struct keyedit_callback_s {
67     gpgme_editkey_t ek;
68     const char * pass;
69     listview_ctrl_t lv;
70     void * opaque;
71     };
72     typedef struct keyedit_callback_s KEYEDIT_CB;
73    
74     struct keygen_callback_s {
75     int bits;
76     int algo;
77     u32 expire;
78     char * fpr;
79     };
80     typedef struct keygen_callback_s KEYGEN_CB;
81    
82    
83     static subclass_s keyedit_subkey_proc;
84     static subclass_s keyedit_uid_proc;
85    
86     int keygen_check_date( SYSTEMTIME * st );
87     void get_userid_preflist (char ** r_prefs, int * r_flags);
88    
89     static void
90     do_init_keylist (HWND dlg, winpt_key_t k)
91     {
92     gpgme_keycache_t pub;
93     gpgme_key_t key;
94     const char * s, * kid;
95     char * u;
96     int i, n;
97    
98     pub = keycache_get_ctx (1);
99     if (!pub)
100     BUG (0);
101    
102     while( !gpgme_keycache_next_key( pub, 0, &key ) ) {
103     s = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
104     kid = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0);
105     if (!s || !strcmp (kid+8, k->keyid+2))
106     continue;
107     u = utf8_to_wincp (s, strlen (s));
108     SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_ADDSTRING,
109     0, (WPARAM)(char *)u);
110     free( u );
111     }
112     gpgme_keycache_rewind( pub );
113     n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );
114     for( i = 0; i < n; i++ ) {
115     gpgme_keycache_next_key( pub, 0, &key );
116     SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
117     (WPARAM)(int)i, (LPARAM)key );
118     }
119     SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_SETCURSEL, 0, 0 );
120     } /* do_init_keylist */
121    
122    
123     static void
124     do_add_new_userid( listview_ctrl_t lv, const char * name, const char *email,
125     const char * comment )
126     {
127     char * p;
128     size_t n;
129    
130     n = strlen( name ) + strlen( email ) + 16;
131     if( comment )
132     n += strlen( comment );
133     p = new char[n+1];
134     if( !p )
135     BUG( NULL );
136     if( comment )
137     sprintf( p, "%s (%s) %s", name, comment, email );
138     else
139     sprintf( p, "%s %s", name, email );
140     listview_add_item( lv, "" );
141     listview_add_sub_item( lv, 0, 0, _("Ultimate" ) );
142     listview_add_sub_item( lv, 0, 1, p );
143     listview_add_sub_item( lv, 0, 2, _("OK") );
144     free_if_alloc( p );
145     } /* do_add_new_userid */
146    
147    
148     static void
149     do_add_new_subkey (listview_ctrl_t lv, KEYGEN_CB * keygen, unsigned int flags)
150     {
151     char info[128], keyid[32];
152     const char * expdate, * s;
153 twoaday 12 int n;
154 twoaday 2
155     expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
156 twoaday 12 _snprintf (info, sizeof info-1, "%d-bit %s",
157     keygen->bits,
158     gpgme_key_expand_attr (GPGME_ATTR_ALGO, keygen->algo));
159     _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+32);
160     n = listview_count_items (lv, 0);
161     listview_add_item_pos (lv, n);
162     listview_add_sub_item (lv, n, 0, info);
163     listview_add_sub_item (lv, n, 1, keyid);
164     listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));
165     listview_add_sub_item (lv, n, 3, expdate);
166     if (flags & KM_FLAG_REVOKED) s = _("Revoked");
167     else if (flags & KM_FLAG_EXPIRED) s = _("Expired");
168 twoaday 2 else s = _("OK");
169 twoaday 12 listview_add_sub_item (lv, n, 4, s);
170 twoaday 2 } /* do_add_new_subkey */
171    
172    
173     static int
174     do_find_userid (const char * keyid, const char * name)
175     {
176     gpgme_uidinfo_t inf;
177     gpgme_ctx_t ctx;
178     gpgme_error_t err;
179     int nitems = 0, pos = -1;
180     const char * s;
181     char * utf8_name=NULL;
182    
183     err = gpgme_new (&ctx);
184     if (err)
185     BUG (0);
186     err = gpgme_op_editkey_get_info (ctx, keyid, &inf);
187     if (err)
188     {
189     log_box (_("user ID"), MB_ERR, _("Could not get key information for: \"%s\""), name);
190     gpgme_release (ctx);
191     return -1;
192     }
193     gpgme_release (ctx);
194     nitems = gpgme_editkey_count_items (inf);
195     while (nitems--)
196     {
197     s = gpgme_editkey_get_string_attr (inf, GPGME_ATTR_NAME, nitems);
198     if (!s)
199     continue;
200     utf8_name = utf8_to_wincp (s, strlen (s));
201     if (!strcmp (utf8_name, name))
202     {
203     pos = gpgme_editkey_get_ulong_attr (inf, GPGME_ATTR_LEVEL, nitems);
204     free (utf8_name);
205     break;
206     }
207     free (utf8_name); utf8_name=NULL;
208     }
209    
210     gpgme_uid_info_release (inf);
211     return pos;
212     } /* do_find_userid */
213    
214    
215     BOOL CALLBACK
216     keyedit_addphoto_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
217     {
218     static winpt_key_t k;
219     gpgme_editkey_t ek;
220     gpgme_error_t ec;
221     gpgme_ctx_t ctx;
222     const char * s;
223     char pwd[128], file[128];
224     int id;
225    
226     switch( msg ) {
227     case WM_INITDIALOG:
228     k = (winpt_key_t)lparam;
229     if( !k )
230     BUG( NULL );
231     SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key. If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));
232     SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
233     SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
234     SetForegroundWindow( dlg );
235     break;
236    
237     case WM_DESTROY:
238     break;
239    
240     case WM_SYSCOMMAND:
241     if( LOWORD (wparam) == SC_CLOSE )
242     EndDialog( dlg, TRUE );
243     break;
244    
245     case WM_COMMAND:
246     switch( LOWORD( wparam ) ) {
247    
248     case IDC_ADDPHOTO_SELFILE:
249     s = get_filename_dlg( dlg, FILE_OPEN, _("Select Image File"), _("JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0"), NULL );
250     if( s && *s )
251     SetDlgItemText( dlg, IDC_ADDPHOTO_FILE, s );
252     break;
253    
254     case IDOK:
255     if( !GetDlgItemText( dlg, IDC_ADDPHOTO_FILE, file, sizeof file-1 ) ){
256     msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR );
257     return FALSE;
258     }
259     if( get_file_size( file ) == 0 || get_file_size( file ) > 6144 ) {
260     id = msg_box( dlg, _("The JPEG is really large.\n"
261     "Are you sure you want to use it?"),
262     _("Add Photo"), MB_YESNO|MB_INFO );
263     if( id == IDNO )
264     return TRUE;
265     }
266     if( k->is_protected ) {
267     if( !GetDlgItemText( dlg, IDC_ADDPHOTO_PASS, pwd, sizeof pwd-1 ) ) {
268     msg_box( dlg, _("Please enter a passphrase."), _("Add Photo"), MB_ERR );
269     return FALSE;
270     }
271     }
272     ec = gpgme_editkey_new( &ek );
273     if( !ec )
274     ec = gpgme_new( &ctx );
275     if( ec )
276     BUG( NULL );
277     gpgme_enable_logging( ctx );
278     gpgme_editkey_addphoto_set( ek, file, k->is_protected? pwd : NULL );
279     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDPHOTO );
280     ec = gpgme_op_editkey( ctx, k->keyid );
281     gpgme_editkey_release( ek );
282     if( ec ) {
283     gpgme_show_error( dlg, ec, ctx, _("Add Photo"), MB_ERR );
284     gpgme_release( ctx );
285     return FALSE;
286     }
287     else {
288     keycache_set_reload( 1 );
289     msg_box( dlg, _("Photo successfully added."), _("GnuPG Status"), MB_OK );
290     }
291     gpgme_release( ctx );
292     EndDialog( dlg, TRUE );
293     break;
294    
295     case IDCANCEL:
296     EndDialog( dlg, FALSE );
297     break;
298     }
299     break;
300     }
301     return FALSE;
302     } /* keyedit_addphoto_dlg_proc */
303    
304    
305     BOOL CALLBACK
306     keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
307     {
308     static winpt_key_t k;
309     static gpgme_key_t seckey;
310     gpgme_editkey_t ek;
311     gpgme_ctx_t ctx;
312     gpgme_error_t ec;
313     char uid[128], pwd[128];
314    
315    
316     switch( msg ) {
317     case WM_INITDIALOG:
318     k = (winpt_key_t)lparam;
319     if( !k )
320     BUG( NULL );
321     if( get_seckey( k->keyid, &seckey ) )
322     BUG( NULL );
323     if( !k->is_protected )
324     EnableWindow( GetDlgItem( dlg, IDC_ADDREV_PASS ), FALSE );
325     do_init_keylist( dlg, k );
326     SetDlgItemText (dlg, IDC_ADDREV_INF, _("Appointing a key as designated revoker cannot be undone."));
327     SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
328     SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
329     SetForegroundWindow( dlg );
330     break;
331    
332     case WM_DESTROY:
333     break;
334    
335     case WM_SYSCOMMAND:
336     if( LOWORD (wparam) == SC_CLOSE )
337     EndDialog( dlg, TRUE );
338     break;
339    
340     case WM_COMMAND:
341     switch( LOWORD( wparam ) ) {
342     case IDOK:
343     if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {
344     msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );
345     return FALSE;
346     }
347    
348     if( k->is_protected ) {
349     if( !GetDlgItemText( dlg, IDC_ADDREV_PASS, pwd, sizeof pwd-1 ) ) {
350     msg_box( dlg, _("Please enter the passphrase."), _("Add Revoker"), MB_ERR );
351     return FALSE;
352     }
353     }
354     ec = gpgme_editkey_new( &ek );
355     if( !ec )
356     ec = gpgme_new( &ctx );
357     if( ec )
358     BUG( NULL );
359     gpgme_enable_logging( ctx );
360     gpgme_editkey_addrev_set( ek, uid, k->is_protected? pwd : NULL );
361     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDREV );
362     ec = gpgme_op_editkey( ctx, k->keyid );
363     gpgme_editkey_release( ek );
364     memset( pwd, 0, sizeof pwd );
365     if( ec ) {
366     gpgme_show_error( dlg, ec, ctx, _("Add Revoker"), MB_ERR );
367     gpgme_release( ctx );
368     return FALSE;
369     }
370     else {
371     msg_box( dlg, _("Revoker successfully addded."), _("GnuPG Status"), MB_OK );
372     keycache_set_reload( 1 );
373     }
374     gpgme_release( ctx );
375     EndDialog( dlg, TRUE );
376     break;
377    
378     case IDCANCEL:
379     EndDialog( dlg, FALSE );
380     break;
381     }
382     break;
383     }
384     return FALSE;
385     } /* keyedit_addrevoker_dlg_proc */
386    
387    
388     BOOL CALLBACK
389     keyedit_adduid_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
390     {
391     static KEYEDIT_CB *ctx;
392     char *utf8_name = NULL;
393     char name[128], email[128], comment[128];
394     int rc;
395    
396     switch ( msg ) {
397     case WM_INITDIALOG:
398     ctx = (KEYEDIT_CB *)lparam;
399     if( !ctx )
400     dlg_fatal_error(dlg, "Could not get dialog param!");
401     #ifndef LANG_DE
402     SetWindowText( dlg, _("Add new User ID") );
403     SetDlgItemText( dlg, IDC_ADDUID_INFNAME, _("&Name") );
404     SetDlgItemText( dlg, IDC_ADDUID_INFEMAIL, _("&Email") );
405     SetDlgItemText( dlg, IDC_ADDUID_INFCOMMENT, _("&Comment") );
406     #endif
407     SetForegroundWindow( dlg );
408     return FALSE;
409    
410     case WM_SYSCOMMAND:
411     if( LOWORD (wparam) == SC_CLOSE ) {
412     gpgme_editkey_make_invalid( ctx->ek );
413     EndDialog(dlg, TRUE);
414     }
415     return FALSE;
416    
417     case WM_COMMAND:
418     switch ( LOWORD( wparam ) ) {
419     case IDOK:
420     rc = GetDlgItemText( dlg, IDC_ADDUID_NAME, name, sizeof name-1 );
421     if( !rc || rc < 5 ) {
422     msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );
423     return FALSE;
424     }
425     if( strchr( name, '@' ) ) {
426     msg_box( dlg, _("Please enter the email address in the email field and not in the name field"), _("UserID"), MB_INFO );
427     return FALSE;
428     }
429    
430     if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {
431     msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
432     return FALSE;
433     }
434     if( !strchr( email, '@' ) ) {
435     msg_box( dlg, _("Invalid email address."), _("UserID"), MB_ERR );
436     return FALSE;
437     }
438    
439     rc = GetDlgItemText( dlg, IDC_ADDUID_COMMENT, comment, sizeof comment -1 );
440    
441     /* xxx: something is wrong with the encoding :-( */
442     utf8_name = wincp_to_utf8 (name, strlen (name));
443    
444     gpgme_editkey_adduid_set( ctx->ek, utf8_name? utf8_name : name, email,
445     rc? comment: NULL, ctx->pass );
446     free( utf8_name );
447     if( ctx->lv )
448     do_add_new_userid( ctx->lv, name, email, rc?comment : NULL );
449     EndDialog( dlg, TRUE );
450     return TRUE;
451    
452     case IDCANCEL:
453     gpgme_editkey_make_invalid( ctx->ek );
454     EndDialog( dlg, FALSE );
455     return FALSE;
456     }
457     break;
458     }
459    
460     return FALSE;
461     } /* keyedit_adduid_dlg_proc */
462    
463    
464     BOOL CALLBACK
465 twoaday 12 keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
466 twoaday 2 {
467     static KEYEDIT_CB * ctx;
468     static KEYGEN_CB * keygen;
469     gpgme_error_t rc;
470     int index, size, valid;
471     HWND lb;
472    
473     switch ( msg ) {
474     case WM_INITDIALOG:
475     ctx = (KEYEDIT_CB *)lparam;
476     if( !ctx )
477     dlg_fatal_error( dlg, "Could not get dialog param!" );
478     keygen = (KEYGEN_CB *)ctx->opaque;
479     #ifndef LANG_DE
480     SetWindowText( dlg, _("Add new Subkey") );
481     SetDlgItemText( dlg, IDC_ADDSUBKEY_INFALGO, _("Key type") );
482     SetDlgItemText( dlg, IDC_ADDSUBKEY_INFSIZE, _("Size") );
483     SetDlgItemText( dlg, IDC_ADDSUBKEY_INFVALID,
484     _("Valid for 'n' days. 0 means forever") );
485     #endif
486     lb = GetDlgItem( dlg, IDC_ADDSUBKEY_ALGO );
487     listbox_add_string( lb, "DSA (sign only)");
488     listbox_add_string( lb, "ElGamal (encrypt only)" );
489     listbox_add_string( lb, "RSA (sign only)");
490     listbox_add_string( lb, "RSA (encrypt only)" );
491     SetDlgItemInt( dlg, IDC_ADDSUBKEY_VALID, 0, FALSE );
492 twoaday 12 SetDlgItemInt( dlg, IDC_ADDSUBKEY_SIZE, DFAULT_KEYSIZE, FALSE );
493 twoaday 2 SetForegroundWindow( dlg );
494     return FALSE;
495    
496     case WM_SYSCOMMAND:
497     if( LOWORD (wparam) == SC_CLOSE ) {
498     gpgme_editkey_make_invalid( ctx->ek );
499     EndDialog( dlg, TRUE );
500     }
501     return FALSE;
502    
503     case WM_COMMAND:
504     switch ( LOWORD(wparam) ) {
505     case IDOK:
506     lb = GetDlgItem( dlg, IDC_ADDSUBKEY_ALGO );
507     switch (listbox_get_cursel (lb)) {
508     case 0: index = 2; break;
509 twoaday 6 case 1: index = 4; break;
510     case 2: index = 5; break;
511     case 3: index = 6; break;
512 twoaday 2 default:
513     msg_box( dlg, _("Please select one entry."), _("Add Subkey"), MB_ERR );
514     return FALSE;
515     }
516     if (gpgver[0] == 1 && gpgver[1] == 2) { /* GPG 1.2.x kludge */
517     if (listbox_get_cursel (lb) > 1)
518     index++;
519     }
520     size = GetDlgItemInt( dlg, IDC_ADDSUBKEY_SIZE, NULL, TRUE );
521     if( !size ) {
522     msg_box( dlg, _("Please enter the keysize."), _("Add Subkey"), MB_ERR );
523     return FALSE;
524     }
525 twoaday 12 else if (index == 2 && size != 1024) {
526 twoaday 2 msg_box( dlg,_("DSS uses a fixed keysize of 1024. Size changed."), _("Add Subkey"), MB_INFO );
527     size = 1024;
528     }
529 twoaday 12 else if (size > 4096) {
530     int id;
531     msg_box (dlg, _("Chosen size must be between 1024 and 4096."), _("Add Subkey"), MB_ERR);
532     id = msg_box (dlg, _("Do you really need such a large key?"), _("Add Subkey"), MB_QUEST_ASK);
533     if (id == IDNO)
534     size = DFAULT_KEYSIZE;
535     else
536     size = 4096;
537     SetDlgItemInt (dlg, IDC_ADDSUBKEY_SIZE, size, TRUE);
538 twoaday 2 }
539 twoaday 12 else if (size < 1024) {
540 twoaday 2 msg_box( dlg, _("Keys with a size of less then 1024 are considered insecure.\n"
541     "Size changed to 1024!"), _("Add Subkey"), MB_INFO );
542     size = 1024;
543     }
544 twoaday 12 valid = GetDlgItemInt (dlg, IDC_ADDSUBKEY_VALID, NULL, TRUE);
545     if (valid < 0) {
546 twoaday 2 msg_box( dlg, _("Please enter the days the key is valid."), _("Add Subkey"), MB_ERR );
547     return FALSE;
548     }
549     rc = gpgme_editkey_addkey_set (ctx->ek, ctx->pass, index, size, valid);
550     if (rc) {
551     msg_box (dlg, gpgme_strerror (rc), _("Add Subkey"), MB_ERR);
552     return FALSE;
553     }
554     keygen->bits = size;
555     switch (index) {
556     case 2: keygen->algo = GPGME_PK_DSA; break;
557 twoaday 6 case 4: keygen->algo = GPGME_PK_ELG_E; break;
558     case 5: keygen->algo = GPGME_PK_RSA_S; break;
559     case 6: keygen->algo = GPGME_PK_RSA_E; break;
560 twoaday 2 }
561     if (valid)
562     keygen->expire = time (NULL) + valid*24*60*60;
563     EndDialog( dlg, TRUE );
564     return TRUE;
565    
566     case IDCANCEL:
567     gpgme_editkey_make_invalid( ctx ->ek );
568     EndDialog( dlg, FALSE );
569     return FALSE;
570     }
571     break;
572     }
573    
574     return FALSE;
575     } /* keyedit_addsubkey_dlg_proc */
576    
577    
578     BOOL
579     keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
580     {
581     gpgme_error_t ec;
582     gpgme_ctx_t ctx;
583     gpgme_editkey_t ek;
584     KEYEDIT_CB cb;
585     char * pass = NULL;
586     int cancel = 0;
587    
588     if( !k->key_pair ) {
589     msg_box( dlg, _("There is no secret key available!"), _("Add user ID"), MB_ERR );
590     return FALSE;
591     }
592    
593     if (k->is_protected) {
594     pass = request_passphrase( _("Key Edit"), 1, &cancel );
595     if( cancel )
596     return FALSE;
597     }
598    
599     ec = gpgme_editkey_new( &ek );
600     if( ec )
601     BUG( dlg );
602    
603     memset( &cb, 0, sizeof cb );
604     cb.ek = ek;
605     cb.pass = k->is_protected? pass : NULL;
606     cb.lv = lv;
607     dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
608     dlg, keyedit_adduid_dlg_proc,
609     (LPARAM)&cb, _("Add user ID"),
610     IDS_WINPT_KEYEDIT_ADDUID );
611     if( !gpgme_editkey_is_valid( ek ) ) {
612     free_if_alloc( pass );
613     return FALSE;
614     }
615    
616     ec = gpgme_new( &ctx );
617     if( ec )
618     BUG( dlg );
619     gpgme_enable_logging( ctx );
620     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDUID );
621     ec = gpgme_op_editkey( ctx, k->keyid );
622     if( ec )
623     gpgme_show_error( dlg, ec, ctx, _("Add user ID"), MB_ERR );
624     else {
625     msg_box(dlg, _("User ID successfully added"), _("GnuPG Status"), MB_OK );
626     keycache_set_reload( 1 );
627     }
628     gpgme_editkey_release( ek );
629     gpgme_release( ctx );
630     free_if_alloc( pass );
631     return TRUE;
632     } /* keyedit_add_userid */
633    
634    
635 twoaday 12 char*
636     get_subkey_fingerprint (gpgme_ctx_t ctx, const char *keyid)
637     {
638     static char fpr[40];
639     const char *s;
640     gpgme_error_t err;
641     gpgme_key_t key, main;
642     int n;
643    
644     /* XXX: this is very slow and complicated */
645     err = gpgme_op_keylist_start (ctx, keyid, 0);
646     if (err)
647     return NULL;
648     err = gpgme_op_keylist_next (ctx, &key);
649     if (err)
650     return NULL;
651    
652     n = gpgme_key_count_items (key, GPGME_ATTR_KEYID);
653     s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, n-1);
654     strcpy (fpr, s);
655    
656     get_pubkey (keyid, &main);
657     gpgme_key_append (main, key, n-1);
658    
659     gpgme_key_release (key);
660     return fpr;
661     }
662    
663    
664 twoaday 2 BOOL
665     keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
666     {
667     gpgme_error_t ec;
668     gpgme_ctx_t ctx;
669     gpgme_editkey_t ek;
670     KEYEDIT_CB cb;
671     KEYGEN_CB keygen;
672     char * pass = NULL;
673     int cancel = 0;
674    
675     if( !k->key_pair ) {
676     msg_box( dlg, _("There is no secret key available!"), _("Add Subkey"), MB_ERR );
677     return FALSE;
678     }
679     if( k->is_protected ) {
680     pass = request_passphrase (_("Key Edit"), 1, &cancel);
681     if( cancel )
682     return FALSE;
683     }
684     ec = gpgme_editkey_new( &ek );
685     if( ec )
686     BUG( dlg );
687    
688 twoaday 12 memset (&keygen, 0, sizeof (keygen));
689     memset (&cb, 0, sizeof (cb));
690 twoaday 2 cb.ek = ek;
691 twoaday 12 cb.pass = k->is_protected? pass : NULL;
692 twoaday 2 cb.opaque = &keygen;
693     dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,
694     dlg, keyedit_addsubkey_dlg_proc,
695     (LPARAM)&cb, _("Add new Subkey" ),
696     IDS_WINPT_KEYEDIT_ADDSUBKEY );
697     if( !gpgme_editkey_is_valid( ek ) ) {
698     free_if_alloc( pass );
699     return FALSE;
700     }
701    
702 twoaday 12 ec = gpgme_new (&ctx);
703     if (ec)
704     BUG (dlg);
705     gpgme_enable_logging (ctx);
706     gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_ADDKEY);
707     gpgme_set_progress_cb (ctx, keygen_cb, NULL);
708 twoaday 2 keygen_cb_dlg_create ();
709    
710 twoaday 12 ec = gpgme_op_editkey (ctx, k->keyid);
711     keygen.fpr = get_subkey_fingerprint (ctx, k->keyid);
712 twoaday 2 keygen_cb_dlg_destroy ();
713     keygen_cb (NULL, NULL, 0, 0, 0); /* flush */
714 twoaday 12 if (ec)
715     gpgme_show_error (dlg, ec, ctx, _("Add Subkey"), MB_ERR);
716 twoaday 2 else {
717 twoaday 12 msg_box (dlg, _("Subkey successfully added."), _("GnuPG Status"), MB_OK);
718     if (lv)
719     do_add_new_subkey (lv, &keygen, k->flags);
720     keycache_set_reload (1);
721 twoaday 2 }
722 twoaday 12 free_if_alloc (pass);
723     gpgme_editkey_release (ek);
724     gpgme_release (ctx);
725 twoaday 2
726     return ec? FALSE : TRUE;
727     } /* keyedit_add_subkey */
728    
729    
730     BOOL
731     keyedit_add_photo( winpt_key_t k, HWND dlg )
732     {
733     if( !k->key_pair ) {
734     msg_box( dlg, _("There is no secret key available!"), _("Add Photo"), MB_ERR );
735     return FALSE;
736     }
737     DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
738     keyedit_addphoto_dlg_proc, (LPARAM)k );
739     return TRUE;
740     } /* keyedit_add_photo */
741    
742    
743     BOOL
744     keyedit_add_revoker (winpt_key_t k, HWND dlg)
745     {
746     if( !k->key_pair ) {
747     msg_box( dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR );
748     return FALSE;
749     }
750     DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
751     keyedit_addrevoker_dlg_proc, (LPARAM)k );
752     return TRUE;
753     } /* keyedit_add_revoker */
754    
755    
756     static int
757     is_idea_protect_algo( const char * keyid )
758     {
759     gpgme_key_t key;
760     const char * sym_prefs;
761     size_t n;
762    
763     if( get_pubkey( keyid, &key ) )
764     BUG( NULL );
765     sym_prefs = gpgme_key_get_string_attr( key, GPGME_ATTR_KEY_SYMPREFS, NULL, 0 );
766     if( !sym_prefs )
767     return 1; /* assume that only v3 keys have no symmetric cipher preferences
768     and thus IDEA is explicit. */
769     for( n = 0; sym_prefs[n]; n++ )
770     ;
771     if( (n == 0 || n == 1) && *sym_prefs == 0x01 )
772     return 1;
773     return 0;
774     } /* is_idea_protect_algo */
775    
776    
777     BOOL
778     keyedit_change_passwd( winpt_key_t k, HWND dlg )
779     {
780     gpgme_error_t ec;
781     gpgme_ctx_t ctx;
782     gpgme_editkey_t ek;
783     char * old_pass = NULL, * new_pass = NULL;
784     int cancel = 0;
785    
786     if( !k->key_pair ) {
787     msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
788     return FALSE;
789     }
790    
791     if( !idea_available && is_idea_protect_algo( k->keyid ) ) {
792     msg_box( dlg, _("Cannot change passphrase because the key\n"
793     "is protected with the IDEA encryption algorithm."),
794     _("Key Edit"), MB_ERR );
795     return FALSE;
796     }
797    
798     if( k->is_protected ) {
799     old_pass = request_passphrase( _("Current (old) Passphrase"), 1, &cancel );
800     if( cancel )
801     return FALSE;
802     }
803     new_pass = request_passphrase( _("New Passphrase" ), 1, &cancel );
804     if( cancel ) {
805     free_if_alloc( old_pass );
806     return FALSE;
807     }
808    
809     if( is_8bit_string( new_pass ) ) {
810     msg_box( dlg, _("The passphrase contains 8-bit characters.\n"
811     "It is not suggested to use charset specific characters."),
812     _("Key Edit"), MB_ERR );
813     free_if_alloc( old_pass );
814     free_if_alloc( new_pass );
815     return FALSE;
816     }
817    
818     ec = gpgme_new( &ctx );
819     if( !ec )
820     ec = gpgme_editkey_new( &ek );
821     if( ec )
822     BUG( NULL );
823     gpgme_enable_logging( ctx );
824     gpgme_editkey_passwd_set( ek, k->is_protected? old_pass : NULL, new_pass, 0 );
825     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_PASSWD );
826     ec = gpgme_op_editkey( ctx, k->keyid );
827     if( ec )
828     gpgme_show_error( dlg, ec, ctx, _("Change Passwd"), MB_ERR );
829     else
830     msg_box( dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK );
831     free_if_alloc( old_pass );
832     free_if_alloc( new_pass );
833     gpgme_editkey_release( ek );
834     gpgme_release( ctx );
835     return TRUE;
836     } /* keyedit_change_passwd */
837    
838    
839     listview_ctrl_t
840     subkey_list_init( HWND dlg, winpt_key_t k )
841     {
842     LV_ITEM lvi;
843     gpgme_key_t key;
844     struct listview_column_s cols[] = {
845     {0, 80, (char *)_("Description")},
846     {1, 78, (char *)_("Key ID")},
847     {2, 66, (char *)_("Creation")},
848     {3, 66, (char *)_("Expires")},
849     {4, 64, (char *)_("Status")},
850     {5, 16, "C"/*ertify*/},
851     {6, 16, "S"/*ign*/},
852     {7, 16, "E"/*ncrypt*/},
853     {8, 16, "A"/*uth*/},
854     {0, 0, 0}
855     };
856     listview_ctrl_t lv;
857     char buf[256], tmp[128];
858     const char *t;
859     int nkeys = 0, rc = 0, i, bits, j;
860    
861     if( get_pubkey( k->keyid, &key ) ) {
862     msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );
863     return NULL;
864     }
865    
866     nkeys = gpgme_key_count_items( key, GPGME_ATTR_KEYID );
867     if( !nkeys ) {
868     msg_box( dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR );
869     return NULL;
870     }
871    
872     rc = listview_new( &lv );
873     if( rc )
874     BUG( dlg );
875    
876     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
877     for( i = 0; cols[i].fieldname != NULL; i++ )
878     listview_add_column( lv, &cols[i] );
879    
880     for( i = 0; i < nkeys; i++ ) {
881     listview_add_item( lv, "" );
882     listview_add_sub_item( lv, 0, 1, "" );
883     memset( &lvi, 0, sizeof lvi );
884     lvi.mask = LVIF_PARAM;
885     lvi.lParam = (LPARAM )key;
886     if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
887     return NULL;
888     }
889    
890     listview_set_ext_style( lv );
891     for( i = 0; i < nkeys; i++ ) {
892     memset( buf, 0, sizeof buf );
893    
894     bits = gpgme_key_get_ulong_attr( key, GPGME_ATTR_LEN, NULL, i );
895     _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
896     strcat( buf, tmp );
897    
898     j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, i );
899     t = gpgme_key_expand_attr( GPGME_ATTR_ALGO, j );
900     _snprintf( tmp, sizeof tmp-1, "%s", t );
901     strcat( buf, tmp );
902    
903     listview_add_sub_item( lv, i, 0, buf );
904     t = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, i );
905     if( !t )
906     t = "DEADBEEFDEADBEEF";
907     _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
908     listview_add_sub_item( lv, i, 1, tmp );
909    
910     j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_CREATED, NULL, i );
911     t = gpgme_key_expand_attr( GPGME_ATTR_CREATED, j );
912     if( !t )
913     t = "????-??-??";
914     listview_add_sub_item( lv, i, 2, t );
915    
916     j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_EXPIRES, NULL, i );
917     if( j ) {
918     t = gpgme_key_expand_attr( GPGME_ATTR_CREATED, j );
919     listview_add_sub_item( lv, i, 3, t );
920     }
921     else
922     listview_add_sub_item( lv, i, 3, _("Never") );
923    
924     if( gpgme_key_get_ulong_attr(key, GPGME_ATTR_KEY_EXPIRED, NULL, i ) )
925     t = _("Expired");
926     else if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_REVOKED, NULL, i ) )
927     t = _("Revoked");
928     else
929     t = _("OK");
930     listview_add_sub_item( lv, i, 4, t );
931    
932     gpgme_key_get_cability( key, GPGME_ATTR_CAN_CERTIFY, i )?
933     t = "*" : t = "";
934     listview_add_sub_item( lv, i, 5, t );
935     gpgme_key_get_cability( key, GPGME_ATTR_CAN_SIGN, i )?
936     t = "*" : t = "";
937     listview_add_sub_item( lv, i, 6, t );
938     gpgme_key_get_cability( key, GPGME_ATTR_CAN_ENCRYPT, i )?
939     t = "*" : t = "";
940     listview_add_sub_item( lv, i, 7, t );
941    
942     gpgme_key_get_cability (key, GPGME_ATTR_CAN_AUTH, i)?
943     t = "*" : t = "";
944     listview_add_sub_item (lv, i, 8, t);
945     }
946     return lv;
947     } /* subkey_list_init */
948    
949    
950     static listview_ctrl_t
951     userid_list_init (HWND dlg, winpt_key_t k)
952     {
953     listview_ctrl_t lv = NULL;
954     gpgme_key_t key;
955     int nuids = 0, rc, j, u_attr;
956     struct listview_column_s cols[] = {
957     {0, 72, (char *)_("Validity")},
958     {1, 250, (char *)_("Name")},
959     {2, 76, (char *)_("Creation")},
960     {0, 0, 0}
961     };
962     const char *attr;
963    
964     if( get_pubkey( k->keyid, &key ) ) {
965     msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );
966     return NULL;
967     }
968    
969     nuids = gpgme_key_count_items( key, GPGME_ATTR_USERID );
970     if( !nuids ) {
971     msg_box( dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR );
972     return NULL;
973     }
974    
975     rc = listview_new( &lv );
976     if( rc )
977     BUG( dlg );
978     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
979     for( j = 0; cols[j].fieldname != NULL; j++ )
980     listview_add_column( lv, &cols[j] );
981    
982     for( j = 0; j < nuids; j++ ) {
983     listview_add_item( lv, " " );
984     listview_add_sub_item( lv, 0, 1, " " );
985     }
986    
987     listview_set_ext_style (lv);
988     for (j = 0; j < nuids; j++) {
989     if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_UID_REVOKED, NULL, j))
990     attr = _("Revoked");
991     else {
992     u_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_VALIDITY, NULL, j);
993     attr = gpgme_key_expand_attr (GPGME_ATTR_VALIDITY, u_attr);
994     }
995     listview_add_sub_item( lv, j, 0, (char *)attr );
996    
997     attr = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, j );
998     if( attr ) {
999     char * uid = utf8_to_wincp (attr, strlen (attr));
1000     if (uid) {
1001     listview_add_sub_item( lv, j, 1, uid );
1002     free( uid );
1003     }
1004     }
1005     else
1006     listview_add_sub_item( lv, j, 1, _("Invalid user ID") );
1007     u_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_UID_CREATED, NULL, j);
1008     if (u_attr)
1009     listview_add_sub_item (lv, j, 2, get_key_created (u_attr));
1010     }
1011     if( !k->key_pair ) {
1012     CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );
1013     CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );
1014     }
1015     return lv;
1016     } /* userid_list_init */
1017    
1018    
1019     static void
1020     do_init_cmdlist( HWND dlg )
1021     {
1022     const char *cmdlist[] = {
1023     "ADDKEY",
1024     "ADDUID",
1025     "ADDPHOTO",
1026     "ADDREVOKER",
1027     /*"FPR",*/
1028     "DELUID",
1029     "DELKEY",
1030     "DELPHOTO",
1031     /*"DELSIG",*/
1032     "EXPIRE",
1033     /*"PREF",
1034     "SHOWPREF",
1035     "SETPREF",*/
1036     "UPDPREF",
1037     "PASSWD",
1038     "PRIMARY",
1039     "TRUST",
1040     /*"REVSIG",*/
1041     "REVUID",
1042     "REVKEY",
1043     "DISABLE",
1044     "ENABLE",
1045     "SHOWPHOTO",
1046     NULL
1047     };
1048     const char * s;
1049     int i = 0;
1050    
1051     for( i = 0; (s=cmdlist[i]); i++ ) {
1052     SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1053     (LPARAM)(char *)s );
1054     }
1055     SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0 );
1056     } /* do_init_cmdlist */
1057    
1058    
1059     static int
1060     is_cmd_openpgp( int cmdid )
1061     {
1062     switch( cmdid ) {
1063     case CMD_ADDKEY:
1064     case CMD_ADDPHOTO:
1065     case CMD_ADDREVOKER:
1066     case CMD_DELPHOTO:
1067     /*case CMD_SHOWPHOTO:*/
1068     case CMD_UPDPREF:
1069     return 1;
1070     }
1071     return 0;
1072     } /* is_cmd_openpgp */
1073    
1074    
1075     static void
1076     do_show_help( HWND dlg )
1077     {
1078     char helptext[2048];
1079    
1080     _snprintf( helptext, sizeof helptext-1,
1081     _(/*"FPR \t\tshow fingerprint\r\n"*/
1082     "ADDUID \t\tadd a user ID\r\n"
1083     "ADDPHOTO \t\tadd a photo ID\r\n"
1084     "DELUID \t\tdelete a user ID\r\n"
1085     "ADDKEY \t\tadd a secondard key\r\n"
1086     "DELKEY \t\tdelete a secondary key\r\n"
1087     "ADDREVOKER\t\tadd a revocation key\r\n"
1088     /*"DELSIG \t\tdelete signatures\r\n"*/
1089     "EXPIRE \t\tchange the expire date\r\n"
1090     /*"PREF \t\tlist preferences (expert)\r\n"
1091     "SHOWPREF \t\tlist preferences (verbose)\r\n"
1092     "SETPREF \t\tset preference list\r\n"*/
1093     "UPDPREF \t\tupdated preferences\r\n"
1094     "PASSWD \t\tchange the passphrase\r\n"
1095     "PRIMARY \t\tflag user ID as primary\r\n"
1096     "TRUST \t\tchange the ownertrust\r\n"
1097     /*"REVSIG \t\trevoke signatures\r\n"*/
1098     "REVUID \t\trevoke a user ID\r\n"
1099     "REVKEY \t\trevoke a secondary key\r\n"
1100     "DISABLE \t\tdisable a key\r\n"
1101     "ENABLE \t\tenable a key\r\n"
1102     /*"SHOWPHOTO \t\tshow photo ID\r\n"*/) );
1103     msg_box( dlg, helptext, _("Key Edit Help"), MB_OK );
1104     } /* do_show_help */
1105    
1106    
1107     static int
1108     do_editkey_delkey( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1109     {
1110     int j, id;
1111     char tmp[64];
1112     gpgme_error_t ec;
1113     gpgme_editkey_t ek;
1114     gpgme_ctx_t ctx;
1115    
1116     if( listview_count_items( lv, 0 ) == 1 ) {
1117     msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1118     return FALSE;
1119     }
1120     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1121     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1122     return FALSE;
1123     }
1124     if( j == 0 ) {
1125     msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );
1126     return FALSE;
1127     }
1128    
1129     listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );
1130     id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,
1131     _("\"Subkey %s.\"\n\n"
1132     "Anything encrypted to the selected subkey will no longer\n"
1133     "be able to be decrypted.\n\n"
1134     "Do you really want to delete this subkey?"), tmp );
1135     if( id == IDNO )
1136     return FALSE;
1137    
1138     ec = gpgme_new( &ctx );
1139     if( !ec )
1140     ec = gpgme_editkey_new( &ek );
1141     if( ec )
1142     BUG( dlg );
1143     gpgme_enable_logging( ctx );
1144     gpgme_editkey_delkey_set_id( ek, j );
1145     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_DELKEY );
1146     ec = gpgme_op_editkey( ctx, k->keyid );
1147     if( ec )
1148     gpgme_show_error( dlg, ec, ctx, _("Delete Subkey"), MB_ERR );
1149     else {
1150     listview_del_item( lv, j );
1151     keycache_set_reload( 1 );
1152     status_box( dlg, _("Subkey successfully deleted."), _("GnuPG status") );
1153     }
1154     gpgme_editkey_release( ek );
1155     gpgme_release( ctx );
1156     return ec? FALSE : TRUE;
1157     } /* do_editkey_delkey */
1158    
1159    
1160     static int
1161     do_editkey_expire( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1162     {
1163     gpgme_error_t ec;
1164     gpgme_editkey_t ek;
1165     gpgme_ctx_t ctx;
1166     date_s udd = {0};
1167     char buf[256], * pass = NULL;
1168     int j, cancel = 0;
1169    
1170     if( !k->key_pair ) {
1171     msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
1172     return FALSE;
1173     }
1174     if ( (j = listview_get_curr_pos( lv )) == -1 ) {
1175     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1176     return FALSE;
1177     }
1178    
1179     listview_get_item_text( lv, j, 3, buf, sizeof buf -1 );
1180     if( !strcmp( buf, _("Expired") ) ) {
1181     msg_box( dlg, _("Key already expired!"), _("Key Edit"), MB_ERR );
1182     return FALSE;
1183     }
1184     memset( &udd, 0, sizeof udd );
1185     udd.text = _("Key Expiration Date");
1186     dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,
1187     date_dlg_proc, (LPARAM)&udd,
1188     _("Key Expiration Date"), IDS_WINPT_DATE );
1189     if( udd.cancel == 1 )
1190     return FALSE;
1191     if( !keygen_check_date( &udd.st ) ) {
1192     msg_box( dlg, _("The date you have chosen lies in the past."), _("Key Edit"), MB_ERR );
1193     return FALSE;
1194     }
1195     if( k->is_protected ) {
1196     pass = request_passphrase (_("Key Edit"), 1, &cancel );
1197     if( cancel )
1198     return FALSE;
1199     }
1200     _snprintf( buf, sizeof buf - 1, "%04d-%02d-%02d",
1201     udd.st.wYear, udd.st.wMonth, udd.st.wDay );
1202     ec = gpgme_editkey_new( &ek );
1203     if( !ec )
1204     ec = gpgme_new( &ctx );
1205     if( ec )
1206     BUG( dlg );
1207     gpgme_editkey_expire_set( ek, j, 0, buf, k->is_protected? pass : NULL );
1208     gpgme_enable_logging( ctx );
1209     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_EXPIRE );
1210     ec = gpgme_op_editkey( ctx, k->keyid );
1211     if( ec )
1212     gpgme_show_error( dlg, ec, ctx, _("Expire Subkey"), MB_ERR );
1213     else {
1214     listview_add_sub_item( lv, j, 3, buf );
1215     keycache_set_reload( 1 );
1216     msg_box( dlg, _("Subkey expire date successfully set."), _("GnuPG status"), MB_OK );
1217     }
1218     free_if_alloc( pass );
1219     gpgme_release( ctx );
1220     gpgme_editkey_release( ek );
1221     return TRUE;
1222     } /* do_editkey_expire */
1223    
1224    
1225     static int
1226     do_editkey_revoke( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1227     {
1228     gpgme_ctx_t ctx;
1229     gpgme_error_t ec;
1230     gpgme_editkey_t ek;
1231     char buf[256], * pass = NULL;
1232     int j, cancel = 0;
1233    
1234     if( !k->key_pair ) {
1235     msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
1236     return FALSE;
1237    
1238     }
1239    
1240     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1241     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1242     return FALSE;
1243     }
1244     else if( listview_count_items( lv, 0 ) == 1 ) {
1245     msg_box( dlg, _("No subkeys were found, if you want to revoke the\n"
1246     "whole key, please use the Key Manager command directly.\n\n"
1247     "This command is only available to revoke single subkeys"),
1248     _("Key Edit"), MB_INFO );
1249     return FALSE;
1250     }
1251    
1252     listview_get_item_text( lv, j, 3, buf, sizeof buf-1 );
1253     if( !strcmp( buf, _("Revoked") ) ) {
1254     msg_box( dlg, _("Key already revoked."), _("Key Edit"), MB_ERR );
1255     return FALSE;
1256     }
1257    
1258     if( k->is_protected ) {
1259     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1260     if( cancel )
1261     return FALSE;
1262     }
1263    
1264     ec = gpgme_editkey_new( &ek );
1265     if( !ec )
1266     ec = gpgme_new( &ctx );
1267     if( ec )
1268     BUG( NULL );
1269     gpgme_enable_logging( ctx );
1270     gpgme_editkey_revkey_set( ek, j, 0, k->is_protected? pass : NULL );
1271     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_REVKEY );
1272     ec = gpgme_op_editkey( ctx, k->keyid );
1273     if( ec )
1274     gpgme_show_error( dlg, ec, ctx, _("Revoke Subkey"), MB_ERR );
1275     else {
1276     listview_add_sub_item( lv, j, 5, _("Revoked") );
1277     keycache_set_reload( 1 );
1278     msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1279     }
1280     free_if_alloc( pass );
1281     gpgme_release( ctx );
1282     gpgme_editkey_release( ek );
1283     return TRUE;
1284     } /* do_editkey_revoke */
1285    
1286    
1287     int
1288     do_editkey_revuid( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1289     {
1290     gpgme_ctx_t ctx;
1291     gpgme_error_t ec;
1292     gpgme_editkey_t ek;
1293     char buf[256], t[512], * pass;
1294     int cancel = 0, id = 0, j;
1295    
1296     if( !k->key_pair ) {
1297     msg_box( dlg, _("There is no secret key available!"), _("Revoke user ID"), MB_ERR );
1298     return FALSE;
1299     }
1300    
1301     if( listview_count_items( lv, 0 ) == 1 ) {
1302     msg_box( dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR );
1303     return FALSE;
1304     }
1305    
1306     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1307     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1308     return FALSE;
1309     }
1310    
1311     listview_get_item_text( lv, j, 0, buf, sizeof buf - 1 );
1312     if( strstr( buf, _("Revoked") ) ) {
1313     msg_box( dlg, _("This user ID has been already revoked."), _("Key Edit"), MB_INFO );
1314     return FALSE;
1315     }
1316    
1317     listview_get_item_text( lv, j, 1, buf, sizeof buf -1 );
1318     _snprintf( t, sizeof t -1, _("user ID \"%s\".\n\n"
1319     "Do you really want to revoke this user ID?"), buf );
1320     if( msg_box( dlg, t, _("Key Edit"), MB_YESNO|MB_ICONWARNING ) == IDNO )
1321     return FALSE;
1322     if( k->is_protected ) {
1323     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1324     if( cancel )
1325     return FALSE;
1326     }
1327     id = do_find_userid( k->keyid, buf );
1328     if( id == -1 )
1329     BUG( dlg );
1330     ec = gpgme_new( &ctx );
1331     if( !ec )
1332     ec = gpgme_editkey_new( &ek );
1333     if( ec )
1334     BUG( dlg );
1335     gpgme_enable_logging( ctx );
1336     gpgme_editkey_revsig_set( ek, id, k->is_protected? pass : NULL );
1337     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_REVSIG );
1338     ec = gpgme_op_editkey( ctx, k->keyid );
1339     if( ec )
1340     gpgme_show_error( dlg, ec, ctx, _("Revoke Signature"), MB_ERR );
1341     else {
1342     listview_add_sub_item( lv, j, 2, _("Revoked") );
1343     keycache_set_reload( 1 );
1344     status_box( dlg, _("User ID successfully revoked"), _("GnuPG Status") );
1345     }
1346     free_if_alloc( pass );
1347     gpgme_editkey_release( ek );
1348     gpgme_release( ctx );
1349     return ec? FALSE : TRUE;
1350     } /* do_editkey_revuid */
1351    
1352    
1353     static int
1354     do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1355     {
1356     gpgme_ctx_t ctx;
1357     gpgme_editkey_t ek;
1358     gpgme_error_t rc;
1359     char buf[256], * pass = NULL, * prefs;
1360     int j, id, cancel=0, flags=0;
1361    
1362     if ((j = listview_get_curr_pos (lv)) == -1) {
1363     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1364     return FALSE;
1365     }
1366     listview_get_item_text (lv, j, 1, buf, sizeof buf-1);
1367     id = do_find_userid (k->keyid, buf);
1368     if (id == -1)
1369     BUG (dlg);
1370     if (k->is_protected) {
1371     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1372     if (cancel)
1373     return FALSE;
1374     }
1375     rc = gpgme_new (&ctx);
1376     if (!rc)
1377     rc = gpgme_editkey_new (&ek);
1378     if (rc)
1379     BUG (NULL);
1380    
1381     get_userid_preflist (&prefs, &flags);
1382     gpgme_editkey_setpref_set (ek, prefs, id, pass);
1383     gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_SETPREF);
1384     rc = gpgme_op_editkey (ctx, k->keyid);
1385     free_if_alloc (pass);
1386    
1387     free_if_alloc (prefs);
1388     gpgme_release (ctx);
1389     gpgme_editkey_release (ek);
1390     return 0;
1391     }
1392    
1393    
1394     static int
1395     do_editkey_primary( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1396     {
1397     gpgme_ctx_t ctx;
1398     gpgme_editkey_t ek;
1399     gpgme_error_t ec;
1400     int j, id, cancel=0;
1401     char buf[256], * pass = NULL;
1402    
1403     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1404     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1405     return FALSE;
1406     }
1407     listview_get_item_text( lv, j, 1, buf, sizeof buf-1 );
1408     id = do_find_userid (k->keyid, buf);
1409     if( id == -1 )
1410     BUG( dlg );
1411     if( k->is_protected ) {
1412     pass = request_passphrase( _("Key Edit"), 1, &cancel );
1413     if( cancel )
1414     return FALSE;
1415     }
1416    
1417     ec = gpgme_new( &ctx );
1418     if( !ec )
1419     ec = gpgme_editkey_new( &ek );
1420     if( ec )
1421     BUG( dlg );
1422     gpgme_enable_logging( ctx );
1423     gpgme_editkey_primary_set( ek, id, k->is_protected? pass : NULL );
1424     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_PRIMARY );
1425     ec = gpgme_op_editkey( ctx, k->keyid );
1426     if( ec )
1427     gpgme_show_error( dlg, ec, ctx, _("Primary"), MB_ERR );
1428     else {
1429     keycache_set_reload( 1 );
1430     status_box( dlg, _("User ID successfully flagged"), _("GnuPG Status") );
1431     }
1432    
1433     free_if_alloc( pass );
1434     gpgme_editkey_release( ek );
1435     gpgme_release( ctx );
1436     return ec? FALSE : TRUE;
1437     } /* do_editkey_primary */
1438    
1439    
1440     static int
1441     do_editkey_deluid( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1442     {
1443     gpgme_ctx_t ctx;
1444     gpgme_editkey_t ek;
1445     gpgme_error_t ec;
1446     char buf[256], t[512];
1447     int j, id = 0;
1448    
1449     if( listview_count_items( lv, 0 ) == 1 ) {
1450     msg_box( dlg, _("Primary user ID can not be deleted!"), _("Key Edit"), MB_ERR );
1451     return FALSE;
1452     }
1453     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1454     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1455     return FALSE;
1456     }
1457    
1458     listview_get_item_text( lv, j, 1, buf, sizeof buf -1 );
1459     _snprintf( t, sizeof t -1, _("user ID \"%s\".\n\n"
1460     "Do you really want to delete this user ID?"), buf );
1461     if( msg_box( dlg, t, _("Key Edit"), MB_YESNO|MB_ICONWARNING ) == IDNO )
1462     return FALSE;
1463    
1464     id = do_find_userid( k->keyid, buf );
1465     if( id == -1 )
1466     BUG( dlg );
1467     ec = gpgme_new( &ctx );
1468     if( !ec )
1469     ec = gpgme_editkey_new( &ek );
1470     if( ec )
1471     BUG( dlg );
1472     gpgme_enable_logging( ctx );
1473     gpgme_editkey_deluid_set_id( ek, id );
1474     gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_DELUID );
1475     ec = gpgme_op_editkey( ctx, k->keyid );
1476     if( ec )
1477     gpgme_show_error( dlg, ec, ctx, _("Delete user ID"), MB_ERR );
1478     else {
1479     listview_del_item( lv, j );
1480     keycache_set_reload( 1 );
1481     status_box( dlg, _("User ID successfully deleted"), _("GnuPG Status") );
1482     }
1483     gpgme_editkey_release( ek );
1484     gpgme_release( ctx );
1485     return ec? FALSE : TRUE;
1486     } /* do_editkey_deluid */
1487    
1488    
1489    
1490     static BOOL CALLBACK
1491     subkey_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
1492     {
1493     switch( msg ) {
1494     case WM_KEYUP:
1495     int virt_key = (int)wparam;
1496     switch( virt_key ) {
1497     case VK_DELETE:
1498     SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1499     CB_SETCURSEL, CMD_DELKEY, 0 );
1500     send_cmd_id( keyedit_subkey_proc.dlg, IDOK );
1501     break;
1502    
1503     case VK_INSERT:
1504     SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1505     CB_SETCURSEL, CMD_ADDKEY, 0 );
1506     send_cmd_id( keyedit_subkey_proc.dlg, IDOK );
1507     break;
1508     }
1509     }
1510     return CallWindowProc( keyedit_subkey_proc.old, dlg, msg, wparam, lparam );
1511     } /* subkey_subclass_proc */
1512    
1513    
1514     static BOOL CALLBACK
1515     uid_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
1516     {
1517     switch( msg ) {
1518     case WM_KEYUP:
1519     int virt_key = (int)wparam;
1520     switch( virt_key ) {
1521     case VK_DELETE:
1522     SendDlgItemMessage( keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1523     CB_SETCURSEL, CMD_DELUID, 0 );
1524     send_cmd_id( keyedit_uid_proc.dlg, IDOK );
1525     break;
1526    
1527     case VK_INSERT:
1528     SendDlgItemMessage( keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1529     CB_SETCURSEL, CMD_ADDUID, 0 );
1530     send_cmd_id( keyedit_uid_proc.dlg, IDOK );
1531     break;
1532     }
1533     }
1534     return CallWindowProc( keyedit_uid_proc.old, dlg, msg, wparam, lparam );
1535     } /* uid_subclass_proc */
1536    
1537    
1538     BOOL CALLBACK
1539     keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1540     {
1541     static winpt_key_t k;
1542     static listview_ctrl_t lvsub = NULL, lvuid = NULL;
1543     int cmd, idxsub = 0;
1544     HWND item;
1545    
1546     switch( msg ) {
1547     case WM_INITDIALOG:
1548     k = (winpt_key_t)lparam;
1549     if( !k )
1550     BUG( NULL );
1551     do_init_cmdlist( dlg );
1552     lvsub = subkey_list_init( dlg, k );
1553     if( !lvsub )
1554     BUG( NULL );
1555     lvuid = userid_list_init (dlg, k);
1556     if( !lvuid )
1557     BUG( NULL );
1558     item = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
1559     keyedit_subkey_proc.dlg = dlg;
1560     keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
1561     keyedit_subkey_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );
1562     if( keyedit_subkey_proc.old ) {
1563     if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_subkey_proc.current ) ) {
1564     msg_box( dlg, _("Could not set subkey window procedure."), _("Key Edit"), MB_ERR );
1565     BUG( NULL );
1566     }
1567     }
1568     item = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
1569     keyedit_uid_proc.dlg = dlg;
1570     keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
1571     keyedit_uid_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );
1572     if( keyedit_uid_proc.old ) {
1573     if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_uid_proc.current ) ) {
1574     msg_box( dlg, _("Could not set user ID window procedure."), _("Key Edit"), MB_ERR );
1575     BUG( NULL );
1576     }
1577     }
1578     if (!k->key_pair) {
1579     EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
1580     EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
1581     }
1582     SetForegroundWindow( dlg );
1583     center_window( dlg );
1584     return TRUE;
1585    
1586     case WM_DESTROY:
1587     if( lvsub ) {
1588     listview_release( lvsub );
1589     lvsub = NULL;
1590     }
1591     if( lvuid ) {
1592     listview_release( lvuid );
1593     lvuid = NULL;
1594     }
1595     break;
1596    
1597     case WM_COMMAND:
1598     switch( LOWORD( wparam ) ) {
1599     case IDOK:
1600     cmd = SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0 );
1601     if( cmd == LB_ERR ) {
1602     msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
1603     return FALSE;
1604     }
1605     idxsub = listview_get_curr_pos( lvsub );
1606     if( km_key_is_v3( lvsub, idxsub==-1? 0 : idxsub ) && is_cmd_openpgp( cmd ) ) {
1607     msg_box( dlg, _("This command cannot be used with PGP 2 (v3) keys\n"
1608     " because it is not OpenPGP compliant."),
1609     _("Key Edit"), MB_ERR );
1610     return FALSE;
1611     }
1612     switch( cmd ) {
1613     case CMD_DELKEY: do_editkey_delkey( k, dlg, lvsub ); break;
1614     case CMD_ADDKEY: keyedit_add_subkey( k, dlg, lvsub ); break;
1615     case CMD_EXPIRE: do_editkey_expire( k, dlg, lvsub ); break;
1616     case CMD_REVKEY: do_editkey_revoke( k, dlg, lvsub ); break;
1617     case CMD_UPDPREF:do_editkey_setpref( k, dlg, lvuid ); break;
1618     case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
1619     case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
1620     case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
1621     case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
1622     case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
1623     case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
1624     case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
1625     case CMD_ENABLE: km_enable_disable_key( lvsub, dlg, idxsub, 1 ); break;
1626     case CMD_DISABLE: km_enable_disable_key( lvsub, dlg, idxsub, 0 ); break;
1627     }
1628     break;
1629    
1630     case IDCANCEL:
1631     EndDialog( dlg, FALSE );
1632     break;
1633    
1634     case IDC_KEYEDIT_HELP:
1635     do_show_help( dlg );
1636     break;
1637     }
1638     break;
1639     }
1640     return FALSE;
1641     } /* keyedit_main_dlg_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26