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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 195 - (show annotations)
Mon Apr 3 17:10:47 2006 UTC (18 years, 10 months ago) by twoaday
File size: 56550 byte(s)
Prepare new release.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26