25 |
|
|
26 |
#include <windows.h> |
#include <windows.h> |
27 |
#include <commctrl.h> |
#include <commctrl.h> |
28 |
|
#include <assert.h> |
29 |
#include <stdio.h> |
#include <stdio.h> |
30 |
|
|
31 |
#include "gpgme.h" |
#include "gpgme.h" |
52 |
#include "wptGPGME.h" |
#include "wptGPGME.h" |
53 |
|
|
54 |
|
|
|
/* Macros to change the cursor */ |
|
|
#define op_begin() SetCursor (LoadCursor (NULL, IDC_WAIT)) |
|
|
#define op_end() SetCursor (LoadCursor (NULL, IDC_ARROW)) |
|
|
|
|
|
|
|
55 |
/* Return a user friendly key representation in @buf of |
/* Return a user friendly key representation in @buf of |
56 |
the key given by @keyid. */ |
the key given by @keyid. */ |
57 |
static void |
static void |
62 |
|
|
63 |
if (get_pubkey (keyid, &pk)) |
if (get_pubkey (keyid, &pk)) |
64 |
BUG (NULL); |
BUG (NULL); |
65 |
uid = utf8_to_wincp2 (pk->uids->uid); |
uid = utf8_to_native (pk->uids->uid); |
66 |
_snprintf (buf, buflen-1, |
_snprintf (buf, buflen-1, |
67 |
"pub %04d%s/%s %s %s\r\n" |
"pub %04d%s/%s %s %s\r\n" |
68 |
" Primary key fingerprint: %s\r\n", |
" Primary key fingerprint: %s\r\n", |
88 |
p = new char[n+1]; |
p = new char[n+1]; |
89 |
if (!p) |
if (!p) |
90 |
BUG (NULL); |
BUG (NULL); |
91 |
uid = utf8_to_wincp2 (pk->uids->uid); |
uid = utf8_to_native (pk->uids->uid); |
92 |
_snprintf (p, n, fmt, is_sec? "sec" : "pub", |
_snprintf (p, n, fmt, is_sec? "sec" : "pub", |
93 |
pk->subkeys->length, |
pk->subkeys->length, |
94 |
get_key_pubalgo2 (pk->subkeys->pubkey_algo), |
get_key_pubalgo2 (pk->subkeys->pubkey_algo), |
99 |
} |
} |
100 |
|
|
101 |
|
|
|
#if 0 |
|
|
/* Quoted the user-id given by @uid. If @uid is already |
|
|
quoted @uid is returned without any modifications. |
|
|
Return value: quoted @uid. */ |
|
|
char* |
|
|
km_quote_uid (const char *uid) |
|
|
{ |
|
|
char *q; |
|
|
|
|
|
if (*uid == '"' && uid[strlen (uid)-1] == '"') |
|
|
return m_strdup (uid); |
|
|
q = new char[strlen (uid) + 4]; |
|
|
if (!q) |
|
|
BUG (NULL); |
|
|
_snprintf (q, strlen (uid) + 3, "\"%s\"", uid); |
|
|
return q; |
|
|
} |
|
|
#endif |
|
|
|
|
|
|
|
102 |
/* Check if list view @lv contains a secret key at position @pos. |
/* Check if list view @lv contains a secret key at position @pos. |
103 |
If utrust is valid, set it to 1 if the key is valid -1 otherwise. |
If utrust is valid, set it to 1 if the key is valid -1 otherwise. |
104 |
Return value: 1 normal key, 2 smart card key. */ |
Return value: 1 normal key, 2 smart card key. */ |
174 |
if (pos == -1) |
if (pos == -1) |
175 |
return 0; |
return 0; |
176 |
key = (gpgme_key_t)listview_get_item2 (lv, pos); |
key = (gpgme_key_t)listview_get_item2 (lv, pos); |
177 |
if (key == NULL) |
if (!key) |
178 |
return 0; |
return 0; |
179 |
|
|
180 |
if (key->expired) |
if (key->expired) |
235 |
} |
} |
236 |
|
|
237 |
|
|
|
/* Export the keys given in @rset to the clipboard. |
|
|
Return value: 0 on success. */ |
|
|
static gpgme_error_t |
|
|
gpg_clip_export (gpgme_key_t *rset, int n) |
|
|
{ |
|
|
gpgme_error_t err = 0; |
|
|
gpgme_ctx_t ctx = NULL; |
|
|
gpgme_data_t keydata = NULL; |
|
|
char *patt=NULL; |
|
|
|
|
|
err = gpgme_new (&ctx); |
|
|
if (err) |
|
|
return err; |
|
|
gpgme_set_armor (ctx, 1); |
|
|
err = gpgme_data_new (&keydata); |
|
|
if (err) |
|
|
goto leave; |
|
|
|
|
|
patt = gpg_keylist_to_pattern (rset, n); |
|
|
if (!patt) { |
|
|
err = gpg_error (GPG_ERR_ENOMEM); |
|
|
goto leave; |
|
|
} |
|
|
|
|
|
err = gpgme_op_export (ctx, patt, 0, keydata); |
|
|
if (err) |
|
|
goto leave; |
|
|
|
|
|
gpg_data_release_and_set_clipboard (keydata, 1); |
|
|
|
|
|
leave: |
|
|
if (patt) |
|
|
free (patt); |
|
|
gpgme_release (ctx); |
|
|
return err; |
|
|
} |
|
|
|
|
|
|
|
238 |
/* Export the selected keys in @lv to the clipboard. */ |
/* Export the selected keys in @lv to the clipboard. */ |
239 |
int |
int |
240 |
km_clip_export (HWND dlg, listview_ctrl_t lv) |
km_clip_export (HWND dlg, listview_ctrl_t lv) |
241 |
{ |
{ |
242 |
gpgme_error_t err; |
gpgme_error_t err; |
243 |
gpgme_key_t *rset; |
gpgme_key_t *rset; |
244 |
|
GPGME *ctx; |
245 |
|
char *patt=NULL; |
246 |
char buf[256]; |
char buf[256]; |
247 |
int n=0; |
int n=0; |
248 |
int rc=0; |
int rc=0; |
251 |
if (!n) { |
if (!n) { |
252 |
msg_box (dlg, _("No key was selected for export."), |
msg_box (dlg, _("No key was selected for export."), |
253 |
_("Key Manager"), MB_ERR); |
_("Key Manager"), MB_ERR); |
254 |
rc = WPTERR_GENERAL; |
return WPTERR_GENERAL; |
|
goto leave; |
|
255 |
} |
} |
256 |
|
|
257 |
err = gpg_clip_export (rset, n); |
patt = gpg_keylist_to_pattern (rset, n); |
258 |
|
|
259 |
|
ctx = new GPGME (); |
260 |
|
if (!ctx) |
261 |
|
BUG (0); |
262 |
|
ctx->setArmor (true); |
263 |
|
err = ctx->exportToClipboard (patt); |
264 |
if (err) { |
if (err) { |
265 |
msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR); |
msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR); |
266 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
267 |
goto leave; |
goto leave; |
268 |
} |
} |
274 |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
275 |
|
|
276 |
leave: |
leave: |
277 |
free (rset); |
safe_free (rset); |
278 |
|
safe_free (patt); |
279 |
|
delete ctx; |
280 |
return rc; |
return rc; |
281 |
} |
} |
282 |
|
|
372 |
} |
} |
373 |
|
|
374 |
|
|
375 |
|
/* Import the PGP key data from the clipboard. |
376 |
|
Return value: 0 on success. */ |
377 |
|
static gpgme_error_t |
378 |
|
gpg_op_clip_import (gpgme_ctx_t ctx) |
379 |
|
{ |
380 |
|
gpgme_error_t err = 0; |
381 |
|
gpgme_data_t keydata = NULL; |
382 |
|
|
383 |
|
err = gpg_data_new_from_clipboard (&keydata, 0); |
384 |
|
if (!err) |
385 |
|
err = gpgme_op_import (ctx, keydata); |
386 |
|
|
387 |
|
gpgme_data_release (keydata); |
388 |
|
return err; |
389 |
|
} |
390 |
|
|
391 |
/* Import keys from the clipboard. */ |
/* Import keys from the clipboard. */ |
392 |
int |
int |
393 |
km_clip_import (HWND dlg, int *r_newkeys) |
km_clip_import (HWND dlg, int *r_newkeys, int *r_newsks) |
394 |
{ |
{ |
395 |
gpgme_error_t err; |
gpgme_error_t err; |
396 |
|
gpgme_ctx_t ctx = NULL; |
397 |
|
gpgme_import_result_t res; |
398 |
|
fm_state_s fm_stat; |
399 |
int pgptype; |
int pgptype; |
400 |
int id; |
int id, has_data = 0; |
401 |
int new_keys = 0, has_data = 0; |
int new_keys = 0, new_sks = 0; |
402 |
|
|
403 |
if (!gpg_clip_istext_avail (&has_data) && !has_data) { |
if (!gpg_clip_istext_avail (&has_data) && !has_data) { |
404 |
msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), |
msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), |
405 |
_("Key Manager"), MB_ERR); |
_("Key Manager"), MB_ERR); |
429 |
_("Key Manager"), MB_INFO); |
_("Key Manager"), MB_INFO); |
430 |
} |
} |
431 |
|
|
432 |
new_keys = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
memset (&fm_stat, 0, sizeof (fm_stat)); |
433 |
clip_import_dlg_proc, 0, |
fm_stat.opaque = m_strdup ("Clipboard"); |
434 |
|
fm_stat.import.is_clip = 1; |
435 |
|
has_data = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
436 |
|
file_import_dlg_proc, (LPARAM)&fm_stat, |
437 |
_("Key Import"), IDS_WINPT_IMPORT); |
_("Key Import"), IDS_WINPT_IMPORT); |
438 |
|
if (!has_data) |
439 |
|
goto leave; |
440 |
|
|
441 |
|
err = gpgme_new (&ctx); |
442 |
|
if (err) |
443 |
|
BUG (NULL); |
444 |
|
op_begin (); |
445 |
|
err = gpg_op_clip_import (ctx); |
446 |
|
op_end (); |
447 |
|
if (err) { |
448 |
|
msg_box (dlg, gpgme_strerror (err), _("Import"), MB_ERR); |
449 |
|
goto leave; |
450 |
|
} |
451 |
|
|
452 |
|
res = gpgme_op_import_result (ctx); |
453 |
|
print_import_status (res); |
454 |
|
new_keys = res->considered - res->unchanged; |
455 |
|
new_sks = res->secret_imported - res->secret_unchanged; |
456 |
|
if (res->no_user_id > 0) { |
457 |
|
msg_box (dlg, _("Key without a self signature was dectected!\n" |
458 |
|
"(This key is NOT usable for encryption, etc)\n"), |
459 |
|
_("Import"), MB_WARN); |
460 |
|
} |
461 |
|
|
462 |
|
leave: |
463 |
|
if (ctx) |
464 |
|
gpgme_release (ctx); |
465 |
|
free_if_alloc (fm_stat.opaque); |
466 |
if (r_newkeys) |
if (r_newkeys) |
467 |
*r_newkeys = new_keys; |
*r_newkeys = new_keys; |
468 |
if (!new_keys) |
if (r_newsks) |
469 |
|
*r_newsks = new_sks; |
470 |
|
if (!new_keys || !has_data) |
471 |
return WPTERR_NODATA; |
return WPTERR_NODATA; |
472 |
return 0; |
return (int)err; |
473 |
} |
} |
474 |
|
|
475 |
|
|
477 |
int |
int |
478 |
km_http_import (HWND dlg, const char *url) |
km_http_import (HWND dlg, const char *url) |
479 |
{ |
{ |
|
http_hd_t hd; |
|
480 |
FILE *fp; |
FILE *fp; |
481 |
char *p; |
wHTTP *hd; |
482 |
char tmpfile[500]; |
char tmpfile[500]; |
|
int statcode; |
|
483 |
int rc = 0; |
int rc = 0; |
484 |
|
|
485 |
if (strncmp (url, "http://", 7)) { |
if (strncmp (url, "http://", 7)) { |
487 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
488 |
} |
} |
489 |
|
|
490 |
GetTempPath (sizeof (tmpfile)-128, tmpfile); |
get_temp_name (tmpfile, sizeof (tmpfile)-1, "winpt_http.tmp"); |
491 |
p = make_filename (tmpfile, "winpt_file_http", "tmp"); |
fp = fopen (tmpfile, "wb"); |
|
if (!p) |
|
|
BUG (0); |
|
|
fp = fopen (p, "wb"); |
|
492 |
if (!fp) { |
if (!fp) { |
493 |
free_if_alloc (p); |
log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", tmpfile, |
|
log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, |
|
494 |
winpt_strerror (WPTERR_FILE_CREAT)); |
winpt_strerror (WPTERR_FILE_CREAT)); |
495 |
return WPTERR_FILE_CREAT; |
return WPTERR_FILE_CREAT; |
496 |
} |
} |
497 |
|
|
498 |
/* parse URL */ |
hd = new wHTTP (url); |
499 |
rc = http_send_request2 (url, &hd); |
if (hd->getStatusCode () == HTTP_STAT_200) |
500 |
if (!rc) |
hd->readData (fp); |
501 |
rc = http_parse_response (hd, &statcode); |
else { |
502 |
if (!rc) |
log_box (_("Key Import HTTP"), MB_ERR, |
503 |
rc = http_parse_data (hd, fp); |
_("Could not fetch key from URL: %s"), url); |
|
http_hd_free (hd); |
|
|
fclose (fp); |
|
|
if (rc) { |
|
|
msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR); |
|
504 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
505 |
} |
} |
506 |
km_file_import (dlg, p, NULL); |
|
507 |
remove (p); |
delete hd; |
508 |
free_if_alloc (p); |
fclose (fp); |
509 |
|
if (!rc) |
510 |
|
km_file_import (dlg, tmpfile, NULL, NULL); |
511 |
|
DeleteFile (tmpfile); |
512 |
return rc; |
return rc; |
513 |
} |
} |
514 |
|
|
515 |
|
|
516 |
/* Import a key from the given file @fname. |
/* Import a key from the given file @fname, if @fname is |
517 |
|
NULL use the common 'file open' dialog. |
518 |
On success an import statistics dialog is shown. */ |
On success an import statistics dialog is shown. */ |
519 |
int |
int |
520 |
km_file_import (HWND dlg, const char *fname, int *r_newkeys) |
km_file_import (HWND dlg, const char *fname, int *r_newkeys, int *r_newsks) |
521 |
{ |
{ |
522 |
gpgme_data_t keydata = NULL; |
gpgme_data_t keydata = NULL; |
523 |
gpgme_ctx_t ctx; |
gpgme_ctx_t ctx; |
524 |
gpgme_error_t err; |
gpgme_error_t err; |
525 |
fm_state_s fm_stat; |
fm_state_s fm_stat; |
526 |
gpgme_import_result_t res; |
gpgme_import_result_t res; |
527 |
|
const char *name; |
528 |
int no_data = 0; |
int no_data = 0; |
529 |
|
int new_keys = 0, new_sks = 0; |
530 |
|
|
531 |
|
if (!fname) { |
532 |
|
name = get_fileopen_dlg (dlg, _("Choose Name of the Key File"), |
533 |
|
NULL, NULL); |
534 |
|
if (!name) |
535 |
|
return WPTERR_GENERAL; |
536 |
|
} |
537 |
|
else |
538 |
|
name = fname; |
539 |
|
|
540 |
memset (&fm_stat, 0, sizeof (fm_stat)); |
memset (&fm_stat, 0, sizeof (fm_stat)); |
541 |
fm_stat.opaque = m_strdup (fname); |
fm_stat.opaque = m_strdup (name); |
542 |
|
|
543 |
dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
544 |
file_import_dlg_proc, (LPARAM)&fm_stat, |
file_import_dlg_proc, (LPARAM)&fm_stat, |
551 |
err = gpgme_new (&ctx); |
err = gpgme_new (&ctx); |
552 |
if (err) |
if (err) |
553 |
BUG (NULL); |
BUG (NULL); |
554 |
err = gpgme_data_new_from_file (&keydata, fname, 1); |
err = gpgme_data_new_from_file (&keydata, name, 1); |
555 |
if (err) { |
if (err) { |
556 |
msg_box (dlg, _("Could not read key-data from file."), |
msg_box (dlg, _("Could not read key-data from file."), |
557 |
_("Key Manager"), MB_ERR); |
_("Key Manager"), MB_ERR); |
567 |
} |
} |
568 |
|
|
569 |
res = gpgme_op_import_result (ctx); |
res = gpgme_op_import_result (ctx); |
570 |
if (res->unchanged == res->considered) |
if (res->unchanged == res->considered && |
571 |
|
res->secret_unchanged == res->secret_imported) |
572 |
no_data = 1; |
no_data = 1; |
573 |
if (r_newkeys) |
new_keys = res->considered - res->unchanged; |
574 |
*r_newkeys = res->considered - res->unchanged; |
new_sks = res->secret_imported - res->secret_unchanged; |
575 |
if (res->new_revocations == 0 && fm_stat.import.revcert == 1) |
if (res->new_revocations == 0 && fm_stat.import.revcert == 1) |
576 |
res->new_revocations = 1; |
res->new_revocations = 1; |
577 |
if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1) |
if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1) |
583 |
print_import_status (res); |
print_import_status (res); |
584 |
if (res->no_user_id > 0) { |
if (res->no_user_id > 0) { |
585 |
msg_box (dlg, _("Key without a self signature was dectected!\n" |
msg_box (dlg, _("Key without a self signature was dectected!\n" |
586 |
"(This key is NOT usable for encryption, etc)\n" |
"(This key is NOT usable for encryption, etc)\n"), |
587 |
"\n" |
_("Import"), MB_WARN); |
|
"Cannot import these key(s)!"), _("Import"), MB_INFO); |
|
588 |
} |
} |
589 |
|
|
590 |
leave: |
leave: |
591 |
gpgme_data_release (keydata); |
gpgme_data_release (keydata); |
592 |
gpgme_release (ctx); |
gpgme_release (ctx); |
593 |
free_if_alloc (fm_stat.opaque); |
free_if_alloc (fm_stat.opaque); |
594 |
|
if (r_newkeys) |
595 |
|
*r_newkeys = new_keys; |
596 |
|
if (r_newsks) |
597 |
|
*r_newsks = new_sks; |
598 |
if (no_data) |
if (no_data) |
599 |
return WPTERR_NODATA; |
return WPTERR_NODATA; |
600 |
return (int)err; |
return (int)err; |
601 |
} |
} |
602 |
|
|
603 |
|
|
604 |
|
/* Import all dropped files. */ |
605 |
|
int |
606 |
|
km_dropped_file_import (HWND dlg, HDROP hdrop, |
607 |
|
int *r_newkeys, int *r_newsks) |
608 |
|
{ |
609 |
|
char name[MAX_PATH+1]; |
610 |
|
UINT n = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); |
611 |
|
UINT i; |
612 |
|
int newk=0, newsk=0, err=0; |
613 |
|
|
614 |
|
for (i=0; i < n; i++) { |
615 |
|
DragQueryFile (hdrop, i, name, MAX_PATH); |
616 |
|
err = km_file_import (dlg, name, &newk, &newsk); |
617 |
|
*r_newkeys = (*r_newkeys) + newk; |
618 |
|
*r_newsks = (*r_newsks) + newsk; |
619 |
|
} |
620 |
|
DragFinish (hdrop); |
621 |
|
return err; |
622 |
|
} |
623 |
|
|
624 |
|
|
625 |
/* Mark the keys in @rset as deleted in the keycache. */ |
/* Mark the keys in @rset as deleted in the keycache. */ |
626 |
static void |
static void |
627 |
delete_keys_from_cache (gpgme_key_t *rset, size_t n) |
delete_keys_from_cache (gpgme_key_t *rset, size_t n) |
640 |
} |
} |
641 |
|
|
642 |
|
|
643 |
|
/* Check that the selected default secret key is still |
644 |
|
available. If not, delete the entry in gpg.conf. */ |
645 |
|
static void |
646 |
|
check_exist_default_key (void) |
647 |
|
{ |
648 |
|
gpgme_key_t sk; |
649 |
|
char *defkey; |
650 |
|
|
651 |
|
defkey = get_gnupg_default_key (); |
652 |
|
if (defkey && get_seckey (defkey, &sk)) |
653 |
|
set_gnupg_default_key (NULL); |
654 |
|
free_if_alloc (defkey); |
655 |
|
} |
656 |
|
|
657 |
|
|
658 |
/* Delete all selected keys from the list view @lv. */ |
/* Delete all selected keys from the list view @lv. */ |
659 |
int |
int |
660 |
km_delete_keys (listview_ctrl_t lv, HWND dlg) |
km_delete_keys (listview_ctrl_t lv, HWND dlg) |
702 |
"%s"), p); |
"%s"), p); |
703 |
if (rc == IDYES) |
if (rc == IDYES) |
704 |
rset[k_pos++] = key; |
rset[k_pos++] = key; |
|
with_seckey = 0; |
|
705 |
free_if_alloc (p); |
free_if_alloc (p); |
706 |
} |
} |
707 |
else if (confirm) { |
else if (confirm) { |
749 |
} |
} |
750 |
op_end (); |
op_end (); |
751 |
if (n == 0) |
if (n == 0) |
752 |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
753 |
gpgme_release (ctx); |
gpgme_release (ctx); |
754 |
listview_del_sel_items (lv); |
listview_del_sel_items (lv); |
755 |
delete_keys_from_cache (rset, k_pos); |
delete_keys_from_cache (rset, k_pos); |
756 |
free (rset); |
free (rset); |
757 |
|
if (with_seckey) |
758 |
|
check_exist_default_key (); |
759 |
return (int)err; |
return (int)err; |
760 |
} |
} |
761 |
|
|
762 |
|
|
763 |
/* Send the select key in @lv to the keyserver @host:@port. */ |
/* Send the select key in @lv to the keyserver @host:@port. */ |
764 |
int |
int |
765 |
km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char *host, u16 port) |
km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, |
766 |
|
const char *host, WORD port) |
767 |
{ |
{ |
768 |
gpgme_key_t key; |
gpgme_key_t key; |
769 |
int id; |
int id; |
778 |
if (!key) |
if (!key) |
779 |
BUG (NULL); |
BUG (NULL); |
780 |
id = log_box (_("Key Manager"), MB_YESNO, |
id = log_box (_("Key Manager"), MB_YESNO, |
781 |
_("Do you really want to send '%s' to keyserver %s?"), |
_("Do you really want to send '0x%s' to keyserver %s?"), |
782 |
key->subkeys->keyid+8, host); |
key->subkeys->keyid+8, host); |
783 |
if (id == IDYES) |
if (id == IDYES) |
784 |
hkp_send_key (dlg, host, port, key->subkeys->keyid+8); |
hkp_send_key (dlg, host, port, key->subkeys->keyid+8); |
792 |
km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg) |
km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg) |
793 |
{ |
{ |
794 |
gpgme_key_t key; |
gpgme_key_t key; |
|
gpgme_ctx_t ctx=NULL; |
|
|
gpgme_data_t out; |
|
795 |
gpgme_error_t rc; |
gpgme_error_t rc; |
796 |
char tmp[128]; |
GPGME *ctx; |
797 |
char *fname; |
char *fname; |
798 |
char *name; |
char *name; |
799 |
int pos; |
int pos; |
800 |
|
int n; |
801 |
|
|
802 |
if (listview_count_items (lv, 1) > 1) { |
if (listview_count_items (lv, 1) > 1) { |
803 |
msg_box (dlg, _("Please only select one key."), |
msg_box (dlg, _("Please only select one key."), |
813 |
if (!key) |
if (!key) |
814 |
BUG (NULL); |
BUG (NULL); |
815 |
|
|
816 |
GetTempPath (sizeof (tmp)-1, tmp); |
name = utf8_to_native (key->uids->name); |
817 |
if (tmp[strlen (tmp)-1] == '\\') |
n = strlen (name)+1 + MAX_PATH + 5; |
818 |
tmp[strlen (tmp)-1] = 0; |
fname = new char[n+1]; |
819 |
name = utf8_to_wincp2 (key->uids->name); |
get_temp_name (fname, n-5, name); |
|
fname = make_filename (tmp, name, "asc"); |
|
820 |
for (pos=0; pos < (int)strlen (fname); pos++) { |
for (pos=0; pos < (int)strlen (fname); pos++) { |
821 |
if (fname[pos] == ' ') |
if (fname[pos] == ' ') |
822 |
fname[pos] = '_'; |
fname[pos] = '_'; |
823 |
} |
} |
824 |
|
strcat (fname, ".asc"); |
825 |
rc = gpgme_new (&ctx); |
ctx = new GPGME (); |
826 |
if (rc) |
ctx->setArmor (true); |
827 |
BUG (NULL); |
rc = ctx->exportToFile (key->subkeys->keyid, fname); |
|
rc = gpgme_data_new (&out); |
|
828 |
if (rc) |
if (rc) |
|
BUG (NULL); |
|
|
|
|
|
gpgme_set_armor (ctx, 1); |
|
|
rc = gpgme_op_export (ctx, key->subkeys->keyid, 0, out); |
|
|
if (rc) { |
|
|
gpgme_data_release (out); |
|
829 |
msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR); |
msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR); |
830 |
} |
else |
|
else { |
|
|
gpg_data_release_and_set_file (out, fname); |
|
831 |
mapi_send_pubkey (key->subkeys->keyid+8, fname); |
mapi_send_pubkey (key->subkeys->keyid+8, fname); |
|
} |
|
832 |
|
|
833 |
gpgme_release (ctx); |
delete ctx; |
834 |
safe_free (name); |
safe_free (name); |
835 |
free_if_alloc (fname); |
free_if_alloc (fname); |
836 |
return rc; |
return rc; |
837 |
} |
} |
838 |
|
|
839 |
|
|
840 |
|
/* Refresh the selected key in the listview @lv at position @pos. |
841 |
|
Legal flags are 0 = single key. */ |
842 |
static void |
static void |
843 |
km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos, int flags) |
km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos, int flags) |
844 |
{ |
{ |
845 |
|
winpt_key_s pk; |
846 |
gpgme_key_t key; |
gpgme_key_t key; |
847 |
int idx; |
const char *pref_kserv = default_keyserver; |
848 |
|
char keyid[16+1]; |
849 |
|
int idx, err = 0; |
850 |
|
|
851 |
if (pos != 0) |
if (pos != 0) |
852 |
idx = pos; |
idx = pos; |
853 |
else |
else |
856 |
key = (gpgme_key_t)listview_get_item2 (lv, idx); |
key = (gpgme_key_t)listview_get_item2 (lv, idx); |
857 |
if (!key) |
if (!key) |
858 |
BUG (0); |
BUG (0); |
859 |
hkp_recv_key (dlg, default_keyserver, default_keyserver_port, |
/* In single refresh mode, try to use the users preferred keyserver. */ |
860 |
key->subkeys->keyid+8, 0, flags); |
if (flags == 0 && |
861 |
|
!winpt_get_pubkey (key->subkeys->keyid+8, &pk) && |
862 |
|
!gpg_keycache_update_attr (pk.ext, KC_ATTR_PREFKSERV, 0) |
863 |
|
&& pk.ext->pref_keyserver) |
864 |
|
pref_kserv = pk.ext->pref_keyserver; |
865 |
|
_snprintf (keyid, sizeof (keyid)-1, "%s", key->subkeys->keyid+8); |
866 |
|
err = hkp_recv_key (dlg, pref_kserv, default_keyserver_port, |
867 |
|
keyid, 0, flags); |
868 |
|
/* if we receive just a single key (no refresh mode), update it. */ |
869 |
|
if (!flags && !err) |
870 |
|
keycache_update (0, keyid); |
871 |
} |
} |
872 |
} |
} |
873 |
|
|
876 |
void |
void |
877 |
km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg) |
km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg) |
878 |
{ |
{ |
879 |
int cnt, id, i; |
int cnt, id, i; |
|
|
|
|
if (kserver_check_inet_connection ()) { |
|
|
msg_box (dlg, _("Could not connect to keyserver, abort procedure."), |
|
|
_("Key Manager"), MB_ERR); |
|
|
return; |
|
|
} |
|
880 |
|
|
881 |
cnt = listview_count_items (lv, 0); |
cnt = listview_count_items (lv, 0); |
882 |
if (listview_count_items (lv, 1) == cnt) { |
if (listview_count_items (lv, 1) == cnt) { |
884 |
_("Key Manager"), MB_YESNO); |
_("Key Manager"), MB_YESNO); |
885 |
if (id == IDNO) |
if (id == IDNO) |
886 |
return; |
return; |
887 |
|
if (kserver_check_inet_connection ()) { |
888 |
|
msg_box (dlg, _("Could not connect to keyserver, abort procedure."), |
889 |
|
_("Key Manager"), MB_ERR); |
890 |
|
return; |
891 |
|
} |
892 |
} |
} |
893 |
if (listview_count_items (lv, 1) == 1) |
if (listview_count_items (lv, 1) == 1) |
894 |
km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0); |
km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0); |
993 |
|
|
994 |
if (get_pubkey (keyid, &key)) |
if (get_pubkey (keyid, &key)) |
995 |
return m_strdup (keyid); |
return m_strdup (keyid); |
996 |
uid = utf8_to_wincp2 (key->uids->name); |
uid = utf8_to_native (key->uids->name); |
997 |
if (!uid) |
if (!uid) |
998 |
return m_strdup (keyid); |
return m_strdup (keyid); |
999 |
p = new char[strlen (uid) + 8 + 16]; |
p = new char[strlen (uid) + 8 + 16]; |
1007 |
safe_free (uid); |
safe_free (uid); |
1008 |
return p; |
return p; |
1009 |
} |
} |
1010 |
|
|
1011 |
|
|
1012 |
|
/* Retrieve the GPGME pointer from the selected list view |
1013 |
|
item and return the WinPT specific key context. */ |
1014 |
|
int |
1015 |
|
km_get_key (listview_ctrl_t lv, int pos, winpt_key_t k) |
1016 |
|
{ |
1017 |
|
gpgme_key_t key; |
1018 |
|
|
1019 |
|
if (pos == -1) |
1020 |
|
return -1; |
1021 |
|
key = (gpgme_key_t)listview_get_item2 (lv, pos); |
1022 |
|
if (!key) |
1023 |
|
BUG (NULL); |
1024 |
|
memset (k, 0, sizeof (*k)); |
1025 |
|
strncpy (k->tmp_keyid, key->subkeys->keyid+8, 8); |
1026 |
|
k->keyid = k->tmp_keyid; |
1027 |
|
k->is_protected = km_check_if_protected (lv, pos); |
1028 |
|
k->key_pair = km_check_for_seckey (lv, pos, NULL); |
1029 |
|
k->is_v3 = km_key_is_v3 (lv, pos); |
1030 |
|
k->flags = km_get_key_status (lv, pos); |
1031 |
|
k->ctx = key; |
1032 |
|
k->uid = key->uids->uid; |
1033 |
|
return 0; |
1034 |
|
} |
1035 |
|
|
1036 |
|
|
1037 |
|
/* Show details of the revocation of the key @k. */ |
1038 |
|
void |
1039 |
|
km_key_show_revoc_info (winpt_key_t k) |
1040 |
|
{ |
1041 |
|
const char *desc; |
1042 |
|
char *val=NULL, *p; |
1043 |
|
int len, reason; |
1044 |
|
const char *reasons[] = { |
1045 |
|
_("0. No reason specified"), |
1046 |
|
_("1. Key has been compromised"), |
1047 |
|
_("2. Key is superseded"), |
1048 |
|
_("3. Key is no longer used"), |
1049 |
|
NULL |
1050 |
|
}; |
1051 |
|
|
1052 |
|
/* spk:29:1:19:%00This key is kaputt */ |
1053 |
|
gpg_find_key_subpacket (k->keyid, 29, &val); |
1054 |
|
if (!val || strlen (val) < 3) { |
1055 |
|
safe_free (val); |
1056 |
|
return; |
1057 |
|
} |
1058 |
|
|
1059 |
|
len = atoi (val+9); |
1060 |
|
p = strchr (val+9, ':'); |
1061 |
|
assert (p); |
1062 |
|
p++; |
1063 |
|
reason = atoi (p+1); |
1064 |
|
if (strlen (p+1) > 0) |
1065 |
|
desc = p+3; |
1066 |
|
else |
1067 |
|
desc = "none"; |
1068 |
|
log_box (_("Key Manager"), MB_OK, |
1069 |
|
"Key revocation info for '%s':\n" |
1070 |
|
"Reason for revocation: %s\n" |
1071 |
|
"Description: %s\n", |
1072 |
|
k->ctx->uids->name, reasons[reason % 4]+3, |
1073 |
|
desc); |
1074 |
|
safe_free (val); |
1075 |
|
} |