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

Contents of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations)
Thu Oct 20 12:35:59 2005 UTC (19 years, 4 months ago) by twoaday
File size: 30376 byte(s)
Minor cleanups and prepare the translation.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26