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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 160 - (show annotations)
Thu Jan 19 09:22:09 2006 UTC (19 years, 1 month ago) by twoaday
File size: 51106 byte(s)
2006-01-18  Timo Schulz  <ts@g10code.com>
 
        * wptKeyEditCB.cpp (cmd_delsig_handler): Do not assume
        the self sig is always index 0. Noted by Kurt.
        * wptPassphraseCB.cpp (passphrase_dlg_proc): Do not assume
        the key user-ID contains an email address.
        * wptKeyEditDlgs.cpp (do_find_userid): Likewise.
        (do_editkey_deluid): Likewise.
        (do_editkey_revuid): Likewise.
         

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26