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

Contents of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77 - (show annotations)
Mon Nov 14 15:01:01 2005 UTC (19 years, 3 months ago) by twoaday
File size: 29427 byte(s)
2005-11-12  Timo Schulz  <ts@g10code.com>
 
        Fix more GCC warnings.
 
2005-11-10  Timo Schulz  <ts@g10code.com>
 
        * wptClipSignDlg.cpp (one_key_proc): Use
        release_gpg_passphrase_cb() to free the context.
        * wptListView.cpp (listview_deselect_all): New.
        * wptMAPI.cpp (mapi_send_pubkey): Works again.
        * wptFileManagerDlg.cpp (file_manager_dlg_proc): Support encrypt &
        zip.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Fix passphrase
        caching for signing operations.
        * wptKeyManager.cpp (km_send_to_mail_recipient): Works again.
        * wptFileManager.cpp (fm_send_file): Likewise.
        (fm_encrypt_into_zip): New.
         

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 <commctrl.h>
27 #include <stdio.h>
28
29 #include "gpgme.h"
30 #include "resource.h"
31 #include "wptTypes.h"
32 #include "wptW32API.h"
33 #include "wptVersion.h"
34 #include "wptCommonCtl.h"
35 #include "wptNLS.h"
36 #include "wptErrors.h"
37 #include "wptContext.h"
38 #include "wptGPG.h"
39 #include "wptKeylist.h"
40 #include "wptFileManager.h"
41 #include "wptDlgs.h"
42 #include "wptKeyserver.h"
43 #include "wptKeyManager.h"
44 #include "wptKeylist.h"
45 #include "wptHTTP.h"
46 #include "wptKeyEdit.h"
47 #include "wptImport.h"
48 #include "wptCrypto.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, 0,
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 remove (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 /* Send the selected key in @lv via MAPI to a mail recipient. */
692 int
693 km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg)
694 {
695 gpgme_key_t key;
696 gpgme_ctx_t ctx=NULL;
697 gpgme_data_t out;
698 gpgme_error_t rc;
699 const char *s;
700 char keyid[32], tmp[192+256];
701 int pos;
702
703 if (listview_count_items (lv, 1 ) > 1) {
704 msg_box (dlg, _("Please only select one key."),
705 _("Key Manager"), MB_INFO|MB_OK);
706 return WPTERR_GENERAL;
707 }
708 pos = listview_get_curr_pos (lv);
709 if (pos == -1) {
710 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
711 return WPTERR_GENERAL;
712 }
713 listview_get_item_text(lv, pos, 1, keyid, sizeof keyid-1);
714 if (get_pubkey (keyid, &key))
715 BUG (NULL);
716 s = key->uids->name;
717 GetTempPath (sizeof tmp-1, tmp);
718 strncat (tmp, s, sizeof tmp-200);
719 strncat (tmp, ".asc", sizeof tmp-200);
720
721 rc = gpgme_new (&ctx);
722 if (rc)
723 BUG (NULL);
724 rc = gpgme_data_new (&out);
725 if (rc)
726 BUG (NULL);
727
728 gpgme_set_armor (ctx, 1);
729 rc = gpgme_op_export (ctx, key->subkeys->keyid, 0, out);
730 if (rc)
731 msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
732 else
733 mapi_send_pubkey (keyid, tmp);
734
735 gpg_data_release_and_set_file (out, tmp);
736 gpgme_release (ctx);
737 return rc;
738 }
739
740
741 static void
742 km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
743 {
744 int idx;
745 char keyid[32];
746 const char *t;
747
748 if (pos != 0)
749 idx = pos;
750 else
751 idx = listview_get_curr_pos (lv);
752 if (idx != -1)
753 {
754 listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
755 t = keyid;
756 if (!strncmp (keyid, "0x", 2))
757 t += 2;
758 hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
759 }
760 }
761
762
763 void
764 km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
765 {
766 int idx, id, i;
767
768 if (kserver_check_inet_connection ())
769 {
770 msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
771 _("Key Manager"), MB_ERR);
772 return;
773 }
774 idx = listview_count_items (lv, 0);
775 if (listview_count_items (lv, 1) == idx) {
776 id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
777 if (id == IDNO)
778 return;
779 for (i = 0; i < idx; i++)
780 km_refresh_one_key (lv, dlg, i);
781 }
782 else if (idx == 1)
783 km_refresh_one_key (lv, dlg, 0);
784 else {
785 for (i=0; i < listview_count_items (lv, 0); i++) {
786 if (listview_get_item_state (lv, i))
787 km_refresh_one_key (lv, dlg, i);
788 }
789 }
790 } /* km_refresh_from_keyserver */
791
792
793 void
794 km_set_clip_info (const char *uid)
795 {
796 char buf[256];
797
798 key_get_clip_info (uid, buf, 255);
799 set_clip_text (NULL, buf, strlen (buf));
800 } /* km_set_clip_info */
801
802
803
804 /* Return TRUE if the key in the list @lv at pos @pos is an
805 old version 3 key. */
806 int
807 km_key_is_v3 (listview_ctrl_t lv, int pos)
808 {
809 gpgme_key_t pk;
810 char keyid[32];
811
812 listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
813 if (get_pubkey (keyid, &pk))
814 BUG (NULL);
815 if (strlen (pk->subkeys->fpr) == 32 &&
816 pk->subkeys->pubkey_algo == GPGME_PK_RSA)
817 return -1;
818 return 0;
819 }
820
821
822 /* Update the default key entry in the status bar for dialog @dlg. */
823 void
824 km_update_default_key_str (HWND dlg)
825 {
826 char *keyid, defkeyinf[512];
827 const char *fmt;
828
829 /* XXX: also show the name? */
830 keyid = get_gnupg_default_key ();
831 if (!keyid)
832 return;
833 if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
834 || (keyid[0] == '0' && keyid[1] == 'x') )
835 fmt = _("Default Key: %s");
836 else
837 fmt = _("Default Key: 0x%s");
838 _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
839 SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
840 free_if_alloc (keyid);
841 }
842
843
844 /* Count all keys and show from @lv results in the status bar @sb. */
845 void
846 km_complete_status_bar (HWND sb, listview_ctrl_t lv)
847 {
848 char txt_sec[128], txt_pub[128];
849 int nkeys = 0, nsec = 0, i;
850
851 nkeys = listview_count_items (lv, 0);
852 for (i = 0; i < nkeys; i++) {
853 if (km_check_for_seckey (lv, i, NULL))
854 nsec++;
855 }
856 _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
857 _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
858 SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
859 SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
860 }
861
862
863 /* Set trust of selected key in @lv (at @pos) to ultimate. */
864 int
865 km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
866 {
867 GpgKeyEdit *ke;
868 gpgme_error_t err;
869 char keyid[32];
870
871 listview_get_item_text (lv, pos, 1, keyid, 31);
872
873 ke = new GpgKeyEdit (keyid);
874 if (!ke)
875 BUG (0);
876
877 err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
878 if (err)
879 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
880 else
881 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
882
883 delete ke;
884 return (int)err;
885 }
886
887
888 void
889 km_find_key (HWND dlg, listview_ctrl_t lv)
890 {
891 int oldpos = listview_get_curr_pos (lv);
892 int n;
893 char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
894 if (name == NULL)
895 return;
896 if (oldpos < 0)
897 oldpos = 0;
898 n = listview_find (lv, name);
899 if (n != -1) {
900 listview_select_one (lv, n);
901 listview_scroll (lv, oldpos, n);
902 }
903 else {
904 const char *s = _("String pattern \"%s\" not found.");
905 char *p = new char[strlen (s) + strlen (name) + 2];
906 if (!p)
907 BUG (0);
908 sprintf (p, s, name);
909 msg_box (dlg, p, _("Key Manager"), MB_INFO);
910 free_if_alloc (p);
911 }
912 free_if_alloc (name);
913 }
914
915
916
917 void
918 km_dump_key (gpgme_key_t key)
919 {
920 #if _DEBUG
921 log_box ("DEBUG", MB_OK,
922 "%d %d %s %d\n%s", key->subkeys->length,
923 key->subkeys->pubkey_algo,
924 key->subkeys->keyid,
925 key->subkeys->timestamp,
926 key->uids->uid);
927 #endif
928 }
929
930 #if 0
931 gpg_optfile_t
932 km_groupdb_open (void)
933 {
934 gpg_optfile_t opt;
935 char * optfile;
936 int err = 0;
937
938 optfile = get_gnupg_cfgfile();
939 if( !optfile )
940 BUG( NULL );
941 if( parse_gpg_options( optfile, &opt ) )
942 err = 1;
943 free_if_alloc( optfile );
944 return err? NULL : opt;
945 } /* km_groupdb_open */
946
947
948 int
949 km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
950 {
951 gpg_keycache_t kc;
952 gpgme_key_t pk;
953 gpg_optfile_t opt;
954 gpg_group_t grp;
955 gpg_member_t mbr;
956 int no_trust = 0, n;
957
958 kc = keycache_get_ctx( 1 );
959 if( !kc )
960 BUG( NULL );
961
962 opt = km_groupdb_open( );
963 if( !opt )
964 return WPTERR_FILE_OPEN;
965
966 grp = find_group( opt, name );
967 if( !grp )
968 return WPTERR_GENERAL;
969
970 /* we are paranoid and check that all group members exist in the
971 key cache. there is no need that it is really the real key, but
972 an entry should be available. the rest is up to GPG. */
973 for( mbr = grp->list; mbr; mbr = mbr->next ) {
974 if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
975 BUG( NULL );
976 n = count_userids (pk);
977 while( n-- ) {
978 gpgme_user_id_t u = get_nth_userid (pk, n);
979 const char * s = u->uid;
980 if( s && stristr( s, mbr->name )
981 && u->validity < 3 )
982 no_trust++;
983 }
984 }
985
986 gpgme_recipients_add_name( rset, name );
987 release_gpg_options( opt );
988
989 return no_trust;
990 } /* km_groupdb_expand_recipients */
991
992
993 static HTREEITEM
994 km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
995 {
996 TVINSERTSTRUCT tvis;
997 HTREEITEM node;
998
999 memset( &tvis, 0, sizeof tvis );
1000 tvis.hParent = parent;
1001 tvis.hInsertAfter = TVI_LAST;
1002 tvis.item.mask = TVIF_TEXT;
1003 tvis.item.pszText = (char *)text;
1004 node = TreeView_InsertItem( tree, &tvis );
1005 return node;
1006 } /* km_tv_insert_item */
1007
1008
1009 int
1010 km_groups_new( km_group_t *r_gc, HWND ctrl )
1011 {
1012 km_group_t gc;
1013
1014 gc = new km_group_s;
1015 if (!gc)
1016 BUG (NULL);
1017 gc->tree = ctrl;
1018 gc->gh = km_groupdb_open ();
1019 *r_gc = gc;
1020 return 0;
1021 } /* km_groups_new */
1022
1023
1024 void
1025 km_groups_sync( km_group_t gc )
1026 {
1027 char * optfile;
1028
1029 optfile = get_gnupg_cfgfile ();
1030 if( !optfile )
1031 BUG( NULL );
1032 commit_gpg_options( optfile, gc->gh );
1033 free_if_alloc( optfile );
1034 gc->need_sync = 0;
1035 } /* km_groups_sync */
1036
1037
1038 void
1039 km_groups_release (km_group_t gc)
1040 {
1041 if( gc ) {
1042 /* xxx: this reset the default key (sync=1) */
1043 gc->need_sync=0;
1044 if (gc->need_sync)
1045 km_groups_sync (gc);
1046 if (gc->gh)
1047 release_gpg_options( gc->gh );
1048 gc->gh = NULL;
1049 gc->tree = NULL;
1050 delete gc;
1051 }
1052 } /* km_groups_release */
1053
1054
1055 int
1056 km_groups_load( km_group_t gc )
1057 {
1058 HTREEITEM n;
1059 gpg_group_t grp, g;
1060 gpg_member_t mbr;
1061 u32 gid = 0;
1062
1063 if( !gc->gh )
1064 return 0;
1065 grp = gc->gh->grp;
1066 if( !grp )
1067 return 0; /* no groups */
1068
1069 for( g = grp; g; g = g->next ) {
1070 n = km_tv_insert_item( gc->tree, NULL, g->name );
1071 for( mbr = g->list; mbr; mbr = mbr->next ) {
1072 if( mbr->used && mbr->name )
1073 km_tv_insert_item( gc->tree, n, mbr->name );
1074 }
1075 }
1076 DragAcceptFiles( gc->tree, TRUE );
1077 gc->need_sync = 0;
1078 return 0;
1079 } /* km_groups_load */
1080
1081
1082 int
1083 km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1084 {
1085 TVITEM tvi;
1086 char uid[128], valid[64], text[128];
1087 int i_valid;
1088
1089 memset( &tvi, 0, sizeof tvi );
1090 tvi.hItem = TreeView_GetSelection( gc->tree );
1091 tvi.pszText = text;
1092 tvi.cchTextMax = sizeof text -1;
1093 tvi.mask = TVIF_TEXT;
1094 TreeView_GetItem( gc->tree, &tvi );
1095
1096
1097 listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1098 listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1099
1100 if( strstr( valid, "Ultimate" ) )
1101 i_valid = 5;
1102 else if( !strstr( valid, "Full" ) )
1103 i_valid = 4;
1104 else if( !strstr( valid, "Marginal" ) )
1105 i_valid = 3;
1106 else
1107 i_valid = 0;
1108
1109 /* we can't add the full name. one way would be to use the first
1110 text until a space appears.
1111 group_add_entry(&gc->gh, gid, i_valid, uid);
1112 treeview_add_item(gc->tree, tvi.hItem, uid);
1113 */
1114 gc->need_sync = 1;
1115
1116 return 0;
1117 } /* km_groups_add */
1118
1119
1120 static int
1121 km_groups_del_main( km_group_t gc )
1122 {
1123 TVITEM tvi;
1124 char text[128];
1125 int id;
1126
1127 memset( &tvi, 0, sizeof tvi );
1128 tvi.hItem = TreeView_GetSelection( gc->tree );
1129 tvi.pszText = text;
1130 tvi.cchTextMax = sizeof text -1;
1131 tvi.mask = TVIF_TEXT;
1132 TreeView_GetItem( gc->tree, &tvi );
1133
1134 id = log_box( _("Key Manager"), MB_INFO_ASK,
1135 _("Do you really want to delete this group?\n\n%s"), text);
1136 if( id == IDNO )
1137 return 0;
1138 delete_group( gc->gh, text );
1139 TreeView_DeleteItem( gc->tree, &tvi );
1140 gc->need_sync = 1;
1141
1142 return 0;
1143 } /* km_groups_del */
1144
1145
1146 static int
1147 km_groups_del_entry( km_group_t gc )
1148 {
1149 TVITEM tvi;
1150 HTREEITEM root;
1151 int id;
1152 char text[128], info[256];
1153 gpg_group_t grp = NULL;
1154
1155 memset( &tvi, 0, sizeof tvi );
1156 tvi.hItem = TreeView_GetSelection( gc->tree );
1157 tvi.pszText = text;
1158 tvi.cchTextMax = sizeof text-1;
1159 tvi.mask = TVIF_TEXT;
1160 TreeView_GetItem( gc->tree, &tvi );
1161
1162 _snprintf( info, sizeof info -1,
1163 _("Do you really want to delete this entry?\n\n%s"), text );
1164
1165 id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1166 if( id == IDNO )
1167 return 0;
1168
1169 root = TreeView_GetParent( gc->tree, tvi.hItem );
1170 if( root ) {
1171 }
1172
1173 delete_member( gc->gh, /*fixme*/NULL, text );
1174 TreeView_DeleteItem( gc->tree, &tvi );
1175 gc->need_sync = 1;
1176 return 0;
1177 } /* km_groups_del_entry */
1178
1179
1180 int
1181 km_groups_del( km_group_t gc )
1182 {
1183 if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1184 return km_groups_del_entry( gc );
1185 else
1186 return km_groups_del_main( gc );
1187 } /* km_groups_del */
1188 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26