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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 117 - (hide annotations)
Thu Dec 8 09:26:32 2005 UTC (19 years, 2 months ago) by twoaday
File size: 49940 byte(s)
2005-12-07  Timo Schulz  <ts@g10code.com>
 
        * wptOwnertrustDlg.cpp (ownertrust_dlg_proc):
        Use 'Close' instead of 'Exit'.
        * wptKeyEditDlgs.cpp (keyedit_dlg_proc): Likewise.
        * wptGPG.cpp (gnupg_backup_keyrings): Use $APPDATA
        as the destination dir. Thanks to Werner.
        * wptRegistry.cpp (is_gpgee_installed): New.
        (regist_inst_winpt): Do not register file extensions
        if GPGee is available.
        * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Limit
        use of local vars.
        * wptPreferencesDlg.cpp (prefs_dlg_proc): Make sure
        no illegal backup mode is saved.
        * wptKeyserverDlg.cpp (show_imported_key): New.
        (hkp_recv_key2): Show imported keys if the blob
        contained more than one.
         


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26