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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77 - (hide annotations)
Mon Nov 14 15:01:01 2005 UTC (19 years, 3 months ago) by twoaday
File size: 49431 byte(s)
2005-11-12  Timo Schulz  <ts@g10code.com>
 
        Fix more GCC warnings.
 
2005-11-10  Timo Schulz  <ts@g10code.com>
 
        * wptClipSignDlg.cpp (one_key_proc): Use
        release_gpg_passphrase_cb() to free the context.
        * wptListView.cpp (listview_deselect_all): New.
        * wptMAPI.cpp (mapi_send_pubkey): Works again.
        * wptFileManagerDlg.cpp (file_manager_dlg_proc): Support encrypt &
        zip.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Fix passphrase
        caching for signing operations.
        * wptKeyManager.cpp (km_send_to_mail_recipient): Works again.
        * wptFileManager.cpp (fm_send_file): Likewise.
        (fm_encrypt_into_zip): New.
         

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26