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

Contents of /trunk/Src/wptKeyManager.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: 29944 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26