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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 176 - (hide annotations)
Mon Feb 13 09:38:03 2006 UTC (19 years ago) by twoaday
File size: 55281 byte(s)


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26