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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 175 - (hide annotations)
Tue Feb 7 08:58:04 2006 UTC (19 years ago) by twoaday
File size: 54617 byte(s)
2006-02-04  Timo Schulz  <ts@g10code.de>
                                                                                                                            
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Check for
        at least one ultimately trusted key.
        * wptKeyManager.cpp (km_refresh_key_from_keyserver):
        Only check inet connection if we refresh all keys.
        * wptGPGUtil.cpp (gpg_extract_keys): New.
        * wptClipEncryptDlg.cpp (clip_encrypt_dlg_proc): Use textmode.
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Likewise.
        * wptClipSignDlg.cpp (get_selected_key): New.
        (one_key_proc): Use it here.
        (count_useable_seckeys): New.
        * wptSigTreeDlg.cpp (sigtree_dlg_proc): New.
        * wptKeyEditDlgs.cpp (diff_time): Removed.
        (w32_mktime): New.
        (keyedit_addsubkey_dlg_proc): Use it here.
                                                                                                                            
2006-02-02  Timo Schulz  <ts@g10code.de>
                                                                                                                            
        * wptW32API.cpp (get_temp_name): New.
        * wptKeyserver.cpp (ldap_recvkey): Use it here.
        * wptKeyPropsDlg.cpp (get_photo_tmpname): Likewise.
        * wptGPGUtil.cpp (create_tempfile): Likewise.
        * wptImportList.cpp (implist_load): Likewise.
        * wptKeyCache.cpp (parse_attr_data): Likewise.
        (w32_tempfile): Removed.
        * wptGPGME.cpp (check_ultimate_trusted_key): New.
                                                                                                                            

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26