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

Contents of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show annotations)
Mon Oct 31 14:04:59 2005 UTC (19 years, 4 months ago) by werner
File size: 29501 byte(s)
Minor changes; compiles now but gettext is still missing.

1 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 * Copyright (C) 2001-2005 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <windows.h>
26 #include <windows.h>
27 #include <commctrl.h>
28 #include <stdio.h>
29
30 #include "gpgme.h"
31 #include "resource.h"
32 #include "wptTypes.h"
33 #include "wptW32API.h"
34 #include "wptVersion.h"
35 #include "wptCommonCtl.h"
36 #include "wptNLS.h"
37 #include "wptErrors.h"
38 #include "wptContext.h"
39 #include "wptGPG.h"
40 #include "wptKeylist.h"
41 #include "wptFileManager.h"
42 #include "wptDlgs.h"
43 #include "wptKeyserver.h"
44 #include "wptKeyManager.h"
45 #include "wptKeylist.h"
46 #include "wptHTTP.h"
47 #include "wptKeyEdit.h"
48 #include "wptImport.h"
49
50
51 /* Return a user friendly key representation in @buf of
52 the key given by @keyid. */
53 static void
54 key_get_clip_info (const char *keyid, char *buf, size_t buflen)
55 {
56 gpgme_key_t pk;
57
58 if (get_pubkey (keyid, &pk))
59 BUG (NULL);
60 _snprintf (buf, buflen-1,
61 "pub %04d%s/%s %s %s\r\n"
62 " Primary key fingerprint: %s\r\n",
63 pk->subkeys->length,
64 get_key_pubalgo (pk->subkeys->pubkey_algo),
65 pk->subkeys->keyid+8,
66 get_key_created (pk->subkeys->timestamp),
67 pk->uids->uid,
68 get_key_fpr (pk));
69 }
70
71
72 #if 0
73 /* Quoted the user-id given by @uid. If @uid is already
74 quoted @uid is returned without any modifications.
75 Return value: quoted @uid. */
76 char*
77 km_quote_uid (const char *uid)
78 {
79 char *q;
80
81 if (*uid == '"' && uid[strlen (uid)-1] == '"')
82 return m_strdup (uid);
83 q = new char[strlen (uid) + 4];
84 if (!q)
85 BUG (NULL);
86 _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
87 return q;
88 }
89 #endif
90
91
92 /* Check if list view @lv contains a secret key at position @pos.
93 If utrust is valid, set it to 1 if the key is valid -1 otherwise.
94 Return value: 1 normal key, 2 smart card key. */
95 int
96 km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
97 {
98 char t[32], t2[64];
99 int type = 0;
100
101 if (utrust)
102 *utrust = 0;
103 listview_get_item_text (lv, pos, 5, t, DIM (t)-1);
104 listview_get_item_text (lv, pos, 2, t2, DIM (t2)-1);
105 if (!strcmp (t2, "pub/sec"))
106 type = 1;
107 else if (!strcmp (t2, "pub/crd"))
108 type = 2;
109 if ((strstr (t, "Expired") || strstr (t, "Revoked")) && utrust)
110 *utrust = -1;
111 else if (stristr (t, "Ultimate") && utrust)
112 *utrust = 1;
113 return type;
114 }
115
116
117 /* Check if the key at position @pos is protected with a passwd. */
118 int
119 km_check_if_protected (listview_ctrl_t lv, int pos)
120 {
121 gpgme_key_t key;
122 winpt_key_s k;
123
124 key = (gpgme_key_t)listview_get_item2 (lv, pos);
125 if (!key)
126 return 1; /* assume yes */
127 winpt_get_pubkey (key->subkeys->keyid, &k);
128 return k.is_protected;
129 }
130
131
132 int
133 km_check_key_status (listview_ctrl_t lv, int pos)
134 {
135 int flags = km_get_key_status (lv, pos);
136
137 if (flags & KM_FLAG_EXPIRED) {
138 msg_box (lv->ctrl, _("This key has expired!\n"
139 "Key check failed."), _("Key Manager"), MB_ERR);
140 return -1;
141 }
142 else if (flags & KM_FLAG_REVOKED) {
143 msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
144 "Key check failed."), _("Key Manager"), MB_ERR);
145 return -1;
146 }
147
148 return 0;
149 } /* km_check_key_status */
150
151
152 int
153 km_get_key_status (listview_ctrl_t lv, int pos)
154 {
155 gpgme_key_t key;
156 int flags = 0;
157
158 if (pos == -1)
159 return 0;
160 key = (gpgme_key_t)listview_get_item2 (lv, pos);
161 if (key == NULL)
162 return 0;
163
164 if (key->expired)
165 flags |= KM_FLAG_EXPIRED;
166 if (key->revoked)
167 flags |= KM_FLAG_REVOKED;
168 if (key->disabled)
169 flags |= KM_FLAG_DISABLED;
170 return flags;
171 } /* km_get_key_status */
172
173
174 /* Interface to enable or disable a key (@enable = 1 then enable).
175 The key is retrieved from a list control @lv at the pos @pos. */
176 int
177 km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
178 {
179 GpgKeyEdit *ke;
180 gpgme_error_t err;
181 char keyid[32];
182
183 listview_get_item_text (lv, pos, 1, keyid, DIM (keyid)-1);
184
185 ke = new GpgKeyEdit (keyid);
186 if (!ke)
187 BUG (NULL);
188
189 err = enable? ke->enable () : ke->disable ();
190 if (!err) {
191 show_msg (dlg, 1500, _("Key status changed."));
192 keycache_set_reload (1); /* XXX: set update flag */
193 }
194 else
195 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
196 delete ke;
197 return err? WPTERR_GENERAL : 0;
198 }
199
200
201
202 /* Create a string that contain all keyids from
203 the key list @rset separated by a space. */
204 char*
205 gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
206 {
207 char *p;
208 int i;
209
210 if (!n)
211 return NULL;
212 p = (char *)calloc (1, n*(16+1)+n+2);
213 if (!p)
214 BUG (NULL);
215 for (i=0; i < n; i++) {
216 strcat (p, rset[i]->subkeys->keyid);
217 strcat (p, " ");
218 }
219 return p;
220 }
221
222
223 /* Export the keys given in @rset to the clipboard.
224 Return value: 0 on success. */
225 static gpgme_error_t
226 gpg_clip_export (gpgme_key_t *rset, int n)
227 {
228 gpgme_error_t err = 0;
229 gpgme_ctx_t ctx = NULL;
230 gpgme_data_t keydata = NULL;
231 char *patt=NULL;
232
233 err = gpgme_new (&ctx);
234 if (err)
235 return err;
236 gpgme_set_armor (ctx, 1);
237 err = gpgme_data_new (&keydata);
238 if (err)
239 goto leave;
240
241 patt = gpg_keylist_to_pattern (rset, n);
242 if (!patt) {
243 err = gpg_error (GPG_ERR_ENOMEM);
244 goto leave;
245 }
246
247 err = gpgme_op_export (ctx, patt, 0, keydata);
248 if (err)
249 goto leave;
250
251 gpg_data_release_and_set_clipboard (keydata, 1);
252
253 leave:
254 if (patt)
255 free (patt);
256 gpgme_release (ctx);
257 return err;
258 }
259
260
261 /* Export the selected keys in @lv to the clipboard. */
262 int
263 km_clip_export (HWND dlg, listview_ctrl_t lv)
264 {
265 gpgme_error_t err;
266 gpgme_key_t *rset;
267 char buf[256];
268 int n=0;
269 int rc=0;
270
271 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
272 if (!n) {
273 msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
274 rc = WPTERR_GENERAL;
275 goto leave;
276 }
277
278 err = gpg_clip_export (rset, n);
279 if (err) {
280 msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
281 rc = WPTERR_GENERAL;
282 goto leave;
283 }
284 if (n == 1) {
285 key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
286 set_clip_text2 (NULL, buf, strlen (buf), 0);
287 }
288
289 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
290
291 leave:
292 free (rset);
293 return rc;
294 } /* km_clip_export */
295
296
297 /* Export the selected secret key from @lv into @fname.
298 It is only allowed to export a single secret key. */
299 int
300 km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
301 {
302 gpgme_key_t *rset;
303 gpgme_error_t err;
304 int n = 0;
305
306 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
307 if (!n) {
308 msg_box (dlg, _("No key was selected for export."),
309 _("Key Manager"), MB_ERR);
310 return WPTERR_GENERAL;
311 }
312 if (n > 1) {
313 msg_box (dlg, _("Only one secret key can be exported."),
314 _("Key Manager"), MB_ERR);
315 free (rset);
316 return 0; /* we checked this before, so we just quit */
317 }
318
319 err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
320 if (err)
321 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
322 else
323 log_box (_("Key Manager"), MB_OK,
324 _("Secret key successfully saved in '%s'."), fname);
325
326 free (rset);
327 return err? WPTERR_GENERAL : 0;
328 }
329
330
331 int
332 km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
333 {
334 gpgme_key_t *rset;
335 gpgme_data_t keydata;
336 gpgme_error_t err;
337 gpgme_ctx_t ctx;
338 char *patt;
339 int n;
340
341 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
342 if (!n) {
343 msg_box (dlg, _("No key was selected for export."),
344 _("Key Manager"), MB_ERR);
345 return WPTERR_GENERAL;
346 }
347
348 err = gpgme_data_new (&keydata);
349 if (err)
350 BUG (NULL);
351 err = gpgme_new (&ctx);
352 if (err)
353 BUG (NULL);
354 gpgme_set_armor (ctx, 1);
355
356 /*gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);*/
357 patt = gpg_keylist_to_pattern (rset, n);
358
359 err = gpgme_op_export( ctx, patt, 0, keydata);
360 if( err ) {
361 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
362 goto leave;
363 }
364
365 log_box( _("Key Manager"), MB_OK,
366 _("Key(s) successfully saved in '%s'."), fname );
367
368 leave:
369 err = gpg_data_release_and_set_file( keydata, fname );
370 if (err)
371 log_box (_("Key Manager"), MB_OK,
372 _("Could not save data to '%s'."), fname);
373 gpgme_release (ctx);
374 free (patt);
375 return (int)err;
376 } /* km_file_export */
377
378
379 static int
380 extract_dash_escaped_key (void)
381 {
382 gpgme_data_t inp, plain;
383 gpgme_error_t err;
384
385 err = gpg_data_new_from_clipboard (&inp, 0);
386 if (err) {
387 msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
388 return -1;
389 }
390 gpg_data_extract_plaintext (inp, &plain);
391 gpg_data_release_and_set_clipboard (plain, 0);
392 gpgme_data_release (inp);
393
394 return 0;
395 } /* extract_dash_escaped_key */
396
397
398 /* Import keys from the clipboard. */
399 int
400 km_clip_import (HWND dlg)
401 {
402 gpgme_error_t err;
403 int pgptype;
404 int id;
405 int has_data = 0;
406
407 if (!gpg_clip_istext_avail (&has_data) && !has_data) {
408 msg_box( dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), _("Key Manager"), MB_ERR);
409 return WPTERR_CLIP_ISEMPTY;
410 }
411 err = gpg_clip_is_secured (&pgptype, &has_data);
412 if (err)
413 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
414 if (!has_data) {
415 msg_box (dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR);
416 return WPTERR_GENERAL;
417 }
418 if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
419 msg_box (dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR);
420 return WPTERR_GENERAL;
421 }
422 if (pgptype & PGP_DASH_ESCAPED) {
423 id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
424 "Do you want to extract the key?"),
425 _("Key Manager"), MB_YESNO);
426 if (id == IDYES)
427 extract_dash_escaped_key ();
428 else
429 msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
430 _("Key Manager"), MB_INFO);
431 }
432
433 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
434 clip_import_dlg_proc, NULL,
435 _("Key Import"), IDS_WINPT_IMPORT);
436
437 return 0;
438 }
439
440
441 /* Import a key from the http URL @url. */
442 int
443 km_http_import (HWND dlg, const char *url)
444 {
445 http_hd_t hd;
446 FILE *fp;
447 char *p;
448 char tmpfile[500];
449 int statcode;
450 int rc = 0;
451
452 if (strncmp (url, "http://", 7)) {
453 log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
454 return WPTERR_GENERAL;
455 }
456
457 GetTempPath (sizeof (tmpfile)-128, tmpfile);
458 p = make_filename (tmpfile, "winpt_file_http", "tmp");
459 if (!p)
460 BUG (0);
461 fp = fopen (p, "wb");
462 if (!fp) {
463 free_if_alloc (p);
464 log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
465 return WPTERR_FILE_CREAT;
466 }
467
468 /* parse URL */
469 rc = http_send_request2 (url, &hd);
470 if (!rc)
471 rc = http_parse_response (hd, &statcode);
472 if (!rc)
473 rc = http_parse_data (hd, fp);
474 http_hd_free (hd);
475 fclose (fp);
476 if (rc) {
477 msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
478 rc = WPTERR_GENERAL;
479 }
480 km_file_import (dlg, p);
481 unlink (p);
482 free_if_alloc (p);
483 return rc;
484 }
485
486
487 /* Import a key from the given file @fname.
488 On success an import statistics dialog is shown. */
489 int
490 km_file_import (HWND dlg, const char *fname)
491 {
492 gpgme_data_t keydata = NULL;
493 gpgme_ctx_t ctx;
494 gpgme_error_t err;
495 fm_state_s fm_stat;
496 gpgme_import_result_t res;
497
498 memset (&fm_stat, 0, sizeof (fm_stat));
499 fm_stat.opaque = m_strdup (fname);
500
501 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
502 file_import_dlg_proc, (LPARAM)&fm_stat,
503 _("File Import"), IDS_WINPT_IMPORT);
504 if (fm_stat.cancel == 1) {
505 free_if_alloc (fm_stat.opaque);
506 return WPTERR_GENERAL;
507 }
508
509 err = gpgme_new (&ctx);
510 if (err)
511 BUG (NULL);
512 err = gpgme_data_new_from_file (&keydata, fname, 1);
513 if (err) {
514 msg_box (dlg, _("Could not read key-data from file."),
515 _("Key Manager"), MB_ERR);
516 goto leave;
517 }
518
519 SetCursor (LoadCursor (NULL, IDC_WAIT));
520 err = gpgme_op_import (ctx, keydata);
521 SetCursor (LoadCursor (NULL, IDC_ARROW));
522 if (err) {
523 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
524 goto leave;
525 }
526
527 res = gpgme_op_import_result (ctx);
528 if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
529 res->new_revocations = 1;
530 if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
531 res->secret_imported = 1;
532
533 print_import_status (res);
534 if (res->no_user_id > 0) {
535 msg_box (dlg, _("Key without a self signature was dectected!\n"
536 "(This key is NOT usable for encryption, etc)\n"
537 "\n"
538 "Cannot import these key(s)!"), _("Import"), MB_INFO);
539 }
540
541 leave:
542 gpgme_data_release (keydata);
543 gpgme_release (ctx);
544 free_if_alloc (fm_stat.opaque);
545 return (int)err;
546 }
547
548
549 /* Mark the keys in @rset as deleted in the keycache. */
550 static void
551 delete_keys_from_cache (gpgme_key_t *rset, size_t n)
552 {
553 gpg_keycache_t pub = keycache_get_ctx (1);
554 int i=0;
555
556 while (n-- > 0)
557 gpg_keycache_delete_key (pub, rset[i++]->subkeys->keyid);
558 }
559
560
561 /* Delete all selected keys from the list view @lv. */
562 int
563 km_delete_keys (listview_ctrl_t lv, HWND dlg)
564 {
565 gpgme_error_t err;
566 gpgme_ctx_t ctx;
567 gpgme_key_t *rset, k;
568 char keyid[32], uid[256], date[64], keylen[64];
569 int with_seckey=0, seckey_type=0, confirm=0;
570 int i, rc, n, k_pos=0;
571
572 if (listview_get_curr_pos (lv) == -1) {
573 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
574 return WPTERR_GENERAL;
575 }
576
577 if (listview_count_items (lv, 1) > 8) {
578 i = msg_box (NULL, _("Do you really want to confirm each key?"),
579 _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
580 if (i == IDCANCEL)
581 return 0;
582 if (i != IDNO)
583 confirm = 1;
584 }
585 else
586 confirm = 1;
587
588 n = listview_count_items (lv, 0);
589 rset = (gpgme_key_t *)calloc (n+1, sizeof (gpgme_key_t));
590 if (!rset)
591 BUG (NULL);
592 for( i = 0; i < n; i++ ) {
593 if( listview_get_item_state( lv, i ) ) {
594 listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
595 listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
596 listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
597 listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
598 seckey_type = km_check_for_seckey (lv, i, NULL);
599 if (confirm && !seckey_type) {
600 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
601 _("Do you really want to delete this key?\n\n"
602 "pub %s %s %s\n"
603 " \"%s\""), keylen, keyid, date, uid );
604 if (rc == IDYES) {
605 get_pubkey (keyid, &k);
606 rset[k_pos++] = k;
607 }
608 with_seckey = 0;
609 }
610 else if (confirm) {
611 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
612 _("Do you really want to delete this KEY PAIR?\n\n"
613 "Please remember that you are not able to decrypt\n"
614 "messages you stored with this key any longer.\n"
615 "\n"
616 "pub/sec %s %s %s\n"
617 " \"%s\""), keylen, keyid, date, uid );
618 if( rc == IDYES ) {
619 if (seckey_type == 2)
620 msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
621 "Only the public key and the secret key \n"
622 "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
623 get_pubkey (keyid, &k);
624 rset[k_pos++] = k;
625 }
626 with_seckey = 1;
627 }
628 else {
629 with_seckey = 1;
630 get_pubkey (keyid, &k);
631 rset[k_pos++] = k;
632 }
633 }
634 }
635
636 if (k_pos == 0) {
637 free (rset);
638 return 0;
639 }
640
641 err = gpgme_new (&ctx);
642 if (err)
643 BUG (NULL);
644 n=k_pos;
645 for (i=0; i < k_pos; i++) {
646 err = gpgme_op_delete (ctx, rset[i], with_seckey);
647 if (err)
648 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
649 else
650 n--;
651 }
652 if (n == 0)
653 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
654 gpgme_release (ctx);
655 listview_del_items (lv);
656 delete_keys_from_cache (rset, k_pos);
657 free (rset);
658
659 return (int)err;
660 }
661
662
663 int
664 km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
665 {
666 char keyid[32];
667 const char *t;
668 int id;
669
670 id = listview_get_curr_pos( lv );
671 if( id == -1 ) {
672 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
673 return WPTERR_GENERAL;
674 }
675
676 listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
677 id = log_box (_("Key Manager"), MB_YESNO,
678 _("Do you really want to send '%s' to keyserver %s?"),
679 keyid, host);
680 if (id == IDYES) {
681 t = keyid;
682 if (!strncmp (keyid, "0x", 2))
683 t += 2;
684 hkp_send_key (dlg, host, port, t);
685 }
686
687 return 0;
688 } /* km_send_to_keyserver */
689
690
691 int
692 km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
693 {
694 #if 0 /*FIXME*/
695 gpgme_key_t key;
696 gpgme_ctx_t ctx=NULL;
697 gpgme_recipients_t rset=NULL;
698 gpgme_error_t rc;
699 const char * s;
700 char keyid[32], tmp[192+256], * p =NULL;
701 int pos;
702
703 if( listview_count_items( lv, 1 ) > 1 ) {
704 msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
705 return WPTERR_GENERAL;
706 }
707 pos = listview_get_curr_pos( lv );
708 if( pos == -1 ) {
709 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
710 return WPTERR_GENERAL;
711 }
712 listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
713 if( get_pubkey( keyid, &key ) )
714 BUG( NULL );
715 s = key->uids->name;
716 GetTempPath (sizeof tmp-1, tmp);
717 strncat (tmp, s, sizeof tmp-200);
718 strncat (tmp, ".asc", sizeof tmp-200);
719 p = fm_quote_file (tmp);
720
721 rc = gpgme_recipients_new (&rset);
722 if (!rc)
723 rc = gpgme_recipients_add_name (rset, keyid);
724 if (!rc)
725 rc = gpgme_new (&ctx);
726 if (!rc) {
727 gpgme_set_armor (ctx, 1);
728 rc = gpgme_op_file_export (ctx, rset, p);
729 }
730 if (rc)
731 msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
732 else
733 mapi_send_pubkey (keyid, tmp);
734
735 free_if_alloc (p);
736 gpgme_recipients_release (rset);
737 gpgme_release (ctx);
738 return rc;
739 #endif
740 return 0;
741 }
742
743
744 static void
745 km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
746 {
747 int idx;
748 char keyid[32];
749 const char *t;
750
751 if (pos != 0)
752 idx = pos;
753 else
754 idx = listview_get_curr_pos (lv);
755 if (idx != -1)
756 {
757 listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
758 t = keyid;
759 if (!strncmp (keyid, "0x", 2))
760 t += 2;
761 hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
762 }
763 }
764
765
766 void
767 km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
768 {
769 int idx, id, i;
770
771 if (kserver_check_inet_connection ())
772 {
773 msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
774 _("Key Manager"), MB_ERR);
775 return;
776 }
777 idx = listview_count_items (lv, 0);
778 if (listview_count_items (lv, 1) == idx) {
779 id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
780 if (id == IDNO)
781 return;
782 for (i = 0; i < idx; i++)
783 km_refresh_one_key (lv, dlg, i);
784 }
785 else if (idx == 1)
786 km_refresh_one_key (lv, dlg, 0);
787 else {
788 for (i=0; i < listview_count_items (lv, 0); i++) {
789 if (listview_get_item_state (lv, i))
790 km_refresh_one_key (lv, dlg, i);
791 }
792 }
793 } /* km_refresh_from_keyserver */
794
795
796 void
797 km_set_clip_info (const char *uid)
798 {
799 char buf[256];
800
801 key_get_clip_info (uid, buf, 255);
802 set_clip_text (NULL, buf, strlen (buf));
803 } /* km_set_clip_info */
804
805
806
807 /* Return TRUE if the key in the list @lv at pos @pos is an
808 old version 3 key. */
809 int
810 km_key_is_v3 (listview_ctrl_t lv, int pos)
811 {
812 gpgme_key_t pk;
813 char keyid[32];
814
815 listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
816 if (get_pubkey (keyid, &pk))
817 BUG (NULL);
818 if (strlen (pk->subkeys->fpr) == 32 &&
819 pk->subkeys->pubkey_algo == GPGME_PK_RSA)
820 return -1;
821 return 0;
822 }
823
824
825 /* Update the default key entry in the status bar for dialog @dlg. */
826 void
827 km_update_default_key_str (HWND dlg)
828 {
829 char *keyid, defkeyinf[512];
830 const char *fmt;
831
832 /* XXX: also show the name? */
833 keyid = get_gnupg_default_key ();
834 if (!keyid)
835 BUG (0);
836 if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
837 || (keyid[0] == '0' && keyid[1] == 'x') )
838 fmt = _("Default Key: %s");
839 else
840 fmt = _("Default Key: 0x%s");
841 _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
842 SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
843 free_if_alloc (keyid);
844 }
845
846
847 /* Count all keys and show from @lv results in the status bar @sb. */
848 void
849 km_complete_status_bar (HWND sb, listview_ctrl_t lv)
850 {
851 char txt_sec[128], txt_pub[128];
852 int nkeys = 0, nsec = 0, i;
853
854 nkeys = listview_count_items (lv, 0);
855 for (i = 0; i < nkeys; i++) {
856 if (km_check_for_seckey (lv, i, NULL))
857 nsec++;
858 }
859 _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
860 _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
861 SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
862 SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
863 }
864
865
866 /* Set trust of selected key in @lv (at @pos) to ultimate. */
867 int
868 km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
869 {
870 GpgKeyEdit *ke;
871 gpgme_error_t err;
872 char keyid[32];
873
874 listview_get_item_text (lv, pos, 1, keyid, 31);
875
876 ke = new GpgKeyEdit (keyid);
877 if (!ke)
878 BUG (0);
879
880 err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
881 if (err)
882 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
883 else
884 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
885
886 delete ke;
887 return (int)err;
888 }
889
890
891 void
892 km_find_key (HWND dlg, listview_ctrl_t lv)
893 {
894 int oldpos = listview_get_curr_pos (lv);
895 int n;
896 char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
897 if (name == NULL)
898 return;
899 if (oldpos < 0)
900 oldpos = 0;
901 n = listview_find (lv, name);
902 if (n != -1) {
903 listview_select_one (lv, n);
904 listview_scroll (lv, oldpos, n);
905 }
906 else {
907 const char *s = _("String pattern \"%s\" not found.");
908 char *p = new char[strlen (s) + strlen (name) + 2];
909 if (!p)
910 BUG (0);
911 sprintf (p, s, name);
912 msg_box (dlg, p, _("Key Manager"), MB_INFO);
913 free_if_alloc (p);
914 }
915 free_if_alloc (name);
916 }
917
918
919
920 void
921 km_dump_key (gpgme_key_t key)
922 {
923 #if _DEBUG
924 log_box ("DEBUG", MB_OK,
925 "%d %d %s %d\n%s", key->subkeys->length,
926 key->subkeys->pubkey_algo,
927 key->subkeys->keyid,
928 key->subkeys->timestamp,
929 key->uids->uid);
930 #endif
931 }
932
933 #if 0
934 gpg_optfile_t
935 km_groupdb_open (void)
936 {
937 gpg_optfile_t opt;
938 char * optfile;
939 int err = 0;
940
941 optfile = get_gnupg_cfgfile();
942 if( !optfile )
943 BUG( NULL );
944 if( parse_gpg_options( optfile, &opt ) )
945 err = 1;
946 free_if_alloc( optfile );
947 return err? NULL : opt;
948 } /* km_groupdb_open */
949
950
951 int
952 km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
953 {
954 gpg_keycache_t kc;
955 gpgme_key_t pk;
956 gpg_optfile_t opt;
957 gpg_group_t grp;
958 gpg_member_t mbr;
959 int no_trust = 0, n;
960
961 kc = keycache_get_ctx( 1 );
962 if( !kc )
963 BUG( NULL );
964
965 opt = km_groupdb_open( );
966 if( !opt )
967 return WPTERR_FILE_OPEN;
968
969 grp = find_group( opt, name );
970 if( !grp )
971 return WPTERR_GENERAL;
972
973 /* we are paranoid and check that all group members exist in the
974 key cache. there is no need that it is really the real key, but
975 an entry should be available. the rest is up to GPG. */
976 for( mbr = grp->list; mbr; mbr = mbr->next ) {
977 if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
978 BUG( NULL );
979 n = count_userids (pk);
980 while( n-- ) {
981 gpgme_user_id_t u = get_nth_userid (pk, n);
982 const char * s = u->uid;
983 if( s && stristr( s, mbr->name )
984 && u->validity < 3 )
985 no_trust++;
986 }
987 }
988
989 gpgme_recipients_add_name( rset, name );
990 release_gpg_options( opt );
991
992 return no_trust;
993 } /* km_groupdb_expand_recipients */
994
995
996 static HTREEITEM
997 km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
998 {
999 TVINSERTSTRUCT tvis;
1000 HTREEITEM node;
1001
1002 memset( &tvis, 0, sizeof tvis );
1003 tvis.hParent = parent;
1004 tvis.hInsertAfter = TVI_LAST;
1005 tvis.item.mask = TVIF_TEXT;
1006 tvis.item.pszText = (char *)text;
1007 node = TreeView_InsertItem( tree, &tvis );
1008 return node;
1009 } /* km_tv_insert_item */
1010
1011
1012 int
1013 km_groups_new( km_group_t *r_gc, HWND ctrl )
1014 {
1015 km_group_t gc;
1016
1017 gc = new km_group_s;
1018 if (!gc)
1019 BUG (NULL);
1020 gc->tree = ctrl;
1021 gc->gh = km_groupdb_open ();
1022 *r_gc = gc;
1023 return 0;
1024 } /* km_groups_new */
1025
1026
1027 void
1028 km_groups_sync( km_group_t gc )
1029 {
1030 char * optfile;
1031
1032 optfile = get_gnupg_cfgfile ();
1033 if( !optfile )
1034 BUG( NULL );
1035 commit_gpg_options( optfile, gc->gh );
1036 free_if_alloc( optfile );
1037 gc->need_sync = 0;
1038 } /* km_groups_sync */
1039
1040
1041 void
1042 km_groups_release (km_group_t gc)
1043 {
1044 if( gc ) {
1045 /* xxx: this reset the default key (sync=1) */
1046 gc->need_sync=0;
1047 if (gc->need_sync)
1048 km_groups_sync (gc);
1049 if (gc->gh)
1050 release_gpg_options( gc->gh );
1051 gc->gh = NULL;
1052 gc->tree = NULL;
1053 delete gc;
1054 }
1055 } /* km_groups_release */
1056
1057
1058 int
1059 km_groups_load( km_group_t gc )
1060 {
1061 HTREEITEM n;
1062 gpg_group_t grp, g;
1063 gpg_member_t mbr;
1064 u32 gid = 0;
1065
1066 if( !gc->gh )
1067 return 0;
1068 grp = gc->gh->grp;
1069 if( !grp )
1070 return 0; /* no groups */
1071
1072 for( g = grp; g; g = g->next ) {
1073 n = km_tv_insert_item( gc->tree, NULL, g->name );
1074 for( mbr = g->list; mbr; mbr = mbr->next ) {
1075 if( mbr->used && mbr->name )
1076 km_tv_insert_item( gc->tree, n, mbr->name );
1077 }
1078 }
1079 DragAcceptFiles( gc->tree, TRUE );
1080 gc->need_sync = 0;
1081 return 0;
1082 } /* km_groups_load */
1083
1084
1085 int
1086 km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1087 {
1088 TVITEM tvi;
1089 char uid[128], valid[64], text[128];
1090 int i_valid;
1091
1092 memset( &tvi, 0, sizeof tvi );
1093 tvi.hItem = TreeView_GetSelection( gc->tree );
1094 tvi.pszText = text;
1095 tvi.cchTextMax = sizeof text -1;
1096 tvi.mask = TVIF_TEXT;
1097 TreeView_GetItem( gc->tree, &tvi );
1098
1099
1100 listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1101 listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1102
1103 if( strstr( valid, "Ultimate" ) )
1104 i_valid = 5;
1105 else if( !strstr( valid, "Full" ) )
1106 i_valid = 4;
1107 else if( !strstr( valid, "Marginal" ) )
1108 i_valid = 3;
1109 else
1110 i_valid = 0;
1111
1112 /* we can't add the full name. one way would be to use the first
1113 text until a space appears.
1114 group_add_entry(&gc->gh, gid, i_valid, uid);
1115 treeview_add_item(gc->tree, tvi.hItem, uid);
1116 */
1117 gc->need_sync = 1;
1118
1119 return 0;
1120 } /* km_groups_add */
1121
1122
1123 static int
1124 km_groups_del_main( km_group_t gc )
1125 {
1126 TVITEM tvi;
1127 char text[128];
1128 int id;
1129
1130 memset( &tvi, 0, sizeof tvi );
1131 tvi.hItem = TreeView_GetSelection( gc->tree );
1132 tvi.pszText = text;
1133 tvi.cchTextMax = sizeof text -1;
1134 tvi.mask = TVIF_TEXT;
1135 TreeView_GetItem( gc->tree, &tvi );
1136
1137 id = log_box( _("Key Manager"), MB_INFO_ASK,
1138 _("Do you really want to delete this group?\n\n%s"), text);
1139 if( id == IDNO )
1140 return 0;
1141 delete_group( gc->gh, text );
1142 TreeView_DeleteItem( gc->tree, &tvi );
1143 gc->need_sync = 1;
1144
1145 return 0;
1146 } /* km_groups_del */
1147
1148
1149 static int
1150 km_groups_del_entry( km_group_t gc )
1151 {
1152 TVITEM tvi;
1153 HTREEITEM root;
1154 int id;
1155 char text[128], info[256];
1156 gpg_group_t grp = NULL;
1157
1158 memset( &tvi, 0, sizeof tvi );
1159 tvi.hItem = TreeView_GetSelection( gc->tree );
1160 tvi.pszText = text;
1161 tvi.cchTextMax = sizeof text-1;
1162 tvi.mask = TVIF_TEXT;
1163 TreeView_GetItem( gc->tree, &tvi );
1164
1165 _snprintf( info, sizeof info -1,
1166 _("Do you really want to delete this entry?\n\n%s"), text );
1167
1168 id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1169 if( id == IDNO )
1170 return 0;
1171
1172 root = TreeView_GetParent( gc->tree, tvi.hItem );
1173 if( root ) {
1174 }
1175
1176 delete_member( gc->gh, /*fixme*/NULL, text );
1177 TreeView_DeleteItem( gc->tree, &tvi );
1178 gc->need_sync = 1;
1179 return 0;
1180 } /* km_groups_del_entry */
1181
1182
1183 int
1184 km_groups_del( km_group_t gc )
1185 {
1186 if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1187 return km_groups_del_entry( gc );
1188 else
1189 return km_groups_del_main( gc );
1190 } /* km_groups_del */
1191 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26