mutt stable branch with some hacks
at master 1865 lines 44 kB view raw
1/* 2 * Copyright (C) 1996-1997,2000,2010 Michael R. Elkins <me@mutt.org> 3 * Copyright (C) 1998-2005 Thomas Roessler <roessler@does-not-exist.org> 4 * Copyright (C) 2004 g10 Code GmbH 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21/* 22 * This file contains all of the PGP routines necessary to sign, encrypt, 23 * verify and decrypt PGP messages in either the new PGP/MIME format, or 24 * in the older Application/Pgp format. It also contains some code to 25 * cache the user's passphrase for repeat use when decrypting or signing 26 * a message. 27 */ 28 29#if HAVE_CONFIG_H 30# include "config.h" 31#endif 32 33#include "mutt.h" 34#include "mutt_crypt.h" 35#include "mutt_curses.h" 36#include "pgp.h" 37#include "mime.h" 38#include "copy.h" 39 40#include <sys/wait.h> 41#include <string.h> 42#include <stdlib.h> 43#include <unistd.h> 44#include <sys/stat.h> 45#include <errno.h> 46#include <ctype.h> 47 48#ifdef HAVE_LOCALE_H 49#include <locale.h> 50#endif 51 52#ifdef HAVE_SYS_TIME_H 53# include <sys/time.h> 54#endif 55 56#ifdef HAVE_SYS_RESOURCE_H 57# include <sys/resource.h> 58#endif 59 60#ifdef CRYPT_BACKEND_CLASSIC_PGP 61 62#include "mutt_crypt.h" 63#include "mutt_menu.h" 64 65 66char PgpPass[LONG_STRING]; 67time_t PgpExptime = 0; /* when does the cached passphrase expire? */ 68 69void pgp_void_passphrase (void) 70{ 71 memset (PgpPass, 0, sizeof (PgpPass)); 72 PgpExptime = 0; 73} 74 75int pgp_valid_passphrase (void) 76{ 77 time_t now = time (NULL); 78 79 if (pgp_use_gpg_agent()) 80 { 81 *PgpPass = 0; 82 return 1; /* handled by gpg-agent */ 83 } 84 85 if (now < PgpExptime) 86 /* Use cached copy. */ 87 return 1; 88 89 pgp_void_passphrase (); 90 91 if (mutt_get_password (_("Enter PGP passphrase:"), PgpPass, sizeof (PgpPass)) == 0) 92 { 93 PgpExptime = time (NULL) + PgpTimeout; 94 return (1); 95 } 96 else 97 PgpExptime = 0; 98 99 return 0; 100} 101 102void pgp_forget_passphrase (void) 103{ 104 pgp_void_passphrase (); 105 mutt_message _("PGP passphrase forgotten."); 106} 107 108int pgp_use_gpg_agent (void) 109{ 110 char *tty; 111 112 /* GnuPG 2.1 no longer exports GPG_AGENT_INFO */ 113 if (!option (OPTUSEGPGAGENT)) 114 return 0; 115 116 if ((tty = ttyname(0))) 117 setenv("GPG_TTY", tty, 0); 118 119 return 1; 120} 121 122static pgp_key_t _pgp_parent(pgp_key_t k) 123{ 124 if((k->flags & KEYFLAG_SUBKEY) && k->parent && option(OPTPGPIGNORESUB)) 125 k = k->parent; 126 127 return k; 128} 129 130char *pgp_long_keyid(pgp_key_t k) 131{ 132 k = _pgp_parent(k); 133 134 return k->keyid; 135} 136 137char *pgp_short_keyid(pgp_key_t k) 138{ 139 k = _pgp_parent(k); 140 141 return k->keyid + 8; 142} 143 144char *pgp_keyid(pgp_key_t k) 145{ 146 k = _pgp_parent(k); 147 148 return _pgp_keyid(k); 149} 150 151char *_pgp_keyid(pgp_key_t k) 152{ 153 if(option(OPTPGPLONGIDS)) 154 return k->keyid; 155 else 156 return (k->keyid + 8); 157} 158 159char *pgp_fingerprint(pgp_key_t k) 160{ 161 k = _pgp_parent(k); 162 163 return k->fingerprint; 164} 165 166/* Grab the longest key identifier available: fingerprint or else 167 * the long keyid. 168 * 169 * The longest available should be used for internally identifying 170 * the key and for invoking pgp commands. 171 */ 172char *pgp_fpr_or_lkeyid(pgp_key_t k) 173{ 174 char *fingerprint; 175 176 fingerprint = pgp_fingerprint (k); 177 return fingerprint ? fingerprint : pgp_long_keyid (k); 178} 179 180/* ---------------------------------------------------------------------------- 181 * Routines for handing PGP input. 182 */ 183 184 185 186/* Copy PGP output messages and look for signs of a good signature */ 187 188static int pgp_copy_checksig (FILE *fpin, FILE *fpout) 189{ 190 int rv = -1; 191 192 if (PgpGoodSign.pattern) 193 { 194 char *line = NULL; 195 int lineno = 0; 196 size_t linelen; 197 198 while ((line = mutt_read_line (line, &linelen, fpin, &lineno, 0)) != NULL) 199 { 200 if (regexec (PgpGoodSign.rx, line, 0, NULL, 0) == 0) 201 { 202 dprint (2, (debugfile, "pgp_copy_checksig: \"%s\" matches regexp.\n", 203 line)); 204 rv = 0; 205 } 206 else 207 dprint (2, (debugfile, "pgp_copy_checksig: \"%s\" doesn't match regexp.\n", 208 line)); 209 210 if (strncmp (line, "[GNUPG:] ", 9) == 0) 211 continue; 212 fputs (line, fpout); 213 fputc ('\n', fpout); 214 } 215 FREE (&line); 216 } 217 else 218 { 219 dprint (2, (debugfile, "pgp_copy_checksig: No pattern.\n")); 220 mutt_copy_stream (fpin, fpout); 221 rv = 1; 222 } 223 224 return rv; 225} 226 227/* Checks PGP output messages to look for the $pgp_decryption_okay message. 228 * This protects against messages with multipart/encrypted headers 229 * but which aren't actually encrypted. See ticket #3770 230 */ 231static int pgp_check_decryption_okay (FILE *fpin) 232{ 233 int rv = -1; 234 235 if (PgpDecryptionOkay.pattern) 236 { 237 char *line = NULL; 238 int lineno = 0; 239 size_t linelen; 240 241 while ((line = mutt_read_line (line, &linelen, fpin, &lineno, 0)) != NULL) 242 { 243 if (regexec (PgpDecryptionOkay.rx, line, 0, NULL, 0) == 0) 244 { 245 dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" matches regexp.\n", 246 line)); 247 rv = 0; 248 break; 249 } 250 else 251 dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" doesn't match regexp.\n", 252 line)); 253 } 254 FREE (&line); 255 } 256 else 257 { 258 dprint (2, (debugfile, "pgp_check_decryption_okay: No pattern.\n")); 259 rv = 1; 260 } 261 262 return rv; 263} 264 265 266/* 267 * Copy a clearsigned message, and strip the signature and PGP's 268 * dash-escaping. 269 * 270 * XXX - charset handling: We assume that it is safe to do 271 * character set decoding first, dash decoding second here, while 272 * we do it the other way around in the main handler. 273 * 274 * (Note that we aren't worse than Outlook &c in this, and also 275 * note that we can successfully handle anything produced by any 276 * existing versions of mutt.) 277 */ 278 279static void pgp_copy_clearsigned (FILE *fpin, STATE *s, char *charset) 280{ 281 char buf[HUGE_STRING]; 282 short complete, armor_header; 283 284 FGETCONV *fc; 285 286 rewind (fpin); 287 288 /* fromcode comes from the MIME Content-Type charset label. It might 289 * be a wrong label, so we want the ability to do corrections via 290 * charset-hooks. Therefore we set flags to MUTT_ICONV_HOOK_FROM. 291 */ 292 fc = fgetconv_open (fpin, charset, Charset, MUTT_ICONV_HOOK_FROM); 293 294 for (complete = 1, armor_header = 1; 295 fgetconvs (buf, sizeof (buf), fc) != NULL; 296 complete = strchr (buf, '\n') != NULL) 297 { 298 if (!complete) 299 { 300 if (!armor_header) 301 state_puts (buf, s); 302 continue; 303 } 304 305 if (mutt_strcmp (buf, "-----BEGIN PGP SIGNATURE-----\n") == 0) 306 break; 307 308 if (armor_header) 309 { 310 char *p = mutt_skip_whitespace (buf); 311 if (*p == '\0') 312 armor_header = 0; 313 continue; 314 } 315 316 if (s->prefix) 317 state_puts (s->prefix, s); 318 319 if (buf[0] == '-' && buf[1] == ' ') 320 state_puts (buf + 2, s); 321 else 322 state_puts (buf, s); 323 } 324 325 fgetconv_close (&fc); 326} 327 328 329/* Support for the Application/PGP Content Type. */ 330 331int pgp_application_pgp_handler (BODY *m, STATE *s) 332{ 333 int could_not_decrypt = 0; 334 int needpass = -1, pgp_keyblock = 0; 335 int clearsign = 0, rv, rc; 336 int c = 1; /* silence GCC warning */ 337 long bytes; 338 LOFF_T last_pos, offset; 339 char buf[HUGE_STRING]; 340 char outfile[_POSIX_PATH_MAX]; 341 char tmpfname[_POSIX_PATH_MAX]; 342 FILE *pgpout = NULL, *pgpin = NULL, *pgperr = NULL; 343 FILE *tmpfp = NULL; 344 pid_t thepid; 345 346 short maybe_goodsig = 1; 347 short have_any_sigs = 0; 348 349 char *gpgcharset = NULL; 350 char body_charset[STRING]; 351 mutt_get_body_charset (body_charset, sizeof (body_charset), m); 352 353 rc = 0; /* silence false compiler warning if (s->flags & MUTT_DISPLAY) */ 354 355 fseeko (s->fpin, m->offset, 0); 356 last_pos = m->offset; 357 358 for (bytes = m->length; bytes > 0;) 359 { 360 if (fgets (buf, sizeof (buf), s->fpin) == NULL) 361 break; 362 363 offset = ftello (s->fpin); 364 bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */ 365 last_pos = offset; 366 367 if (mutt_strncmp ("-----BEGIN PGP ", buf, 15) == 0) 368 { 369 clearsign = 0; 370 371 if (mutt_strcmp ("MESSAGE-----\n", buf + 15) == 0) 372 needpass = 1; 373 else if (mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) 374 { 375 clearsign = 1; 376 needpass = 0; 377 } 378 else if (!mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15)) 379 { 380 needpass = 0; 381 pgp_keyblock = 1; 382 } 383 else 384 { 385 /* XXX - we may wish to recode here */ 386 if (s->prefix) 387 state_puts (s->prefix, s); 388 state_puts (buf, s); 389 continue; 390 } 391 392 have_any_sigs = have_any_sigs || (clearsign && (s->flags & MUTT_VERIFY)); 393 394 /* Copy PGP material to temporary file */ 395 mutt_mktemp (tmpfname, sizeof (tmpfname)); 396 if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL) 397 { 398 mutt_perror (tmpfname); 399 return -1; 400 } 401 402 fputs (buf, tmpfp); 403 while (bytes > 0 && fgets (buf, sizeof (buf) - 1, s->fpin) != NULL) 404 { 405 offset = ftello (s->fpin); 406 bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */ 407 last_pos = offset; 408 409 fputs (buf, tmpfp); 410 411 if ((needpass && mutt_strcmp ("-----END PGP MESSAGE-----\n", buf) == 0) || 412 (!needpass 413 && (mutt_strcmp ("-----END PGP SIGNATURE-----\n", buf) == 0 414 || mutt_strcmp ("-----END PGP PUBLIC KEY BLOCK-----\n",buf) == 0))) 415 break; 416 /* remember optional Charset: armor header as defined by RfC4880 */ 417 if (mutt_strncmp ("Charset: ", buf, 9) == 0) 418 { 419 size_t l = 0; 420 gpgcharset = safe_strdup (buf + 9); 421 if ((l = mutt_strlen (gpgcharset)) > 0 && gpgcharset[l-1] == '\n') 422 gpgcharset[l-1] = 0; 423 if (mutt_check_charset (gpgcharset, 0) < 0) 424 mutt_str_replace (&gpgcharset, "UTF-8"); 425 } 426 } 427 428 /* leave tmpfp open in case we still need it - but flush it! */ 429 fflush (tmpfp); 430 431 /* Invoke PGP if needed */ 432 if (!clearsign || (s->flags & MUTT_VERIFY)) 433 { 434 mutt_mktemp (outfile, sizeof (outfile)); 435 if ((pgpout = safe_fopen (outfile, "w+")) == NULL) 436 { 437 mutt_perror (outfile); 438 return -1; 439 } 440 441 if ((thepid = pgp_invoke_decode (&pgpin, NULL, &pgperr, -1, 442 fileno (pgpout), -1, tmpfname, 443 needpass)) == -1) 444 { 445 safe_fclose (&pgpout); 446 maybe_goodsig = 0; 447 pgpin = NULL; 448 pgperr = NULL; 449 state_attach_puts (_("[-- Error: unable to create PGP subprocess! --]\n"), s); 450 } 451 else /* PGP started successfully */ 452 { 453 if (needpass) 454 { 455 if (!pgp_valid_passphrase ()) pgp_void_passphrase(); 456 if (pgp_use_gpg_agent()) 457 *PgpPass = 0; 458 fprintf (pgpin, "%s\n", PgpPass); 459 } 460 461 safe_fclose (&pgpin); 462 463 if (s->flags & MUTT_DISPLAY) 464 { 465 crypt_current_time (s, "PGP"); 466 rc = pgp_copy_checksig (pgperr, s->fpout); 467 } 468 469 safe_fclose (&pgperr); 470 rv = mutt_wait_filter (thepid); 471 472 if (s->flags & MUTT_DISPLAY) 473 { 474 if (rc == 0) have_any_sigs = 1; 475 /* 476 * Sig is bad if 477 * gpg_good_sign-pattern did not match || pgp_decode_command returned not 0 478 * Sig _is_ correct if 479 * gpg_good_sign="" && pgp_decode_command returned 0 480 */ 481 if (rc == -1 || rv) maybe_goodsig = 0; 482 483 state_attach_puts (_("[-- End of PGP output --]\n\n"), s); 484 } 485 if (pgp_use_gpg_agent()) 486 mutt_need_hard_redraw (); 487 } 488 489 /* treat empty result as sign of failure */ 490 /* TODO: maybe on failure mutt should include the original undecoded text. */ 491 if (pgpout) 492 { 493 rewind (pgpout); 494 c = fgetc (pgpout); 495 ungetc (c, pgpout); 496 } 497 if (!clearsign && (!pgpout || c == EOF)) 498 { 499 could_not_decrypt = 1; 500 pgp_void_passphrase (); 501 } 502 503 if (could_not_decrypt && !(s->flags & MUTT_DISPLAY)) 504 { 505 mutt_error _("Could not decrypt PGP message"); 506 mutt_sleep (1); 507 rc = -1; 508 goto out; 509 } 510 } 511 512 /* 513 * Now, copy cleartext to the screen. 514 */ 515 516 if(s->flags & MUTT_DISPLAY) 517 { 518 if (needpass) 519 state_attach_puts (_("[-- BEGIN PGP MESSAGE --]\n\n"), s); 520 else if (pgp_keyblock) 521 state_attach_puts (_("[-- BEGIN PGP PUBLIC KEY BLOCK --]\n"), s); 522 else 523 state_attach_puts (_("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"), s); 524 } 525 526 if (clearsign) 527 { 528 rewind (tmpfp); 529 if (tmpfp) 530 pgp_copy_clearsigned (tmpfp, s, body_charset); 531 } 532 else if (pgpout) 533 { 534 FGETCONV *fc; 535 int c; 536 char *expected_charset = gpgcharset && *gpgcharset ? gpgcharset : "utf-8"; 537 538 dprint(4,(debugfile,"pgp: recoding inline from [%s] to [%s]\n", 539 expected_charset, Charset)); 540 541 rewind (pgpout); 542 state_set_prefix (s); 543 fc = fgetconv_open (pgpout, expected_charset, Charset, MUTT_ICONV_HOOK_FROM); 544 while ((c = fgetconv (fc)) != EOF) 545 state_prefix_putc (c, s); 546 fgetconv_close (&fc); 547 } 548 549 /* 550 * Multiple PGP blocks can exist, so these need to be closed and 551 * unlinked inside the loop. 552 */ 553 safe_fclose (&tmpfp); 554 mutt_unlink (tmpfname); 555 if (pgpout) 556 { 557 safe_fclose (&pgpout); 558 mutt_unlink (outfile); 559 } 560 561 if (s->flags & MUTT_DISPLAY) 562 { 563 state_putc ('\n', s); 564 if (needpass) 565 { 566 state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s); 567 if (could_not_decrypt) 568 mutt_error _("Could not decrypt PGP message"); 569 else 570 mutt_message _("PGP message successfully decrypted."); 571 } 572 else if (pgp_keyblock) 573 state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s); 574 else 575 state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s); 576 } 577 } 578 else 579 { 580 /* A traditional PGP part may mix signed and unsigned content */ 581 /* XXX - we may wish to recode here */ 582 if (s->prefix) 583 state_puts (s->prefix, s); 584 state_puts (buf, s); 585 } 586 } 587 588 rc = 0; 589 590out: 591 m->goodsig = (maybe_goodsig && have_any_sigs); 592 593 if (tmpfp) 594 { 595 safe_fclose (&tmpfp); 596 mutt_unlink (tmpfname); 597 } 598 if (pgpout) 599 { 600 safe_fclose (&pgpout); 601 mutt_unlink (outfile); 602 } 603 604 FREE(&gpgcharset); 605 606 if (needpass == -1) 607 { 608 state_attach_puts (_("[-- Error: could not find beginning of PGP message! --]\n\n"), s); 609 return -1; 610 } 611 612 return rc; 613} 614 615static int pgp_check_traditional_one_body (FILE *fp, BODY *b, int tagged_only) 616{ 617 char tempfile[_POSIX_PATH_MAX]; 618 char buf[HUGE_STRING]; 619 FILE *tfp; 620 621 short sgn = 0; 622 short enc = 0; 623 short key = 0; 624 625 if (b->type != TYPETEXT) 626 return 0; 627 628 if (tagged_only && !b->tagged) 629 return 0; 630 631 mutt_mktemp (tempfile, sizeof (tempfile)); 632 if (mutt_decode_save_attachment (fp, b, tempfile, 0, 0) != 0) 633 { 634 unlink (tempfile); 635 return 0; 636 } 637 638 if ((tfp = fopen (tempfile, "r")) == NULL) 639 { 640 unlink (tempfile); 641 return 0; 642 } 643 644 while (fgets (buf, sizeof (buf), tfp)) 645 { 646 if (mutt_strncmp ("-----BEGIN PGP ", buf, 15) == 0) 647 { 648 if (mutt_strcmp ("MESSAGE-----\n", buf + 15) == 0) 649 enc = 1; 650 else if (mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) 651 sgn = 1; 652 else if (mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) 653 key = 1; 654 } 655 } 656 safe_fclose (&tfp); 657 unlink (tempfile); 658 659 if (!enc && !sgn && !key) 660 return 0; 661 662 /* fix the content type */ 663 664 mutt_set_parameter ("format", "fixed", &b->parameter); 665 if (enc) 666 mutt_set_parameter ("x-action", "pgp-encrypted", &b->parameter); 667 else if (sgn) 668 mutt_set_parameter ("x-action", "pgp-signed", &b->parameter); 669 else if (key) 670 mutt_set_parameter ("x-action", "pgp-keys", &b->parameter); 671 672 return 1; 673} 674 675int pgp_check_traditional (FILE *fp, BODY *b, int tagged_only) 676{ 677 int rv = 0; 678 int r; 679 for (; b; b = b->next) 680 { 681 if (is_multipart (b)) 682 rv = pgp_check_traditional (fp, b->parts, tagged_only) || rv; 683 else if (b->type == TYPETEXT) 684 { 685 if ((r = mutt_is_application_pgp (b))) 686 rv = rv || r; 687 else 688 rv = pgp_check_traditional_one_body (fp, b, tagged_only) || rv; 689 } 690 } 691 692 return rv; 693} 694 695 696 697 698 699int pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) 700{ 701 char sigfile[_POSIX_PATH_MAX], pgperrfile[_POSIX_PATH_MAX]; 702 FILE *fp, *pgpout, *pgperr; 703 pid_t thepid; 704 int badsig = -1; 705 int rv; 706 707 snprintf (sigfile, sizeof (sigfile), "%s.asc", tempfile); 708 709 if(!(fp = safe_fopen (sigfile, "w"))) 710 { 711 mutt_perror(sigfile); 712 return -1; 713 } 714 715 fseeko (s->fpin, sigbdy->offset, 0); 716 mutt_copy_bytes (s->fpin, fp, sigbdy->length); 717 safe_fclose (&fp); 718 719 mutt_mktemp (pgperrfile, sizeof (pgperrfile)); 720 if(!(pgperr = safe_fopen(pgperrfile, "w+"))) 721 { 722 mutt_perror(pgperrfile); 723 unlink(sigfile); 724 return -1; 725 } 726 727 crypt_current_time (s, "PGP"); 728 729 if((thepid = pgp_invoke_verify (NULL, &pgpout, NULL, 730 -1, -1, fileno(pgperr), 731 tempfile, sigfile)) != -1) 732 { 733 if (pgp_copy_checksig (pgpout, s->fpout) >= 0) 734 badsig = 0; 735 736 737 safe_fclose (&pgpout); 738 fflush (pgperr); 739 rewind (pgperr); 740 741 if (pgp_copy_checksig (pgperr, s->fpout) >= 0) 742 badsig = 0; 743 744 if ((rv = mutt_wait_filter (thepid))) 745 badsig = -1; 746 747 dprint (1, (debugfile, "pgp_verify_one: mutt_wait_filter returned %d.\n", rv)); 748 } 749 750 safe_fclose (&pgperr); 751 752 state_attach_puts (_("[-- End of PGP output --]\n\n"), s); 753 754 mutt_unlink (sigfile); 755 mutt_unlink (pgperrfile); 756 757 dprint (1, (debugfile, "pgp_verify_one: returning %d.\n", badsig)); 758 759 return badsig; 760} 761 762 763/* Extract pgp public keys from messages or attachments */ 764 765void pgp_extract_keys_from_messages (HEADER *h) 766{ 767 int i; 768 char tempfname[_POSIX_PATH_MAX]; 769 FILE *fpout; 770 771 if (h) 772 { 773 mutt_parse_mime_message (Context, h); 774 if(h->security & PGPENCRYPT && !pgp_valid_passphrase ()) 775 return; 776 } 777 778 mutt_mktemp (tempfname, sizeof (tempfname)); 779 if (!(fpout = safe_fopen (tempfname, "w"))) 780 { 781 mutt_perror (tempfname); 782 return; 783 } 784 785 set_option (OPTDONTHANDLEPGPKEYS); 786 787 if (!h) 788 { 789 for (i = 0; i < Context->vcount; i++) 790 { 791 if (Context->hdrs[Context->v2r[i]]->tagged) 792 { 793 mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]); 794 if (Context->hdrs[Context->v2r[i]]->security & PGPENCRYPT 795 && !pgp_valid_passphrase()) 796 { 797 safe_fclose (&fpout); 798 goto bailout; 799 } 800 mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]], 801 MUTT_CM_DECODE|MUTT_CM_CHARCONV, 0); 802 } 803 } 804 } 805 else 806 { 807 mutt_parse_mime_message (Context, h); 808 if (h->security & PGPENCRYPT && !pgp_valid_passphrase()) 809 { 810 safe_fclose (&fpout); 811 goto bailout; 812 } 813 mutt_copy_message (fpout, Context, h, MUTT_CM_DECODE|MUTT_CM_CHARCONV, 0); 814 } 815 816 safe_fclose (&fpout); 817 mutt_endwin (NULL); 818 pgp_invoke_import (tempfname); 819 mutt_any_key_to_continue (NULL); 820 821 bailout: 822 823 mutt_unlink (tempfname); 824 unset_option (OPTDONTHANDLEPGPKEYS); 825 826} 827 828static void pgp_extract_keys_from_attachment (FILE *fp, BODY *top) 829{ 830 STATE s; 831 FILE *tempfp; 832 char tempfname[_POSIX_PATH_MAX]; 833 834 mutt_mktemp (tempfname, sizeof (tempfname)); 835 if (!(tempfp = safe_fopen (tempfname, "w"))) 836 { 837 mutt_perror (tempfname); 838 return; 839 } 840 841 memset (&s, 0, sizeof (STATE)); 842 843 s.fpin = fp; 844 s.fpout = tempfp; 845 846 mutt_body_handler (top, &s); 847 848 safe_fclose (&tempfp); 849 850 pgp_invoke_import (tempfname); 851 mutt_any_key_to_continue (NULL); 852 853 mutt_unlink (tempfname); 854} 855 856void pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top) 857{ 858 if(!fp) 859 { 860 mutt_error _("Internal error. Please submit a bug report."); 861 return; 862 } 863 864 mutt_endwin (NULL); 865 set_option(OPTDONTHANDLEPGPKEYS); 866 867 for(; top; top = top->next) 868 { 869 if(!tag || top->tagged) 870 pgp_extract_keys_from_attachment (fp, top); 871 872 if(!tag) 873 break; 874 } 875 876 unset_option(OPTDONTHANDLEPGPKEYS); 877} 878 879BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) 880{ 881 char buf[LONG_STRING]; 882 FILE *pgpin, *pgpout, *pgperr, *pgptmp; 883 struct stat info; 884 BODY *tattach; 885 int len; 886 char pgperrfile[_POSIX_PATH_MAX]; 887 char pgptmpfile[_POSIX_PATH_MAX]; 888 pid_t thepid; 889 int rv; 890 891 mutt_mktemp (pgperrfile, sizeof (pgperrfile)); 892 if ((pgperr = safe_fopen (pgperrfile, "w+")) == NULL) 893 { 894 mutt_perror (pgperrfile); 895 return NULL; 896 } 897 unlink (pgperrfile); 898 899 mutt_mktemp (pgptmpfile, sizeof (pgptmpfile)); 900 if((pgptmp = safe_fopen (pgptmpfile, "w")) == NULL) 901 { 902 mutt_perror (pgptmpfile); 903 safe_fclose (&pgperr); 904 return NULL; 905 } 906 907 /* Position the stream at the beginning of the body, and send the data to 908 * the temporary file. 909 */ 910 911 fseeko (s->fpin, a->offset, 0); 912 mutt_copy_bytes (s->fpin, pgptmp, a->length); 913 safe_fclose (&pgptmp); 914 915 if ((thepid = pgp_invoke_decrypt (&pgpin, &pgpout, NULL, -1, -1, 916 fileno (pgperr), pgptmpfile)) == -1) 917 { 918 safe_fclose (&pgperr); 919 unlink (pgptmpfile); 920 if (s->flags & MUTT_DISPLAY) 921 state_attach_puts (_("[-- Error: could not create a PGP subprocess! --]\n\n"), s); 922 return (NULL); 923 } 924 925 /* send the PGP passphrase to the subprocess. Never do this if the 926 agent is active, because this might lead to a passphrase send as 927 the message. */ 928 if (!pgp_use_gpg_agent()) 929 fputs (PgpPass, pgpin); 930 fputc ('\n', pgpin); 931 safe_fclose (&pgpin); 932 933 /* Read the output from PGP, and make sure to change CRLF to LF, otherwise 934 * read_mime_header has a hard time parsing the message. 935 */ 936 while (fgets (buf, sizeof (buf) - 1, pgpout) != NULL) 937 { 938 len = mutt_strlen (buf); 939 if (len > 1 && buf[len - 2] == '\r') 940 strcpy (buf + len - 2, "\n"); /* __STRCPY_CHECKED__ */ 941 fputs (buf, fpout); 942 } 943 944 safe_fclose (&pgpout); 945 rv = mutt_wait_filter (thepid); 946 mutt_unlink(pgptmpfile); 947 948 fflush (pgperr); 949 rewind (pgperr); 950 if (pgp_check_decryption_okay (pgperr) < 0) 951 { 952 mutt_error _("Decryption failed"); 953 pgp_void_passphrase (); 954 return NULL; 955 } 956 957 if (s->flags & MUTT_DISPLAY) 958 { 959 rewind (pgperr); 960 if (pgp_copy_checksig (pgperr, s->fpout) == 0 && !rv && p) 961 p->goodsig = 1; 962 else 963 p->goodsig = 0; 964 state_attach_puts (_("[-- End of PGP output --]\n\n"), s); 965 } 966 safe_fclose (&pgperr); 967 968 fflush (fpout); 969 rewind (fpout); 970 971 if (pgp_use_gpg_agent()) 972 mutt_need_hard_redraw (); 973 974 if (fgetc (fpout) == EOF) 975 { 976 mutt_error _("Decryption failed"); 977 pgp_void_passphrase (); 978 return NULL; 979 } 980 981 rewind (fpout); 982 983 if ((tattach = mutt_read_mime_header (fpout, 0)) != NULL) 984 { 985 /* 986 * Need to set the length of this body part. 987 */ 988 fstat (fileno (fpout), &info); 989 tattach->length = info.st_size - tattach->offset; 990 991 /* See if we need to recurse on this MIME part. */ 992 993 mutt_parse_part (fpout, tattach); 994 } 995 996 return (tattach); 997} 998 999int pgp_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) 1000{ 1001 char tempfile[_POSIX_PATH_MAX]; 1002 STATE s; 1003 BODY *p = b; 1004 int need_decode = 0; 1005 int saved_type; 1006 LOFF_T saved_offset; 1007 size_t saved_length; 1008 FILE *decoded_fp = NULL; 1009 int rv = 0; 1010 1011 if (mutt_is_valid_multipart_pgp_encrypted (b)) 1012 b = b->parts->next; 1013 else if (mutt_is_malformed_multipart_pgp_encrypted (b)) 1014 { 1015 b = b->parts->next->next; 1016 need_decode = 1; 1017 } 1018 else 1019 return -1; 1020 1021 memset (&s, 0, sizeof (s)); 1022 s.fpin = fpin; 1023 1024 if (need_decode) 1025 { 1026 saved_type = b->type; 1027 saved_offset = b->offset; 1028 saved_length = b->length; 1029 1030 mutt_mktemp (tempfile, sizeof (tempfile)); 1031 if ((decoded_fp = safe_fopen (tempfile, "w+")) == NULL) 1032 { 1033 mutt_perror (tempfile); 1034 return (-1); 1035 } 1036 unlink (tempfile); 1037 1038 fseeko (s.fpin, b->offset, 0); 1039 s.fpout = decoded_fp; 1040 1041 mutt_decode_attachment (b, &s); 1042 1043 fflush (decoded_fp); 1044 b->length = ftello (decoded_fp); 1045 b->offset = 0; 1046 rewind (decoded_fp); 1047 s.fpin = decoded_fp; 1048 s.fpout = 0; 1049 } 1050 1051 mutt_mktemp (tempfile, sizeof (tempfile)); 1052 if ((*fpout = safe_fopen (tempfile, "w+")) == NULL) 1053 { 1054 mutt_perror (tempfile); 1055 rv = -1; 1056 goto bail; 1057 } 1058 unlink (tempfile); 1059 1060 if ((*cur = pgp_decrypt_part (b, &s, *fpout, p)) == NULL) 1061 rv = -1; 1062 rewind (*fpout); 1063 1064bail: 1065 if (need_decode) 1066 { 1067 b->type = saved_type; 1068 b->length = saved_length; 1069 b->offset = saved_offset; 1070 safe_fclose (&decoded_fp); 1071 } 1072 1073 return rv; 1074} 1075 1076/* 1077 * This handler is passed the application/octet-stream directly. 1078 * The caller must propagate a->goodsig to its parent. 1079 */ 1080int pgp_encrypted_handler (BODY *a, STATE *s) 1081{ 1082 char tempfile[_POSIX_PATH_MAX]; 1083 FILE *fpout, *fpin; 1084 BODY *tattach; 1085 int rc = 0; 1086 1087 mutt_mktemp (tempfile, sizeof (tempfile)); 1088 if ((fpout = safe_fopen (tempfile, "w+")) == NULL) 1089 { 1090 if (s->flags & MUTT_DISPLAY) 1091 state_attach_puts (_("[-- Error: could not create temporary file! --]\n"), s); 1092 return -1; 1093 } 1094 1095 if (s->flags & MUTT_DISPLAY) crypt_current_time (s, "PGP"); 1096 1097 if ((tattach = pgp_decrypt_part (a, s, fpout, a)) != NULL) 1098 { 1099 if (s->flags & MUTT_DISPLAY) 1100 state_attach_puts (_("[-- The following data is PGP/MIME encrypted --]\n\n"), s); 1101 1102 fpin = s->fpin; 1103 s->fpin = fpout; 1104 rc = mutt_body_handler (tattach, s); 1105 s->fpin = fpin; 1106 1107 /* 1108 * if a multipart/signed is the _only_ sub-part of a 1109 * multipart/encrypted, cache signature verification 1110 * status. 1111 * 1112 */ 1113 1114 if (mutt_is_multipart_signed (tattach) && !tattach->next) 1115 a->goodsig |= tattach->goodsig; 1116 1117 if (s->flags & MUTT_DISPLAY) 1118 { 1119 state_puts ("\n", s); 1120 state_attach_puts (_("[-- End of PGP/MIME encrypted data --]\n"), s); 1121 } 1122 1123 mutt_free_body (&tattach); 1124 /* clear 'Invoking...' message, since there's no error */ 1125 mutt_message _("PGP message successfully decrypted."); 1126 } 1127 else 1128 { 1129 mutt_error _("Could not decrypt PGP message"); 1130 mutt_sleep (2); 1131 /* void the passphrase, even if it's not necessarily the problem */ 1132 pgp_void_passphrase (); 1133 rc = -1; 1134 } 1135 1136 safe_fclose (&fpout); 1137 mutt_unlink(tempfile); 1138 1139 return rc; 1140} 1141 1142/* ---------------------------------------------------------------------------- 1143 * Routines for sending PGP/MIME messages. 1144 */ 1145 1146 1147BODY *pgp_sign_message (BODY *a) 1148{ 1149 BODY *t; 1150 char buffer[LONG_STRING]; 1151 char sigfile[_POSIX_PATH_MAX], signedfile[_POSIX_PATH_MAX]; 1152 FILE *pgpin, *pgpout, *pgperr, *fp, *sfp; 1153 int err = 0; 1154 int empty = 1; 1155 pid_t thepid; 1156 1157 convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ 1158 1159 mutt_mktemp (sigfile, sizeof (sigfile)); 1160 if ((fp = safe_fopen (sigfile, "w")) == NULL) 1161 { 1162 return (NULL); 1163 } 1164 1165 mutt_mktemp (signedfile, sizeof (signedfile)); 1166 if ((sfp = safe_fopen(signedfile, "w")) == NULL) 1167 { 1168 mutt_perror(signedfile); 1169 safe_fclose (&fp); 1170 unlink(sigfile); 1171 return NULL; 1172 } 1173 1174 mutt_write_mime_header (a, sfp); 1175 fputc ('\n', sfp); 1176 mutt_write_mime_body (a, sfp); 1177 safe_fclose (&sfp); 1178 1179 if ((thepid = pgp_invoke_sign (&pgpin, &pgpout, &pgperr, 1180 -1, -1, -1, signedfile)) == -1) 1181 { 1182 mutt_perror _("Can't open PGP subprocess!"); 1183 safe_fclose (&fp); 1184 unlink(sigfile); 1185 unlink(signedfile); 1186 return NULL; 1187 } 1188 1189 if (!pgp_use_gpg_agent()) 1190 fputs(PgpPass, pgpin); 1191 fputc('\n', pgpin); 1192 safe_fclose (&pgpin); 1193 1194 /* 1195 * Read back the PGP signature. Also, change MESSAGE=>SIGNATURE as 1196 * recommended for future releases of PGP. 1197 */ 1198 while (fgets (buffer, sizeof (buffer) - 1, pgpout) != NULL) 1199 { 1200 if (mutt_strcmp ("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) 1201 fputs ("-----BEGIN PGP SIGNATURE-----\n", fp); 1202 else if (mutt_strcmp("-----END PGP MESSAGE-----\n", buffer) == 0) 1203 fputs ("-----END PGP SIGNATURE-----\n", fp); 1204 else 1205 fputs (buffer, fp); 1206 empty = 0; /* got some output, so we're ok */ 1207 } 1208 1209 /* check for errors from PGP */ 1210 err = 0; 1211 while (fgets (buffer, sizeof (buffer) - 1, pgperr) != NULL) 1212 { 1213 err = 1; 1214 fputs (buffer, stdout); 1215 } 1216 1217 if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) 1218 empty=1; 1219 1220 safe_fclose (&pgperr); 1221 safe_fclose (&pgpout); 1222 unlink (signedfile); 1223 1224 if (fclose (fp) != 0) 1225 { 1226 mutt_perror ("fclose"); 1227 unlink (sigfile); 1228 return (NULL); 1229 } 1230 1231 if (err) 1232 mutt_any_key_to_continue (NULL); 1233 if (empty) 1234 { 1235 unlink (sigfile); 1236 /* most likely error is a bad passphrase, so automatically forget it */ 1237 pgp_void_passphrase (); 1238 return (NULL); /* fatal error while signing */ 1239 } 1240 1241 t = mutt_new_body (); 1242 t->type = TYPEMULTIPART; 1243 t->subtype = safe_strdup ("signed"); 1244 t->encoding = ENC7BIT; 1245 t->use_disp = 0; 1246 t->disposition = DISPINLINE; 1247 1248 mutt_generate_boundary (&t->parameter); 1249 mutt_set_parameter ("protocol", "application/pgp-signature", &t->parameter); 1250 mutt_set_parameter ("micalg", pgp_micalg (sigfile), &t->parameter); 1251 1252 t->parts = a; 1253 a = t; 1254 1255 t->parts->next = mutt_new_body (); 1256 t = t->parts->next; 1257 t->type = TYPEAPPLICATION; 1258 t->subtype = safe_strdup ("pgp-signature"); 1259 t->filename = safe_strdup (sigfile); 1260 t->use_disp = 0; 1261 t->disposition = DISPNONE; 1262 t->encoding = ENC7BIT; 1263 t->unlink = 1; /* ok to remove this file after sending. */ 1264 mutt_set_parameter ("name", "signature.asc", &t->parameter); 1265 1266 return (a); 1267} 1268 1269/* This routine attempts to find the keyids of the recipients of a message. 1270 * It returns NULL if any of the keys can not be found. 1271 * If oppenc_mode is true, only keys that can be determined without 1272 * prompting will be used. 1273 */ 1274char *pgp_findKeys (ADDRESS *adrlist, int oppenc_mode) 1275{ 1276 LIST *crypt_hook_list, *crypt_hook = NULL; 1277 char *keyID, *keylist = NULL; 1278 size_t keylist_size = 0; 1279 size_t keylist_used = 0; 1280 ADDRESS *addr = NULL; 1281 ADDRESS *p, *q; 1282 pgp_key_t k_info = NULL; 1283 char buf[LONG_STRING]; 1284 int r; 1285 int key_selected; 1286 1287 const char *fqdn = mutt_fqdn (1); 1288 1289 for (p = adrlist; p ; p = p->next) 1290 { 1291 key_selected = 0; 1292 crypt_hook_list = crypt_hook = mutt_crypt_hook (p); 1293 do 1294 { 1295 q = p; 1296 k_info = NULL; 1297 1298 if (crypt_hook != NULL) 1299 { 1300 keyID = crypt_hook->data; 1301 r = MUTT_YES; 1302 if (! oppenc_mode && option(OPTCRYPTCONFIRMHOOK)) 1303 { 1304 snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox); 1305 r = mutt_yesorno (buf, MUTT_YES); 1306 } 1307 if (r == MUTT_YES) 1308 { 1309 if (crypt_is_numerical_keyid (keyID)) 1310 { 1311 if (strncmp (keyID, "0x", 2) == 0) 1312 keyID += 2; 1313 goto bypass_selection; /* you don't see this. */ 1314 } 1315 1316 /* check for e-mail address */ 1317 if (strchr (keyID, '@') && 1318 (addr = rfc822_parse_adrlist (NULL, keyID))) 1319 { 1320 if (fqdn) rfc822_qualify (addr, fqdn); 1321 q = addr; 1322 } 1323 else if (! oppenc_mode) 1324 { 1325 k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING); 1326 } 1327 } 1328 else if (r == MUTT_NO) 1329 { 1330 if (key_selected || (crypt_hook->next != NULL)) 1331 { 1332 crypt_hook = crypt_hook->next; 1333 continue; 1334 } 1335 } 1336 else if (r == -1) 1337 { 1338 FREE (&keylist); 1339 rfc822_free_address (&addr); 1340 mutt_free_list (&crypt_hook_list); 1341 return NULL; 1342 } 1343 } 1344 1345 if (k_info == NULL) 1346 { 1347 pgp_invoke_getkeys (q); 1348 k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING, oppenc_mode); 1349 } 1350 1351 if ((k_info == NULL) && (! oppenc_mode)) 1352 { 1353 snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); 1354 k_info = pgp_ask_for_key (buf, q->mailbox, 1355 KEYFLAG_CANENCRYPT, PGP_PUBRING); 1356 } 1357 1358 if (k_info == NULL) 1359 { 1360 FREE (&keylist); 1361 rfc822_free_address (&addr); 1362 mutt_free_list (&crypt_hook_list); 1363 return NULL; 1364 } 1365 1366 keyID = pgp_fpr_or_lkeyid (k_info); 1367 1368 bypass_selection: 1369 keylist_size += mutt_strlen (keyID) + 4; 1370 safe_realloc (&keylist, keylist_size); 1371 sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */ 1372 keyID); 1373 keylist_used = mutt_strlen (keylist); 1374 1375 key_selected = 1; 1376 1377 pgp_free_key (&k_info); 1378 rfc822_free_address (&addr); 1379 1380 if (crypt_hook != NULL) 1381 crypt_hook = crypt_hook->next; 1382 1383 } while (crypt_hook != NULL); 1384 1385 mutt_free_list (&crypt_hook_list); 1386 } 1387 return (keylist); 1388} 1389 1390/* Warning: "a" is no longer freed in this routine, you need 1391 * to free it later. This is necessary for $fcc_attach. */ 1392 1393BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) 1394{ 1395 char buf[LONG_STRING]; 1396 char tempfile[_POSIX_PATH_MAX], pgperrfile[_POSIX_PATH_MAX]; 1397 char pgpinfile[_POSIX_PATH_MAX]; 1398 FILE *pgpin, *pgperr, *fpout, *fptmp; 1399 BODY *t; 1400 int err = 0; 1401 int empty = 0; 1402 pid_t thepid; 1403 1404 mutt_mktemp (tempfile, sizeof (tempfile)); 1405 if ((fpout = safe_fopen (tempfile, "w+")) == NULL) 1406 { 1407 mutt_perror (tempfile); 1408 return (NULL); 1409 } 1410 1411 mutt_mktemp (pgperrfile, sizeof (pgperrfile)); 1412 if ((pgperr = safe_fopen (pgperrfile, "w+")) == NULL) 1413 { 1414 mutt_perror (pgperrfile); 1415 unlink(tempfile); 1416 safe_fclose (&fpout); 1417 return NULL; 1418 } 1419 unlink (pgperrfile); 1420 1421 mutt_mktemp (pgpinfile, sizeof (pgpinfile)); 1422 if((fptmp = safe_fopen(pgpinfile, "w")) == NULL) 1423 { 1424 mutt_perror(pgpinfile); 1425 unlink(tempfile); 1426 safe_fclose (&fpout); 1427 safe_fclose (&pgperr); 1428 return NULL; 1429 } 1430 1431 if (sign) 1432 convert_to_7bit (a); 1433 1434 mutt_write_mime_header (a, fptmp); 1435 fputc ('\n', fptmp); 1436 mutt_write_mime_body (a, fptmp); 1437 safe_fclose (&fptmp); 1438 1439 if ((thepid = pgp_invoke_encrypt (&pgpin, NULL, NULL, -1, 1440 fileno (fpout), fileno (pgperr), 1441 pgpinfile, keylist, sign)) == -1) 1442 { 1443 safe_fclose (&pgperr); 1444 unlink(pgpinfile); 1445 return (NULL); 1446 } 1447 1448 if (sign) 1449 { 1450 if (!pgp_use_gpg_agent()) 1451 fputs (PgpPass, pgpin); 1452 fputc ('\n', pgpin); 1453 } 1454 safe_fclose (&pgpin); 1455 1456 if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) 1457 empty=1; 1458 1459 unlink(pgpinfile); 1460 1461 fflush (fpout); 1462 rewind (fpout); 1463 if(!empty) 1464 empty = (fgetc (fpout) == EOF); 1465 safe_fclose (&fpout); 1466 1467 fflush (pgperr); 1468 rewind (pgperr); 1469 while (fgets (buf, sizeof (buf) - 1, pgperr) != NULL) 1470 { 1471 err = 1; 1472 fputs (buf, stdout); 1473 } 1474 safe_fclose (&pgperr); 1475 1476 /* pause if there is any error output from PGP */ 1477 if (err) 1478 mutt_any_key_to_continue (NULL); 1479 1480 if (empty) 1481 { 1482 /* fatal error while trying to encrypt message */ 1483 if (sign) 1484 pgp_void_passphrase (); /* just in case */ 1485 unlink (tempfile); 1486 return (NULL); 1487 } 1488 1489 t = mutt_new_body (); 1490 t->type = TYPEMULTIPART; 1491 t->subtype = safe_strdup ("encrypted"); 1492 t->encoding = ENC7BIT; 1493 t->use_disp = 0; 1494 t->disposition = DISPINLINE; 1495 1496 mutt_generate_boundary(&t->parameter); 1497 mutt_set_parameter("protocol", "application/pgp-encrypted", &t->parameter); 1498 1499 t->parts = mutt_new_body (); 1500 t->parts->type = TYPEAPPLICATION; 1501 t->parts->subtype = safe_strdup ("pgp-encrypted"); 1502 t->parts->encoding = ENC7BIT; 1503 1504 t->parts->next = mutt_new_body (); 1505 t->parts->next->type = TYPEAPPLICATION; 1506 t->parts->next->subtype = safe_strdup ("octet-stream"); 1507 t->parts->next->encoding = ENC7BIT; 1508 t->parts->next->filename = safe_strdup (tempfile); 1509 t->parts->next->use_disp = 1; 1510 t->parts->next->disposition = DISPATTACH; 1511 t->parts->next->unlink = 1; /* delete after sending the message */ 1512 t->parts->next->d_filename = safe_strdup ("msg.asc"); /* non pgp/mime can save */ 1513 1514 return (t); 1515} 1516 1517BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) 1518{ 1519 BODY *b; 1520 1521 char pgpoutfile[_POSIX_PATH_MAX]; 1522 char pgperrfile[_POSIX_PATH_MAX]; 1523 char pgpinfile[_POSIX_PATH_MAX]; 1524 1525 char body_charset[STRING]; 1526 char *from_charset; 1527 const char *send_charset; 1528 1529 FILE *pgpout = NULL, *pgperr = NULL, *pgpin = NULL; 1530 FILE *fp; 1531 1532 int empty = 0; 1533 int err; 1534 1535 char buff[STRING]; 1536 1537 pid_t thepid; 1538 1539 if (a->type != TYPETEXT) 1540 return NULL; 1541 if (ascii_strcasecmp (a->subtype, "plain")) 1542 return NULL; 1543 1544 if ((fp = fopen (a->filename, "r")) == NULL) 1545 { 1546 mutt_perror (a->filename); 1547 return NULL; 1548 } 1549 1550 mutt_mktemp (pgpinfile, sizeof (pgpinfile)); 1551 if ((pgpin = safe_fopen (pgpinfile, "w")) == NULL) 1552 { 1553 mutt_perror (pgpinfile); 1554 safe_fclose (&fp); 1555 return NULL; 1556 } 1557 1558 /* The following code is really correct: If noconv is set, 1559 * a's charset parameter contains the on-disk character set, and 1560 * we have to convert from that to utf-8. If noconv is not set, 1561 * we have to convert from $charset to utf-8. 1562 */ 1563 1564 mutt_get_body_charset (body_charset, sizeof (body_charset), a); 1565 if (a->noconv) 1566 from_charset = body_charset; 1567 else 1568 from_charset = Charset; 1569 1570 if (!mutt_is_us_ascii (body_charset)) 1571 { 1572 int c; 1573 FGETCONV *fc; 1574 1575 if (flags & ENCRYPT) 1576 send_charset = "us-ascii"; 1577 else 1578 send_charset = "utf-8"; 1579 1580 /* fromcode is assumed to be correct: we set flags to 0 */ 1581 fc = fgetconv_open (fp, from_charset, "utf-8", 0); 1582 while ((c = fgetconv (fc)) != EOF) 1583 fputc (c, pgpin); 1584 1585 fgetconv_close (&fc); 1586 } 1587 else 1588 { 1589 send_charset = "us-ascii"; 1590 mutt_copy_stream (fp, pgpin); 1591 } 1592 safe_fclose (&fp); 1593 safe_fclose (&pgpin); 1594 1595 mutt_mktemp (pgpoutfile, sizeof (pgpoutfile)); 1596 mutt_mktemp (pgperrfile, sizeof (pgperrfile)); 1597 if ((pgpout = safe_fopen (pgpoutfile, "w+")) == NULL || 1598 (pgperr = safe_fopen (pgperrfile, "w+")) == NULL) 1599 { 1600 mutt_perror (pgpout ? pgperrfile : pgpoutfile); 1601 unlink (pgpinfile); 1602 if (pgpout) 1603 { 1604 safe_fclose (&pgpout); 1605 unlink (pgpoutfile); 1606 } 1607 return NULL; 1608 } 1609 1610 unlink (pgperrfile); 1611 1612 if ((thepid = pgp_invoke_traditional (&pgpin, NULL, NULL, 1613 -1, fileno (pgpout), fileno (pgperr), 1614 pgpinfile, keylist, flags)) == -1) 1615 { 1616 mutt_perror _("Can't invoke PGP"); 1617 safe_fclose (&pgpout); 1618 safe_fclose (&pgperr); 1619 mutt_unlink (pgpinfile); 1620 unlink (pgpoutfile); 1621 return NULL; 1622 } 1623 1624 if (pgp_use_gpg_agent()) 1625 *PgpPass = 0; 1626 if (flags & SIGN) 1627 fprintf (pgpin, "%s\n", PgpPass); 1628 safe_fclose (&pgpin); 1629 1630 if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) 1631 empty=1; 1632 1633 mutt_unlink (pgpinfile); 1634 1635 fflush (pgpout); 1636 fflush (pgperr); 1637 1638 rewind (pgpout); 1639 rewind (pgperr); 1640 1641 if(!empty) 1642 empty = (fgetc (pgpout) == EOF); 1643 safe_fclose (&pgpout); 1644 1645 err = 0; 1646 1647 while (fgets (buff, sizeof (buff), pgperr)) 1648 { 1649 err = 1; 1650 fputs (buff, stdout); 1651 } 1652 1653 safe_fclose (&pgperr); 1654 1655 if (err) 1656 mutt_any_key_to_continue (NULL); 1657 1658 if (empty) 1659 { 1660 if (flags & SIGN) 1661 pgp_void_passphrase (); /* just in case */ 1662 unlink (pgpoutfile); 1663 return NULL; 1664 } 1665 1666 b = mutt_new_body (); 1667 1668 b->encoding = ENC7BIT; 1669 1670 b->type = TYPETEXT; 1671 b->subtype = safe_strdup ("plain"); 1672 1673 mutt_set_parameter ("x-action", flags & ENCRYPT ? "pgp-encrypted" : "pgp-signed", 1674 &b->parameter); 1675 mutt_set_parameter ("charset", send_charset, &b->parameter); 1676 1677 b->filename = safe_strdup (pgpoutfile); 1678 1679#if 0 1680 /* The following is intended to give a clue to some completely brain-dead 1681 * "mail environments" which are typically used by large corporations. 1682 */ 1683 1684 b->d_filename = safe_strdup ("msg.pgp"); 1685 b->use_disp = 1; 1686 1687#endif 1688 1689 b->disposition = DISPNONE; 1690 b->unlink = 1; 1691 1692 b->noconv = 1; 1693 b->use_disp = 0; 1694 1695 if (!(flags & ENCRYPT)) 1696 b->encoding = a->encoding; 1697 1698 return b; 1699} 1700 1701int pgp_send_menu (HEADER *msg, int *redraw) 1702{ 1703 pgp_key_t p; 1704 char input_signas[SHORT_STRING]; 1705 char *prompt, *letters, *choices; 1706 char promptbuf[LONG_STRING]; 1707 int choice; 1708 1709 if (!(WithCrypto & APPLICATION_PGP)) 1710 return msg->security; 1711 1712 /* If autoinline and no crypto options set, then set inline. */ 1713 if (option (OPTPGPAUTOINLINE) && 1714 !((msg->security & APPLICATION_PGP) && (msg->security & (SIGN|ENCRYPT)))) 1715 msg->security |= INLINE; 1716 1717 msg->security |= APPLICATION_PGP; 1718 1719 /* 1720 * Opportunistic encrypt is controlling encryption. Allow to toggle 1721 * between inline and mime, but not turn encryption on or off. 1722 * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different 1723 * letter choices for those. 1724 */ 1725 if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT)) 1726 { 1727 if (msg->security & (ENCRYPT | SIGN)) 1728 { 1729 snprintf (promptbuf, sizeof (promptbuf), 1730 _("PGP (s)ign, sign (a)s, %s format, (c)lear, or (o)ppenc mode off? "), 1731 (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline")); 1732 prompt = promptbuf; 1733 /* L10N: The 'f' is from "forget it", an old undocumented synonym of 1734 'clear'. Please use a corresponding letter in your language. 1735 Alternatively, you may duplicate the letter 'c' is translated to. 1736 This comment also applies to the five following letter sequences. */ 1737 letters = _("safcoi"); 1738 choices = "SaFCoi"; 1739 } 1740 else 1741 { 1742 prompt = _("PGP (s)ign, sign (a)s, (c)lear, or (o)ppenc mode off? "); 1743 letters = _("safco"); 1744 choices = "SaFCo"; 1745 } 1746 } 1747 /* 1748 * Opportunistic encryption option is set, but is toggled off 1749 * for this message. 1750 */ 1751 else if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) 1752 { 1753 /* When the message is not selected for signing or encryption, the toggle 1754 * between PGP/MIME and Traditional doesn't make sense. 1755 */ 1756 if (msg->security & (ENCRYPT | SIGN)) 1757 { 1758 1759 snprintf (promptbuf, sizeof (promptbuf), 1760 _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, (c)lear, or (o)ppenc mode? "), 1761 (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline")); 1762 prompt = promptbuf; 1763 letters = _("esabfcoi"); 1764 choices = "esabfcOi"; 1765 } 1766 else 1767 { 1768 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode? "); 1769 letters = _("esabfco"); 1770 choices = "esabfcO"; 1771 } 1772 } 1773 /* 1774 * Opportunistic encryption is unset 1775 */ 1776 else 1777 { 1778 if (msg->security & (ENCRYPT | SIGN)) 1779 { 1780 1781 snprintf (promptbuf, sizeof (promptbuf), 1782 _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, or (c)lear? "), 1783 (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline")); 1784 prompt = promptbuf; 1785 letters = _("esabfci"); 1786 choices = "esabfci"; 1787 } 1788 else 1789 { 1790 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, or (c)lear? "); 1791 letters = _("esabfc"); 1792 choices = "esabfc"; 1793 } 1794 } 1795 1796 choice = mutt_multi_choice (prompt, letters); 1797 if (choice > 0) 1798 { 1799 switch (choices[choice - 1]) 1800 { 1801 case 'e': /* (e)ncrypt */ 1802 msg->security |= ENCRYPT; 1803 msg->security &= ~SIGN; 1804 break; 1805 1806 case 's': /* (s)ign */ 1807 msg->security &= ~ENCRYPT; 1808 msg->security |= SIGN; 1809 break; 1810 1811 case 'S': /* (s)ign in oppenc mode */ 1812 msg->security |= SIGN; 1813 break; 1814 1815 case 'a': /* sign (a)s */ 1816 unset_option(OPTPGPCHECKTRUST); 1817 1818 if ((p = pgp_ask_for_key (_("Sign as: "), NULL, 0, PGP_SECRING))) 1819 { 1820 snprintf (input_signas, sizeof (input_signas), "0x%s", 1821 pgp_fpr_or_lkeyid (p)); 1822 mutt_str_replace (&PgpSignAs, input_signas); 1823 pgp_free_key (&p); 1824 1825 msg->security |= SIGN; 1826 1827 crypt_pgp_void_passphrase (); /* probably need a different passphrase */ 1828 } 1829 *redraw = REDRAW_FULL; 1830 break; 1831 1832 case 'b': /* (b)oth */ 1833 msg->security |= (ENCRYPT | SIGN); 1834 break; 1835 1836 case 'f': /* (f)orget it: kept for backward compatibility. */ 1837 case 'c': /* (c)lear */ 1838 msg->security &= ~(ENCRYPT | SIGN); 1839 break; 1840 1841 case 'F': /* (f)orget it or (c)lear in oppenc mode */ 1842 case 'C': 1843 msg->security &= ~SIGN; 1844 break; 1845 1846 case 'O': /* oppenc mode on */ 1847 msg->security |= OPPENCRYPT; 1848 crypt_opportunistic_encrypt (msg); 1849 break; 1850 1851 case 'o': /* oppenc mode off */ 1852 msg->security &= ~OPPENCRYPT; 1853 break; 1854 1855 case 'i': /* toggle (i)nline */ 1856 msg->security ^= INLINE; 1857 break; 1858 } 1859 } 1860 1861 return (msg->security); 1862} 1863 1864 1865#endif /* CRYPT_BACKEND_CLASSIC_PGP */