425 |
} |
} |
426 |
|
|
427 |
|
|
428 |
|
/* Import the PGP key data from the clipboard. |
429 |
|
Return value: 0 on success. */ |
430 |
|
static gpgme_error_t |
431 |
|
gpg_op_clip_import (gpgme_ctx_t ctx) |
432 |
|
{ |
433 |
|
gpgme_error_t err = 0; |
434 |
|
gpgme_data_t keydata = NULL; |
435 |
|
|
436 |
|
err = gpg_data_new_from_clipboard (&keydata, 0); |
437 |
|
if (!err) |
438 |
|
err = gpgme_op_import (ctx, keydata); |
439 |
|
|
440 |
|
gpgme_data_release (keydata); |
441 |
|
return err; |
442 |
|
} |
443 |
|
|
444 |
/* Import keys from the clipboard. */ |
/* Import keys from the clipboard. */ |
445 |
int |
int |
446 |
km_clip_import (HWND dlg, int *r_newkeys) |
km_clip_import (HWND dlg, int *r_newkeys, int *r_newsks) |
447 |
{ |
{ |
448 |
gpgme_error_t err; |
gpgme_error_t err; |
449 |
|
gpgme_ctx_t ctx = NULL; |
450 |
|
gpgme_import_result_t res; |
451 |
|
fm_state_s fm_stat; |
452 |
int pgptype; |
int pgptype; |
453 |
int id; |
int id, has_data = 0; |
454 |
int new_keys = 0, has_data = 0; |
int new_keys = 0, new_sks = 0; |
455 |
|
|
456 |
if (!gpg_clip_istext_avail (&has_data) && !has_data) { |
if (!gpg_clip_istext_avail (&has_data) && !has_data) { |
457 |
msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), |
msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), |
458 |
_("Key Manager"), MB_ERR); |
_("Key Manager"), MB_ERR); |
482 |
_("Key Manager"), MB_INFO); |
_("Key Manager"), MB_INFO); |
483 |
} |
} |
484 |
|
|
485 |
new_keys = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
memset (&fm_stat, 0, sizeof (fm_stat)); |
486 |
clip_import_dlg_proc, 0, |
fm_stat.opaque = m_strdup ("Clipboard"); |
487 |
|
fm_stat.import.is_clip = 1; |
488 |
|
has_data = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
489 |
|
file_import_dlg_proc, (LPARAM)&fm_stat, |
490 |
_("Key Import"), IDS_WINPT_IMPORT); |
_("Key Import"), IDS_WINPT_IMPORT); |
491 |
|
if (!has_data) |
492 |
|
goto leave; |
493 |
|
|
494 |
|
err = gpgme_new (&ctx); |
495 |
|
if (err) |
496 |
|
BUG (NULL); |
497 |
|
op_begin (); |
498 |
|
err = gpg_op_clip_import (ctx); |
499 |
|
op_end (); |
500 |
|
if (err) { |
501 |
|
msg_box (dlg, gpgme_strerror (err), _("Import"), MB_ERR); |
502 |
|
goto leave; |
503 |
|
} |
504 |
|
|
505 |
|
res = gpgme_op_import_result (ctx); |
506 |
|
print_import_status (res); |
507 |
|
new_keys = res->considered - res->unchanged; |
508 |
|
new_sks = res->secret_imported - res->secret_unchanged; |
509 |
|
if (res->no_user_id > 0) { |
510 |
|
msg_box (dlg, _("Key without a self signature was dectected!\n" |
511 |
|
"(This key is NOT usable for encryption, etc)\n"), |
512 |
|
_("Import"), MB_WARN); |
513 |
|
} |
514 |
|
|
515 |
|
leave: |
516 |
|
if (ctx) |
517 |
|
gpgme_release (ctx); |
518 |
|
free_if_alloc (fm_stat.opaque); |
519 |
if (r_newkeys) |
if (r_newkeys) |
520 |
*r_newkeys = new_keys; |
*r_newkeys = new_keys; |
521 |
if (!new_keys) |
if (r_newsks) |
522 |
|
*r_newsks = new_sks; |
523 |
|
if (!new_keys || !has_data) |
524 |
return WPTERR_NODATA; |
return WPTERR_NODATA; |
525 |
return 0; |
return (int)err; |
526 |
} |
} |
527 |
|
|
528 |
|
|
530 |
int |
int |
531 |
km_http_import (HWND dlg, const char *url) |
km_http_import (HWND dlg, const char *url) |
532 |
{ |
{ |
|
http_hd_t hd; |
|
533 |
FILE *fp; |
FILE *fp; |
534 |
char *p; |
wHTTP *hd; |
535 |
char tmpfile[500]; |
char tmpfile[500]; |
|
int statcode; |
|
536 |
int rc = 0; |
int rc = 0; |
537 |
|
|
538 |
if (strncmp (url, "http://", 7)) { |
if (strncmp (url, "http://", 7)) { |
540 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
541 |
} |
} |
542 |
|
|
543 |
GetTempPath (sizeof (tmpfile)-128, tmpfile); |
get_temp_name (tmpfile, sizeof (tmpfile), "winpt_file_http.tmp"); |
544 |
p = make_filename (tmpfile, "winpt_file_http", "tmp"); |
fp = fopen (tmpfile, "wb"); |
|
if (!p) |
|
|
BUG (0); |
|
|
fp = fopen (p, "wb"); |
|
545 |
if (!fp) { |
if (!fp) { |
546 |
free_if_alloc (p); |
log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", tmpfile, |
|
log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, |
|
547 |
winpt_strerror (WPTERR_FILE_CREAT)); |
winpt_strerror (WPTERR_FILE_CREAT)); |
548 |
return WPTERR_FILE_CREAT; |
return WPTERR_FILE_CREAT; |
549 |
} |
} |
550 |
|
|
551 |
/* parse URL */ |
hd = new wHTTP (url); |
552 |
rc = http_send_request2 (url, &hd); |
if (hd->getStatusCode () == HTTP_STAT_200) |
553 |
if (!rc) |
hd->readData (fp); |
554 |
rc = http_parse_response (hd, &statcode); |
else { |
555 |
if (!rc) |
log_box (_("Key Import HTTP"), MB_ERR, |
556 |
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); |
|
557 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
558 |
} |
} |
559 |
km_file_import (dlg, p, NULL); |
|
560 |
remove (p); |
delete hd; |
561 |
free_if_alloc (p); |
fclose (fp); |
562 |
|
if (!rc) |
563 |
|
km_file_import (dlg, tmpfile, NULL, NULL); |
564 |
|
DeleteFile (tmpfile); |
565 |
return rc; |
return rc; |
566 |
} |
} |
567 |
|
|
568 |
|
|
569 |
/* Import a key from the given file @fname. |
/* Import a key from the given file @fname, if @fname is |
570 |
|
NULL use the common 'file open' dialog. |
571 |
On success an import statistics dialog is shown. */ |
On success an import statistics dialog is shown. */ |
572 |
int |
int |
573 |
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) |
574 |
{ |
{ |
575 |
gpgme_data_t keydata = NULL; |
gpgme_data_t keydata = NULL; |
576 |
gpgme_ctx_t ctx; |
gpgme_ctx_t ctx; |
577 |
gpgme_error_t err; |
gpgme_error_t err; |
578 |
fm_state_s fm_stat; |
fm_state_s fm_stat; |
579 |
gpgme_import_result_t res; |
gpgme_import_result_t res; |
580 |
|
const char *name; |
581 |
int no_data = 0; |
int no_data = 0; |
582 |
|
int new_keys = 0, new_sks = 0; |
583 |
|
|
584 |
|
if (!fname) { |
585 |
|
name = get_fileopen_dlg (dlg, _("Choose Name of the Key File"), |
586 |
|
NULL, NULL); |
587 |
|
if (!name) |
588 |
|
return WPTERR_GENERAL; |
589 |
|
} |
590 |
|
else |
591 |
|
name = fname; |
592 |
|
|
593 |
memset (&fm_stat, 0, sizeof (fm_stat)); |
memset (&fm_stat, 0, sizeof (fm_stat)); |
594 |
fm_stat.opaque = m_strdup (fname); |
fm_stat.opaque = m_strdup (name); |
595 |
|
|
596 |
dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg, |
597 |
file_import_dlg_proc, (LPARAM)&fm_stat, |
file_import_dlg_proc, (LPARAM)&fm_stat, |
604 |
err = gpgme_new (&ctx); |
err = gpgme_new (&ctx); |
605 |
if (err) |
if (err) |
606 |
BUG (NULL); |
BUG (NULL); |
607 |
err = gpgme_data_new_from_file (&keydata, fname, 1); |
err = gpgme_data_new_from_file (&keydata, name, 1); |
608 |
if (err) { |
if (err) { |
609 |
msg_box (dlg, _("Could not read key-data from file."), |
msg_box (dlg, _("Could not read key-data from file."), |
610 |
_("Key Manager"), MB_ERR); |
_("Key Manager"), MB_ERR); |
620 |
} |
} |
621 |
|
|
622 |
res = gpgme_op_import_result (ctx); |
res = gpgme_op_import_result (ctx); |
623 |
if (res->unchanged == res->considered) |
if (res->unchanged == res->considered && |
624 |
|
res->secret_unchanged == res->secret_imported) |
625 |
no_data = 1; |
no_data = 1; |
626 |
if (r_newkeys) |
new_keys = res->considered - res->unchanged; |
627 |
*r_newkeys = res->considered - res->unchanged; |
new_sks = res->secret_imported - res->secret_unchanged; |
628 |
if (res->new_revocations == 0 && fm_stat.import.revcert == 1) |
if (res->new_revocations == 0 && fm_stat.import.revcert == 1) |
629 |
res->new_revocations = 1; |
res->new_revocations = 1; |
630 |
if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1) |
if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1) |
636 |
print_import_status (res); |
print_import_status (res); |
637 |
if (res->no_user_id > 0) { |
if (res->no_user_id > 0) { |
638 |
msg_box (dlg, _("Key without a self signature was dectected!\n" |
msg_box (dlg, _("Key without a self signature was dectected!\n" |
639 |
"(This key is NOT usable for encryption, etc)\n" |
"(This key is NOT usable for encryption, etc)\n"), |
640 |
"\n" |
_("Import"), MB_WARN); |
|
"Cannot import these key(s)!"), _("Import"), MB_INFO); |
|
641 |
} |
} |
642 |
|
|
643 |
leave: |
leave: |
644 |
gpgme_data_release (keydata); |
gpgme_data_release (keydata); |
645 |
gpgme_release (ctx); |
gpgme_release (ctx); |
646 |
free_if_alloc (fm_stat.opaque); |
free_if_alloc (fm_stat.opaque); |
647 |
|
if (r_newkeys) |
648 |
|
*r_newkeys = new_keys; |
649 |
|
if (r_newsks) |
650 |
|
*r_newsks = new_sks; |
651 |
if (no_data) |
if (no_data) |
652 |
return WPTERR_NODATA; |
return WPTERR_NODATA; |
653 |
return (int)err; |
return (int)err; |
654 |
} |
} |
655 |
|
|
656 |
|
|
657 |
|
/* Import all dropped files. */ |
658 |
|
int |
659 |
|
km_dropped_file_import (HWND dlg, HDROP hdrop, |
660 |
|
int *r_newkeys, int *r_newsks) |
661 |
|
{ |
662 |
|
char name[MAX_PATH+1]; |
663 |
|
UINT n = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); |
664 |
|
UINT i; |
665 |
|
int newk=0, newsk=0, err=0; |
666 |
|
|
667 |
|
for (i=0; i < n; i++) { |
668 |
|
DragQueryFile (hdrop, i, name, MAX_PATH); |
669 |
|
err = km_file_import (dlg, name, &newk, &newsk); |
670 |
|
*r_newkeys = (*r_newkeys) + newk; |
671 |
|
*r_newsks = (*r_newsks) + newsk; |
672 |
|
} |
673 |
|
DragFinish (hdrop); |
674 |
|
return err; |
675 |
|
} |
676 |
|
|
677 |
|
|
678 |
/* Mark the keys in @rset as deleted in the keycache. */ |
/* Mark the keys in @rset as deleted in the keycache. */ |
679 |
static void |
static void |
680 |
delete_keys_from_cache (gpgme_key_t *rset, size_t n) |
delete_keys_from_cache (gpgme_key_t *rset, size_t n) |
693 |
} |
} |
694 |
|
|
695 |
|
|
696 |
|
/* Check that the selected default secret key is still |
697 |
|
available. If not, delete the entry in gpg.conf. */ |
698 |
|
static void |
699 |
|
check_exist_default_key (void) |
700 |
|
{ |
701 |
|
gpgme_key_t sk; |
702 |
|
char *defkey; |
703 |
|
|
704 |
|
defkey = get_gnupg_default_key (); |
705 |
|
if (defkey && get_seckey (defkey, &sk)) |
706 |
|
set_gnupg_default_key (NULL); |
707 |
|
free_if_alloc (defkey); |
708 |
|
} |
709 |
|
|
710 |
|
|
711 |
/* Delete all selected keys from the list view @lv. */ |
/* Delete all selected keys from the list view @lv. */ |
712 |
int |
int |
713 |
km_delete_keys (listview_ctrl_t lv, HWND dlg) |
km_delete_keys (listview_ctrl_t lv, HWND dlg) |
803 |
} |
} |
804 |
op_end (); |
op_end (); |
805 |
if (n == 0) |
if (n == 0) |
806 |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
show_msg (dlg, 1500, _("GnuPG Status: Finished")); |
807 |
gpgme_release (ctx); |
gpgme_release (ctx); |
808 |
listview_del_sel_items (lv); |
listview_del_sel_items (lv); |
809 |
delete_keys_from_cache (rset, k_pos); |
delete_keys_from_cache (rset, k_pos); |
810 |
free (rset); |
free (rset); |
811 |
|
if (with_seckey) |
812 |
|
check_exist_default_key (); |
813 |
return (int)err; |
return (int)err; |
814 |
} |
} |
815 |
|
|
816 |
|
|
817 |
/* Send the select key in @lv to the keyserver @host:@port. */ |
/* Send the select key in @lv to the keyserver @host:@port. */ |
818 |
int |
int |
819 |
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, |
820 |
|
const char *host, WORD port) |
821 |
{ |
{ |
822 |
gpgme_key_t key; |
gpgme_key_t key; |
823 |
int id; |
int id; |
846 |
km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg) |
km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg) |
847 |
{ |
{ |
848 |
gpgme_key_t key; |
gpgme_key_t key; |
|
gpgme_ctx_t ctx=NULL; |
|
|
gpgme_data_t out; |
|
849 |
gpgme_error_t rc; |
gpgme_error_t rc; |
850 |
char tmp[128]; |
GPGME *ctx; |
851 |
char *fname; |
char *fname; |
852 |
char *name; |
char *name; |
853 |
int pos; |
int pos; |
854 |
|
int n; |
855 |
|
|
856 |
if (listview_count_items (lv, 1) > 1) { |
if (listview_count_items (lv, 1) > 1) { |
857 |
msg_box (dlg, _("Please only select one key."), |
msg_box (dlg, _("Please only select one key."), |
867 |
if (!key) |
if (!key) |
868 |
BUG (NULL); |
BUG (NULL); |
869 |
|
|
870 |
GetTempPath (sizeof (tmp)-1, tmp); |
name = utf8_to_wincp2 (key->uids->name); |
871 |
if (tmp[strlen (tmp)-1] == '\\') |
n = strlen (name)+1 + MAX_PATH + 5; |
872 |
tmp[strlen (tmp)-1] = 0; |
fname = new char[n+1]; |
873 |
name = utf8_to_wincp2 (key->uids->name); |
get_temp_name (fname, n-5, name); |
|
fname = make_filename (tmp, name, "asc"); |
|
874 |
for (pos=0; pos < (int)strlen (fname); pos++) { |
for (pos=0; pos < (int)strlen (fname); pos++) { |
875 |
if (fname[pos] == ' ') |
if (fname[pos] == ' ') |
876 |
fname[pos] = '_'; |
fname[pos] = '_'; |
877 |
} |
} |
878 |
|
strcat (fname, ".asc"); |
879 |
rc = gpgme_new (&ctx); |
ctx = new GPGME (); |
880 |
|
ctx->setArmor (true); |
881 |
|
rc = ctx->exportToFile (key->subkeys->keyid, fname); |
882 |
if (rc) |
if (rc) |
|
BUG (NULL); |
|
|
rc = gpgme_data_new (&out); |
|
|
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); |
|
883 |
msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR); |
msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR); |
884 |
} |
else |
|
else { |
|
|
gpg_data_release_and_set_file (out, fname); |
|
885 |
mapi_send_pubkey (key->subkeys->keyid+8, fname); |
mapi_send_pubkey (key->subkeys->keyid+8, fname); |
|
} |
|
886 |
|
|
887 |
gpgme_release (ctx); |
delete ctx; |
888 |
safe_free (name); |
safe_free (name); |
889 |
free_if_alloc (fname); |
free_if_alloc (fname); |
890 |
return rc; |
return rc; |
891 |
} |
} |
892 |
|
|
893 |
|
|
894 |
|
/* Refresh the selected key in the listview @lv at position @pos. |
895 |
|
Legal flags are 0 = single key. */ |
896 |
static void |
static void |
897 |
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) |
898 |
{ |
{ |
899 |
|
winpt_key_s pk; |
900 |
gpgme_key_t key; |
gpgme_key_t key; |
901 |
int idx; |
const char *pref_kserv = default_keyserver; |
902 |
|
char keyid[16+1]; |
903 |
|
int idx, err = 0; |
904 |
|
|
905 |
if (pos != 0) |
if (pos != 0) |
906 |
idx = pos; |
idx = pos; |
907 |
else |
else |
910 |
key = (gpgme_key_t)listview_get_item2 (lv, idx); |
key = (gpgme_key_t)listview_get_item2 (lv, idx); |
911 |
if (!key) |
if (!key) |
912 |
BUG (0); |
BUG (0); |
913 |
hkp_recv_key (dlg, default_keyserver, default_keyserver_port, |
/* In single refresh mode, try to use the users preferred keyserver. */ |
914 |
key->subkeys->keyid+8, 0, flags); |
if (flags == 0 && |
915 |
|
!winpt_get_pubkey (key->subkeys->keyid+8, &pk) && |
916 |
|
!gpg_keycache_update_attr (pk.ext, KC_ATTR_PREFKSERV, 0)) |
917 |
|
pref_kserv = pk.ext->pref_keyserver; |
918 |
|
_snprintf (keyid, sizeof (keyid)-1, "%s", key->subkeys->keyid+8); |
919 |
|
err = hkp_recv_key (dlg, pref_kserv, default_keyserver_port, |
920 |
|
keyid, 0, flags); |
921 |
|
/* if we receive just a single key (no refresh mode), update it. */ |
922 |
|
if (!flags && !err) |
923 |
|
keycache_update (0, keyid); |
924 |
} |
} |
925 |
} |
} |
926 |
|
|
929 |
void |
void |
930 |
km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg) |
km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg) |
931 |
{ |
{ |
932 |
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; |
|
|
} |
|
933 |
|
|
934 |
cnt = listview_count_items (lv, 0); |
cnt = listview_count_items (lv, 0); |
935 |
if (listview_count_items (lv, 1) == cnt) { |
if (listview_count_items (lv, 1) == cnt) { |
937 |
_("Key Manager"), MB_YESNO); |
_("Key Manager"), MB_YESNO); |
938 |
if (id == IDNO) |
if (id == IDNO) |
939 |
return; |
return; |
940 |
|
if (kserver_check_inet_connection ()) { |
941 |
|
msg_box (dlg, _("Could not connect to keyserver, abort procedure."), |
942 |
|
_("Key Manager"), MB_ERR); |
943 |
|
return; |
944 |
|
} |
945 |
} |
} |
946 |
if (listview_count_items (lv, 1) == 1) |
if (listview_count_items (lv, 1) == 1) |
947 |
km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0); |
km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0); |