2415{
2416 int needpass = -1;
2417 bool pgp_keyblock = false;
2418 bool clearsign = false;
2419 long bytes;
2420 LOFF_T last_pos;
2421 char buf[8192] = { 0 };
2422 FILE *fp_out = NULL;
2423
2424 gpgme_error_t err = 0;
2425 gpgme_data_t armored_data = NULL;
2426
2427 bool maybe_goodsig = true;
2428 bool have_any_sigs = false;
2429
2430 char body_charset[256] = { 0 };
2431
2433
2434
2435
2437 mutt_str_copy(body_charset,
"iso-8859-1",
sizeof(body_charset));
2438
2440 {
2441 return -1;
2442 }
2444
2445 for (bytes = m->
length; bytes > 0;)
2446 {
2447 if (!fgets(buf,
sizeof(buf), s->
fp_in))
2448 break;
2449
2450 LOFF_T offset = ftello(s->
fp_in);
2451 bytes -= (offset - last_pos);
2452 last_pos = offset;
2453
2456 {
2457 clearsign = false;
2458
2460 needpass = 1;
2462 {
2463 clearsign = true;
2464 needpass = 0;
2465 }
2467 {
2468 needpass = 0;
2469 pgp_keyblock = true;
2470 }
2471 else
2472 {
2473
2477 continue;
2478 }
2479
2480 have_any_sigs = (have_any_sigs || (clearsign && (s->
flags &
MUTT_VERIFY)));
2481
2482
2484
2485 if (pgp_keyblock)
2486 {
2488 }
2490 {
2493
2494 if (clearsign)
2495 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2496 else
2497 {
2498 err = gpgme_op_decrypt_verify(ctx, armored_data, plaintext);
2499 if (gpg_err_code(err) == GPG_ERR_NO_DATA)
2500 {
2501
2502 gpgme_data_seek(armored_data, 0, SEEK_SET);
2503
2504 gpgme_data_release(plaintext);
2506 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2507 }
2508 }
2510
2511 if (err != 0)
2512 {
2513 char errbuf[200] = { 0 };
2514
2515 snprintf(errbuf, sizeof(errbuf) - 1,
2516 _(
"Error: decryption/verification failed: %s\n"), gpgme_strerror(err));
2518 }
2519 else
2520 {
2521
2522
2524
2525 bool sig_stat = false;
2526 char *tmpfname = NULL;
2527
2528 {
2529
2530 gpgme_verify_result_t verify_result = gpgme_op_verify_result(ctx);
2531 if (verify_result->signatures)
2532 sig_stat = true;
2533 }
2534
2535 have_any_sigs = false;
2536 maybe_goodsig = false;
2538 {
2539 int res, idx;
2540 bool anybad = false;
2541
2543 have_any_sigs = true;
2545 {
2546 if (res == 1)
2547 anybad = true;
2548 }
2549 if (!anybad && idx)
2550 maybe_goodsig = true;
2551
2553 }
2554
2556 if (tmpfname)
2557 {
2558 unlink(tmpfname);
2560 }
2561 else
2562 {
2565 }
2566 }
2567 gpgme_data_release(plaintext);
2568 gpgme_release(ctx);
2569 }
2570
2571
2572
2573
2575 {
2576 if (needpass)
2578 else if (pgp_keyblock)
2580 else
2582 }
2583
2584 if (clearsign)
2585 {
2587 }
2588 else if (fp_out)
2589 {
2590 int c;
2591 rewind(fp_out);
2596 {
2598 if ((c ==
'\n') && s->
prefix)
2600 }
2602 }
2603
2605 {
2607 if (needpass)
2609 else if (pgp_keyblock)
2611 else
2613 }
2614
2615 gpgme_data_release(armored_data);
2617 }
2618 else
2619 {
2620
2621
2625 }
2626 }
2627
2628 m->
goodsig = (maybe_goodsig && have_any_sigs);
2629
2630 if (needpass == -1)
2631 {
2632 state_attach_puts(s,
_(
"[-- Error: could not find beginning of PGP message --]\n\n"));
2633 return 1;
2634 }
2636
2637 return err;
2638}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
static gpgme_data_t create_gpgme_data(void)
Create a new GPGME data object.
gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
#define SIGNED_MESSAGE(_y)
static int show_one_sig_status(gpgme_ctx_t ctx, int idx, struct State *s)
Show information about one signature.
static gpgme_data_t file_to_data_object(FILE *fp, long offset, size_t length)
Create GPGME data object from file.
#define PUBLIC_KEY_BLOCK(_y)
static char * data_object_to_tempfile(gpgme_data_t data, FILE **fp_ret)
Copy a data object to a temporary file.
static void copy_clearsigned(gpgme_data_t data, struct State *s, char *charset)
Copy a clearsigned message.
static void redraw_if_needed(gpgme_ctx_t ctx)
Accommodate for a redraw if needed.
static int pgp_gpgme_extract_keys(gpgme_data_t keydata, FILE **fp)
Write PGP keys to a file.
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body's character set.
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
#define mutt_message(...)
#define mutt_debug(LEVEL,...)
@ LL_DEBUG2
Log at debug level 2.
void mutt_ch_fgetconv_close(struct FgetConv **fc)
Close an fgetconv handle.
int mutt_ch_fgetconv(struct FgetConv *fc)
Convert a file's character set.
struct FgetConv * mutt_ch_fgetconv_open(FILE *fp, const char *from, const char *to, uint8_t flags)
Prepare a file for charset conversion.
#define MUTT_ICONV_NO_FLAGS
No flags are set.
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
#define state_puts(STATE, STR)
#define MUTT_VERIFY
Perform signature verification.
#define state_putc(STATE, STR)
#define MUTT_DISPLAY
Output is displayed to the user.
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
static size_t plen
Length of cached packet.
LOFF_T offset
offset where the actual data begins
LOFF_T length
length (in bytes) of attachment
bool goodsig
Good cryptographic signature.
Cursor for converting a file's encoding.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
char * prefix
String to add to the beginning of each output line.
FILE * fp_in
File to read from.