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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 51539 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26