2427{
2428 int needpass = -1;
2429 bool pgp_keyblock = false;
2430 bool clearsign = false;
2431 long bytes;
2432 LOFF_T last_pos;
2433 char buf[8192] = { 0 };
2434 FILE *fp_out = NULL;
2435
2436 gpgme_error_t err = 0;
2437 gpgme_data_t armored_data = NULL;
2438
2439 bool maybe_goodsig = true;
2440 bool have_any_sigs = false;
2441
2442 char body_charset[256] = { 0 };
2443
2445
2446
2447
2449 mutt_str_copy(body_charset,
"iso-8859-1",
sizeof(body_charset));
2450
2452 {
2453 return -1;
2454 }
2456
2457 for (bytes = b->
length; bytes > 0;)
2458 {
2459 if (!fgets(buf,
sizeof(buf), state->
fp_in))
2460 break;
2461
2462 LOFF_T offset = ftello(state->
fp_in);
2463 bytes -= (offset - last_pos);
2464 last_pos = offset;
2465
2467 if (plen != 0)
2468 {
2469 clearsign = false;
2470
2472 {
2473 needpass = 1;
2474 }
2476 {
2477 clearsign = true;
2478 needpass = 0;
2479 }
2481 {
2482 needpass = 0;
2483 pgp_keyblock = true;
2484 }
2485 else
2486 {
2487
2491 continue;
2492 }
2493
2494 have_any_sigs = (have_any_sigs || (clearsign && (state->
flags &
STATE_VERIFY)));
2495
2496
2498
2499 if (pgp_keyblock)
2500 {
2502 }
2504 {
2507
2508 if (clearsign)
2509 {
2510 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2511 }
2512 else
2513 {
2514 err = gpgme_op_decrypt_verify(ctx, armored_data, plaintext);
2515 if (gpg_err_code(err) == GPG_ERR_NO_DATA)
2516 {
2517
2518 gpgme_data_seek(armored_data, 0, SEEK_SET);
2519
2520 gpgme_data_release(plaintext);
2522 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2523 }
2524 }
2526
2527 if (err != 0)
2528 {
2529 char errbuf[200] = { 0 };
2530
2531 snprintf(errbuf, sizeof(errbuf) - 1,
2532 _(
"Error: decryption/verification failed: %s\n"), gpgme_strerror(err));
2534 }
2535 else
2536 {
2537
2538
2540
2541 bool sig_stat = false;
2542 char *tmpfname = NULL;
2543
2544
2545 gpgme_verify_result_t verify_result = gpgme_op_verify_result(ctx);
2546 if (verify_result->signatures)
2547 sig_stat = true;
2548
2549 have_any_sigs = false;
2550 maybe_goodsig = false;
2552 {
2553 int res, idx;
2554 bool anybad = false;
2555
2557 have_any_sigs = true;
2559 {
2560 if (res == 1)
2561 anybad = true;
2562 }
2563 if (!anybad && idx)
2564 maybe_goodsig = true;
2565
2567 }
2568
2570 if (tmpfname)
2571 {
2572 unlink(tmpfname);
2574 }
2575 else
2576 {
2578 state_puts(state,
_(
"Error: copy data failed\n"));
2579 }
2580 }
2581 gpgme_data_release(plaintext);
2582 gpgme_release(ctx);
2583 }
2584
2585
2586
2587
2589 {
2590 if (needpass)
2592 else if (pgp_keyblock)
2594 else
2596 }
2597
2598 if (clearsign)
2599 {
2601 }
2602 else if (fp_out)
2603 {
2604 int c;
2605 rewind(fp_out);
2609 {
2611 if ((c ==
'\n') && state->
prefix)
2613 }
2615 }
2616
2618 {
2620 if (needpass)
2622 else if (pgp_keyblock)
2624 else
2626 }
2627
2628 gpgme_data_release(armored_data);
2630 }
2631 else
2632 {
2633
2634
2638 }
2639 }
2640
2641 b->
goodsig = (maybe_goodsig && have_any_sigs);
2642
2643 if (needpass == -1)
2644 {
2645 state_attach_puts(state,
_(
"[-- Error: could not find beginning of PGP message --]\n\n"));
2646 return 1;
2647 }
2649
2650 return err;
2651}
const char * cc_charset(void)
Get the cached value of $charset.
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 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 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.
static void copy_clearsigned(gpgme_data_t data, struct State *state, char *charset)
Copy a clearsigned message.
static int show_one_sig_status(gpgme_ctx_t ctx, int idx, struct State *state)
Show information about one signature.
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.
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.
void mutt_ch_fgetconv_close(struct FgetConv **ptr)
Close an fgetconv handle.
#define MUTT_ICONV_NO_FLAGS
No flags are set.
void state_attach_puts(struct State *state, const char *t)
Write a string to the state.
#define state_puts(STATE, STR)
#define STATE_DISPLAY
Output is displayed to the user.
#define state_putc(STATE, STR)
#define STATE_VERIFY
Perform signature verification.
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)
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.
StateFlags flags
Flags, e.g. STATE_DISPLAY.
char * prefix
String to add to the beginning of each output line.
FILE * fp_in
File to read from.