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

Annotation of /trunk/Src/wptKeyEditDlgs.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: 48365 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26