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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (show annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 56034 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26