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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 180 - (show annotations)
Mon Mar 6 14:41:58 2006 UTC (18 years, 11 months ago) by twoaday
File size: 55360 byte(s)
2006-02-27  Timo Schulz  <twoaday@freakmail.de>
 
        * wptSOCKS.cpp (socks_handshake): New.
        * wptMainProc.cpp (winpt_main_proc): A dbl-click forces
        the key manager in teh foreground if possible.
        * wptHotkey.cpp (hotkey_unregister): Unregister all hotkeys.
        * wptRegistry.cpp (get_reg_proxy_prefs,
        set_reg_proxy_prefs): Use directly the proxy context.
        Changed all callers.
        * wptProxySettingsDlg.cpp (init_proxy_protocols): New.
        (keyserver_proxy_dlg_proc): Use directly the proxy context.
        * wptKeyserver.cpp (kserver_connect): Better proxy support.
        (kserver_send_request, kserver_recvkey_request): Likewise.
        * wptKeyserverDlg.cpp (name_from_proto): New.
        (set_proxy): Adjusted for the new code.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26