23 |
#endif |
#endif |
24 |
#include <windows.h> |
#include <windows.h> |
25 |
#include <assert.h> |
#include <assert.h> |
26 |
|
#include <commctrl.h> |
27 |
|
|
28 |
#include "resource.h" |
#include "resource.h" |
29 |
#include "gpgme.h" |
#include "gpgme.h" |
30 |
#include "GPGOE.h" |
#include "GPGOE.h" |
32 |
|
|
33 |
/* Valid OpenPGP message types. */ |
/* Valid OpenPGP message types. */ |
34 |
enum { |
enum { |
35 |
PGP_MESSAGE = 1, |
PGP_MESSAGE = 1, |
36 |
PGP_CLEARSIG = 2, |
PGP_CLEARSIG = 2, |
37 |
PGP_SIG = 4, |
PGP_SIG = 4, |
38 |
PGP_KEY = 8, |
PGP_KEY = 8, |
39 |
}; |
}; |
40 |
|
|
41 |
|
|
71 |
{ |
{ |
72 |
set_focus (main_hwnd); |
set_focus (main_hwnd); |
73 |
SetForegroundWindow (main_hwnd); |
SetForegroundWindow (main_hwnd); |
74 |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM(ID_OE5_SELECTALL, 0), 0); |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE_SELECTALL, 0), 0); |
75 |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM(ID_OE5_COPY, 0), 0); |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE_COPY, 0), 0); |
76 |
|
|
77 |
/* even so SendMessage() should wait, we wait for safety reasons. */ |
/* even so SendMessage() should wait, we wait for safety reasons. */ |
78 |
Sleep (200); |
Sleep (200); |
89 |
set_clip_text (NULL, msg, strlen (msg)); |
set_clip_text (NULL, msg, strlen (msg)); |
90 |
set_focus (main_hwnd); |
set_focus (main_hwnd); |
91 |
SetForegroundWindow (main_hwnd); |
SetForegroundWindow (main_hwnd); |
92 |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE5_SELECTALL, 0), 0); |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE_SELECTALL, 0), 0); |
93 |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE5_PASTE, 0), 0); |
SendMessage (main_hwnd, WM_COMMAND, MAKEWPARAM (ID_OE_PASTE, 0), 0); |
94 |
} |
} |
95 |
|
|
96 |
|
|
233 |
} |
} |
234 |
|
|
235 |
|
|
236 |
|
/* Create gpgme input data object. If @encode is 1, use UTF8 conversion. */ |
237 |
|
gpgme_error_t |
238 |
|
create_in_data (gpgme_data_t *in, const char *buf, int encode) |
239 |
|
{ |
240 |
|
gpgme_error_t err; |
241 |
|
char *enc_buf; |
242 |
|
|
243 |
|
enc_buf = encode? native_to_utf8 (buf) : xstrdup (buf); |
244 |
|
err = gpgme_data_new_from_mem (in, enc_buf, strlen (enc_buf), 1); |
245 |
|
free_if_alloc (enc_buf); |
246 |
|
return err; |
247 |
|
} |
248 |
|
|
249 |
|
|
250 |
/* Map gpgme data object to a string. */ |
/* Map gpgme data object to a string. */ |
251 |
void |
void |
252 |
map_gpgme_data (gpgme_data_t out, char **r_msg) |
map_gpgme_data (gpgme_data_t out, char **r_msg) |
265 |
/* Try to extract the needed key information and retrieve |
/* Try to extract the needed key information and retrieve |
266 |
the keys if possible. */ |
the keys if possible. */ |
267 |
static gpgme_error_t |
static gpgme_error_t |
268 |
get_keys (plugin_ctx_t ctx, recip_list_t *r_list, |
get_keys (plugin_ctx_t ctx, recip_list_t *r_list, gpgme_key_t **r_keys) |
|
gpgme_key_t **r_keys, int *r_n) |
|
269 |
{ |
{ |
270 |
gpgme_key_t *keys; |
gpgme_key_t *keys; |
271 |
recip_list_t addrs = NULL, n; |
recip_list_t addrs = NULL, n; |
297 |
} |
} |
298 |
*r_list = addrs; |
*r_list = addrs; |
299 |
*r_keys = keys; |
*r_keys = keys; |
|
*r_n = nkeys; |
|
300 |
return 0; |
return 0; |
301 |
} |
} |
302 |
|
|
312 |
gpgme_ctx_t gctx = NULL; |
gpgme_ctx_t gctx = NULL; |
313 |
gpgme_data_t in = NULL, out = NULL; |
gpgme_data_t in = NULL, out = NULL; |
314 |
recip_list_t list = NULL; |
recip_list_t list = NULL; |
|
int nkeys=0; |
|
315 |
char *msg = *r_msg; |
char *msg = *r_msg; |
316 |
|
|
317 |
assert (ctx); |
assert (ctx); |
318 |
|
|
319 |
err = get_keys (ctx, &list, &keys, &nkeys); |
err = get_keys (ctx, &list, &keys); |
320 |
if (err) |
if (err) |
321 |
return err; |
return err; |
322 |
|
|
323 |
err = gpgme_new (&gctx); |
err = gpgme_new (&gctx); |
324 |
if (!err) |
if (!err) |
325 |
err = gpgme_data_new_from_mem (&in, msg, strlen (msg), 1); |
err = create_in_data (&in, msg, ctx->use_utf8); |
326 |
if (!err) |
if (!err) |
327 |
err = gpgme_data_new (&out); |
err = gpgme_data_new (&out); |
328 |
if (!err) { |
if (!err) { |
335 |
gpgme_release (gctx); |
gpgme_release (gctx); |
336 |
gpgme_data_release (in); |
gpgme_data_release (in); |
337 |
release_recipient (list); |
release_recipient (list); |
338 |
free (keys); |
free_if_alloc (keys); |
339 |
|
|
340 |
if (err) |
if (err) |
341 |
gpgme_data_release (out); |
gpgme_data_release (out); |
353 |
gpgme_ctx_t gctx; |
gpgme_ctx_t gctx; |
354 |
gpgme_data_t in, out; |
gpgme_data_t in, out; |
355 |
pass_cb_t cb_val; |
pass_cb_t cb_val; |
356 |
|
int cancel; |
357 |
|
|
358 |
cb_val = new_pass_cb (ctx->main_wnd); |
cb_val = new_pass_cb (ctx->main_wnd); |
359 |
|
|
367 |
err = gpgme_op_sign (gctx, in, out, GPGME_SIG_MODE_CLEAR); |
err = gpgme_op_sign (gctx, in, out, GPGME_SIG_MODE_CLEAR); |
368 |
} |
} |
369 |
|
|
370 |
|
cancel = pass_cb_cancelled (cb_val); |
371 |
|
|
372 |
gpgme_release (gctx); |
gpgme_release (gctx); |
373 |
gpgme_data_release (in); |
gpgme_data_release (in); |
374 |
free_pass_cb (cb_val); |
free_pass_cb (cb_val); |
375 |
|
|
376 |
if (err) |
if (err || cancel) |
377 |
gpgme_data_release (out); |
gpgme_data_release (out); |
378 |
else |
else |
379 |
map_gpgme_data (out, r_msg); |
map_gpgme_data (out, r_msg); |
380 |
|
|
381 |
return err; |
return cancel? 0 : err; |
382 |
} |
} |
383 |
|
|
384 |
|
|
392 |
gpgme_key_t *keys; |
gpgme_key_t *keys; |
393 |
pass_cb_t cb_val; |
pass_cb_t cb_val; |
394 |
recip_list_t list = NULL; |
recip_list_t list = NULL; |
395 |
int ec, nkeys = 0; |
int cancel; |
396 |
|
|
397 |
ec = get_keys (ctx, &list, &keys, &nkeys); |
err = get_keys (ctx, &list, &keys); |
398 |
if (ec) |
if (err) |
399 |
return ec; |
return err; |
400 |
|
|
401 |
cb_val = new_pass_cb (ctx->main_wnd); |
cb_val = new_pass_cb (ctx->main_wnd); |
402 |
|
|
403 |
err = gpgme_new (&gctx); |
err = gpgme_new (&gctx); |
404 |
if (!err) |
if (!err) |
405 |
err = gpgme_data_new_from_mem (&in, *r_msg, strlen (*r_msg), 1); |
err = create_in_data (&in, *r_msg, ctx->use_utf8); |
406 |
if (!err) |
if (!err) |
407 |
err = gpgme_data_new (&out); |
err = gpgme_data_new (&out); |
408 |
if (!err) { |
if (!err) { |
413 |
in, out); |
in, out); |
414 |
} |
} |
415 |
|
|
416 |
|
cancel = pass_cb_cancelled (cb_val); |
417 |
|
|
418 |
gpgme_release (gctx); |
gpgme_release (gctx); |
419 |
gpgme_data_release (in); |
gpgme_data_release (in); |
420 |
release_recipient (list); |
release_recipient (list); |
421 |
free (keys); |
free_if_alloc (keys); |
422 |
free_pass_cb (cb_val); |
free_pass_cb (cb_val); |
423 |
|
|
424 |
if (err) |
if (err || cancel) |
425 |
gpgme_data_release (out); |
gpgme_data_release (out); |
426 |
else |
else |
427 |
map_gpgme_data (out, r_msg); |
map_gpgme_data (out, r_msg); |
428 |
return err; |
return cancel? 0 : err; |
429 |
} |
} |
430 |
|
|
431 |
|
|
483 |
algo = res->recipients->pubkey_algo; |
algo = res->recipients->pubkey_algo; |
484 |
if (!key) |
if (!key) |
485 |
_snprintf (buf, buflen, _("encrypted with %s key, ID %s\n" |
_snprintf (buf, buflen, _("encrypted with %s key, ID %s\n" |
486 |
"decryption failed: secret keyn not available"), |
"decryption failed: secret key not available"), |
487 |
algo == 1? "RSA" : algo==16? "ELG": "???", |
algo == 1? "RSA" : algo==16? "ELG": "???", |
488 |
res->recipients->keyid+8); |
res->recipients->keyid+8); |
489 |
else { |
else { |
490 |
char *uid = utf8_to_native (key->uids->uid); |
char *uid = utf8_to_native (key->uids->uid); |
491 |
_snprintf (buf, buflen, _("encrypted with %d-bit %s key, ID %s\n" |
_snprintf (buf, buflen, _("encrypted with %d-bit %s key, ID %s\n" |
492 |
"\t\"%s\"\n" |
"\t\"%s\"\n" |
493 |
"decryption failed: secret keyn not available"), |
"decryption failed: secret key not available"), |
494 |
key->subkeys->length, |
key->subkeys->length, |
495 |
algo == 1? "RSA" : algo==16? "ELG": "???", |
algo == 1? "RSA" : algo==16? "ELG": "???", |
496 |
key->subkeys->keyid+8, uid); |
key->subkeys->keyid+8, uid); |
501 |
} |
} |
502 |
|
|
503 |
|
|
504 |
|
/* Decrypt the message given in @r_msg. |
505 |
|
The old message will be freed and replaced with the plaintext. */ |
506 |
|
gpgme_error_t |
507 |
|
oe_decrypt_msg (HWND main_wnd, char **r_msg) |
508 |
|
{ |
509 |
|
gpgme_ctx_t gctx = NULL; |
510 |
|
gpgme_data_t in = NULL, out = NULL; |
511 |
|
gpgme_error_t err; |
512 |
|
pass_cb_t cb_val; |
513 |
|
int cancel; |
514 |
|
char *msg = *r_msg; |
515 |
|
|
516 |
|
cb_val = new_pass_cb (main_wnd); |
517 |
|
err = gpgme_new (&gctx); |
518 |
|
if (!err) |
519 |
|
err = gpgme_data_new_from_mem (&in, msg, strlen (msg), 1); |
520 |
|
if (!err) |
521 |
|
err = gpgme_data_new (&out); |
522 |
|
if (!err) { |
523 |
|
gpgme_set_passphrase_cb (gctx, passphrase_cb, cb_val); |
524 |
|
err = gpgme_op_decrypt (gctx, in, out); |
525 |
|
} |
526 |
|
|
527 |
|
cancel = pass_cb_cancelled (cb_val); |
528 |
|
|
529 |
|
gpgme_release (gctx); |
530 |
|
gpgme_data_release (in); |
531 |
|
free_pass_cb (cb_val); |
532 |
|
|
533 |
|
if (err || cancel) |
534 |
|
gpgme_data_release (out); |
535 |
|
else |
536 |
|
map_gpgme_data (out, r_msg); |
537 |
|
|
538 |
|
return cancel? 0 : err; |
539 |
|
} |
540 |
|
|
541 |
|
|
542 |
/* Decrypt the message @r_msg. If the type @type is actually a signature, |
/* Decrypt the message @r_msg. If the type @type is actually a signature, |
543 |
the verify function is called instead of decryption. */ |
the verify function is called instead of decryption. */ |
544 |
static gpgme_error_t |
static gpgme_error_t |
545 |
decrypt_msg (plugin_ctx_t ctx, char **r_msg, int type) |
decrypt_msg (plugin_ctx_t ctx, char **r_msg, int type, int *r_cancel) |
546 |
{ |
{ |
547 |
gpgme_ctx_t gctx = NULL; |
gpgme_ctx_t gctx = NULL; |
548 |
gpgme_data_t in = NULL, out = NULL; |
gpgme_data_t in = NULL, out = NULL; |
569 |
DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_VERIFY, ctx->main_wnd, |
DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_VERIFY, ctx->main_wnd, |
570 |
verify_dlg_proc, (LPARAM)res->signatures); |
verify_dlg_proc, (LPARAM)res->signatures); |
571 |
} |
} |
572 |
if (err) { |
*r_cancel = pass_cb_cancelled (cb_val); |
573 |
|
|
574 |
|
if (!*r_cancel && err) { |
575 |
gpgme_decrypt_result_t r = gpgme_op_decrypt_result (gctx); |
gpgme_decrypt_result_t r = gpgme_op_decrypt_result (gctx); |
576 |
store_decrypt_info (ctx->errbuf, sizeof (ctx->errbuf)-1, r); |
store_decrypt_info (ctx->errbuf, sizeof (ctx->errbuf)-1, r); |
577 |
} |
} |
580 |
gpgme_data_release (in); |
gpgme_data_release (in); |
581 |
free_pass_cb (cb_val); |
free_pass_cb (cb_val); |
582 |
|
|
583 |
if (err) |
if (err || *r_cancel) |
584 |
gpgme_data_release (out); |
gpgme_data_release (out); |
585 |
else |
else |
586 |
map_gpgme_data (out, r_msg); |
map_gpgme_data (out, r_msg); |
587 |
|
|
588 |
return err; |
return *r_cancel? 0 : err; |
589 |
} |
} |
590 |
|
|
591 |
|
|
607 |
} |
} |
608 |
|
|
609 |
|
|
610 |
|
static int |
611 |
|
winpt_key_import (void) |
612 |
|
{ |
613 |
|
HWND winpt; |
614 |
|
|
615 |
|
winpt = FindWindow ("WinPT", "WinPT"); |
616 |
|
if (winpt != NULL) { |
617 |
|
PostMessage (winpt, WM_COMMAND, 40014, 0); |
618 |
|
return 0; |
619 |
|
} |
620 |
|
return -1; |
621 |
|
} |
622 |
|
|
623 |
|
|
624 |
|
/* Try to decrypt a PGP/MIME message. */ |
625 |
|
static gpgme_error_t |
626 |
|
oe_handle_pgp_mime_mail (plugin_ctx_t ctx) |
627 |
|
{ |
628 |
|
SetEvent (plugin_active); |
629 |
|
|
630 |
|
/* Select attachment number 0. */ |
631 |
|
AttachThreadInput (GetCurrentThreadId (), |
632 |
|
GetWindowThreadProcessId (ctx->main_wnd, NULL), |
633 |
|
TRUE); |
634 |
|
|
635 |
|
SetFocus (ctx->addr_wnd); |
636 |
|
SetFocus (ctx->attach); |
637 |
|
ListView_SetItemState (ctx->attach, 0, LVIS_SELECTED|LVIS_FOCUSED, |
638 |
|
LVIS_FOCUSED|LVIS_SELECTED); |
639 |
|
|
640 |
|
AttachThreadInput (GetCurrentThreadId (), |
641 |
|
GetWindowThreadProcessId (ctx->main_wnd, NULL), |
642 |
|
FALSE); |
643 |
|
|
644 |
|
SendMessage (ctx->addr_wnd, WM_COMMAND, ID_OE_SAVE_ATT, 0); |
645 |
|
|
646 |
|
ResetEvent (plugin_active); |
647 |
|
|
648 |
|
return 0; |
649 |
|
} |
650 |
|
|
651 |
|
|
652 |
/* This function can be use for all kind of OE messages. |
/* This function can be use for all kind of OE messages. |
653 |
It automatically choose the right procedure to handle the data. */ |
It automatically choose the right procedure to handle the data. */ |
654 |
gpgme_error_t |
gpgme_error_t |
657 |
gpgme_error_t rc = 0; |
gpgme_error_t rc = 0; |
658 |
char *msg; |
char *msg; |
659 |
int msg_type = 0; |
int msg_type = 0; |
660 |
|
int cancel; |
661 |
|
|
662 |
assert (ctx); |
assert (ctx); |
663 |
|
|
664 |
msg = window_get_message (ctx->main_wnd); |
msg = window_get_message (ctx->main_wnd); |
665 |
|
#if 0 |
666 |
|
if ((!msg || strlen (msg)) < 2 && |
667 |
|
ctx->attach && ListView_GetItemCount (ctx->attach) == 2) { |
668 |
|
free_if_alloc (msg); |
669 |
|
return oe_handle_pgp_mime_mail (ctx); |
670 |
|
} |
671 |
|
#endif |
672 |
if (!msg || strlen (msg) == 2) { |
if (!msg || strlen (msg) == 2) { |
673 |
free_if_alloc (msg); |
free_if_alloc (msg); |
674 |
return 0; |
return 0; |
679 |
msg_type = parse_pgp_id (msg); |
msg_type = parse_pgp_id (msg); |
680 |
|
|
681 |
if (msg_type & PGP_KEY) { |
if (msg_type & PGP_KEY) { |
682 |
MessageBox (ctx->main_wnd, |
if (winpt_key_import ()) |
683 |
|
MessageBox (ctx->main_wnd, |
684 |
_("This mail contains one or more public or secret keys.\n\n" |
_("This mail contains one or more public or secret keys.\n\n" |
685 |
"Please save the mail text in a file to use WinPT to import them."), |
"Please save the mail text in a file to use WinPT to import them."), |
686 |
_("GPG Plug-in Info"), MB_ICONINFORMATION|MB_OK); |
_("GPG Plug-in Info"), MB_ICONINFORMATION|MB_OK); |
687 |
} |
} |
688 |
else if (msg_type) { |
else if (msg_type) { |
689 |
rc = decrypt_msg (ctx, &msg, msg_type); |
rc = decrypt_msg (ctx, &msg, msg_type, &cancel); |
690 |
SendMessage (ctx->msg_wnd, WM_CLEAR, 0, 0); |
SendMessage (ctx->msg_wnd, WM_CLEAR, 0, 0); |
691 |
SendMessage (ctx->msg_wnd, WM_UNDO, 0, 0); |
SendMessage (ctx->msg_wnd, WM_UNDO, 0, 0); |
692 |
if (!rc && (msg_type & PGP_MESSAGE) && msg && strlen (msg) > 0) { |
if (!cancel && !rc && (msg_type & PGP_MESSAGE) |
693 |
|
&& msg && strlen (msg) > 0) { |
694 |
struct viewer_ctx_s viewer; |
struct viewer_ctx_s viewer; |
695 |
viewer.msg = msg; |
viewer.msg = msg; |
696 |
|
viewer.main_wnd = ctx->main_wnd; |
697 |
DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_VIEWER, ctx->main_wnd, |
DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_VIEWER, ctx->main_wnd, |
698 |
viewer_dlg_proc, (LPARAM)&viewer); |
viewer_dlg_proc, (LPARAM)&viewer); |
699 |
} |
} |
700 |
} |
} |
701 |
else { |
else if (ctx->sign || ctx->encrypt) { |
702 |
if (!ctx->to && !ctx->cc && !ctx->bcc) { |
if (!ctx->to && !ctx->cc && !ctx->bcc) { |
703 |
free_if_alloc (msg); |
free_if_alloc (msg); |
704 |
return gpg_error (GPG_ERR_NO_DATA); |
return gpg_error (GPG_ERR_NO_DATA); |